Index: linux-2.6.12-rc6-ck2/include/linux/sched.h
===================================================================
--- linux-2.6.12-rc6-ck2.orig/include/linux/sched.h	2005-06-11 22:18:44.000000000 +1000
+++ linux-2.6.12-rc6-ck2/include/linux/sched.h	2005-06-11 22:18:45.000000000 +1000
@@ -134,9 +134,10 @@ extern unsigned long nr_iowait(void);
 #define SCHED_FIFO		1
 #define SCHED_RR		2
 #define SCHED_BATCH		3
+#define SCHED_ISO		4
 
 #define SCHED_MIN		0
-#define SCHED_MAX		3
+#define SCHED_MAX		4
 
 #define SCHED_RANGE(policy)	((policy) >= SCHED_MIN && \
 					(policy) <= SCHED_MAX)
@@ -407,6 +408,7 @@ struct signal_struct {
 
 #define rt_task(p)		(unlikely((p)->prio < MAX_RT_PRIO))
 #define batch_task(p)		((p)->policy == SCHED_BATCH)
+#define iso_task(p)		((p)->policy == SCHED_ISO)
 
 /*
  * Some day this will be a full-fledged user tracking system..
Index: linux-2.6.12-rc6-ck2/kernel/sched.c
===================================================================
--- linux-2.6.12-rc6-ck2.orig/kernel/sched.c	2005-06-11 22:18:44.000000000 +1000
+++ linux-2.6.12-rc6-ck2/kernel/sched.c	2005-06-11 22:18:45.000000000 +1000
@@ -523,11 +523,18 @@ static inline void __activate_idle_task(
  */
 static inline unsigned int burst(task_t *p)
 {
+	unsigned int burst = p->burst;
+
 	if (likely(!rt_task(p))) {
 		unsigned int task_user_prio = TASK_USER_PRIO(p);
-		return 39 - task_user_prio;
-	} else
-		return p->burst;
+		burst = 39 - task_user_prio;
+		if (iso_task(p)) {
+			burst <<= 1;
+			if (burst > 39)
+				burst = 39;
+		}
+	}
+	return burst;
 }
 
 static void inc_burst(task_t *p)
@@ -551,6 +558,11 @@ static inline unsigned int rr_interval(t
 
 	if (nice < 0 && !rt_task(p))
 		rr_interval += -(nice);
+	if (iso_task(p)) {
+		rr_interval = rr_interval / 2 ? : 1;
+		if (nice < 0)
+			rr_interval += -(nice << 1);
+	}
 	return rr_interval;
 }
 
@@ -604,7 +616,7 @@ static int effective_prio(task_t *p)
 	if (p->burst > best_burst)
 		p->burst = best_burst;
 	first_slice = rr;
-	if (sched_interactive && !sched_compute && p->mm)
+	if (sched_interactive && !sched_compute && p->mm && !iso_task(p))
 		first_slice *= (p->burst + 1);
 	prio = MAX_PRIO - 2 - best_burst;
 
@@ -3226,9 +3238,19 @@ int sched_setscheduler(struct task_struc
 {
 	int retval;
 	int queued, oldprio, oldpolicy = -1;
+	struct sched_param zero_param = { .sched_priority = 0 };
 	unsigned long flags;
 	runqueue_t *rq;
 
+	if (SCHED_RT(policy) && !capable(CAP_SYS_NICE)) {
+		/*
+		 * If the caller requested an RT policy without having the
+		 * necessary rights, we downgrade the policy to SCHED_ISO.
+		 * We also set the parameter to zero to pass the checks.
+		 */
+		policy = SCHED_ISO;
+		param = &zero_param;
+	}
 recheck:
 	/* double check policy once rq lock held */
 	if (policy < 0)
@@ -3701,6 +3723,7 @@ asmlinkage long sys_sched_get_priority_m
 		break;
 	case SCHED_NORMAL:
 	case SCHED_BATCH:
+	case SCHED_ISO:
 		ret = 0;
 		break;
 	}
@@ -3725,6 +3748,7 @@ asmlinkage long sys_sched_get_priority_m
 		break;
 	case SCHED_NORMAL:
 	case SCHED_BATCH:
+	case SCHED_ISO:
 		ret = 0;
 	}
 	return ret;

