Skip to content

Commit

Permalink
x86/svm: Fold nsvm_{wr,rd}msr() into svm_msr_{read,write}_intercept()
Browse files Browse the repository at this point in the history
... to simplify the default cases.

There are multiple errors with the handling of these three MSRs, but they are
deliberately not addressed at this point.

This removes the dance converting -1/0/1 into X86EMUL_*, allowing for the
removal of the 'ret' variable.

While cleaning this up, drop the gdprintk()'s for #GP conditions, and the
'result' variable from svm_msr_write_intercept() as it is never modified.

No functional change.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
  • Loading branch information
andyhhp committed Jul 22, 2020
1 parent f3885e8 commit 26707b7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 96 deletions.
77 changes: 0 additions & 77 deletions xen/arch/x86/hvm/svm/nestedsvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,22 +47,6 @@ nestedsvm_vcpu_stgi(struct vcpu *v)
local_event_delivery_enable(); /* unmask events for PV drivers */
}

static int
nestedsvm_vmcb_isvalid(struct vcpu *v, uint64_t vmcxaddr)
{
/* Address must be 4k aligned */
if ( (vmcxaddr & ~PAGE_MASK) != 0 )
return 0;

/* Maximum valid physical address.
* See AMD BKDG for HSAVE_PA MSR.
*/
if ( vmcxaddr > 0xfd00000000ULL )
return 0;

return 1;
}

int nestedsvm_vmcb_map(struct vcpu *v, uint64_t vmcbaddr)
{
struct nestedvcpu *nv = &vcpu_nestedhvm(v);
Expand Down Expand Up @@ -1263,67 +1247,6 @@ enum hvm_intblk nsvm_intr_blocked(struct vcpu *v)
return hvm_intblk_none;
}

/* MSR handling */
int nsvm_rdmsr(struct vcpu *v, unsigned int msr, uint64_t *msr_content)
{
struct nestedsvm *svm = &vcpu_nestedsvm(v);
int ret = 1;

*msr_content = 0;

switch (msr) {
case MSR_K8_VM_CR:
break;
case MSR_K8_VM_HSAVE_PA:
*msr_content = svm->ns_msr_hsavepa;
break;
case MSR_AMD64_TSC_RATIO:
*msr_content = svm->ns_tscratio;
break;
default:
ret = 0;
break;
}

return ret;
}

int nsvm_wrmsr(struct vcpu *v, unsigned int msr, uint64_t msr_content)
{
int ret = 1;
struct nestedsvm *svm = &vcpu_nestedsvm(v);

switch (msr) {
case MSR_K8_VM_CR:
/* ignore write. handle all bits as read-only. */
break;
case MSR_K8_VM_HSAVE_PA:
if (!nestedsvm_vmcb_isvalid(v, msr_content)) {
gdprintk(XENLOG_ERR,
"MSR_K8_VM_HSAVE_PA value invalid %#"PRIx64"\n", msr_content);
ret = -1; /* inject #GP */
break;
}
svm->ns_msr_hsavepa = msr_content;
break;
case MSR_AMD64_TSC_RATIO:
if ((msr_content & ~TSC_RATIO_RSVD_BITS) != msr_content) {
gdprintk(XENLOG_ERR,
"reserved bits set in MSR_AMD64_TSC_RATIO %#"PRIx64"\n",
msr_content);
ret = -1; /* inject #GP */
break;
}
svm->ns_tscratio = msr_content;
break;
default:
ret = 0;
break;
}

return ret;
}

/* VMEXIT emulation */
void
nestedsvm_vmexit_defer(struct vcpu *v,
Expand Down
46 changes: 31 additions & 15 deletions xen/arch/x86/hvm/svm/svm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1788,10 +1788,10 @@ static void svm_dr_access(struct vcpu *v, struct cpu_user_regs *regs)

static int svm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
{
int ret;
struct vcpu *v = current;
const struct domain *d = v->domain;
struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
const struct nestedsvm *nsvm = &vcpu_nestedsvm(v);

switch ( msr )
{
Expand Down Expand Up @@ -1914,6 +1914,18 @@ static int svm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
goto gpf;
break;

case MSR_K8_VM_CR:
*msr_content = 0;
break;

case MSR_K8_VM_HSAVE_PA:
*msr_content = nsvm->ns_msr_hsavepa;
break;

case MSR_AMD64_TSC_RATIO:
*msr_content = nsvm->ns_tscratio;
break;

case MSR_AMD_OSVW_ID_LENGTH:
case MSR_AMD_OSVW_STATUS:
if ( !d->arch.cpuid->extd.osvw )
Expand All @@ -1922,12 +1934,6 @@ static int svm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)
break;

default:
ret = nsvm_rdmsr(v, msr, msr_content);
if ( ret < 0 )
goto gpf;
else if ( ret )
break;

if ( rdmsr_safe(msr, *msr_content) == 0 )
break;

Expand Down Expand Up @@ -1956,10 +1962,10 @@ static int svm_msr_read_intercept(unsigned int msr, uint64_t *msr_content)

static int svm_msr_write_intercept(unsigned int msr, uint64_t msr_content)
{
int ret, result = X86EMUL_OKAY;
struct vcpu *v = current;
struct domain *d = v->domain;
struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
struct nestedsvm *nsvm = &vcpu_nestedsvm(v);

switch ( msr )
{
Expand Down Expand Up @@ -2085,6 +2091,22 @@ static int svm_msr_write_intercept(unsigned int msr, uint64_t msr_content)
goto gpf;
break;

case MSR_K8_VM_CR:
/* ignore write. handle all bits as read-only. */
break;

case MSR_K8_VM_HSAVE_PA:
if ( (msr_content & ~PAGE_MASK) || msr_content > 0xfd00000000ULL )
goto gpf;
nsvm->ns_msr_hsavepa = msr_content;
break;

case MSR_AMD64_TSC_RATIO:
if ( msr_content & TSC_RATIO_RSVD_BITS )
goto gpf;
nsvm->ns_tscratio = msr_content;
break;

case MSR_IA32_MCx_MISC(4): /* Threshold register */
case MSR_F10_MC4_MISC1 ... MSR_F10_MC4_MISC3:
/*
Expand All @@ -2102,20 +2124,14 @@ static int svm_msr_write_intercept(unsigned int msr, uint64_t msr_content)
break;

default:
ret = nsvm_wrmsr(v, msr, msr_content);
if ( ret < 0 )
goto gpf;
else if ( ret )
break;

/* Match up with the RDMSR side; ultimately this should go away. */
if ( rdmsr_safe(msr, msr_content) == 0 )
break;

goto gpf;
}

return result;
return X86EMUL_OKAY;

gpf:
return X86EMUL_EXCEPTION;
Expand Down
4 changes: 0 additions & 4 deletions xen/include/asm-x86/hvm/svm/nestedsvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,6 @@ bool_t nsvm_vmcb_guest_intercepts_event(
bool_t nsvm_vmcb_hap_enabled(struct vcpu *v);
enum hvm_intblk nsvm_intr_blocked(struct vcpu *v);

/* MSRs */
int nsvm_rdmsr(struct vcpu *v, unsigned int msr, uint64_t *msr_content);
int nsvm_wrmsr(struct vcpu *v, unsigned int msr, uint64_t msr_content);

/* Interrupts, vGIF */
void svm_vmexit_do_clgi(struct cpu_user_regs *regs, struct vcpu *v);
void svm_vmexit_do_stgi(struct cpu_user_regs *regs, struct vcpu *v);
Expand Down

0 comments on commit 26707b7

Please sign in to comment.