mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-07 04:09:21 +00:00
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 <JBeulich@suse.com> Signed-off-by: Andy Lutomirski <luto@kernel.org> Cc: Andrew Cooper <andrew.cooper3@citrix.com> Cc: Andy Lutomirski <luto@amacapital.net> Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: David Vrabel <david.vrabel@citrix.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Jan Beulich <JBeulich@suse.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: stable@vger.kernel.org Link: http://lkml.kernel.org/r/8ce12013e6e4c0a44a97e316be4a6faff31bd5ea.1458162709.git.luto@kernel.org Signed-off-by: Ingo Molnar <mingo@kernel.org> Signed-off-by: Willy Tarreau <w@1wt.eu>
This commit is contained in:
parent
a47831b0d8
commit
721485b62f
1 changed files with 9 additions and 3 deletions
|
@ -96,9 +96,14 @@ asmlinkage long sys_ioperm(unsigned long from, unsigned long num, int turn_on)
|
|||
SYSCALL_DEFINE1(iopl, unsigned int, level)
|
||||
{
|
||||
struct pt_regs *regs = current_pt_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 >> X86_EFLAGS_IOPL_BIT;
|
||||
|
||||
if (level > 3)
|
||||
return -EINVAL;
|
||||
/* Trying to gain more privileges? */
|
||||
|
@ -106,8 +111,9 @@ SYSCALL_DEFINE1(iopl, unsigned int, level)
|
|||
if (!capable(CAP_SYS_RAWIO))
|
||||
return -EPERM;
|
||||
}
|
||||
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | (level << 12);
|
||||
t->iopl = level << 12;
|
||||
regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) |
|
||||
(level << X86_EFLAGS_IOPL_BIT);
|
||||
t->iopl = level << X86_EFLAGS_IOPL_BIT;
|
||||
set_iopl_mask(t->iopl);
|
||||
|
||||
return 0;
|
||||
|
|
Loading…
Reference in a new issue