[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v4 04/27] x86: move PV invalid op emulation code
Move the code to pv/emul-inv-op.c. Prefix emulate_* functions with pv_ and export them via pv/traps.h. Pure code motion except for the rename. Signed-off-by: Wei Liu <wei.liu2@xxxxxxxxxx> --- xen/arch/x86/pv/Makefile | 1 + xen/arch/x86/pv/emul-inv-op.c | 123 +++++++++++++++++++++++++++++++++++++++++ xen/arch/x86/traps.c | 75 +------------------------ xen/include/asm-x86/pv/traps.h | 4 ++ 4 files changed, 130 insertions(+), 73 deletions(-) create mode 100644 xen/arch/x86/pv/emul-inv-op.c diff --git a/xen/arch/x86/pv/Makefile b/xen/arch/x86/pv/Makefile index 1f6fbd3f5c..42ca64dc9e 100644 --- a/xen/arch/x86/pv/Makefile +++ b/xen/arch/x86/pv/Makefile @@ -5,5 +5,6 @@ obj-bin-y += dom0_build.init.o obj-y += domain.o obj-y += emulate.o obj-y += emul-gate-op.o +obj-y += emul-inv-op.o obj-y += emul-priv-op.o obj-bin-y += gpr_switch.o diff --git a/xen/arch/x86/pv/emul-inv-op.c b/xen/arch/x86/pv/emul-inv-op.c new file mode 100644 index 0000000000..6a731c6049 --- /dev/null +++ b/xen/arch/x86/pv/emul-inv-op.c @@ -0,0 +1,123 @@ +/****************************************************************************** + * arch/x86/pv/emul-inv-op.c + * + * Emulate invalid op for PV guests + * + * Modifications to Linux original are copyright (c) 2002-2004, K A Fraser + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; If not, see <http://www.gnu.org/licenses/>. + */ + +#include <xen/errno.h> +#include <xen/event.h> +#include <xen/guest_access.h> +#include <xen/iocap.h> +#include <xen/spinlock.h> +#include <xen/trace.h> + +#include <asm/apic.h> +#include <asm/debugreg.h> +#include <asm/hpet.h> +#include <asm/hypercall.h> +#include <asm/mc146818rtc.h> +#include <asm/p2m.h> +#include <asm/pv/traps.h> +#include <asm/shared.h> +#include <asm/traps.h> +#include <asm/x86_emulate.h> + +#include <xsm/xsm.h> + +#include "emulate.h" + +int pv_emulate_invalid_rdtscp(struct cpu_user_regs *regs) +{ + char opcode[3]; + unsigned long eip, rc; + struct vcpu *v = current; + + eip = regs->rip; + if ( (rc = copy_from_user(opcode, (char *)eip, sizeof(opcode))) != 0 ) + { + pv_inject_page_fault(0, eip + sizeof(opcode) - rc); + return EXCRET_fault_fixed; + } + if ( memcmp(opcode, "\xf\x1\xf9", sizeof(opcode)) ) + return 0; + eip += sizeof(opcode); + pv_soft_rdtsc(v, regs, 1); + pv_emul_instruction_done(regs, eip); + return EXCRET_fault_fixed; +} + +int pv_emulate_forced_invalid_op(struct cpu_user_regs *regs) +{ + char sig[5], instr[2]; + unsigned long eip, rc; + struct cpuid_leaf res; + + eip = regs->rip; + + /* Check for forced emulation signature: ud2 ; .ascii "xen". */ + if ( (rc = copy_from_user(sig, (char *)eip, sizeof(sig))) != 0 ) + { + pv_inject_page_fault(0, eip + sizeof(sig) - rc); + return EXCRET_fault_fixed; + } + if ( memcmp(sig, "\xf\xbxen", sizeof(sig)) ) + return 0; + eip += sizeof(sig); + + /* We only emulate CPUID. */ + if ( ( rc = copy_from_user(instr, (char *)eip, sizeof(instr))) != 0 ) + { + pv_inject_page_fault(0, eip + sizeof(instr) - rc); + return EXCRET_fault_fixed; + } + if ( memcmp(instr, "\xf\xa2", sizeof(instr)) ) + return 0; + + /* If cpuid faulting is enabled and CPL>0 inject a #GP in place of #UD. */ + if ( current->arch.cpuid_faulting && !guest_kernel_mode(current, regs) ) + { + regs->rip = eip; + pv_inject_hw_exception(TRAP_gp_fault, regs->error_code); + return EXCRET_fault_fixed; + } + + eip += sizeof(instr); + + guest_cpuid(current, regs->eax, regs->ecx, &res); + + regs->rax = res.a; + regs->rbx = res.b; + regs->rcx = res.c; + regs->rdx = res.d; + + pv_emul_instruction_done(regs, eip); + + trace_trap_one_addr(TRC_PV_FORCED_INVALID_OP, regs->rip); + + return EXCRET_fault_fixed; +} + +/* + * Local variables: + * mode: C + * c-file-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 7b781f17db..ff25f679f5 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -968,77 +968,6 @@ void cpuid_hypervisor_leaves(const struct vcpu *v, uint32_t leaf, } } -static int emulate_invalid_rdtscp(struct cpu_user_regs *regs) -{ - char opcode[3]; - unsigned long eip, rc; - struct vcpu *v = current; - - eip = regs->rip; - if ( (rc = copy_from_user(opcode, (char *)eip, sizeof(opcode))) != 0 ) - { - pv_inject_page_fault(0, eip + sizeof(opcode) - rc); - return EXCRET_fault_fixed; - } - if ( memcmp(opcode, "\xf\x1\xf9", sizeof(opcode)) ) - return 0; - eip += sizeof(opcode); - pv_soft_rdtsc(v, regs, 1); - pv_emul_instruction_done(regs, eip); - return EXCRET_fault_fixed; -} - -static int emulate_forced_invalid_op(struct cpu_user_regs *regs) -{ - char sig[5], instr[2]; - unsigned long eip, rc; - struct cpuid_leaf res; - - eip = regs->rip; - - /* Check for forced emulation signature: ud2 ; .ascii "xen". */ - if ( (rc = copy_from_user(sig, (char *)eip, sizeof(sig))) != 0 ) - { - pv_inject_page_fault(0, eip + sizeof(sig) - rc); - return EXCRET_fault_fixed; - } - if ( memcmp(sig, "\xf\xbxen", sizeof(sig)) ) - return 0; - eip += sizeof(sig); - - /* We only emulate CPUID. */ - if ( ( rc = copy_from_user(instr, (char *)eip, sizeof(instr))) != 0 ) - { - pv_inject_page_fault(0, eip + sizeof(instr) - rc); - return EXCRET_fault_fixed; - } - if ( memcmp(instr, "\xf\xa2", sizeof(instr)) ) - return 0; - - /* If cpuid faulting is enabled and CPL>0 inject a #GP in place of #UD. */ - if ( current->arch.cpuid_faulting && !guest_kernel_mode(current, regs) ) - { - regs->rip = eip; - pv_inject_hw_exception(TRAP_gp_fault, regs->error_code); - return EXCRET_fault_fixed; - } - - eip += sizeof(instr); - - guest_cpuid(current, regs->eax, regs->ecx, &res); - - regs->rax = res.a; - regs->rbx = res.b; - regs->rcx = res.c; - regs->rdx = res.d; - - pv_emul_instruction_done(regs, eip); - - trace_trap_one_addr(TRC_PV_FORCED_INVALID_OP, regs->rip); - - return EXCRET_fault_fixed; -} - void do_invalid_op(struct cpu_user_regs *regs) { const struct bug_frame *bug = NULL; @@ -1053,8 +982,8 @@ void do_invalid_op(struct cpu_user_regs *regs) if ( likely(guest_mode(regs)) ) { - if ( !emulate_invalid_rdtscp(regs) && - !emulate_forced_invalid_op(regs) ) + if ( !pv_emulate_invalid_rdtscp(regs) && + !pv_emulate_forced_invalid_op(regs) ) pv_inject_hw_exception(TRAP_invalid_op, X86_EVENT_NO_EC); return; } diff --git a/xen/include/asm-x86/pv/traps.h b/xen/include/asm-x86/pv/traps.h index 3f3bab4d8c..a4af69e486 100644 --- a/xen/include/asm-x86/pv/traps.h +++ b/xen/include/asm-x86/pv/traps.h @@ -27,11 +27,15 @@ int pv_emulate_privileged_op(struct cpu_user_regs *regs); void pv_emulate_gate_op(struct cpu_user_regs *regs); +int pv_emulate_invalid_rdtscp(struct cpu_user_regs *regs); +int pv_emulate_forced_invalid_op(struct cpu_user_regs *regs); #else /* !CONFIG_PV */ int pv_emulate_privileged_op(struct cpu_user_regs *regs) { return 0; } void pv_emulate_gate_op(struct cpu_user_regs *regs) {} +int pv_emulate_invalid_rdtscp(struct cpu_user_regs *regs) { return 0; } +int pv_emulate_forced_invalid_op(struct cpu_user_regs *regs) { return 0; } #endif /* CONFIG_PV */ -- 2.11.0 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |