[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 2/5] 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> Reviewed-by: Boris Ostrovsky <boris.ostrovsky@xxxxxxxxxx> Reviewed-by: Kevin Tian <kevin.tian@xxxxxxxxx> Reviewed-by: Roger Pau Monné <roger.pau@xxxxxxxxxx> --- CC: Jan Beulich <JBeulich@xxxxxxxx> CC: Paul Durrant <paul.durrant@xxxxxxxxxx> CC: Wei Liu <wei.liu2@xxxxxxxxxx> CC: Sergey Dyasli <sergey.dyasli@xxxxxxxxxx> v2: * Introduce some constants for the hypervisor range. However, I do not think the current code is an improvement over bare numbers. --- 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 | 36 ++++++++++++++++++------------------ xen/include/asm-x86/msr-index.h | 2 ++ xen/include/asm-x86/processor.h | 4 ++-- 7 files changed, 38 insertions(+), 67 deletions(-) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index e8ac2d8..dadf92d 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -1966,9 +1966,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; @@ -2121,25 +2118,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 5fc21a5..b9157af 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -2909,9 +2909,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; @@ -3153,24 +3150,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 2fc2021..62079bb 100644 --- a/xen/arch/x86/msr.c +++ b/xen/arch/x86/msr.c @@ -185,6 +185,10 @@ int guest_rdmsr(const struct vcpu *v, uint32_t msr, uint64_t *val) } /* Fallthrough. */ + case MSR_XEN_ALT_START ... MSR_XEN_ALT_START + NR_XEN_MSRS - 1: + ret = guest_rdmsr_xen(v, msr, val); + goto out; + default: return X86EMUL_UNHANDLEABLE; } @@ -276,6 +280,10 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val) } /* Fallthrough. */ + case MSR_XEN_ALT_START ... MSR_XEN_ALT_START + NR_XEN_MSRS - 1: + 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 ecb3b9c..9ddc5ca 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 19bc174..ea6b17c 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -777,31 +777,29 @@ 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; + uint32_t base = (is_viridian_domain(d) + ? MSR_XEN_ALT_START : MSR_HYPERVISOR_START); switch ( idx - base ) { case 0: /* Write hypercall page MSR. Read as zero. */ - { *val = 0; - return 1; - } + return X86EMUL_OKAY; } - return 0; + 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; + uint32_t base = (is_viridian_domain(d) + ? MSR_XEN_ALT_START : MSR_HYPERVISOR_START); switch ( idx - base ) { @@ -818,7 +816,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); @@ -831,13 +829,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); @@ -845,11 +843,12 @@ 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: + return X86EMUL_EXCEPTION; } void cpuid_hypervisor_leaves(const struct vcpu *v, uint32_t leaf, @@ -887,7 +886,8 @@ void cpuid_hypervisor_leaves(const struct vcpu *v, uint32_t leaf, case 2: res->a = 1; /* Number of hypercall-transfer pages */ /* MSR base address */ - res->b = is_viridian_domain(d) ? 0x40000200 : 0x40000000; + res->b = (is_viridian_domain(d) + ? MSR_XEN_ALT_START : MSR_HYPERVISOR_START); if ( is_pv_domain(d) ) /* Features */ res->c |= XEN_CPUID_FEAT1_MMU_PT_UPDATE_PRESERVE_AD; break; diff --git a/xen/include/asm-x86/msr-index.h b/xen/include/asm-x86/msr-index.h index ee029a2..2b4014c 100644 --- a/xen/include/asm-x86/msr-index.h +++ b/xen/include/asm-x86/msr-index.h @@ -543,5 +543,7 @@ /* Hypervisor leaves in the 0x4xxxxxxx range. */ #define MSR_HYPERVISOR_START 0x40000000 #define NR_VIRIDIAN_MSRS 0x00000200 +#define MSR_XEN_ALT_START 0x40000200 +#define NR_XEN_MSRS 0x00000100 #endif /* __ASM_MSR_INDEX_H */ diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 01bc89f..28f2db6 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -519,8 +519,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 |