public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: x86: Fix the condition of #PF interception caused by MKTME
@ 2024-03-19  3:11 Tao Su
  2024-04-09  2:01 ` Sean Christopherson
  2024-04-09 19:05 ` Sean Christopherson
  0 siblings, 2 replies; 5+ messages in thread
From: Tao Su @ 2024-03-19  3:11 UTC (permalink / raw)
  To: kvm; +Cc: seanjc, pbonzini, chao.gao, xiaoyao.li, tao1.su

Intel MKTME repurposes several high bits of physical address as 'keyID',
so boot_cpu_data.x86_phys_bits doesn't hold physical address bits reported
by CPUID anymore.

If guest.MAXPHYADDR < host.MAXPHYADDR, the bit field of ‘keyID’ belongs
to reserved bits in guest’s view, so intercepting #PF to fix error code
is necessary, just replace boot_cpu_data.x86_phys_bits with
kvm_get_shadow_phys_bits() to fix.

Signed-off-by: Tao Su <tao1.su@linux.intel.com>
---
 arch/x86/kvm/vmx/vmx.h | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
index 65786dbe7d60..79b1757df74a 100644
--- a/arch/x86/kvm/vmx/vmx.h
+++ b/arch/x86/kvm/vmx/vmx.h
@@ -15,6 +15,7 @@
 #include "vmx_ops.h"
 #include "../cpuid.h"
 #include "run_flags.h"
+#include "../mmu.h"
 
 #define MSR_TYPE_R	1
 #define MSR_TYPE_W	2
@@ -719,7 +720,8 @@ static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu)
 	if (!enable_ept)
 		return true;
 
-	return allow_smaller_maxphyaddr && cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits;
+	return allow_smaller_maxphyaddr &&
+		cpuid_maxphyaddr(vcpu) < kvm_get_shadow_phys_bits();
 }
 
 static inline bool is_unrestricted_guest(struct kvm_vcpu *vcpu)

base-commit: b3603fcb79b1036acae10602bffc4855a4b9af80
-- 
2.34.1


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

* Re: [PATCH] KVM: x86: Fix the condition of #PF interception caused by MKTME
  2024-03-19  3:11 [PATCH] KVM: x86: Fix the condition of #PF interception caused by MKTME Tao Su
@ 2024-04-09  2:01 ` Sean Christopherson
  2024-04-09  3:54   ` Xiaoyao Li
  2024-04-09 19:05 ` Sean Christopherson
  1 sibling, 1 reply; 5+ messages in thread
From: Sean Christopherson @ 2024-04-09  2:01 UTC (permalink / raw)
  To: Sean Christopherson, kvm, Tao Su; +Cc: pbonzini, chao.gao, xiaoyao.li

On Tue, 19 Mar 2024 11:11:11 +0800, Tao Su wrote:
> Intel MKTME repurposes several high bits of physical address as 'keyID',
> so boot_cpu_data.x86_phys_bits doesn't hold physical address bits reported
> by CPUID anymore.
> 
> If guest.MAXPHYADDR < host.MAXPHYADDR, the bit field of ‘keyID’ belongs
> to reserved bits in guest’s view, so intercepting #PF to fix error code
> is necessary, just replace boot_cpu_data.x86_phys_bits with
> kvm_get_shadow_phys_bits() to fix.
> 
> [...]

Applied to kvm-x86 fixes, with a massaged shortlog/changelog.

Note, I don't love using kvm_get_shadow_phys_bits(), but only because doing
CPUID every time is so pointlessly suboptimal.  I have a series to clean up all
of the related code, which I'll hopefully post later this week.

But I didn't see any reason to hold up this fix, as I really hope no one is
using allow_smaller_maxphyaddr in a nested VM with EPT enabled, which is the
only case where CPUID is likely to have a meaningful impact (due to causing a
VM-Exit).

[1/1] KVM: x86: Fix the condition of #PF interception caused by MKTME
      https://github.com/kvm-x86/linux/commit/7f2817ef52a1

--
https://github.com/kvm-x86/linux/tree/next

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

* Re: [PATCH] KVM: x86: Fix the condition of #PF interception caused by MKTME
  2024-04-09  2:01 ` Sean Christopherson
@ 2024-04-09  3:54   ` Xiaoyao Li
  0 siblings, 0 replies; 5+ messages in thread
From: Xiaoyao Li @ 2024-04-09  3:54 UTC (permalink / raw)
  To: Sean Christopherson, kvm, Tao Su; +Cc: pbonzini, chao.gao

On 4/9/2024 10:01 AM, Sean Christopherson wrote:
> On Tue, 19 Mar 2024 11:11:11 +0800, Tao Su wrote:
>> Intel MKTME repurposes several high bits of physical address as 'keyID',
>> so boot_cpu_data.x86_phys_bits doesn't hold physical address bits reported
>> by CPUID anymore.
>>
>> If guest.MAXPHYADDR < host.MAXPHYADDR, the bit field of ‘keyID’ belongs
>> to reserved bits in guest’s view, so intercepting #PF to fix error code
>> is necessary, just replace boot_cpu_data.x86_phys_bits with
>> kvm_get_shadow_phys_bits() to fix.
>>
>> [...]
> 
> Applied to kvm-x86 fixes, with a massaged shortlog/changelog.
> 
> Note, I don't love using kvm_get_shadow_phys_bits(), 

cannot agree more.

> but only because doing
> CPUID every time is so pointlessly suboptimal.  I have a series to clean up all
> of the related code, which I'll hopefully post later this week.

Look forward to it.

> But I didn't see any reason to hold up this fix, as I really hope no one is
> using allow_smaller_maxphyaddr in a nested VM with EPT enabled, which is the
> only case where CPUID is likely to have a meaningful impact (due to causing a
> VM-Exit).
> 
> [1/1] KVM: x86: Fix the condition of #PF interception caused by MKTME
>        https://github.com/kvm-x86/linux/commit/7f2817ef52a1
> 
> --
> https://github.com/kvm-x86/linux/tree/next


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

* Re: [PATCH] KVM: x86: Fix the condition of #PF interception caused by MKTME
  2024-03-19  3:11 [PATCH] KVM: x86: Fix the condition of #PF interception caused by MKTME Tao Su
  2024-04-09  2:01 ` Sean Christopherson
@ 2024-04-09 19:05 ` Sean Christopherson
  2024-04-10  1:20   ` Tao Su
  1 sibling, 1 reply; 5+ messages in thread
From: Sean Christopherson @ 2024-04-09 19:05 UTC (permalink / raw)
  To: Tao Su; +Cc: kvm, pbonzini, chao.gao, xiaoyao.li

On Tue, Mar 19, 2024, Tao Su wrote:
> Intel MKTME repurposes several high bits of physical address as 'keyID',
> so boot_cpu_data.x86_phys_bits doesn't hold physical address bits reported
> by CPUID anymore.
> 
> If guest.MAXPHYADDR < host.MAXPHYADDR, the bit field of ‘keyID’ belongs
> to reserved bits in guest’s view, so intercepting #PF to fix error code
> is necessary, just replace boot_cpu_data.x86_phys_bits with
> kvm_get_shadow_phys_bits() to fix.
> 
> Signed-off-by: Tao Su <tao1.su@linux.intel.com>
> ---
>  arch/x86/kvm/vmx/vmx.h | 4 +++-
>  1 file changed, 3 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
> index 65786dbe7d60..79b1757df74a 100644
> --- a/arch/x86/kvm/vmx/vmx.h
> +++ b/arch/x86/kvm/vmx/vmx.h
> @@ -15,6 +15,7 @@
>  #include "vmx_ops.h"
>  #include "../cpuid.h"
>  #include "run_flags.h"
> +#include "../mmu.h"
>  
>  #define MSR_TYPE_R	1
>  #define MSR_TYPE_W	2
> @@ -719,7 +720,8 @@ static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu)
>  	if (!enable_ept)
>  		return true;
>  
> -	return allow_smaller_maxphyaddr && cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits;
> +	return allow_smaller_maxphyaddr &&
> +		cpuid_maxphyaddr(vcpu) < kvm_get_shadow_phys_bits();

For posterity, because I had a brief moment where I thought we done messed up:

No change is needed in the reporting of MAXPHYADDR in KVM_GET_SUPPORTED_CPUID,
as reporting boot_cpu_data.x86_phys_bits as MAXPHYADDR when TDP is disabled is ok
because KVM always intercepts #PF when TDP is disabled, and KVM already reports
the full/raw MAXPHYADDR when TDP is enabled.

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

* Re: [PATCH] KVM: x86: Fix the condition of #PF interception caused by MKTME
  2024-04-09 19:05 ` Sean Christopherson
@ 2024-04-10  1:20   ` Tao Su
  0 siblings, 0 replies; 5+ messages in thread
From: Tao Su @ 2024-04-10  1:20 UTC (permalink / raw)
  To: Sean Christopherson; +Cc: kvm, pbonzini, chao.gao, xiaoyao.li

On Tue, Apr 09, 2024 at 12:05:12PM -0700, Sean Christopherson wrote:
> On Tue, Mar 19, 2024, Tao Su wrote:
> > Intel MKTME repurposes several high bits of physical address as 'keyID',
> > so boot_cpu_data.x86_phys_bits doesn't hold physical address bits reported
> > by CPUID anymore.
> > 
> > If guest.MAXPHYADDR < host.MAXPHYADDR, the bit field of ‘keyID’ belongs
> > to reserved bits in guest’s view, so intercepting #PF to fix error code
> > is necessary, just replace boot_cpu_data.x86_phys_bits with
> > kvm_get_shadow_phys_bits() to fix.
> > 
> > Signed-off-by: Tao Su <tao1.su@linux.intel.com>
> > ---
> >  arch/x86/kvm/vmx/vmx.h | 4 +++-
> >  1 file changed, 3 insertions(+), 1 deletion(-)
> > 
> > diff --git a/arch/x86/kvm/vmx/vmx.h b/arch/x86/kvm/vmx/vmx.h
> > index 65786dbe7d60..79b1757df74a 100644
> > --- a/arch/x86/kvm/vmx/vmx.h
> > +++ b/arch/x86/kvm/vmx/vmx.h
> > @@ -15,6 +15,7 @@
> >  #include "vmx_ops.h"
> >  #include "../cpuid.h"
> >  #include "run_flags.h"
> > +#include "../mmu.h"
> >  
> >  #define MSR_TYPE_R	1
> >  #define MSR_TYPE_W	2
> > @@ -719,7 +720,8 @@ static inline bool vmx_need_pf_intercept(struct kvm_vcpu *vcpu)
> >  	if (!enable_ept)
> >  		return true;
> >  
> > -	return allow_smaller_maxphyaddr && cpuid_maxphyaddr(vcpu) < boot_cpu_data.x86_phys_bits;
> > +	return allow_smaller_maxphyaddr &&
> > +		cpuid_maxphyaddr(vcpu) < kvm_get_shadow_phys_bits();
> 
> For posterity, because I had a brief moment where I thought we done messed up:
> 
> No change is needed in the reporting of MAXPHYADDR in KVM_GET_SUPPORTED_CPUID,
> as reporting boot_cpu_data.x86_phys_bits as MAXPHYADDR when TDP is disabled is ok
> because KVM always intercepts #PF when TDP is disabled, and KVM already reports
> the full/raw MAXPHYADDR when TDP is enabled.

You are right, but userspace can fully control guest.MAXPHYADDR when TDP is enabled.
Please see the unit-test[*], I think this issue could show up earlier if phys-bits
is set larger, such as 46-bits.

[*] https://gitlab.com/kvm-unit-tests/kvm-unit-tests/-/blob/master/x86/unittests.cfg?ref_type=heads#L156

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

end of thread, other threads:[~2024-04-10  1:23 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-03-19  3:11 [PATCH] KVM: x86: Fix the condition of #PF interception caused by MKTME Tao Su
2024-04-09  2:01 ` Sean Christopherson
2024-04-09  3:54   ` Xiaoyao Li
2024-04-09 19:05 ` Sean Christopherson
2024-04-10  1:20   ` Tao Su

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox