[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v6.5 05/26] x86/entry: Remove support for partial cpu_user_regs frames
Save all GPRs on entry to Xen. The entry_int82() path is via a DPL1 gate, only usable by 32bit PV guests, so can get away with only saving the 32bit registers. All other entrypoints can be reached from 32 or 64bit contexts. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> Reviewed-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- tools/tests/x86_emulator/x86-emulate.c | 1 - xen/arch/x86/pv/domain.c | 1 - xen/arch/x86/pv/emul-priv-op.c | 2 - xen/arch/x86/x86_64/compat/entry.S | 7 ++- xen/arch/x86/x86_64/entry.S | 12 ++-- xen/arch/x86/x86_64/traps.c | 13 ++-- xen/arch/x86/x86_emulate.c | 1 - xen/arch/x86/x86_emulate/x86_emulate.c | 8 +-- xen/common/wait.c | 1 - xen/include/asm-x86/asm_defns.h | 105 +++------------------------------ 10 files changed, 26 insertions(+), 125 deletions(-) diff --git a/tools/tests/x86_emulator/x86-emulate.c b/tools/tests/x86_emulator/x86-emulate.c index 975ddc7..9056610 100644 --- a/tools/tests/x86_emulator/x86-emulate.c +++ b/tools/tests/x86_emulator/x86-emulate.c @@ -3,7 +3,6 @@ #include <sys/mman.h> #define cpu_has_amd_erratum(nr) 0 -#define mark_regs_dirty(r) ((void)(r)) #define cpu_has_mpx false #define read_bndcfgu() 0 #define xstate_set_init(what) diff --git a/xen/arch/x86/pv/domain.c b/xen/arch/x86/pv/domain.c index 2234128..74e9e66 100644 --- a/xen/arch/x86/pv/domain.c +++ b/xen/arch/x86/pv/domain.c @@ -20,7 +20,6 @@ static void noreturn continue_nonidle_domain(struct vcpu *v) { check_wakeup_from_wait(); - mark_regs_dirty(guest_cpu_user_regs()); reset_stack_and_jump(ret_from_intr); } diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c index 6115840..1041a4c 100644 --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -337,7 +337,6 @@ static int read_io(unsigned int port, unsigned int bytes, io_emul_stub_t *io_emul = io_emul_stub_setup(poc, ctxt->opcode, port, bytes); - mark_regs_dirty(ctxt->regs); io_emul(ctxt->regs); return X86EMUL_DONE; } @@ -436,7 +435,6 @@ static int write_io(unsigned int port, unsigned int bytes, io_emul_stub_t *io_emul = io_emul_stub_setup(poc, ctxt->opcode, port, bytes); - mark_regs_dirty(ctxt->regs); io_emul(ctxt->regs); if ( (bytes == 1) && pv_post_outb_hook ) pv_post_outb_hook(port, val); diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index ba6e941..3fea54e 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -16,7 +16,8 @@ ENTRY(entry_int82) ASM_CLAC pushq $0 - SAVE_VOLATILE type=HYPERCALL_VECTOR compat=1 + movl $HYPERCALL_VECTOR, 4(%rsp) + SAVE_ALL compat=1 /* DPL1 gate, restricted to 32bit PV guests only. */ CR4_PV32_RESTORE GET_CURRENT(bx) @@ -60,7 +61,6 @@ compat_test_guest_events: /* %rbx: struct vcpu */ compat_process_softirqs: sti - andl $~TRAP_regs_partial,UREGS_entry_vector(%rsp) call do_softirq jmp compat_test_all_events @@ -197,7 +197,8 @@ ENTRY(cstar_enter) pushq $FLAT_USER_CS32 pushq %rcx pushq $0 - SAVE_VOLATILE TRAP_syscall + movl $TRAP_syscall, 4(%rsp) + SAVE_ALL GET_CURRENT(bx) movq VCPU_domain(%rbx),%rcx cmpb $0,DOMAIN_is_32bit_pv(%rcx) diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index 6066ed8..1dd9ccf 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -98,7 +98,8 @@ ENTRY(lstar_enter) pushq $FLAT_KERNEL_CS64 pushq %rcx pushq $0 - SAVE_VOLATILE TRAP_syscall + movl $TRAP_syscall, 4(%rsp) + SAVE_ALL GET_CURRENT(bx) testb $TF_kernel_mode,VCPU_thread_flags(%rbx) jz switch_to_kernel @@ -140,7 +141,6 @@ test_guest_events: /* %rbx: struct vcpu */ process_softirqs: sti - SAVE_PRESERVED call do_softirq jmp test_all_events @@ -190,7 +190,8 @@ GLOBAL(sysenter_eflags_saved) pushq $3 /* ring 3 null cs */ pushq $0 /* null rip */ pushq $0 - SAVE_VOLATILE TRAP_syscall + movl $TRAP_syscall, 4(%rsp) + SAVE_ALL GET_CURRENT(bx) cmpb $0,VCPU_sysenter_disables_events(%rbx) movq VCPU_sysenter_addr(%rbx),%rax @@ -207,7 +208,6 @@ UNLIKELY_END(sysenter_nt_set) leal (,%rcx,TBF_INTERRUPT),%ecx UNLIKELY_START(z, sysenter_gpf) movq VCPU_trap_ctxt(%rbx),%rsi - SAVE_PRESERVED movl $TRAP_gp_fault,UREGS_entry_vector(%rsp) movl %eax,TRAPBOUNCE_error_code(%rdx) movq TRAP_gp_fault * TRAPINFO_sizeof + TRAPINFO_eip(%rsi),%rax @@ -225,7 +225,8 @@ UNLIKELY_END(sysenter_gpf) ENTRY(int80_direct_trap) ASM_CLAC pushq $0 - SAVE_VOLATILE 0x80 + movl $0x80, 4(%rsp) + SAVE_ALL cmpb $0,untrusted_msi(%rip) UNLIKELY_START(ne, msi_check) @@ -253,7 +254,6 @@ int80_slow_path: * IDT entry with DPL==0. */ movl $((0x80 << 3) | X86_XEC_IDT),UREGS_error_code(%rsp) - SAVE_PRESERVED movl $TRAP_gp_fault,UREGS_entry_vector(%rsp) /* A GPF wouldn't have incremented the instruction pointer. */ subq $2,UREGS_rip(%rsp) diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 2a326be..3652f5f 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -80,15 +80,10 @@ static void _show_registers( regs->rbp, regs->rsp, regs->r8); printk("r9: %016lx r10: %016lx r11: %016lx\n", regs->r9, regs->r10, regs->r11); - if ( !(regs->entry_vector & TRAP_regs_partial) ) - { - printk("r12: %016lx r13: %016lx r14: %016lx\n", - regs->r12, regs->r13, regs->r14); - printk("r15: %016lx cr0: %016lx cr4: %016lx\n", - regs->r15, crs[0], crs[4]); - } - else - printk("cr0: %016lx cr4: %016lx\n", crs[0], crs[4]); + printk("r12: %016lx r13: %016lx r14: %016lx\n", + regs->r12, regs->r13, regs->r14); + printk("r15: %016lx cr0: %016lx cr4: %016lx\n", + regs->r15, crs[0], crs[4]); printk("cr3: %016lx cr2: %016lx\n", crs[3], crs[2]); printk("fsb: %016lx gsb: %016lx gss: %016lx\n", crs[5], crs[6], crs[7]); diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index cc334ca..c7ba221 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -11,7 +11,6 @@ #include <xen/domain_page.h> #include <asm/x86_emulate.h> -#include <asm/asm_defns.h> /* mark_regs_dirty() */ #include <asm/processor.h> /* current_cpu_info */ #include <asm/xstate.h> #include <asm/amd.h> /* cpu_has_amd_erratum() */ diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c b/xen/arch/x86/x86_emulate/x86_emulate.c index 54a2756..820495f 100644 --- a/xen/arch/x86/x86_emulate/x86_emulate.c +++ b/xen/arch/x86/x86_emulate/x86_emulate.c @@ -1956,10 +1956,10 @@ decode_register( case 9: p = ®s->r9; break; case 10: p = ®s->r10; break; case 11: p = ®s->r11; break; - case 12: mark_regs_dirty(regs); p = ®s->r12; break; - case 13: mark_regs_dirty(regs); p = ®s->r13; break; - case 14: mark_regs_dirty(regs); p = ®s->r14; break; - case 15: mark_regs_dirty(regs); p = ®s->r15; break; + case 12: p = ®s->r12; break; + case 13: p = ®s->r13; break; + case 14: p = ®s->r14; break; + case 15: p = ®s->r15; break; #endif default: BUG(); p = NULL; break; } diff --git a/xen/common/wait.c b/xen/common/wait.c index 9490a17..c5fc094 100644 --- a/xen/common/wait.c +++ b/xen/common/wait.c @@ -127,7 +127,6 @@ static void __prepare_to_wait(struct waitqueue_vcpu *wqv) unsigned long dummy; u32 entry_vector = cpu_info->guest_cpu_user_regs.entry_vector; - cpu_info->guest_cpu_user_regs.entry_vector &= ~TRAP_regs_partial; ASSERT(wqv->esp == 0); /* Save current VCPU affinity; force wakeup on *this* CPU only. */ diff --git a/xen/include/asm-x86/asm_defns.h b/xen/include/asm-x86/asm_defns.h index 388fc93..98192eb 100644 --- a/xen/include/asm-x86/asm_defns.h +++ b/xen/include/asm-x86/asm_defns.h @@ -17,15 +17,6 @@ void ret_from_intr(void); #endif -#ifdef CONFIG_FRAME_POINTER -/* Indicate special exception stack frame by inverting the frame pointer. */ -#define SETUP_EXCEPTION_FRAME_POINTER(offs) \ - leaq offs(%rsp),%rbp; \ - notq %rbp -#else -#define SETUP_EXCEPTION_FRAME_POINTER(offs) -#endif - #ifndef NDEBUG #define ASSERT_INTERRUPT_STATUS(x, msg) \ pushf; \ @@ -42,31 +33,6 @@ void ret_from_intr(void); #define ASSERT_INTERRUPTS_DISABLED \ ASSERT_INTERRUPT_STATUS(z, "INTERRUPTS DISABLED") -/* - * This flag is set in an exception frame when registers R12-R15 did not get - * saved. - */ -#define _TRAP_regs_partial 16 -#define TRAP_regs_partial (1 << _TRAP_regs_partial) -/* - * This flag gets set in an exception frame when registers R12-R15 possibly - * get modified from their originally saved values and hence need to be - * restored even if the normal call flow would restore register values. - * - * The flag being set implies _TRAP_regs_partial to be unset. Restoring - * R12-R15 thus is - * - required when this flag is set, - * - safe when _TRAP_regs_partial is unset. - */ -#define _TRAP_regs_dirty 17 -#define TRAP_regs_dirty (1 << _TRAP_regs_dirty) - -#define mark_regs_dirty(r) ({ \ - struct cpu_user_regs *r__ = (r); \ - ASSERT(!((r__)->entry_vector & TRAP_regs_partial)); \ - r__->entry_vector |= TRAP_regs_dirty; \ -}) - #ifdef __ASSEMBLY__ # define _ASM_EX(p) p-. #else @@ -236,7 +202,7 @@ static always_inline void stac(void) #endif #ifdef __ASSEMBLY__ -.macro SAVE_ALL op +.macro SAVE_ALL op, compat=0 .ifeqs "\op", "CLAC" ASM_CLAC .else @@ -255,40 +221,6 @@ static always_inline void stac(void) movq %rdx,UREGS_rdx(%rsp) movq %rcx,UREGS_rcx(%rsp) movq %rax,UREGS_rax(%rsp) - movq %r8,UREGS_r8(%rsp) - movq %r9,UREGS_r9(%rsp) - movq %r10,UREGS_r10(%rsp) - movq %r11,UREGS_r11(%rsp) - movq %rbx,UREGS_rbx(%rsp) - movq %rbp,UREGS_rbp(%rsp) - SETUP_EXCEPTION_FRAME_POINTER(UREGS_rbp) - movq %r12,UREGS_r12(%rsp) - movq %r13,UREGS_r13(%rsp) - movq %r14,UREGS_r14(%rsp) - movq %r15,UREGS_r15(%rsp) -.endm - -/* - * Save all registers not preserved by C code or used in entry/exit code. Mark - * the frame as partial. - * - * @type: exception type - * @compat: R8-R15 don't need saving, and the frame nevertheless is complete - */ -.macro SAVE_VOLATILE type compat=0 -.if \compat - movl $\type,UREGS_entry_vector-UREGS_error_code(%rsp) -.else - movl $\type|TRAP_regs_partial,\ - UREGS_entry_vector-UREGS_error_code(%rsp) -.endif - addq $-(UREGS_error_code-UREGS_r15),%rsp - cld - movq %rdi,UREGS_rdi(%rsp) - movq %rsi,UREGS_rsi(%rsp) - movq %rdx,UREGS_rdx(%rsp) - movq %rcx,UREGS_rcx(%rsp) - movq %rax,UREGS_rax(%rsp) .if !\compat movq %r8,UREGS_r8(%rsp) movq %r9,UREGS_r9(%rsp) @@ -297,20 +229,17 @@ static always_inline void stac(void) .endif movq %rbx,UREGS_rbx(%rsp) movq %rbp,UREGS_rbp(%rsp) - SETUP_EXCEPTION_FRAME_POINTER(UREGS_rbp) -.endm - -/* - * Complete a frame potentially only partially saved. - */ -.macro SAVE_PRESERVED - btrl $_TRAP_regs_partial,UREGS_entry_vector(%rsp) - jnc 987f +#ifdef CONFIG_FRAME_POINTER +/* Indicate special exception stack frame by inverting the frame pointer. */ + leaq UREGS_rbp(%rsp), %rbp + notq %rbp +#endif +.if !\compat movq %r12,UREGS_r12(%rsp) movq %r13,UREGS_r13(%rsp) movq %r14,UREGS_r14(%rsp) movq %r15,UREGS_r15(%rsp) -987: +.endif .endm #define LOAD_ONE_REG(reg, compat) \ @@ -330,7 +259,6 @@ static always_inline void stac(void) */ .macro RESTORE_ALL adj=0 compat=0 .if !\compat - testl $TRAP_regs_dirty,UREGS_entry_vector(%rsp) movq UREGS_r11(%rsp),%r11 movq UREGS_r10(%rsp),%r10 movq UREGS_r9(%rsp),%r9 @@ -347,33 +275,16 @@ static always_inline void stac(void) LOAD_ONE_REG(si, \compat) LOAD_ONE_REG(di, \compat) .if !\compat - jz 987f movq UREGS_r15(%rsp),%r15 movq UREGS_r14(%rsp),%r14 movq UREGS_r13(%rsp),%r13 movq UREGS_r12(%rsp),%r12 -#ifndef NDEBUG - .subsection 1 -987: testl $TRAP_regs_partial,UREGS_entry_vector(%rsp) - jnz 987f - cmpq UREGS_r15(%rsp),%r15 - jne 789f - cmpq UREGS_r14(%rsp),%r14 - jne 789f - cmpq UREGS_r13(%rsp),%r13 - jne 789f - cmpq UREGS_r12(%rsp),%r12 - je 987f -789: BUG /* Corruption of partial register state. */ - .subsection 0 -#endif .else xor %r15, %r15 xor %r14, %r14 xor %r13, %r13 xor %r12, %r12 .endif -987: LOAD_ONE_REG(bp, \compat) LOAD_ONE_REG(bx, \compat) subq $-(UREGS_error_code-UREGS_r15+\adj), %rsp -- 2.1.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |