Skip to content

Commit 7209a75

Browse files
amlutoH. Peter Anvin
authored andcommitted
x86_64/entry/xen: Do not invoke espfix64 on Xen
This moves the espfix64 logic into native_iret. To make this work, it gets rid of the native patch for INTERRUPT_RETURN: INTERRUPT_RETURN on native kernels is now 'jmp native_iret'. This changes the 16-bit SS behavior on Xen from OOPSing to leaking some bits of the Xen hypervisor's RSP (I think). [ hpa: this is a nonzero cost on native, but probably not enough to measure. Xen needs to fix this in their own code, probably doing something equivalent to espfix64. ] Signed-off-by: Andy Lutomirski <luto@amacapital.net> Link: http://lkml.kernel.org/r/7b8f1d8ef6597cb16ae004a43c56980a7de3cf94.1406129132.git.luto@amacapital.net Signed-off-by: H. Peter Anvin <hpa@linux.intel.com> Cc: <stable@vger.kernel.org>
1 parent 64aa90f commit 7209a75

File tree

3 files changed

+11
-21
lines changed

3 files changed

+11
-21
lines changed

arch/x86/include/asm/irqflags.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@ static inline notrace unsigned long arch_local_irq_save(void)
129129

130130
#define PARAVIRT_ADJUST_EXCEPTION_FRAME /* */
131131

132-
#define INTERRUPT_RETURN iretq
132+
#define INTERRUPT_RETURN jmp native_iret
133133
#define USERGS_SYSRET64 \
134134
swapgs; \
135135
sysretq;

arch/x86/kernel/entry_64.S

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -830,27 +830,24 @@ restore_args:
830830
RESTORE_ARGS 1,8,1
831831

832832
irq_return:
833+
INTERRUPT_RETURN
834+
835+
ENTRY(native_iret)
833836
/*
834837
* Are we returning to a stack segment from the LDT? Note: in
835838
* 64-bit mode SS:RSP on the exception stack is always valid.
836839
*/
837840
#ifdef CONFIG_X86_ESPFIX64
838841
testb $4,(SS-RIP)(%rsp)
839-
jnz irq_return_ldt
842+
jnz native_irq_return_ldt
840843
#endif
841844

842-
irq_return_iret:
843-
INTERRUPT_RETURN
844-
_ASM_EXTABLE(irq_return_iret, bad_iret)
845-
846-
#ifdef CONFIG_PARAVIRT
847-
ENTRY(native_iret)
845+
native_irq_return_iret:
848846
iretq
849-
_ASM_EXTABLE(native_iret, bad_iret)
850-
#endif
847+
_ASM_EXTABLE(native_irq_return_iret, bad_iret)
851848

852849
#ifdef CONFIG_X86_ESPFIX64
853-
irq_return_ldt:
850+
native_irq_return_ldt:
854851
pushq_cfi %rax
855852
pushq_cfi %rdi
856853
SWAPGS
@@ -872,7 +869,7 @@ irq_return_ldt:
872869
SWAPGS
873870
movq %rax,%rsp
874871
popq_cfi %rax
875-
jmp irq_return_iret
872+
jmp native_irq_return_iret
876873
#endif
877874

878875
.section .fixup,"ax"
@@ -956,13 +953,8 @@ __do_double_fault:
956953
cmpl $__KERNEL_CS,CS(%rdi)
957954
jne do_double_fault
958955
movq RIP(%rdi),%rax
959-
cmpq $irq_return_iret,%rax
960-
#ifdef CONFIG_PARAVIRT
961-
je 1f
962-
cmpq $native_iret,%rax
963-
#endif
956+
cmpq $native_irq_return_iret,%rax
964957
jne do_double_fault /* This shouldn't happen... */
965-
1:
966958
movq PER_CPU_VAR(kernel_stack),%rax
967959
subq $(6*8-KERNEL_STACK_OFFSET),%rax /* Reset to original stack */
968960
movq %rax,RSP(%rdi)
@@ -1428,7 +1420,7 @@ error_sti:
14281420
*/
14291421
error_kernelspace:
14301422
incl %ebx
1431-
leaq irq_return_iret(%rip),%rcx
1423+
leaq native_irq_return_iret(%rip),%rcx
14321424
cmpq %rcx,RIP+8(%rsp)
14331425
je error_swapgs
14341426
movl %ecx,%eax /* zero extend */

arch/x86/kernel/paravirt_patch_64.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ DEF_NATIVE(pv_irq_ops, irq_disable, "cli");
66
DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
77
DEF_NATIVE(pv_irq_ops, restore_fl, "pushq %rdi; popfq");
88
DEF_NATIVE(pv_irq_ops, save_fl, "pushfq; popq %rax");
9-
DEF_NATIVE(pv_cpu_ops, iret, "iretq");
109
DEF_NATIVE(pv_mmu_ops, read_cr2, "movq %cr2, %rax");
1110
DEF_NATIVE(pv_mmu_ops, read_cr3, "movq %cr3, %rax");
1211
DEF_NATIVE(pv_mmu_ops, write_cr3, "movq %rdi, %cr3");
@@ -50,7 +49,6 @@ unsigned native_patch(u8 type, u16 clobbers, void *ibuf,
5049
PATCH_SITE(pv_irq_ops, save_fl);
5150
PATCH_SITE(pv_irq_ops, irq_enable);
5251
PATCH_SITE(pv_irq_ops, irq_disable);
53-
PATCH_SITE(pv_cpu_ops, iret);
5452
PATCH_SITE(pv_cpu_ops, irq_enable_sysexit);
5553
PATCH_SITE(pv_cpu_ops, usergs_sysret32);
5654
PATCH_SITE(pv_cpu_ops, usergs_sysret64);

0 commit comments

Comments
 (0)