#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)
{
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;
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[] = {
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,
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) )
{
{
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)
void asmlinkage do_double_fault(struct cpu_user_regs *regs)
{
unsigned int cpu;
- unsigned long crs[8];
+ struct extra_state state;
console_force_unlock();
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);