switch ( input )
{
+ unsigned int sub_leaf, _eax, _ebx, _ecx, _edx;
+
case 0x1:
/* Fix up VLAPIC details. */
*ebx &= 0x00FFFFFFu;
*edx = v->vcpu_id * 2;
break;
case 0xd:
- {
- unsigned int sub_leaf, _eax, _ebx, _ecx, _edx;
/* EBX value of main leaf 0 depends on enabled xsave features */
if ( count == 0 && v->arch.xcr0 )
{
}
}
break;
- }
+
case 0x80000001:
/* We expose RDTSCP feature to guest only when
tsc_mode == TSC_MODE_DEFAULT and host_tsc_is_safe() returns 1 */
if ( !(hvm_pae_enabled(v) || hvm_long_mode_enabled(v)) )
*edx &= ~cpufeat_mask(X86_FEATURE_PSE36);
break;
+
+ case 0x80000008:
+ count = cpuid_eax(0x80000008);
+ count = (count >> 16) & 0xff ?: count & 0xff;
+ if ( (*eax & 0xff) > count )
+ *eax = (*eax & ~0xff) | count;
+
+ hvm_cpuid(1, NULL, NULL, NULL, &_edx);
+ count = _edx & (cpufeat_mask(X86_FEATURE_PAE) |
+ cpufeat_mask(X86_FEATURE_PSE36)) ? 36 : 32;
+ if ( (*eax & 0xff) < count )
+ *eax = (*eax & ~0xff) | count;
+
+ hvm_cpuid(0x80000001, NULL, NULL, NULL, &_edx);
+ *eax = (*eax & ~0xffff00) | (_edx & cpufeat_mask(X86_FEATURE_LM)
+ ? 0x3000 : 0x2000);
+ break;
}
}
static int __init hvm_mtrr_pat_init(void)
{
- unsigned int i, j, phys_addr;
+ unsigned int i, j;
for ( i = 0; i < MTRR_NUM_TYPES; i++ )
{
}
}
- phys_addr = 36;
- if ( cpuid_eax(0x80000000) >= 0x80000008 )
- phys_addr = (uint8_t)cpuid_eax(0x80000008);
-
- size_or_mask = ~((1 << (phys_addr - PAGE_SHIFT)) - 1);
+ size_or_mask = ~((1 << (paddr_bits - PAGE_SHIFT)) - 1);
return 0;
}
bool_t mtrr_var_range_msr_set(
struct domain *d, struct mtrr_state *m, uint32_t msr, uint64_t msr_content)
{
- uint32_t index, phys_addr, eax, ebx, ecx, edx;
+ uint32_t index, phys_addr, eax;
uint64_t msr_mask;
uint64_t *var_range_base = (uint64_t*)m->var_ranges;
if ( unlikely(!valid_mtrr_type((uint8_t)msr_content)) )
return 0;
- phys_addr = 36;
- domain_cpuid(d, 0x80000000, 0, &eax, &ebx, &ecx, &edx);
- if ( eax >= 0x80000008 )
+ if ( d == current->domain )
{
- domain_cpuid(d, 0x80000008, 0, &eax, &ebx, &ecx, &edx);
- phys_addr = (uint8_t)eax;
+ phys_addr = 36;
+ hvm_cpuid(0x80000000, &eax, NULL, NULL, NULL);
+ if ( eax >= 0x80000008 )
+ {
+ hvm_cpuid(0x80000008, &eax, NULL, NULL, NULL);
+ phys_addr = (uint8_t)eax;
+ }
}
+ else
+ phys_addr = paddr_bits;
msr_mask = ~((((uint64_t)1) << phys_addr) - 1);
msr_mask |= (index & 1) ? 0x7ffUL : 0xf00UL;
- if ( unlikely(msr_content && (msr_content & msr_mask)) )
+ if ( unlikely(msr_content & msr_mask) )
{
HVM_DBG_LOG(DBG_LEVEL_MSR, "invalid msr content:%"PRIx64"\n",
msr_content);