linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/2] Fix AMD SEV guest boot issue with PCID feature
@ 2020-11-12 22:17 Babu Moger
  2020-11-12 22:17 ` [PATCH v2 1/2] KVM: x86: Introduce cr3_lm_rsvd_bits in kvm_vcpu_arch Babu Moger
  2020-11-12 22:18 ` [PATCH v2 2/2] KVM:SVM: Update cr3_lm_rsvd_bits for AMD SEV guests Babu Moger
  0 siblings, 2 replies; 4+ messages in thread
From: Babu Moger @ 2020-11-12 22:17 UTC (permalink / raw)
  To: pbonzini
  Cc: junaids, wanpengli, kvm, joro, x86, linux-kernel,
	sean.j.christopherson, mingo, bp, hpa, tglx, vkuznets, jmattson

SEV guests fail to boot on systems that support the PCID feature.

The problem is observed with SMM enabled OVMF bios is used. The guest
crashes with the following messages on the console while loading.

----------------------------------------------------------------------
[    0.264224] tsc: Marking TSC unstable due to TSCs unsynchronized
[    0.264946] Calibrating delay loop (skipped) preset value.. 3194.00
                                                 BogoMIPS (lpj=1597000)
[    0.265946] pid_max: default: 65536 minimum: 512
KVM internal error. Suberror: 1
emulation failure
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=7ffac000 EBP=00000000 ESP=7ffa1ff8
EIP=7ffb4280 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0020 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
CS =0000 00000000 00000fff 00009b00 DPL=0 CS16 [-RA]
SS =0020 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
DS =0020 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
FS =0020 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
GS =0020 00000000 ffffffff 00c09300 DPL=0 DS   [-WA]
LDT=0000 00000000 00000000 00000000
TR =0040 00003000 00004087 00008b00 DPL=0 TSS64-busy
GDT=     fffffe0000001000 0000007f
IDT=     fffffe0000000000 00000fff
CR0=80050033 CR2=ffff88817ffff000 CR3=0008000107e12000 CR4=000606b0
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000
DR3=0000000000000000 DR6=00000000ffff0ff0 DR7=0000000000000400
EFER=0000000000000d01
----------------------------------------------------------------------

The issue is root caused to the way kvm tries to validate the cr3
address in kvm_set_cr3(). The cr3 address in SEV guests have the encryption
bit set. KVM fails because the reserved bit check fails on this address.

This series fixes the problem by introducing a new field in kvm_vcpu_arch
structure. The new field cr3_lm_rsvd_bits is initialized to 
rsvd_bits(cpuid_maxphyaddr(vcpu), 63) in kvm_vcpu_after_set_cpuid
and clear the any reserved bit specific to vendor in
kvm_x86_ops.vcpu_after_set_cpuid
---
v2: Changed the code suggested by Paolo. Added a new field in kvm_vcpu_arch
    to hold the reserved bits in cr3_lm_rsvd_bits.

v1:
https://lore.kernel.org/lkml/160514082171.31583.9995411273370528911.stgit@bmoger-ubuntu/

Babu Moger (2):
      KVM: x86: Introduce cr3_lm_rsvd_bits in kvm_vcpu_arch
      KVM:SVM: Update cr3_lm_rsvd_bits for AMD SEV guests


 arch/x86/include/asm/kvm_host.h |    1 +
 arch/x86/kvm/cpuid.c            |    2 ++
 arch/x86/kvm/svm/svm.c          |   11 +++++++++++
 arch/x86/kvm/x86.c              |    2 +-
 4 files changed, 15 insertions(+), 1 deletion(-)

--

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v2 1/2] KVM: x86: Introduce cr3_lm_rsvd_bits in kvm_vcpu_arch
  2020-11-12 22:17 [PATCH v2 0/2] Fix AMD SEV guest boot issue with PCID feature Babu Moger
@ 2020-11-12 22:17 ` Babu Moger
  2020-11-12 22:18 ` [PATCH v2 2/2] KVM:SVM: Update cr3_lm_rsvd_bits for AMD SEV guests Babu Moger
  1 sibling, 0 replies; 4+ messages in thread
From: Babu Moger @ 2020-11-12 22:17 UTC (permalink / raw)
  To: pbonzini
  Cc: junaids, wanpengli, kvm, joro, x86, linux-kernel,
	sean.j.christopherson, mingo, bp, hpa, tglx, vkuznets, jmattson

SEV guests fail to boot on a system that supports the PCID feature.

While emulating the RSM instruction, KVM reads the guest CR3
and calls kvm_set_cr3(). If the vCPU is in the long mode,
kvm_set_cr3() does a sanity check for the CR3 value. In this case,
it validates whether the value has any reserved bits set. The
reserved bit range is 63:cpuid_maxphysaddr(). When AMD memory
encryption is enabled, the memory encryption bit is set in the CR3
value. The memory encryption bit may fall within the KVM reserved
bit range, causing the KVM emulation failure.

Introduce a new field cr3_lm_rsvd_bits in kvm_vcpu_arch which will
cache the reserved bits in the CR3 value. This will be initialized
to rsvd_bits(cpuid_maxphyaddr(vcpu), 63).

If the architecture has any special bits(like AMD SEV encryption bit)
that needs to be masked from the reserved bits, should be cleared
in vendor specific kvm_x86_ops.vcpu_after_set_cpuid handler.

Fixes: a780a3ea628268b2 ("KVM: X86: Fix reserved bits check for MOV to CR3")
Signed-off-by: Babu Moger <babu.moger@amd.com>
---
 arch/x86/include/asm/kvm_host.h |    1 +
 arch/x86/kvm/cpuid.c            |    2 ++
 arch/x86/kvm/x86.c              |    2 +-
 3 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index d44858b69353..324ddd7fd0aa 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -639,6 +639,7 @@ struct kvm_vcpu_arch {
 	int cpuid_nent;
 	struct kvm_cpuid_entry2 *cpuid_entries;
 
+	unsigned long cr3_lm_rsvd_bits;
 	int maxphyaddr;
 	int max_tdp_level;
 
diff --git a/arch/x86/kvm/cpuid.c b/arch/x86/kvm/cpuid.c
index 06a278b3701d..cb52485cc507 100644
--- a/arch/x86/kvm/cpuid.c
+++ b/arch/x86/kvm/cpuid.c
@@ -169,6 +169,8 @@ static void kvm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 	vcpu->arch.cr4_guest_rsvd_bits =
 	    __cr4_reserved_bits(guest_cpuid_has, vcpu);
 
+	vcpu->arch.cr3_lm_rsvd_bits = rsvd_bits(cpuid_maxphyaddr(vcpu), 63);
+
 	/* Invoke the vendor callback only after the above state is updated. */
 	kvm_x86_ops.vcpu_after_set_cpuid(vcpu);
 }
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index f5ede41bf9e6..ff55e33b268b 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1042,7 +1042,7 @@ int kvm_set_cr3(struct kvm_vcpu *vcpu, unsigned long cr3)
 	}
 
 	if (is_long_mode(vcpu) &&
-	    (cr3 & rsvd_bits(cpuid_maxphyaddr(vcpu), 63)))
+	    (cr3 & vcpu->arch.cr3_lm_rsvd_bits))
 		return 1;
 	else if (is_pae_paging(vcpu) &&
 		 !load_pdptrs(vcpu, vcpu->arch.walk_mmu, cr3))


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v2 2/2] KVM:SVM: Update cr3_lm_rsvd_bits for AMD SEV guests
  2020-11-12 22:17 [PATCH v2 0/2] Fix AMD SEV guest boot issue with PCID feature Babu Moger
  2020-11-12 22:17 ` [PATCH v2 1/2] KVM: x86: Introduce cr3_lm_rsvd_bits in kvm_vcpu_arch Babu Moger
@ 2020-11-12 22:18 ` Babu Moger
  2020-11-13 11:30   ` Paolo Bonzini
  1 sibling, 1 reply; 4+ messages in thread
From: Babu Moger @ 2020-11-12 22:18 UTC (permalink / raw)
  To: pbonzini
  Cc: junaids, wanpengli, kvm, joro, x86, linux-kernel,
	sean.j.christopherson, mingo, bp, hpa, tglx, vkuznets, jmattson

For AMD SEV guests, update the cr3_lm_rsvd_bits to mask
the memory encryption bit in reserved bits.

Signed-off-by: Babu Moger <babu.moger@amd.com>
---
 arch/x86/kvm/svm/svm.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c
index 2f32fd09e259..b418eeabcccc 100644
--- a/arch/x86/kvm/svm/svm.c
+++ b/arch/x86/kvm/svm/svm.c
@@ -3741,6 +3741,7 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio)
 static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 {
 	struct vcpu_svm *svm = to_svm(vcpu);
+	struct kvm_cpuid_entry2 *best;
 
 	vcpu->arch.xsaves_enabled = guest_cpuid_has(vcpu, X86_FEATURE_XSAVE) &&
 				    boot_cpu_has(X86_FEATURE_XSAVE) &&
@@ -3753,6 +3754,16 @@ static void svm_vcpu_after_set_cpuid(struct kvm_vcpu *vcpu)
 	/* Check again if INVPCID interception if required */
 	svm_check_invpcid(svm);
 
+	/*
+	 * For sev guests, update the cr3_lm_rsvd_bits to mask the memory
+	 * encryption bit from reserved bits
+	 */
+	if (sev_guest(vcpu->kvm)) {
+		best = kvm_find_cpuid_entry(vcpu, 0x8000001F, 0);
+		if (best)
+			vcpu->arch.cr3_lm_rsvd_bits &= ~(1UL << (best->ebx & 0x3f));
+	}
+
 	if (!kvm_vcpu_apicv_active(vcpu))
 		return;
 


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v2 2/2] KVM:SVM: Update cr3_lm_rsvd_bits for AMD SEV guests
  2020-11-12 22:18 ` [PATCH v2 2/2] KVM:SVM: Update cr3_lm_rsvd_bits for AMD SEV guests Babu Moger
@ 2020-11-13 11:30   ` Paolo Bonzini
  0 siblings, 0 replies; 4+ messages in thread
From: Paolo Bonzini @ 2020-11-13 11:30 UTC (permalink / raw)
  To: Babu Moger
  Cc: junaids, wanpengli, kvm, joro, x86, linux-kernel,
	sean.j.christopherson, mingo, bp, hpa, tglx, vkuznets, jmattson

On 12/11/20 23:18, Babu Moger wrote:
> +	/*
> +	 * For sev guests, update the cr3_lm_rsvd_bits to mask the memory
> +	 * encryption bit from reserved bits
> +	 */

Say why in the comment, don't repeat what the code already says (ok, 
technically the code didn't say that CPUID[0x8000001F].ebx hosts the 
memory encryption bit).  I changed this to:

/* For sev guests, the memory encryption bit is not reserved in CR3.  */

and queued the patches,

Paolo

> +	if (sev_guest(vcpu->kvm)) {
> +		best = kvm_find_cpuid_entry(vcpu, 0x8000001F, 0);
> +		if (best)
> +			vcpu->arch.cr3_lm_rsvd_bits &= ~(1UL << (best->ebx & 0x3f));
> +	}
> +


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2020-11-13 11:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-12 22:17 [PATCH v2 0/2] Fix AMD SEV guest boot issue with PCID feature Babu Moger
2020-11-12 22:17 ` [PATCH v2 1/2] KVM: x86: Introduce cr3_lm_rsvd_bits in kvm_vcpu_arch Babu Moger
2020-11-12 22:18 ` [PATCH v2 2/2] KVM:SVM: Update cr3_lm_rsvd_bits for AMD SEV guests Babu Moger
2020-11-13 11:30   ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).