mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
x86/msr: Split MSR_SPEC_CTRL handling
In order to fix a VT-x bug, and support MSR_SPEC_CTRL on AMD, move
MSR_SPEC_CTRL handling into the new {pv,hvm}_{get,set}_reg() infrastructure.
Duplicate the msrs->spec_ctrl.raw accesses in the PV and VT-x paths for now.
The SVM path is currently unreachable because of the CPUID policy.
No functional change.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
This commit is contained in:
1 parent
88d3ff7ab1
commit
6536688439
3 files changed
+33
-5
No files matched your search
@@ -2405,6 +2405,9 @@ static uint64_t vmx_get_reg(struct vcpu *v, unsigned int reg)
|
||||
|
||||
switch ( reg )
|
||||
{
|
||||
case MSR_SPEC_CTRL:
|
||||
return v->arch.msrs->spec_ctrl.raw;
|
||||
|
||||
default:
|
||||
printk(XENLOG_G_ERR "%s(%pv, 0x%08x) Bad register\n",
|
||||
__func__, v, reg);
|
||||
@@ -2419,6 +2422,10 @@ static void vmx_set_reg(struct vcpu *v, unsigned int reg, uint64_t val)
|
||||
|
||||
switch ( reg )
|
||||
{
|
||||
case MSR_SPEC_CTRL:
|
||||
v->arch.msrs->spec_ctrl.raw = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(XENLOG_G_ERR "%s(%pv, 0x%08x, 0x%016"PRIx64") Bad register\n",
|
||||
__func__, v, reg, val);
|
||||
|
||||
+17
-5
@@ -28,6 +28,7 @@
|
||||
#include <asm/hvm/nestedhvm.h>
|
||||
#include <asm/hvm/viridian.h>
|
||||
#include <asm/msr.h>
|
||||
#include <asm/pv/domain.h>
|
||||
#include <asm/setup.h>
|
||||
|
||||
#include <public/hvm/params.h>
|
||||
@@ -265,8 +266,7 @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val)
|
||||
case MSR_SPEC_CTRL:
|
||||
if ( !cp->feat.ibrsb )
|
||||
goto gp_fault;
|
||||
*val = msrs->spec_ctrl.raw;
|
||||
break;
|
||||
goto get_reg;
|
||||
|
||||
case MSR_INTEL_PLATFORM_INFO:
|
||||
*val = mp->platform_info.raw;
|
||||
@@ -424,6 +424,13 @@ int guest_rdmsr(struct vcpu *v, uint32_t msr, uint64_t *val)
|
||||
|
||||
return ret;
|
||||
|
||||
get_reg: /* Delegate register access to per-vm-type logic. */
|
||||
if ( is_pv_domain(d) )
|
||||
*val = pv_get_reg(v, msr);
|
||||
else
|
||||
*val = hvm_get_reg(v, msr);
|
||||
return X86EMUL_OKAY;
|
||||
|
||||
gp_fault:
|
||||
return X86EMUL_EXCEPTION;
|
||||
}
|
||||
@@ -513,9 +520,7 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
|
||||
|
||||
if ( val & rsvd )
|
||||
goto gp_fault; /* Rsvd bit set? */
|
||||
|
||||
msrs->spec_ctrl.raw = val;
|
||||
break;
|
||||
goto set_reg;
|
||||
|
||||
case MSR_PRED_CMD:
|
||||
if ( !cp->feat.ibrsb && !cp->extd.ibpb )
|
||||
@@ -663,6 +668,13 @@ int guest_wrmsr(struct vcpu *v, uint32_t msr, uint64_t val)
|
||||
|
||||
return ret;
|
||||
|
||||
set_reg: /* Delegate register access to per-vm-type logic. */
|
||||
if ( is_pv_domain(d) )
|
||||
pv_set_reg(v, msr, val);
|
||||
else
|
||||
hvm_set_reg(v, msr, val);
|
||||
return X86EMUL_OKAY;
|
||||
|
||||
gp_fault:
|
||||
return X86EMUL_EXCEPTION;
|
||||
}
|
||||
|
||||
@@ -92,12 +92,16 @@ void pv_emul_instruction_done(struct cpu_user_regs *regs, unsigned long rip)
|
||||
|
||||
uint64_t pv_get_reg(struct vcpu *v, unsigned int reg)
|
||||
{
|
||||
const struct vcpu_msrs *msrs = v->arch.msrs;
|
||||
struct domain *d = v->domain;
|
||||
|
||||
ASSERT(v == current || !vcpu_runnable(v));
|
||||
|
||||
switch ( reg )
|
||||
{
|
||||
case MSR_SPEC_CTRL:
|
||||
return msrs->spec_ctrl.raw;
|
||||
|
||||
default:
|
||||
printk(XENLOG_G_ERR "%s(%pv, 0x%08x) Bad register\n",
|
||||
__func__, v, reg);
|
||||
@@ -108,12 +112,17 @@ uint64_t pv_get_reg(struct vcpu *v, unsigned int reg)
|
||||
|
||||
void pv_set_reg(struct vcpu *v, unsigned int reg, uint64_t val)
|
||||
{
|
||||
struct vcpu_msrs *msrs = v->arch.msrs;
|
||||
struct domain *d = v->domain;
|
||||
|
||||
ASSERT(v == current || !vcpu_runnable(v));
|
||||
|
||||
switch ( reg )
|
||||
{
|
||||
case MSR_SPEC_CTRL:
|
||||
msrs->spec_ctrl.raw = val;
|
||||
break;
|
||||
|
||||
default:
|
||||
printk(XENLOG_G_ERR "%s(%pv, 0x%08x, 0x%016"PRIx64") Bad register\n",
|
||||
__func__, v, reg, val);
|
||||
|
||||