Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1718656 > unrolled thread

[PATCH 0/2] KVM, pkeys: fix handling of PKRU across migration

Started byPaolo Bonzini <pbonzini@redhat.com>
First post2017-08-23 23:30 +0200
Last post2017-08-23 23:30 +0200
Articles 2 — 1 participant

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/2] KVM, pkeys: fix handling of PKRU across migration Paolo Bonzini <pbonzini@redhat.com> - 2017-08-23 23:30 +0200
    [PATCH 2/2] KVM, pkeys: do not use PKRU value in vcpu->arch.guest_fpu.state Paolo Bonzini <pbonzini@redhat.com> - 2017-08-23 23:30 +0200

#1718656 — [PATCH 0/2] KVM, pkeys: fix handling of PKRU across migration

FromPaolo Bonzini <pbonzini@redhat.com>
Date2017-08-23 23:30 +0200
Subject[PATCH 0/2] KVM, pkeys: fix handling of PKRU across migration
Message-ID<uhLnP-5N6-5@gated-at.bofh.it>
The host pkru is restored right after vcpu exit (commit 1be0e61), so
KVM_GET_XSAVE will return the host PKRU value instead.  In general,
the PKRU value in vcpu->arch.guest_fpu.state cannot be trusted.

The first patch removes an unnecessary abstraction.  The second
fixes the bug.

Please test the patches, as I don't have the affected hardware.

Paolo

Paolo Bonzini (2):
  KVM: x86: simplify handling of PKRU
  KVM, pkeys: do not use PKRU value in vcpu->arch.guest_fpu.state

 arch/x86/include/asm/fpu/internal.h |  6 +++---
 arch/x86/include/asm/kvm_host.h     |  1 +
 arch/x86/kvm/kvm_cache_regs.h       |  5 -----
 arch/x86/kvm/mmu.h                  |  2 +-
 arch/x86/kvm/svm.c                  |  7 -------
 arch/x86/kvm/vmx.c                  | 23 ++++++-----------------
 arch/x86/kvm/x86.c                  | 17 ++++++++++++++---
 7 files changed, 25 insertions(+), 36 deletions(-)

-- 
1.8.3.1

[toc] | [next] | [standalone]


#1718659 — [PATCH 2/2] KVM, pkeys: do not use PKRU value in vcpu->arch.guest_fpu.state

FromPaolo Bonzini <pbonzini@redhat.com>
Date2017-08-23 23:30 +0200
Subject[PATCH 2/2] KVM, pkeys: do not use PKRU value in vcpu->arch.guest_fpu.state
Message-ID<uhLnQ-5N6-21@gated-at.bofh.it>
In reply to#1718656
The host pkru is restored right after vcpu exit (commit 1be0e61), so
KVM_GET_XSAVE will return the host PKRU value instead.  Fix this by
using the guest PKRU explicitly in fill_xsave and load_xsave.  This
part is based on a patch by Junkang Fu.

The host PKRU data may also not match the value in vcpu->arch.guest_fpu.state,
because it could have been changed by userspace since the last time
it was saved, so skip loading it in kvm_load_guest_fpu.

Reported-by: Junkang Fu <junkang.fjk@alibaba-inc.com>
Cc: Yang Zhang <zy107165@alibaba-inc.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 arch/x86/include/asm/fpu/internal.h |  6 +++---
 arch/x86/kvm/x86.c                  | 17 ++++++++++++++---
 2 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/fpu/internal.h b/arch/x86/include/asm/fpu/internal.h
index 255645f60ca2..554cdb205d17 100644
--- a/arch/x86/include/asm/fpu/internal.h
+++ b/arch/x86/include/asm/fpu/internal.h
@@ -450,10 +450,10 @@ static inline int copy_fpregs_to_fpstate(struct fpu *fpu)
 	return 0;
 }
 
-static inline void __copy_kernel_to_fpregs(union fpregs_state *fpstate)
+static inline void __copy_kernel_to_fpregs(union fpregs_state *fpstate, u64 mask)
 {
 	if (use_xsave()) {
-		copy_kernel_to_xregs(&fpstate->xsave, -1);
+		copy_kernel_to_xregs(&fpstate->xsave, mask);
 	} else {
 		if (use_fxsr())
 			copy_kernel_to_fxregs(&fpstate->fxsave);
@@ -477,7 +477,7 @@ static inline void copy_kernel_to_fpregs(union fpregs_state *fpstate)
 			: : [addr] "m" (fpstate));
 	}
 
-	__copy_kernel_to_fpregs(fpstate);
+	__copy_kernel_to_fpregs(fpstate, -1);
 }
 
 extern int copy_fpstate_to_sigframe(void __user *buf, void __user *fp, int size);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 55c709531eb9..f0e64801b457 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3265,7 +3265,12 @@ static void fill_xsave(u8 *dest, struct kvm_vcpu *vcpu)
 			u32 size, offset, ecx, edx;
 			cpuid_count(XSTATE_CPUID, index,
 				    &size, &offset, &ecx, &edx);
-			memcpy(dest + offset, src, size);
+			if (feature == XFEATURE_MASK_PKRU)
+				memcpy(dest + offset, &vcpu->arch.pkru,
+				       sizeof(vcpu->arch.pkru));
+			else
+				memcpy(dest + offset, src, size);
+
 		}
 
 		valid -= feature;
@@ -3303,7 +3308,11 @@ static void load_xsave(struct kvm_vcpu *vcpu, u8 *src)
 			u32 size, offset, ecx, edx;
 			cpuid_count(XSTATE_CPUID, index,
 				    &size, &offset, &ecx, &edx);
-			memcpy(dest, src + offset, size);
+			if (feature == XFEATURE_MASK_PKRU)
+				memcpy(&vcpu->arch.pkru, src + offset,
+				       sizeof(vcpu->arch.pkru));
+			else
+				memcpy(dest, src + offset, size);
 		}
 
 		valid -= feature;
@@ -7651,7 +7660,9 @@ void kvm_load_guest_fpu(struct kvm_vcpu *vcpu)
 	 */
 	vcpu->guest_fpu_loaded = 1;
 	__kernel_fpu_begin();
-	__copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state);
+	/* PKRU is separately restored in kvm_x86_ops->run.  */
+	__copy_kernel_to_fpregs(&vcpu->arch.guest_fpu.state,
+				~XFEATURE_MASK_PKRU);
 	trace_kvm_fpu(1);
 }
 
-- 
1.8.3.1

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web