[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 3/6] x86: Handle the Xen MSRs via the new guest_{rd, wr}msr() infrastructure
Dispatch from the guest_{rd,wr}msr() functions, after falling through from the !is_viridian_domain() case. Rename {rd,wr}msr_hypervisor_regs() to guest_{rd,wr}msr_xen() for consistency, and because the _regs suffix isn't very appropriate. Update them to take a vcpu pointer rather than presuming that they act on current, and switch to using X86EMUL_* return values. Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Jun Nakajima <jun.nakajima@xxxxxxxxx> CC: Paul Durrant <paul.durrant@xxxxxxxxxx> CC: Kevin Tian <kevin.tian@xxxxxxxxx> CC: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> CC: Suravee Suthikulpanit <suravee.suthikulpanit@xxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Roger Pau Monné <roger.pau@xxxxxxxxxx> CC: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx> --- xen/arch/x86/hvm/svm/svm.c | 25 ++++--------------------- xen/arch/x86/hvm/vmx/vmx.c | 24 ++++-------------------- xen/arch/x86/msr.c | 8 ++++++++ xen/arch/x86/pv/emul-priv-op.c | 6 ------ xen/arch/x86/traps.c | 33 ++++++++++++++++----------------- xen/include/asm-x86/processor.h | 4 ++-- 6 files changed, 34 insertions(+), 66 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 6d8ed5c..f90a7b4 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1967,9 +1967,6 @@ static int svm_msr_read_intercept(unsigned int msr, uint64_t *msr_content) else if ( ret ) break; - if ( rdmsr_hypervisor_regs(msr, msr_content) ) - break; - if ( rdmsr_safe(msr, *msr_content) == 0 ) break; @@ -2122,25 +2119,11 @@ static int svm_msr_write_intercept(unsigned int msr, uint64_t msr_content) else if ( ret ) break; - switch ( wrmsr_hypervisor_regs(msr, msr_content) ) - { - case -ERESTART: - result = X86EMUL_RETRY; - break; - case 0: - /* - * Match up with the RDMSR side for now; ultimately this entire - * case block should go away. - */ - if ( rdmsr_safe(msr, msr_content) == 0 ) - break; - goto gpf; - case 1: + /* Match up with the RDMSR side; ultimately this should go away. */ + if ( rdmsr_safe(msr, msr_content) == 0 ) break; - default: - goto gpf; - } - break; + + goto gpf; } if ( sync ) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 5bf6f62..6caaabc 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2871,9 +2871,6 @@ static int vmx_msr_read_intercept(unsigned int msr, uint64_t *msr_content) break; } - if ( rdmsr_hypervisor_regs(msr, msr_content) ) - break; - if ( rdmsr_safe(msr, *msr_content) == 0 ) break; @@ -3115,24 +3112,11 @@ static int vmx_msr_write_intercept(unsigned int msr, uint64_t msr_content) is_last_branch_msr(msr) ) break; - switch ( wrmsr_hypervisor_regs(msr, msr_content) ) - { - case -ERESTART: - return X86EMUL_RETRY; - case 0: - /* - * Match up with the RDMSR side for now; ultimately this - * entire case block should go away. - */ - if ( rdmsr_safe(msr, msr_content) == 0 ) - break; - goto gp_fault; - case 1: + /* Match up with the RDMSR side; ultimately this should go away. */ + if ( rdmsr_safe(msr, msr_content) == 0 ) break; - default: - goto gp_fault; - } - break; + + goto gp_fault; } return X86EMUL_OKAY; diff --git a/xen/arch/x86/msr.c b/xen/arch/x86/msr.c index 2ff9361..9f20fd8 100644 --- a/xen/arch/x86/msr.c +++ b/xen/arch/x86/msr.c @@ -183,6 +183,10 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val) } /* Fallthrough. */ + case 0x40000200 ... 0x400002ff: + ret = guest_rdmsr_xen(v, msr, val); + goto out; + default: return X86EMUL_UNHANDLEABLE; } @@ -274,6 +278,10 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) } /* Fallthrough. */ + case 0x40000200 ... 0x400002ff: + ret = guest_wrmsr_xen(v, msr, val); + goto out; + default: return X86EMUL_UNHANDLEABLE; } diff --git a/xen/arch/x86/pv/emul-priv-op.c b/xen/arch/x86/pv/emul-priv-op.c index 17aaf97..97fcac0 100644 --- a/xen/arch/x86/pv/emul-priv-op.c +++ b/xen/arch/x86/pv/emul-priv-op.c @@ -974,9 +974,6 @@ static int read_msr(unsigned int reg, uint64_t *val, } /* fall through */ default: - if ( rdmsr_hypervisor_regs(reg, val) ) - return X86EMUL_OKAY; - rc = vmce_rdmsr(reg, val); if ( rc < 0 ) break; @@ -1173,9 +1170,6 @@ static int write_msr(unsigned int reg, uint64_t val, } /* fall through */ default: - if ( wrmsr_hypervisor_regs(reg, val) == 1 ) - return X86EMUL_OKAY; - rc = vmce_wrmsr(reg, val); if ( rc < 0 ) break; diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 27190e0..cd5b223 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -776,29 +776,26 @@ static void do_trap(struct cpu_user_regs *regs) trapnr, trapstr(trapnr), regs->error_code); } -/* Returns 0 if not handled, and non-0 for success. */ -int rdmsr_hypervisor_regs(uint32_t idx, uint64_t *val) +int guest_rdmsr_xen(const struct vcpu *v, uint32_t idx, uint64_t *val) { - struct domain *d = current->domain; + const struct domain *d = v->domain; /* Optionally shift out of the way of Viridian architectural MSRs. */ uint32_t base = is_viridian_domain(d) ? 0x40000200 : 0x40000000; switch ( idx - base ) { case 0: /* Write hypercall page MSR. Read as zero. */ - { *val = 0; - return 1; - } - } + return X86EMUL_OKAY; - return 0; + default: + return X86EMUL_EXCEPTION; + } } -/* Returns 1 if handled, 0 if not and -Exx for error. */ -int wrmsr_hypervisor_regs(uint32_t idx, uint64_t val) +int guest_wrmsr_xen(struct vcpu *v, uint32_t idx, uint64_t val) { - struct domain *d = current->domain; + struct domain *d = v->domain; /* Optionally shift out of the way of Viridian architectural MSRs. */ uint32_t base = is_viridian_domain(d) ? 0x40000200 : 0x40000000; @@ -817,7 +814,7 @@ int wrmsr_hypervisor_regs(uint32_t idx, uint64_t val) gdprintk(XENLOG_WARNING, "wrmsr hypercall page index %#x unsupported\n", page_index); - return 0; + goto gp_fault; } page = get_page_from_gfn(d, gmfn, &t, P2M_ALLOC); @@ -830,13 +827,13 @@ int wrmsr_hypervisor_regs(uint32_t idx, uint64_t val) if ( p2m_is_paging(t) ) { p2m_mem_paging_populate(d, gmfn); - return -ERESTART; + return X86EMUL_RETRY; } gdprintk(XENLOG_WARNING, "Bad GMFN %lx (MFN %lx) to MSR %08x\n", gmfn, page ? page_to_mfn(page) : -1UL, base); - return 0; + goto gp_fault; } hypercall_page = __map_domain_page(page); @@ -844,11 +841,13 @@ int wrmsr_hypervisor_regs(uint32_t idx, uint64_t val) unmap_domain_page(hypercall_page); put_page_and_type(page); - return 1; - } + return X86EMUL_OKAY; } - return 0; + gp_fault: + default: + return X86EMUL_EXCEPTION; + } } void cpuid_hypervisor_leaves(const struct vcpu *v, uint32_t leaf, diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 9c70a98..14df6bd 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -521,8 +521,8 @@ unsigned long alloc_stub_page(unsigned int cpu, unsigned long *mfn); void cpuid_hypervisor_leaves(const struct vcpu *v, uint32_t leaf, uint32_t subleaf, struct cpuid_leaf *res); -int rdmsr_hypervisor_regs(uint32_t idx, uint64_t *val); -int wrmsr_hypervisor_regs(uint32_t idx, uint64_t val); +int guest_rdmsr_xen(const struct vcpu *v, uint32_t idx, uint64_t *val); +int guest_wrmsr_xen(struct vcpu *v, uint32_t idx, uint64_t val); void microcode_set_module(unsigned int); int microcode_update(XEN_GUEST_HANDLE_PARAM(const_void), unsigned long len); -- 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 |