Skip to content

Commit b7a5845

Browse files
amlutoIngo Molnar
authored andcommitted
x86/iopl/64: Properly context-switch IOPL on Xen PV
On Xen PV, regs->flags doesn't reliably reflect IOPL and the exit-to-userspace code doesn't change IOPL. We need to context switch it manually. I'm doing this without going through paravirt because this is specific to Xen PV. After the dust settles, we can merge this with the 32-bit code, tidy up the iopl syscall implementation, and remove the set_iopl pvop entirely. Fixes XSA-171. Reviewewd-by: Jan Beulich <[email protected]> Signed-off-by: Andy Lutomirski <[email protected]> Cc: Andrew Cooper <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Boris Ostrovsky <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: David Vrabel <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Jan Beulich <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/693c3bd7aeb4d3c27c92c622b7d0f554a458173c.1458162709.git.luto@kernel.org Signed-off-by: Ingo Molnar <[email protected]>
1 parent b089830 commit b7a5845

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

arch/x86/include/asm/xen/hypervisor.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,6 @@ void xen_arch_register_cpu(int num);
6262
void xen_arch_unregister_cpu(int num);
6363
#endif
6464

65+
extern void xen_set_iopl_mask(unsigned mask);
66+
6567
#endif /* _ASM_X86_XEN_HYPERVISOR_H */

arch/x86/kernel/process_64.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
#include <asm/syscalls.h>
4949
#include <asm/debugreg.h>
5050
#include <asm/switch_to.h>
51+
#include <asm/xen/hypervisor.h>
5152

5253
asmlinkage extern void ret_from_fork(void);
5354

@@ -411,6 +412,17 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
411412
task_thread_info(prev_p)->flags & _TIF_WORK_CTXSW_PREV))
412413
__switch_to_xtra(prev_p, next_p, tss);
413414

415+
#ifdef CONFIG_XEN
416+
/*
417+
* On Xen PV, IOPL bits in pt_regs->flags have no effect, and
418+
* current_pt_regs()->flags may not match the current task's
419+
* intended IOPL. We need to switch it manually.
420+
*/
421+
if (unlikely(static_cpu_has(X86_FEATURE_XENPV) &&
422+
prev->iopl != next->iopl))
423+
xen_set_iopl_mask(next->iopl);
424+
#endif
425+
414426
if (static_cpu_has_bug(X86_BUG_SYSRET_SS_ATTRS)) {
415427
/*
416428
* AMD CPUs have a misfeature: SYSRET sets the SS selector but

arch/x86/xen/enlighten.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -961,7 +961,7 @@ static void xen_load_sp0(struct tss_struct *tss,
961961
tss->x86_tss.sp0 = thread->sp0;
962962
}
963963

964-
static void xen_set_iopl_mask(unsigned mask)
964+
void xen_set_iopl_mask(unsigned mask)
965965
{
966966
struct physdev_set_iopl set_iopl;
967967

0 commit comments

Comments
 (0)