... in preference to the crs[8] array. This avoids abusing crs[5..7] for the fs/gs bases, giving them proper named fields instead, and avoids storage for cr1 which is unused in the x86 architecture.
In show_registers(), remove a redundant read_cr2(). read_registers() already did the same, and it is only the PV path which needs to override with arch_get_cr2(). In vcpu_show_registers(), express the gsb/gss decision using SWAP(). The determination is going to get even more complicated under FRED. No functional change. Signed-off-by: Andrew Cooper <andrew.coop...@citrix.com> --- CC: Jan Beulich <jbeul...@suse.com> CC: Roger Pau Monné <roger....@citrix.com> --- xen/arch/x86/x86_64/traps.c | 96 +++++++++++++++++++++---------------- 1 file changed, 54 insertions(+), 42 deletions(-) diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index ac0fafd72d31..01b4f0623282 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -23,6 +23,11 @@ #include <asm/shared.h> #include <asm/traps.h> +struct extra_state +{ + unsigned long cr0, cr2, cr3, cr4; + unsigned long fsb, gsb, gss; +}; static void print_xen_info(void) { @@ -35,28 +40,29 @@ static void print_xen_info(void) enum context { CTXT_hypervisor, CTXT_pv_guest, CTXT_hvm_guest }; -/* (ab)use crs[5..7] for fs/gs bases. */ -static void read_registers(struct cpu_user_regs *regs, unsigned long crs[8]) +static void read_registers(struct cpu_user_regs *regs, struct extra_state *state) { - crs[0] = read_cr0(); - crs[2] = read_cr2(); - crs[3] = read_cr3(); - crs[4] = read_cr4(); + state->cr0 = read_cr0(); + state->cr2 = read_cr2(); + state->cr3 = read_cr3(); + state->cr4 = read_cr4(); + read_sregs(regs); - crs[5] = read_fs_base(); - crs[6] = read_gs_base(); - crs[7] = read_gs_shadow(); + + state->fsb = read_fs_base(); + state->gsb = read_gs_base(); + state->gss = read_gs_shadow(); } static void get_hvm_registers(struct vcpu *v, struct cpu_user_regs *regs, - unsigned long crs[8]) + struct extra_state *state) { struct segment_register sreg; - crs[0] = v->arch.hvm.guest_cr[0]; - crs[2] = v->arch.hvm.guest_cr[2]; - crs[3] = v->arch.hvm.guest_cr[3]; - crs[4] = v->arch.hvm.guest_cr[4]; + state->cr0 = v->arch.hvm.guest_cr[0]; + state->cr2 = v->arch.hvm.guest_cr[2]; + state->cr3 = v->arch.hvm.guest_cr[3]; + state->cr4 = v->arch.hvm.guest_cr[4]; hvm_get_segment_register(v, x86_seg_cs, &sreg); regs->cs = sreg.sel; @@ -69,20 +75,20 @@ static void get_hvm_registers(struct vcpu *v, struct cpu_user_regs *regs, hvm_get_segment_register(v, x86_seg_fs, &sreg); regs->fs = sreg.sel; - crs[5] = sreg.base; + state->fsb = sreg.base; hvm_get_segment_register(v, x86_seg_gs, &sreg); regs->gs = sreg.sel; - crs[6] = sreg.base; + state->gsb = sreg.base; hvm_get_segment_register(v, x86_seg_ss, &sreg); regs->ss = sreg.sel; - crs[7] = hvm_get_reg(v, MSR_SHADOW_GS_BASE); + state->gss = hvm_get_reg(v, MSR_SHADOW_GS_BASE); } static void _show_registers( - const struct cpu_user_regs *regs, unsigned long crs[8], + const struct cpu_user_regs *regs, const struct extra_state *state, enum context context, const struct vcpu *v) { static const char *const context_names[] = { @@ -112,10 +118,10 @@ static void _show_registers( 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]); + regs->r15, state->cr0, state->cr4); + printk("cr3: %016lx cr2: %016lx\n", state->cr3, state->cr2); printk("fsb: %016lx gsb: %016lx gss: %016lx\n", - crs[5], crs[6], crs[7]); + state->fsb, state->gsb, state->gss); printk("ds: %04x es: %04x fs: %04x gs: %04x " "ss: %04x cs: %04x\n", regs->ds, regs->es, regs->fs, @@ -125,34 +131,33 @@ static void _show_registers( void show_registers(const struct cpu_user_regs *regs) { struct cpu_user_regs fault_regs = *regs; - unsigned long fault_crs[8]; + struct extra_state fault_state; enum context context; struct vcpu *v = system_state >= SYS_STATE_smp_boot ? current : NULL; if ( guest_mode(regs) && is_hvm_vcpu(v) ) { - get_hvm_registers(v, &fault_regs, fault_crs); + get_hvm_registers(v, &fault_regs, &fault_state); context = CTXT_hvm_guest; } else { - read_registers(&fault_regs, fault_crs); + read_registers(&fault_regs, &fault_state); if ( guest_mode(regs) ) { context = CTXT_pv_guest; - fault_crs[2] = arch_get_cr2(v); + fault_state.cr2 = arch_get_cr2(v); } else { context = CTXT_hypervisor; - fault_crs[2] = read_cr2(); } } print_xen_info(); printk("CPU: %d\n", smp_processor_id()); - _show_registers(&fault_regs, fault_crs, context, v); + _show_registers(&fault_regs, &fault_state, context, v); if ( ler_msr && !guest_mode(regs) ) { @@ -173,34 +178,41 @@ void vcpu_show_registers(struct vcpu *v) { const struct cpu_user_regs *regs = &v->arch.user_regs; struct cpu_user_regs aux_regs; + struct extra_state state; enum context context; - unsigned long crs[8]; if ( is_hvm_vcpu(v) ) { aux_regs = *regs; - get_hvm_registers(v, &aux_regs, crs); + get_hvm_registers(v, &aux_regs, &state); regs = &aux_regs; context = CTXT_hvm_guest; } else { bool kernel = guest_kernel_mode(v, regs); + unsigned long gsb, gss; + + state.cr0 = v->arch.pv.ctrlreg[0]; + state.cr2 = arch_get_cr2(v); + state.cr3 = pagetable_get_paddr(kernel + ? v->arch.guest_table + : v->arch.guest_table_user); + state.cr4 = v->arch.pv.ctrlreg[4]; + + gsb = v->arch.pv.gs_base_user; + gss = v->arch.pv.gs_base_kernel; + if ( kernel ) + SWAP(gsb, gss); - crs[0] = v->arch.pv.ctrlreg[0]; - crs[2] = arch_get_cr2(v); - crs[3] = pagetable_get_paddr(kernel ? - v->arch.guest_table : - v->arch.guest_table_user); - crs[4] = v->arch.pv.ctrlreg[4]; - crs[5] = v->arch.pv.fs_base; - crs[6 + !kernel] = v->arch.pv.gs_base_kernel; - crs[7 - !kernel] = v->arch.pv.gs_base_user; + state.fsb = v->arch.pv.fs_base; + state.gsb = gsb; + state.gss = gss; context = CTXT_pv_guest; } - _show_registers(regs, crs, context, v); + _show_registers(regs, &state, context, v); } void show_page_walk(unsigned long addr) @@ -268,7 +280,7 @@ void show_page_walk(unsigned long addr) void asmlinkage do_double_fault(struct cpu_user_regs *regs) { unsigned int cpu; - unsigned long crs[8]; + struct extra_state state; console_force_unlock(); @@ -279,10 +291,10 @@ void asmlinkage do_double_fault(struct cpu_user_regs *regs) printk("*** DOUBLE FAULT ***\n"); print_xen_info(); - read_registers(regs, crs); + read_registers(regs, &state); printk("CPU: %d\n", cpu); - _show_registers(regs, crs, CTXT_hypervisor, NULL); + _show_registers(regs, &state, CTXT_hypervisor, NULL); show_code(regs); show_stack_overflow(cpu, regs); -- 2.39.5