From: Andy Lutomirski Date: Wed, 16 Mar 2016 21:14:22 +0000 (-0700) Subject: x86/iopl: Fix iopl capability check on Xen PV X-Git-Tag: v3.2.80~74 X-Git-Url: https://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-kernel.git;a=commitdiff_plain;h=64731eb996c201464143d6ee701c3ff2e95c1a2c x86/iopl: Fix iopl capability check on Xen PV commit c29016cf41fe9fa994a5ecca607cf5f1cd98801e upstream. iopl(3) is supposed to work if iopl is already 3, even if unprivileged. This didn't work right on Xen PV. Fix it. Reviewewd-by: Jan Beulich Signed-off-by: Andy Lutomirski Cc: Andrew Cooper Cc: Andy Lutomirski Cc: Boris Ostrovsky Cc: Borislav Petkov Cc: Brian Gerst Cc: David Vrabel Cc: Denys Vlasenko Cc: H. Peter Anvin Cc: Jan Beulich Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/8ce12013e6e4c0a44a97e316be4a6faff31bd5ea.1458162709.git.luto@kernel.org Signed-off-by: Ingo Molnar [bwh: Backported to 3.2: adjust context] Signed-off-by: Ben Hutchings --- diff --git a/arch/x86/kernel/ioport.c b/arch/x86/kernel/ioport.c index 8c968974253d..6a2fa4ac5a76 100644 --- a/arch/x86/kernel/ioport.c +++ b/arch/x86/kernel/ioport.c @@ -95,9 +95,14 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on) */ long sys_iopl(unsigned int level, struct pt_regs *regs) { - unsigned int old = (regs->flags >> 12) & 3; struct thread_struct *t = ¤t->thread; + /* + * Careful: the IOPL bits in regs->flags are undefined under Xen PV + * and changing them has no effect. + */ + unsigned int old = t->iopl >> 12; + if (level > 3) return -EINVAL; /* Trying to gain more privileges? */