|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [xen staging] x86/svm: Adjust vNMI handling to update the cleanbit
commit 0e7b01ce3bffb81875aaeb87be723cacd7bac174
Author: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
AuthorDate: Mon Nov 2 11:16:24 2026 +0000
Commit: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
CommitDate: Wed Nov 4 18:11:35 2026 +0000
x86/svm: Adjust vNMI handling to update the cleanbit
Despite prior information to the contrary, APM Vol2 revision 3.46 October
2026
has been adjusted to state that the vNMI fields in vINTR are covered by the
TPR cleanbit.
Adjust svm_inject_nmi() and svm_set_interrupt_shadow() to use
vmcb_set_vintr()
rather than writing into the VMCB directly.
In svm_inject_nmi(), fix an inefficiency from the introduction of vNMI.
Move
the reading of vmcb_get_general1_intercepts() to the point at which it is
used; it does not need reading on the case that vNMIs are enabled.
Fixes: 86a203ab8d38 ("x86/svm: Support vNMI on capable hardware")
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
Reviewed-by: Jan Beulich <jbeulich@xxxxxxxx>
---
xen/arch/x86/hvm/svm/intr.c | 9 ++++++---
xen/arch/x86/hvm/svm/svm.c | 8 ++++++--
2 files changed, 12 insertions(+), 5 deletions(-)
diff --git a/xen/arch/x86/hvm/svm/intr.c b/xen/arch/x86/hvm/svm/intr.c
index 4b0debfa9a..2224f18347 100644
--- a/xen/arch/x86/hvm/svm/intr.c
+++ b/xen/arch/x86/hvm/svm/intr.c
@@ -30,12 +30,14 @@
static void svm_inject_nmi(struct vcpu *v)
{
struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
- u32 general1_intercepts = vmcb_get_general1_intercepts(vmcb);
+ vintr_t vintr = vmcb_get_vintr(vmcb);
+ uint32_t general1_intercepts;
intinfo_t event;
- if ( vmcb->_vintr.fields.vnmi_enable )
+ if ( vintr.fields.vnmi_enable )
{
- vmcb->_vintr.fields.vnmi_pending = true;
+ vintr.fields.vnmi_pending = true;
+ vmcb_set_vintr(vmcb, vintr);
return;
}
@@ -51,6 +53,7 @@ static void svm_inject_nmi(struct vcpu *v)
* SVM does not virtualise the NMI mask, so we emulate it by intercepting
* the next IRET and blocking NMI injection until the intercept triggers.
*/
+ general1_intercepts = vmcb_get_general1_intercepts(vmcb);
vmcb_set_general1_intercepts(
vmcb, general1_intercepts | GENERAL1_INTERCEPT_IRET);
}
diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c
index 1628c5e0ae..57779806bf 100644
--- a/xen/arch/x86/hvm/svm/svm.c
+++ b/xen/arch/x86/hvm/svm/svm.c
@@ -511,12 +511,16 @@ static void cf_check svm_set_interrupt_shadow(
{
struct vmcb_struct *vmcb = v->arch.hvm.svm.vmcb;
bool block_nmi = intr_shadow & HVM_INTR_SHADOW_NMI;
+ vintr_t vintr = vmcb_get_vintr(vmcb);
vmcb->int_stat.intr_shadow =
!!(intr_shadow & (HVM_INTR_SHADOW_MOV_SS|HVM_INTR_SHADOW_STI));
- if ( vmcb->_vintr.fields.vnmi_enable )
- vmcb->_vintr.fields.vnmi_blocking = block_nmi;
+ if ( vintr.fields.vnmi_enable )
+ {
+ vintr.fields.vnmi_blocking = block_nmi;
+ vmcb_set_vintr(vmcb, vintr);
+ }
else
{
uint32_t gen1 = vmcb_get_general1_intercepts(vmcb);
--
generated by git-patchbot for /home/xen/git/xen.git#staging
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |