[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen master] x86: make traps.c build with !CONFIG_PV
commit aa0816b74f1dffe2d9f3e159915f9a399379278a Author: Wei Liu <wei.liu2@xxxxxxxxxx> AuthorDate: Fri Nov 2 15:55:39 2018 +0000 Commit: Wei Liu <wei.liu2@xxxxxxxxxx> CommitDate: Mon Nov 5 16:08:03 2018 +0000 x86: make traps.c build with !CONFIG_PV Provide a stub for pv_inject_event. Put code that accesses PV fields and GDT / LDT fault handling code under CONFIG_PV. Move set_debugreg to pv/misc-hypercalls.c. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- xen/arch/x86/pv/misc-hypercalls.c | 116 ++++++++++++++++++++++++++++++++++ xen/arch/x86/traps.c | 130 ++++---------------------------------- xen/include/asm-x86/domain.h | 7 ++ 3 files changed, 137 insertions(+), 116 deletions(-) diff --git a/xen/arch/x86/pv/misc-hypercalls.c b/xen/arch/x86/pv/misc-hypercalls.c index 9f61f3db3c..136fa10c96 100644 --- a/xen/arch/x86/pv/misc-hypercalls.c +++ b/xen/arch/x86/pv/misc-hypercalls.c @@ -56,6 +56,122 @@ long do_fpu_taskswitch(int set) } /* + * Used by hypercalls and the emulator. + * -ENODEV => #UD + * -EINVAL => #GP Invalid bit + * -EPERM => #GP Valid bit, but not permitted to use + */ +long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value) +{ + struct vcpu *curr = current; + + switch ( reg ) + { + case 0 ... 3: + if ( !access_ok(value, sizeof(long)) ) + return -EPERM; + + v->arch.dr[reg] = value; + if ( v == curr ) + { + switch ( reg ) + { + case 0: write_debugreg(0, value); break; + case 1: write_debugreg(1, value); break; + case 2: write_debugreg(2, value); break; + case 3: write_debugreg(3, value); break; + } + } + break; + + case 4: + if ( v->arch.pv.ctrlreg[4] & X86_CR4_DE ) + return -ENODEV; + + /* Fallthrough */ + case 6: + /* The upper 32 bits are strictly reserved. */ + if ( value != (uint32_t)value ) + return -EINVAL; + + /* + * DR6: Bits 4-11,16-31 reserved (set to 1). + * Bit 12 reserved (set to 0). + */ + value &= ~DR_STATUS_RESERVED_ZERO; /* reserved bits => 0 */ + value |= DR_STATUS_RESERVED_ONE; /* reserved bits => 1 */ + + v->arch.dr6 = value; + if ( v == curr ) + write_debugreg(6, value); + break; + + case 5: + if ( v->arch.pv.ctrlreg[4] & X86_CR4_DE ) + return -ENODEV; + + /* Fallthrough */ + case 7: + /* The upper 32 bits are strictly reserved. */ + if ( value != (uint32_t)value ) + return -EINVAL; + + /* + * DR7: Bit 10 reserved (set to 1). + * Bits 11-12,14-15 reserved (set to 0). + */ + value &= ~DR_CONTROL_RESERVED_ZERO; /* reserved bits => 0 */ + value |= DR_CONTROL_RESERVED_ONE; /* reserved bits => 1 */ + /* + * Privileged bits: + * GD (bit 13): must be 0. + */ + if ( value & DR_GENERAL_DETECT ) + return -EPERM; + + /* DR7.{G,L}E = 0 => debugging disabled for this domain. */ + if ( value & DR7_ACTIVE_MASK ) + { + unsigned int i, io_enable = 0; + + for ( i = DR_CONTROL_SHIFT; i < 32; i += DR_CONTROL_SIZE ) + { + if ( ((value >> i) & 3) == DR_IO ) + { + if ( !(v->arch.pv.ctrlreg[4] & X86_CR4_DE) ) + return -EPERM; + io_enable |= value & (3 << ((i - 16) >> 1)); + } + } + + v->arch.pv.dr7_emul = io_enable; + value &= ~io_enable; + + /* + * If DR7 was previously clear then we need to load all other + * debug registers at this point as they were not restored during + * context switch. Updating DR7 itself happens later. + */ + if ( (v == curr) && !(v->arch.dr7 & DR7_ACTIVE_MASK) ) + activate_debugregs(v); + } + else + /* Zero the emulated controls if %dr7 isn't active. */ + v->arch.pv.dr7_emul = 0; + + v->arch.dr7 = value; + if ( v == curr ) + write_debugreg(7, value); + break; + + default: + return -ENODEV; + } + + return 0; +} + +/* * Local variables: * mode: C * c-file-style: "BSD" diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index c60c8f5c2a..7765f9a5d7 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1115,6 +1115,7 @@ static void reserved_bit_page_fault(unsigned long addr, show_execution_state(regs); } +#ifdef CONFIG_PV static int handle_ldt_mapping_fault(unsigned int offset, struct cpu_user_regs *regs) { @@ -1185,6 +1186,7 @@ static int handle_gdt_ldt_mapping_fault(unsigned long offset, return EXCRET_fault_fixed; } +#endif #define IN_HYPERVISOR_RANGE(va) \ (((va) >= HYPERVISOR_VIRT_START) && ((va) < HYPERVISOR_VIRT_END)) @@ -1335,10 +1337,12 @@ static int fixup_page_fault(unsigned long addr, struct cpu_user_regs *regs) if ( unlikely(IN_HYPERVISOR_RANGE(addr)) ) { +#ifdef CONFIG_PV if ( !(regs->error_code & (PFEC_user_mode | PFEC_reserved_bit)) && (addr >= GDT_LDT_VIRT_START) && (addr < GDT_LDT_VIRT_END) ) return handle_gdt_ldt_mapping_fault( addr - GDT_LDT_VIRT_START, regs); +#endif return 0; } @@ -1494,7 +1498,9 @@ void __init do_early_page_fault(struct cpu_user_regs *regs) void do_general_protection(struct cpu_user_regs *regs) { +#ifdef CONFIG_PV struct vcpu *v = current; +#endif unsigned long fixup; if ( debugger_trap_entry(TRAP_gp_fault, regs) ) @@ -1506,6 +1512,7 @@ void do_general_protection(struct cpu_user_regs *regs) if ( !guest_mode(regs) ) goto gp_in_kernel; +#ifdef CONFIG_PV /* * Cunning trick to allow arbitrary "INT n" handling. * @@ -1557,6 +1564,7 @@ void do_general_protection(struct cpu_user_regs *regs) /* Pass on GPF as is. */ pv_inject_hw_exception(TRAP_gp_fault, regs->error_code); return; +#endif gp_in_kernel: @@ -1744,7 +1752,9 @@ void unset_nmi_callback(void) void do_device_not_available(struct cpu_user_regs *regs) { +#ifdef CONFIG_PV struct vcpu *curr = current; +#endif if ( !guest_mode(regs) ) { @@ -1762,6 +1772,7 @@ void do_device_not_available(struct cpu_user_regs *regs) return; } +#ifdef CONFIG_PV vcpu_restore_fpu_lazy(curr); if ( curr->arch.pv.ctrlreg[0] & X86_CR0_TS ) @@ -1771,6 +1782,9 @@ void do_device_not_available(struct cpu_user_regs *regs) } else TRACE_0D(TRC_PV_MATH_STATE_RESTORE); +#else + ASSERT_UNREACHABLE(); +#endif return; } @@ -2078,122 +2092,6 @@ void activate_debugregs(const struct vcpu *curr) } } -/* - * Used by hypercalls and the emulator. - * -ENODEV => #UD - * -EINVAL => #GP Invalid bit - * -EPERM => #GP Valid bit, but not permitted to use - */ -long set_debugreg(struct vcpu *v, unsigned int reg, unsigned long value) -{ - struct vcpu *curr = current; - - switch ( reg ) - { - case 0 ... 3: - if ( !access_ok(value, sizeof(long)) ) - return -EPERM; - - v->arch.dr[reg] = value; - if ( v == curr ) - { - switch ( reg ) - { - case 0: write_debugreg(0, value); break; - case 1: write_debugreg(1, value); break; - case 2: write_debugreg(2, value); break; - case 3: write_debugreg(3, value); break; - } - } - break; - - case 4: - if ( v->arch.pv.ctrlreg[4] & X86_CR4_DE ) - return -ENODEV; - - /* Fallthrough */ - case 6: - /* The upper 32 bits are strictly reserved. */ - if ( value != (uint32_t)value ) - return -EINVAL; - - /* - * DR6: Bits 4-11,16-31 reserved (set to 1). - * Bit 12 reserved (set to 0). - */ - value &= ~DR_STATUS_RESERVED_ZERO; /* reserved bits => 0 */ - value |= DR_STATUS_RESERVED_ONE; /* reserved bits => 1 */ - - v->arch.dr6 = value; - if ( v == curr ) - write_debugreg(6, value); - break; - - case 5: - if ( v->arch.pv.ctrlreg[4] & X86_CR4_DE ) - return -ENODEV; - - /* Fallthrough */ - case 7: - /* The upper 32 bits are strictly reserved. */ - if ( value != (uint32_t)value ) - return -EINVAL; - - /* - * DR7: Bit 10 reserved (set to 1). - * Bits 11-12,14-15 reserved (set to 0). - */ - value &= ~DR_CONTROL_RESERVED_ZERO; /* reserved bits => 0 */ - value |= DR_CONTROL_RESERVED_ONE; /* reserved bits => 1 */ - /* - * Privileged bits: - * GD (bit 13): must be 0. - */ - if ( value & DR_GENERAL_DETECT ) - return -EPERM; - - /* DR7.{G,L}E = 0 => debugging disabled for this domain. */ - if ( value & DR7_ACTIVE_MASK ) - { - unsigned int i, io_enable = 0; - - for ( i = DR_CONTROL_SHIFT; i < 32; i += DR_CONTROL_SIZE ) - { - if ( ((value >> i) & 3) == DR_IO ) - { - if ( !(v->arch.pv.ctrlreg[4] & X86_CR4_DE) ) - return -EPERM; - io_enable |= value & (3 << ((i - 16) >> 1)); - } - } - - v->arch.pv.dr7_emul = io_enable; - value &= ~io_enable; - - /* - * If DR7 was previously clear then we need to load all other - * debug registers at this point as they were not restored during - * context switch. Updating DR7 itself happens later. - */ - if ( (v == curr) && !(v->arch.dr7 & DR7_ACTIVE_MASK) ) - activate_debugregs(v); - } - else - /* Zero the emulated controls if %dr7 isn't active. */ - v->arch.pv.dr7_emul = 0; - - v->arch.dr7 = value; - if ( v == curr ) - write_debugreg(7, value); - break; - - default: - return -ENODEV; - } - - return 0; -} - void asm_domain_crash_synchronous(unsigned long addr) { /* diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 7214037820..643e69acf9 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -681,7 +681,14 @@ void arch_vcpu_regs_init(struct vcpu *v); struct vcpu_hvm_context; int arch_set_info_hvm_guest(struct vcpu *v, const struct vcpu_hvm_context *ctx); +#ifdef CONFIG_PV void pv_inject_event(const struct x86_event *event); +#else +static inline void pv_inject_event(const struct x86_event *event) +{ + ASSERT_UNREACHABLE(); +} +#endif static inline void pv_inject_hw_exception(unsigned int vector, int errcode) { -- generated by git-patchbot for /home/xen/git/xen.git#master _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |