All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sean Christopherson <seanjc@google.com>
To: Jing Liu <jing2.liu@intel.com>
Cc: x86@kernel.org, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-doc@vger.kernel.org,
	linux-kselftest@vger.kernel.org, tglx@linutronix.de,
	mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
	pbonzini@redhat.com, corbet@lwn.net, shuah@kernel.org,
	jun.nakajima@intel.com, kevin.tian@intel.com,
	jing2.liu@linux.intel.com, guang.zeng@intel.com,
	wei.w.wang@intel.com, yang.zhong@intel.com
Subject: Re: [PATCH v3 13/22] kvm: x86: Intercept #NM for saving IA32_XFD_ERR
Date: Wed, 29 Dec 2021 00:09:45 +0000	[thread overview]
Message-ID: <YcunSb52LlGKT7dC@google.com> (raw)
In-Reply-To: <20211222124052.644626-14-jing2.liu@intel.com>

On Wed, Dec 22, 2021, Jing Liu wrote:
> Guest IA32_XFD_ERR is generally modified in two places:
> 
>   - Set by CPU when #NM is triggered;
>   - Cleared by guest in its #NM handler;
> 
> Intercept #NM for the first case, if guest writes XFD as nonzero for
> the first time which indicates guest is possible to use XFD generating
> the exception. #NM is rare if the guest doesn't use dynamic features.
> Otherwise, there is at most one exception per guest task given a
> dynamic feature.
> 
> Save the current XFD_ERR value to the guest_fpu container in the #NM
> VM-exit handler. This must be done with interrupt/preemption disabled,

Assuming my below understanding is correct, drop the "preemption" bit, it's
misleading.

> otherwise the unsaved MSR value may be clobbered by host operations.
> 
> Inject a virtual #NM to the guest after saving the MSR value.
> 
> Restore the host value (always ZERO outside of the host #NM
> handler) before enabling preemption.

AIUI, changelog is wrong, code is right.  This must be done before _IRQs_ are
enabled, same as handling TIF_NEED_FPU_LOAD. 

> Restore the guest value from the guest_fpu container right before
> entering the guest (with preemption disabled).

Same complaint about preemption.

> Suggested-by: Thomas Gleixner <tglx@linutronix.de>
> Signed-off-by: Jing Liu <jing2.liu@intel.com>
> ---
>  arch/x86/include/asm/kvm_host.h |  1 +
>  arch/x86/kvm/vmx/vmcs.h         |  5 +++++
>  arch/x86/kvm/vmx/vmx.c          | 22 +++++++++++++++++++++-
>  arch/x86/kvm/x86.c              |  6 ++++++
>  4 files changed, 33 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
> index 555f4de47ef2..f7a661f35d1a 100644
> --- a/arch/x86/include/asm/kvm_host.h
> +++ b/arch/x86/include/asm/kvm_host.h
> @@ -640,6 +640,7 @@ struct kvm_vcpu_arch {
>  	u64 smi_count;
>  	bool tpr_access_reporting;
>  	bool xsaves_enabled;
> +	bool trap_nm;
>  	u64 ia32_xss;
>  	u64 microcode_version;
>  	u64 arch_capabilities;

...

> @@ -763,6 +764,9 @@ void vmx_update_exception_bitmap(struct kvm_vcpu *vcpu)
>  		vmcs_write32(PAGE_FAULT_ERROR_CODE_MATCH, match);
>  	}
>  
> +	if (vcpu->arch.trap_nm)
> +		eb |= (1u << NM_VECTOR);
> +
>  	vmcs_write32(EXCEPTION_BITMAP, eb);
>  }
>  
> @@ -1960,6 +1964,13 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
>  	case MSR_KERNEL_GS_BASE:
>  		vmx_write_guest_kernel_gs_base(vmx, data);
>  		break;
> +	case MSR_IA32_XFD:
> +		ret = kvm_set_msr_common(vcpu, msr_info);
> +		if (!ret && data) {
> +			vcpu->arch.trap_nm = true;
> +			vmx_update_exception_bitmap(vcpu);

This is wrong, it fails to clear vcpu->arch.trap_nm and update the bitmap if the
MSR is cleared.

But why even bother with an extra flag?  Can't vmx_update_exception_bitmap() get
the guest's MSR_IA32_XFD value and intercept #NM accordingly?  Then you could
even handle this fully in kvm_set_msr_common(), e.g.

diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 2c9606380bca..c6c936d2b298 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -3704,6 +3704,8 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
                        return 1;

                fpu_update_guest_xfd(&vcpu->arch.guest_fpu, data);
+               /* Blah blah blah blah */
+               static_call(kvm_x86_update_exception_bitmap)(vcpu);
                break;
        case MSR_IA32_XFD_ERR:
                if (!msr_info->host_initiated &&

> +		}
> +		break;
>  #endif
>  	case MSR_IA32_SYSENTER_CS:
>  		if (is_guest_mode(vcpu))
> @@ -4746,7 +4757,7 @@ static int handle_exception_nmi(struct kvm_vcpu *vcpu)
>  	vect_info = vmx->idt_vectoring_info;
>  	intr_info = vmx_get_intr_info(vcpu);
>  
> -	if (is_machine_check(intr_info) || is_nmi(intr_info))
> +	if (is_machine_check(intr_info) || is_nmi(intr_info) || is_nm(intr_info))
>  		return 1; /* handled by handle_exception_nmi_irqoff() */
>  
>  	if (is_invalid_opcode(intr_info))
> @@ -6350,6 +6361,12 @@ static void handle_interrupt_nmi_irqoff(struct kvm_vcpu *vcpu,
>  	kvm_after_interrupt(vcpu);
>  }
>  
> +static void handle_exception_nm(struct kvm_vcpu *vcpu)

This needs a different name, it's waaaay too close to the base handle_exception_nmi(),
which runs with IRQs _on_.  And please add "_irqoff" at the end.  Maybe handle_nm_fault_irqoff()?

> +{
> +	rdmsrl(MSR_IA32_XFD_ERR, vcpu->arch.guest_fpu.xfd_err);
> +	kvm_queue_exception(vcpu, NM_VECTOR);
> +}
> +
>  static void handle_exception_nmi_irqoff(struct vcpu_vmx *vmx)
>  {
>  	const unsigned long nmi_entry = (unsigned long)asm_exc_nmi_noist;
> @@ -6358,6 +6375,9 @@ static void handle_exception_nmi_irqoff(struct vcpu_vmx *vmx)
>  	/* if exit due to PF check for async PF */
>  	if (is_page_fault(intr_info))
>  		vmx->vcpu.arch.apf.host_apf_flags = kvm_read_and_reset_apf_flags();
> +	/* if exit due to NM, handle before preemptions are enabled */
> +	else if (is_nm(intr_info))

Same naming complaint about this helper, it looks like an is_nmi() typo.  is_nm_fault()?

> +		handle_exception_nm(&vmx->vcpu);
>  	/* Handle machine checks before interrupts are enabled */
>  	else if (is_machine_check(intr_info))
>  		kvm_machine_check();

  reply	other threads:[~2021-12-29  0:09 UTC|newest]

Thread overview: 47+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-22 12:40 [PATCH v3 00/22] AMX Support in KVM Jing Liu
2021-12-22 12:40 ` [PATCH v3 01/22] x86/fpu: Extend fpu_xstate_prctl() with guest permissions Jing Liu
2021-12-22 12:40 ` [PATCH v3 02/22] x86/fpu: Prepare guest FPU for dynamically enabled FPU features Jing Liu
2021-12-22 12:40 ` [PATCH v3 03/22] kvm: x86: Fix xstate_required_size() to follow XSTATE alignment rule Jing Liu
2021-12-22 12:40 ` [PATCH v3 04/22] kvm: x86: Exclude unpermitted xfeatures at KVM_GET_SUPPORTED_CPUID Jing Liu
2021-12-22 12:40 ` [PATCH v3 05/22] kvm: x86: Check permitted dynamic xfeatures at KVM_SET_CPUID2 Jing Liu
2021-12-28 23:38   ` Sean Christopherson
2021-12-29  2:18     ` Tian, Kevin
2021-12-22 12:40 ` [PATCH v3 06/22] x86/fpu: Make XFD initialization in __fpstate_reset() a function argument Jing Liu
2021-12-22 12:40 ` [PATCH v3 07/22] x86/fpu: Add guest support to xfd_enable_feature() Jing Liu
2021-12-22 12:40 ` [PATCH v3 08/22] x86/fpu: Provide fpu_update_guest_perm_features() for guest Jing Liu
2021-12-22 12:40 ` [PATCH v3 09/22] kvm: x86: Enable dynamic XSAVE features at KVM_SET_CPUID2 Jing Liu
2021-12-28 23:54   ` Sean Christopherson
2021-12-29  2:23     ` Tian, Kevin
2021-12-22 12:40 ` [PATCH v3 10/22] x86/fpu: Provide fpu_update_guest_xfd() for IA32_XFD emulation Jing Liu
2021-12-22 12:40 ` [PATCH v3 11/22] kvm: x86: Add emulation for IA32_XFD Jing Liu
2021-12-22 12:40 ` [PATCH v3 12/22] x86/fpu: Prepare xfd_err in struct fpu_guest Jing Liu
2021-12-22 12:40 ` [PATCH v3 13/22] kvm: x86: Intercept #NM for saving IA32_XFD_ERR Jing Liu
2021-12-29  0:09   ` Sean Christopherson [this message]
2021-12-29  2:52     ` Tian, Kevin
2021-12-29 17:37       ` Sean Christopherson
2021-12-29  6:50     ` Tian, Kevin
2021-12-29  8:13     ` Tian, Kevin
2021-12-22 12:40 ` [PATCH v3 14/22] kvm: x86: Emulate IA32_XFD_ERR for guest Jing Liu
2021-12-22 12:40 ` [PATCH v3 15/22] kvm: x86: Disable RDMSR interception of IA32_XFD_ERR Jing Liu
2021-12-22 12:40 ` [PATCH v3 16/22] kvm: x86: Add XCR0 support for Intel AMX Jing Liu
2021-12-29  0:21   ` Sean Christopherson
2021-12-29  3:01     ` Tian, Kevin
2021-12-22 12:40 ` [PATCH v3 17/22] kvm: x86: Add CPUID " Jing Liu
2021-12-22 12:40 ` [PATCH v3 18/22] x86/fpu: Add uabi_size to guest_fpu Jing Liu
2021-12-22 12:40 ` [PATCH v3 19/22] kvm: x86: Get/set expanded xstate buffer Jing Liu
2021-12-29  0:38   ` Sean Christopherson
2021-12-29  2:57     ` Wang, Wei W
2021-12-29  6:36       ` Tian, Kevin
2021-12-22 12:40 ` [PATCH v3 20/22] kvm: selftests: Add support for KVM_CAP_XSAVE2 Jing Liu
2021-12-22 12:40 ` [PATCH v3 21/22] x86/fpu: Provide fpu_sync_guest_vmexit_xfd_state() Jing Liu
2021-12-22 12:40 ` [PATCH v3 22/22] kvm: x86: Disable interception for IA32_XFD on demand Jing Liu
2021-12-29  1:04   ` Sean Christopherson
2021-12-29  3:35     ` Tian, Kevin
2021-12-29  7:16     ` Tian, Kevin
2021-12-29 17:26       ` Sean Christopherson
2021-12-30  1:28         ` Tian, Kevin
2021-12-30  7:04         ` Tian, Kevin
2021-12-31  9:42         ` Tian, Kevin
2021-12-29  7:37     ` Tian, Kevin
2022-01-04 18:32     ` Paolo Bonzini
2022-01-04 18:58       ` Sean Christopherson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YcunSb52LlGKT7dC@google.com \
    --to=seanjc@google.com \
    --cc=bp@alien8.de \
    --cc=corbet@lwn.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=guang.zeng@intel.com \
    --cc=jing2.liu@intel.com \
    --cc=jing2.liu@linux.intel.com \
    --cc=jun.nakajima@intel.com \
    --cc=kevin.tian@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=pbonzini@redhat.com \
    --cc=shuah@kernel.org \
    --cc=tglx@linutronix.de \
    --cc=wei.w.wang@intel.com \
    --cc=x86@kernel.org \
    --cc=yang.zhong@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.