@@ -144,4 +144,7 @@
#define X86_FEATURE_CLFLUSHOPT 23 /* CLFLUSHOPT instruction */
#define X86_FEATURE_CLWB 24 /* CLWB instruction */
+/* Intel-defined CPU features, CPUID level 0x00000007:0 (ecx) */
+#define X86_FEATURE_PKU 3
+
#endif /* __LIBXC_CPUFEATURE_H */
@@ -430,9 +430,11 @@ static void xc_cpuid_hvm_policy(xc_interface *xch,
bitmaskof(X86_FEATURE_PCOMMIT) |
bitmaskof(X86_FEATURE_CLWB) |
bitmaskof(X86_FEATURE_CLFLUSHOPT));
+ regs[2] &= bitmaskof(X86_FEATURE_PKU);
} else
- regs[1] = 0;
- regs[0] = regs[2] = regs[3] = 0;
+ regs[1] = regs[2] = 0;
+
+ regs[0] = regs[3] = 0;
break;
case 0x0000000d:
@@ -4572,9 +4572,11 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
__clear_bit(X86_FEATURE_APIC & 31, edx);
/* Fix up OSXSAVE. */
- if ( cpu_has_xsave )
- *ecx |= (v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSXSAVE) ?
- cpufeat_mask(X86_FEATURE_OSXSAVE) : 0;
+ if ( *ecx & cpufeat_mask(X86_FEATURE_XSAVE) &&
+ (v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_OSXSAVE) )
+ *ecx |= cpufeat_mask(X86_FEATURE_OSXSAVE);
+ else
+ *ecx &= ~cpufeat_mask(X86_FEATURE_OSXSAVE);
/* Don't expose PCID to non-hap hvm. */
if ( !hap_enabled(d) )
@@ -4593,16 +4595,26 @@ void hvm_cpuid(unsigned int input, unsigned int *eax, unsigned int *ebx,
if ( !cpu_has_smap )
*ebx &= ~cpufeat_mask(X86_FEATURE_SMAP);
- /* Don't expose MPX to hvm when VMX support is not available */
+ /* Don't expose MPX to hvm when VMX support is not available. */
if ( !(vmx_vmexit_control & VM_EXIT_CLEAR_BNDCFGS) ||
!(vmx_vmentry_control & VM_ENTRY_LOAD_BNDCFGS) )
*ebx &= ~cpufeat_mask(X86_FEATURE_MPX);
- /* Don't expose INVPCID to non-hap hvm. */
if ( !hap_enabled(d) )
- *ebx &= ~cpufeat_mask(X86_FEATURE_INVPCID);
+ {
+ /* Don't expose INVPCID to non-hap hvm. */
+ *ebx &= ~cpufeat_mask(X86_FEATURE_INVPCID);
+ /* X86_FEATURE_PKU is not yet implemented for shadow paging. */
+ *ecx &= ~cpufeat_mask(X86_FEATURE_PKU);
+ }
+
+ if ( (*ecx & cpufeat_mask(X86_FEATURE_PKU)) &&
+ (v->arch.hvm_vcpu.guest_cr[4] & X86_CR4_PKE) )
+ *ecx |= cpufeat_mask(X86_FEATURE_OSPKE);
+ else
+ *ecx &= ~cpufeat_mask(X86_FEATURE_OSPKE);
- /* Don't expose PCOMMIT to hvm when VMX support is not available */
+ /* Don't expose PCOMMIT to hvm when VMX support is not available. */
if ( !cpu_has_vmx_pcommit )
*ebx &= ~cpufeat_mask(X86_FEATURE_PCOMMIT);
}