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);
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);
#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>
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;
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;
}
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 )
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;
}
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);
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);