From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.ozlabs.org (lists.ozlabs.org [112.213.38.117]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E764BCD8C9D for ; Mon, 8 Jun 2026 14:52:31 +0000 (UTC) Received: from boromir.ozlabs.org (localhost [127.0.0.1]) by lists.ozlabs.org (Postfix) with ESMTP id 4gYw4F3hdtz2ytV; Tue, 09 Jun 2026 00:52:13 +1000 (AEST) Authentication-Results: lists.ozlabs.org; arc=none smtp.remote-ip="2a01:238:42d9:3f00:e505:6202:4f0c:f051" ARC-Seal: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1780930333; cv=none; b=gUMbAeKBUkLCpvI0xF/hZoElQwWPvy6WdmvVua8+5U2qmWfrdRrET+6eXbU04l4LWfC9opKOoRoaPkqXEQCiZbm9gF1VRBSMo2qLPzj29hWYsdRfpn0x/So4lhC/jRm33uVvVKIkDN0yD8NROuBY3n4UrwVxgfrYlg03IgxnMFCicFTrirTjDVqxT1vuG0RtdbWtk1rABeouZbIgYt/z7pzrHl/dsaCKbit5dSfSzO3y93uVeiGGGQ1PudWPvHZ5rhL22xN1obe0Xy89v8DD6py5ld86DupJDOc724IiATLHIsgQgDJq0EwQYBxr3gpcseMpkEo0qZ3EoS+jGUWkFQ== ARC-Message-Signature: i=1; a=rsa-sha256; d=lists.ozlabs.org; s=201707; t=1780930333; c=relaxed/relaxed; bh=SFY8osBOGiT7rOUrtwhyKbRMW9LibB8EPQscRy+C6vc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=bGbl+k1gessS7yu3ux9GJwd9LUncGliz2ZzmWibjMr/BXlq3HRw5mxIJ3AiUokeoRTr/W38rYNsMe26YQgzBwebDrCArwzJhlvlDy4YZiBGeF/uJu9CWFrLf0ePvBYVi2kOek8ZtUvog5MUuwKcDq6d3ijE8Vch0pSh6iUSvWlKCf//RC79np286g20pBU/sL37q2oLaNQ6Plz/7LCHHSmasO2WIPJ6WK7BpdDIwMZRCxefA3hn7gaDdqrMdJcPSGhO4QwG91RAHMHQ293OyKkpFK+G03jpZULaqiiGWPkwZrYRcyykrBfdLjReycgWyCer+B37v3i7AmfIBALLtPA== ARC-Authentication-Results: i=1; lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=8bytes.org; spf=pass (client-ip=2a01:238:42d9:3f00:e505:6202:4f0c:f051; helo=mail.8bytes.org; envelope-from=joro@8bytes.org; receiver=lists.ozlabs.org) smtp.mailfrom=8bytes.org Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=8bytes.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=8bytes.org (client-ip=2a01:238:42d9:3f00:e505:6202:4f0c:f051; helo=mail.8bytes.org; envelope-from=joro@8bytes.org; receiver=lists.ozlabs.org) Received: from mail.8bytes.org (mail.8bytes.org [IPv6:2a01:238:42d9:3f00:e505:6202:4f0c:f051]) by lists.ozlabs.org (Postfix) with ESMTP id 4gYw483YzTz2ytj for ; Tue, 09 Jun 2026 00:52:07 +1000 (AEST) Received: from io.home.8bytes.org (p4ffe1d30.dip0.t-ipconnect.de [79.254.29.48]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mail.8bytes.org (Postfix) with ESMTPSA id 7F2382028AA; Mon, 8 Jun 2026 16:43:06 +0200 (CEST) From: =?UTF-8?q?J=C3=B6rg=20R=C3=B6del?= To: Paolo Bonzini , Sean Christopherson Cc: Tom Lendacky , ashish.kalra@amd.com, michael.roth@amd.com, nsaenz@amazon.com, anelkz@amazon.de, James.Bottomley@HansenPartnership.com, Melody Wang , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, kvmarm@lists.linux.dev, loongarch@lists.linux.dev, linux-mips@vger.kernel.org, linuxppc-dev@lists.ozlabs.org, kvm-riscv@lists.infradead.org, x86@kernel.org, coconut-svsm@lists.linux.dev, joerg.roedel@amd.com Subject: [PATCH 07/60] KVM: SVM: Add support for the SEV-SNP #HV IPI NAE event Date: Mon, 8 Jun 2026 16:41:59 +0200 Message-ID: <20260608144252.351443-8-joro@8bytes.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260608144252.351443-1-joro@8bytes.org> References: <20260608144252.351443-1-joro@8bytes.org> X-Mailing-List: linuxppc-dev@lists.ozlabs.org List-Id: List-Help: List-Owner: List-Post: List-Archive: , List-Subscribe: , , List-Unsubscribe: Precedence: list MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: Melody Wang The #HV IPI NAE event allows the guest to send an IPI to other vCPUs in the guest when the Restricted Injection feature is enabled. Implement the NAE event as per GHCB specification. Co-developed-by: Thomas Lendacky Signed-off-by: Thomas Lendacky Signed-off-by: Melody Wang Signed-off-by: Joerg Roedel --- arch/x86/include/uapi/asm/svm.h | 1 + arch/x86/kvm/lapic.c | 24 +++++++++++++++++++++++- arch/x86/kvm/lapic.h | 2 ++ arch/x86/kvm/svm/sev.c | 28 ++++++++++++++++++++++++++++ 4 files changed, 54 insertions(+), 1 deletion(-) diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h index d84a13ac4627..d281dd21c540 100644 --- a/arch/x86/include/uapi/asm/svm.h +++ b/arch/x86/include/uapi/asm/svm.h @@ -122,6 +122,7 @@ #define SVM_VMGEXIT_HVDB_SET 1 #define SVM_VMGEXIT_HVDB_QUERY 2 #define SVM_VMGEXIT_HVDB_CLEAR 3 +#define SVM_VMGEXIT_HV_IPI 0x80000015ull #define SVM_VMGEXIT_SNP_RUN_VMPL 0x80000018ull #define SVM_VMGEXIT_SAVIC 0x8000001aull #define SVM_VMGEXIT_SAVIC_REGISTER_GPA 0 diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 4078e624ca66..ab40a2e4ab9d 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c @@ -2558,7 +2558,7 @@ static int kvm_lapic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) static int apic_mmio_write(struct kvm_vcpu *vcpu, struct kvm_io_device *this, gpa_t address, int len, const void *data) { - struct kvm_lapic *apic = to_lapic(this); + struct kvm_lapic *apic = this ? to_lapic(this) : vcpu->arch.apic; unsigned int offset = address - apic->base_address; u32 val; @@ -3583,3 +3583,25 @@ void kvm_lapic_exit(void) static_key_deferred_flush(&apic_sw_disabled); WARN_ON(static_branch_unlikely(&apic_sw_disabled.key)); } + +/* Send IPI by writing ICR with MSR write when X2APIC enabled, with mmio write when XAPIC enabled */ +int kvm_xapic_x2apic_send_ipi(struct kvm_vcpu *vcpu, u64 data) +{ + u32 icr_msr_addr = APIC_BASE_MSR + (APIC_ICR >> 4); + struct kvm_lapic *apic = vcpu->arch.apic; + gpa_t gpa = apic->base_address + APIC_ICR; + + if (!kvm_lapic_enabled(vcpu)) + return 1; + + if (vcpu->arch.apic_base & X2APIC_ENABLE) { + if (!kvm_x2apic_msr_write(vcpu, icr_msr_addr, data)) + return 0; + } else { + if (!apic_mmio_write(vcpu, NULL, gpa, 4, &data)) + return 0; + } + + return 1; +} +EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_xapic_x2apic_send_ipi); diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 274885af4ebc..afd440c88981 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h @@ -156,6 +156,8 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data); int kvm_lapic_set_pv_eoi(struct kvm_vcpu *vcpu, u64 data, unsigned long len); void kvm_lapic_exit(void); +int kvm_xapic_x2apic_send_ipi(struct kvm_vcpu *vcpu, u64 data); + u64 kvm_lapic_readable_reg_mask(struct kvm_lapic *apic); static inline void kvm_lapic_set_irr(int vec, struct kvm_lapic *apic) diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c index 369fb1e36f58..d04f71836ef7 100644 --- a/arch/x86/kvm/svm/sev.c +++ b/arch/x86/kvm/svm/sev.c @@ -35,6 +35,7 @@ #include "svm_ops.h" #include "cpuid.h" #include "trace.h" +#include "lapic.h" #define GHCB_VERSION_MAX 2ULL #define GHCB_VERSION_MIN 1ULL @@ -3538,6 +3539,10 @@ static int sev_es_validate_vmgexit(struct vcpu_svm *svm) if (!is_sev_snp_guest(vcpu)) goto vmgexit_err; break; + case SVM_VMGEXIT_HV_IPI: + if (!sev_snp_guest(vcpu->kvm)) + goto vmgexit_err; + break; default: reason = GHCB_ERR_INVALID_EVENT; goto vmgexit_err; @@ -4416,6 +4421,22 @@ static int sev_snp_hv_doorbell_page(struct vcpu_svm *svm) return 0; } +static int sev_snp_hv_ipi(struct vcpu_svm *svm) +{ + struct kvm_vcpu *vcpu = &svm->vcpu; + u64 icr_info; + + if (!sev_snp_guest(vcpu->kvm)) + return -EINVAL; + + icr_info = svm->vmcb->control.exit_info_1; + + if (kvm_xapic_x2apic_send_ipi(vcpu, icr_info)) + return -EINVAL; + + return 0; +} + static int sev_handle_vmgexit_msr_protocol(struct vcpu_svm *svm) { struct vmcb_control_area *control = &svm->vmcb->control; @@ -4698,6 +4719,13 @@ int sev_handle_vmgexit(struct kvm_vcpu *vcpu) ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_INPUT); } + ret = 1; + break; + case SVM_VMGEXIT_HV_IPI: + if (sev_snp_hv_ipi(svm)) { + ghcb_set_sw_exit_info_1(svm->sev_es.ghcb, 2); + ghcb_set_sw_exit_info_2(svm->sev_es.ghcb, GHCB_ERR_INVALID_INPUT); + } ret = 1; break; case SVM_VMGEXIT_UNSUPPORTED_EVENT: -- 2.53.0