diff mbox series

[RFC] Check if X86_FEATURE_OSPKE is supported before accessing pkru

Message ID 7A2C95E1327F7148AB122F200A3EFA4081905E57@dggema521-mbx.china.huawei.com (mailing list archive)
State New, archived
Headers show
Series [RFC] Check if X86_FEATURE_OSPKE is supported before accessing pkru | expand

Commit Message

Xiangyou Xie April 10, 2019, 3:43 p.m. UTC
Hi,

Commit b9dd21e104bcd45e124acfe978a79df71259e59b describes guest_CR4.PKE=1 implies host_CR4.PKE=1, and there is no need to judge OSPKE on the host.

However, I have found that the following scenarios may lead to inconsistencies with expectations:

1. The VM is migrated from the A host to the B host. The A host is configured
   with nopku but the B host is not.
2. The VM has an internal restart on the B host. The "setup_pku" is executed
   during the booting of the VM kernel. Because pku is supported, CR4.PKE is set.
3. Next, migrate the VM from the B host back to the A host. Panic will be
   triggered. Because vcpu vmexit will do host pkru restoring if guest_CR4.PKE
   is enabled.

static void vmx_vcpu_run(struct kvm_vcpu *vcpu) ...
	if (static_cpu_has(X86_FEATURE_PKU) &&
	    kvm_read_cr4_bits(vcpu, X86_CR4_PKE)) {
		vcpu->arch.pkru = __read_pkru();
		if (vcpu->arch.pkru != vmx->host_pkru)
			__write_pkru(vmx->host_pkru);
	}
...

Since hostos is configured with 'nopku', host CR4.PKE is 0, According to the intel manual, UD exception will occur when pkru is accessed in this case.

It is more appropriate to check X86_FEATURE_OSPKE than X86_FEATURE_PKU before accessing pkru.

Best Regards.
---
 arch/x86/kvm/vmx/vmx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

--
1.8.3.1

Comments

Paolo Bonzini April 10, 2019, 4:34 p.m. UTC | #1
On 10/04/19 17:43, Xiexiangyou wrote:
> 1. The VM is migrated from the A host to the B host. The A host is configured
>    with nopku but the B host is not.
> 2. The VM has an internal restart on the B host. The "setup_pku" is executed
>    during the booting of the VM kernel. Because pku is supported, CR4.PKE is set.
> 3. Next, migrate the VM from the B host back to the A host. Panic will be
>    triggered. Because vcpu vmexit will do host pkru restoring if guest_CR4.PKE
>    is enabled.

The VM should have never been migrated to host B, since it does not 
support setting guest CPUID.PKU

                        /* PKU is not yet implemented for shadow paging. */
                        if (!tdp_enabled || !boot_cpu_has(X86_FEATURE_OSPKE))
                                entry->ecx &= ~F(PKU);

Paolo
diff mbox series

Patch

diff --git a/arch/x86/kvm/vmx/vmx.c b/arch/x86/kvm/vmx/vmx.c index 30a6bcd..c4d4b09 100644
--- a/arch/x86/kvm/vmx/vmx.c
+++ b/arch/x86/kvm/vmx/vmx.c
@@ -6553,7 +6553,7 @@  static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 	if (vcpu->guest_debug & KVM_GUESTDBG_SINGLESTEP)
 		vmx_set_interrupt_shadow(vcpu, 0);
 
-	if (static_cpu_has(X86_FEATURE_PKU) &&
+	if (boot_cpu_has(X86_FEATURE_OSPKE) &&
 	    kvm_read_cr4_bits(vcpu, X86_CR4_PKE) &&
 	    vcpu->arch.pkru != vmx->host_pkru)
 		__write_pkru(vcpu->arch.pkru);
@@ -6633,7 +6633,7 @@  static void vmx_vcpu_run(struct kvm_vcpu *vcpu)
 	 * back on host, so it is safe to read guest PKRU from current
 	 * XSAVE.
 	 */
-	if (static_cpu_has(X86_FEATURE_PKU) &&
+	if (boot_cpu_has(X86_FEATURE_OSPKE) &&
 	    kvm_read_cr4_bits(vcpu, X86_CR4_PKE)) {
 		vcpu->arch.pkru = __read_pkru();
 		if (vcpu->arch.pkru != vmx->host_pkru)