... rather than from the default clauses of the PV and HVM MSR handlers.
This means that we no longer take the vmce lock for any unknown MSR, and
accesses to architectural MCE banks outside of the subset implemented for the
guest no longer fall further through the unknown MSR path.
The bank limit of 32 isn't stated anywhere I can locate, but is a consequence
of the MSR layout described in SDM Volume 4.
With the vmce calls removed, the hvm alternative_call()'s expression can be
simplified substantially.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>
break;
default:
- if ( (ret = vmce_rdmsr(msr, msr_content)) < 0 )
- goto gp_fault;
- /* If ret == 0 then this is not an MCE MSR, see other MSRs. */
- ret = ((ret == 0)
- ? alternative_call(hvm_funcs.msr_read_intercept,
- msr, msr_content)
- : X86EMUL_OKAY);
+ ret = alternative_call(hvm_funcs.msr_read_intercept, msr, msr_content);
break;
}
break;
default:
- if ( (ret = vmce_wrmsr(msr, msr_content)) < 0 )
- goto gp_fault;
- /* If ret == 0 then this is not an MCE MSR, see other MSRs. */
- ret = ((ret == 0)
- ? alternative_call(hvm_funcs.msr_write_intercept,
- msr, msr_content)
- : X86EMUL_OKAY);
+ ret = alternative_call(hvm_funcs.msr_write_intercept, msr, msr_content);
break;
}
*val = msrs->misc_features_enables.raw;
break;
+ case MSR_IA32_MCG_CAP ... MSR_IA32_MCG_CTL: /* 0x179 -> 0x17b */
+ case MSR_IA32_MCx_CTL2(0) ... MSR_IA32_MCx_CTL2(31): /* 0x280 -> 0x29f */
+ case MSR_IA32_MCx_CTL(0) ... MSR_IA32_MCx_MISC(31): /* 0x400 -> 0x47f */
+ case MSR_IA32_MCG_EXT_CTL: /* 0x4d0 */
+ if ( vmce_rdmsr(msr, val) < 0 )
+ goto gp_fault;
+ break;
+
case MSR_X2APIC_FIRST ... MSR_X2APIC_LAST:
if ( !is_hvm_domain(d) || v != curr )
goto gp_fault;
break;
}
+ case MSR_IA32_MCG_CAP ... MSR_IA32_MCG_CTL: /* 0x179 -> 0x17b */
+ case MSR_IA32_MCx_CTL2(0) ... MSR_IA32_MCx_CTL2(31): /* 0x280 -> 0x29f */
+ case MSR_IA32_MCx_CTL(0) ... MSR_IA32_MCx_MISC(31): /* 0x400 -> 0x47f */
+ case MSR_IA32_MCG_EXT_CTL: /* 0x4d0 */
+ if ( vmce_wrmsr(msr, val) < 0 )
+ goto gp_fault;
+ break;
+
case MSR_X2APIC_FIRST ... MSR_X2APIC_LAST:
if ( !is_hvm_domain(d) || v != curr )
goto gp_fault;
switch ( reg )
{
- int rc;
-
case MSR_FS_BASE:
if ( is_pv_32bit_domain(currd) )
break;
}
/* fall through */
default:
- rc = vmce_rdmsr(reg, val);
- if ( rc < 0 )
- break;
- if ( rc )
- return X86EMUL_OKAY;
- /* fall through */
normal:
/* Everyone can read the MSR space. */
/* gdprintk(XENLOG_WARNING, "Domain attempted RDMSR %08x\n", reg); */
switch ( reg )
{
uint64_t temp;
- int rc;
case MSR_FS_BASE:
if ( is_pv_32bit_domain(currd) || !is_canonical_address(val) )
}
/* fall through */
default:
- rc = vmce_wrmsr(reg, val);
- if ( rc < 0 )
- break;
- if ( rc )
- return X86EMUL_OKAY;
-
if ( (rdmsr_safe(reg, temp) != 0) || (val != temp) )
invalid:
gdprintk(XENLOG_WARNING,