Many applications explicitly set SCHED_NORMAL on threads thus undoing the
usefulness of the SCHED_ISO, SCHED_BATCH and SCHED_IDLEPRIO policies.

For unprivileged users:

Only allow non realtime policies to be downgraded from ISO->BATCH->IDLEPRIO
but not back to NORMAL.

Signed-off-by: Con Kolivas <kernel@kolivas.org>

---
 kernel/sched.c |   26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)

Index: linux-2.6.22-rc4-ck1/kernel/sched.c
===================================================================
--- linux-2.6.22-rc4-ck1.orig/kernel/sched.c	2007-06-10 21:59:54.000000000 +1000
+++ linux-2.6.22-rc4-ck1/kernel/sched.c	2007-06-10 21:59:54.000000000 +1000
@@ -4536,6 +4536,31 @@ recheck:
 			if (param->sched_priority > p->rt_priority &&
 			    param->sched_priority > rlim_rtprio)
 				return -EPERM;
+		} else {
+			switch (p->policy) {
+				/*
+				 * Can only downgrade policies but not back to
+				 * SCHED_NORMAL
+				 */
+				case SCHED_ISO:
+					if (policy == SCHED_ISO)
+						goto out;
+					if (policy == SCHED_NORMAL)
+						return -EPERM;
+					break;
+				case SCHED_BATCH:
+					if (policy == SCHED_BATCH)
+						goto out;
+					if (policy != SCHED_IDLEPRIO)
+					    	return -EPERM;
+					break;
+				case SCHED_IDLEPRIO:
+					if (policy == SCHED_IDLEPRIO)
+						goto out;
+					return -EPERM;
+				default:
+					break;
+			}
 		}
 
 		/* can't change other user's priorities */
@@ -4592,6 +4617,7 @@ recheck:
 
 	rt_mutex_adjust_pi(p);
 
+out:
 	return 0;
 }
 EXPORT_SYMBOL_GPL(sched_setscheduler);
