* [PATCH v9 01/18] x86/apic: Add new driver for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 02/18] x86/apic: Initialize Secure AVIC APIC backing page Neeraj Upadhyay
` (17 subsequent siblings)
18 siblings, 0 replies; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
The Secure AVIC feature provides SEV-SNP guests hardware acceleration
for performance sensitive APIC accesses while securely managing the
guest-owned APIC state through the use of a private APIC backing page.
This helps prevent hypervisor from generating unexpected interrupts for
a vCPU or otherwise violate architectural assumptions around APIC
behavior.
Add a new x2APIC driver that will serve as the base of the Secure AVIC
support. It is initially the same as the x2APIC phys driver (without
IPI callbacks), but will be modified as features of Secure AVIC are
implemented.
As the new driver does not implement Secure AVIC features yet, if the
hypervisor sets the Secure AVIC bit in SEV_STATUS, maintain the existing
behavior to enforce the guest termination.
Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- No changes.
arch/x86/Kconfig | 13 ++++++
arch/x86/boot/compressed/sev.c | 1 +
arch/x86/coco/core.c | 3 ++
arch/x86/coco/sev/core.c | 1 +
arch/x86/include/asm/msr-index.h | 4 +-
arch/x86/kernel/apic/Makefile | 1 +
arch/x86/kernel/apic/x2apic_savic.c | 63 +++++++++++++++++++++++++++++
include/linux/cc_platform.h | 8 ++++
8 files changed, 93 insertions(+), 1 deletion(-)
create mode 100644 arch/x86/kernel/apic/x2apic_savic.c
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 58d890fe2100..70ce4f7b2f69 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -483,6 +483,19 @@ config X86_X2APIC
If in doubt, say Y.
+config AMD_SECURE_AVIC
+ bool "AMD Secure AVIC"
+ depends on AMD_MEM_ENCRYPT && X86_X2APIC
+ help
+ Enable this to get AMD Secure AVIC support on guests that have this feature.
+
+ AMD Secure AVIC provides hardware acceleration for performance sensitive
+ APIC accesses and support for managing guest owned APIC state for SEV-SNP
+ guests. Secure AVIC does not support xapic mode. It has functional
+ dependency on x2apic being enabled in the guest.
+
+ If you don't know what to do here, say N.
+
config X86_POSTED_MSI
bool "Enable MSI and MSI-x delivery by posted interrupts"
depends on X86_64 && IRQ_REMAP
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index fd1b67dfea22..74e083feb2d9 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -235,6 +235,7 @@ bool sev_es_check_ghcb_fault(unsigned long address)
MSR_AMD64_SNP_VMSA_REG_PROT | \
MSR_AMD64_SNP_RESERVED_BIT13 | \
MSR_AMD64_SNP_RESERVED_BIT15 | \
+ MSR_AMD64_SNP_SECURE_AVIC | \
MSR_AMD64_SNP_RESERVED_MASK)
/*
diff --git a/arch/x86/coco/core.c b/arch/x86/coco/core.c
index d4610af68114..989ca9f72ba3 100644
--- a/arch/x86/coco/core.c
+++ b/arch/x86/coco/core.c
@@ -104,6 +104,9 @@ static bool noinstr amd_cc_platform_has(enum cc_attr attr)
case CC_ATTR_HOST_SEV_SNP:
return cc_flags.host_sev_snp;
+ case CC_ATTR_SNP_SECURE_AVIC:
+ return sev_status & MSR_AMD64_SNP_SECURE_AVIC;
+
default:
return false;
}
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index fc59ce78c477..a19691436ea6 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -79,6 +79,7 @@ static const char * const sev_status_feat_names[] = {
[MSR_AMD64_SNP_IBS_VIRT_BIT] = "IBSVirt",
[MSR_AMD64_SNP_VMSA_REG_PROT_BIT] = "VMSARegProt",
[MSR_AMD64_SNP_SMT_PROT_BIT] = "SMTProt",
+ [MSR_AMD64_SNP_SECURE_AVIC_BIT] = "SecureAVIC",
};
/*
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index b65c3ba5fa14..2a6d4fd8659a 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -699,7 +699,9 @@
#define MSR_AMD64_SNP_VMSA_REG_PROT BIT_ULL(MSR_AMD64_SNP_VMSA_REG_PROT_BIT)
#define MSR_AMD64_SNP_SMT_PROT_BIT 17
#define MSR_AMD64_SNP_SMT_PROT BIT_ULL(MSR_AMD64_SNP_SMT_PROT_BIT)
-#define MSR_AMD64_SNP_RESV_BIT 18
+#define MSR_AMD64_SNP_SECURE_AVIC_BIT 18
+#define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)
+#define MSR_AMD64_SNP_RESV_BIT 19
#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
#define MSR_AMD64_RMP_BASE 0xc0010132
#define MSR_AMD64_RMP_END 0xc0010133
diff --git a/arch/x86/kernel/apic/Makefile b/arch/x86/kernel/apic/Makefile
index 52d1808ee360..581db89477f9 100644
--- a/arch/x86/kernel/apic/Makefile
+++ b/arch/x86/kernel/apic/Makefile
@@ -18,6 +18,7 @@ ifeq ($(CONFIG_X86_64),y)
# APIC probe will depend on the listing order here
obj-$(CONFIG_X86_NUMACHIP) += apic_numachip.o
obj-$(CONFIG_X86_UV) += x2apic_uv_x.o
+obj-$(CONFIG_AMD_SECURE_AVIC) += x2apic_savic.o
obj-$(CONFIG_X86_X2APIC) += x2apic_phys.o
obj-$(CONFIG_X86_X2APIC) += x2apic_cluster.o
obj-y += apic_flat_64.o
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
new file mode 100644
index 000000000000..bea844f28192
--- /dev/null
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -0,0 +1,63 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * AMD Secure AVIC Support (SEV-SNP Guests)
+ *
+ * Copyright (C) 2024 Advanced Micro Devices, Inc.
+ *
+ * Author: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
+ */
+
+#include <linux/cc_platform.h>
+
+#include <asm/apic.h>
+#include <asm/sev.h>
+
+#include "local.h"
+
+static int savic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
+{
+ return x2apic_enabled() && cc_platform_has(CC_ATTR_SNP_SECURE_AVIC);
+}
+
+static int savic_probe(void)
+{
+ if (!cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
+ return 0;
+
+ if (!x2apic_mode) {
+ pr_err("Secure AVIC enabled in non x2APIC mode\n");
+ snp_abort();
+ /* unreachable */
+ }
+
+ return 1;
+}
+
+static struct apic apic_x2apic_savic __ro_after_init = {
+
+ .name = "secure avic x2apic",
+ .probe = savic_probe,
+ .acpi_madt_oem_check = savic_acpi_madt_oem_check,
+
+ .dest_mode_logical = false,
+
+ .disable_esr = 0,
+
+ .cpu_present_to_apicid = default_cpu_present_to_apicid,
+
+ .max_apic_id = UINT_MAX,
+ .x2apic_set_max_apicid = true,
+ .get_apic_id = x2apic_get_apic_id,
+
+ .calc_dest_apicid = apic_default_calc_apicid,
+
+ .nmi_to_offline_cpu = true,
+
+ .read = native_apic_msr_read,
+ .write = native_apic_msr_write,
+ .eoi = native_apic_msr_eoi,
+ .icr_read = native_x2apic_icr_read,
+ .icr_write = native_x2apic_icr_write,
+};
+
+apic_driver(apic_x2apic_savic);
diff --git a/include/linux/cc_platform.h b/include/linux/cc_platform.h
index 0bf7d33a1048..7fcec025c5e0 100644
--- a/include/linux/cc_platform.h
+++ b/include/linux/cc_platform.h
@@ -96,6 +96,14 @@ enum cc_attr {
* enabled to run SEV-SNP guests.
*/
CC_ATTR_HOST_SEV_SNP,
+
+ /**
+ * @CC_ATTR_SNP_SECURE_AVIC: Secure AVIC mode is active.
+ *
+ * The host kernel is running with the necessary features enabled
+ * to run SEV-SNP guests with full Secure AVIC capabilities.
+ */
+ CC_ATTR_SNP_SECURE_AVIC,
};
#ifdef CONFIG_ARCH_HAS_CC_PLATFORM
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v9 02/18] x86/apic: Initialize Secure AVIC APIC backing page
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 01/18] x86/apic: Add new driver for Secure AVIC Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-15 10:25 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver Neeraj Upadhyay
` (16 subsequent siblings)
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
With Secure AVIC, the APIC backing page is owned and managed by guest.
Allocate and initialize APIC backing page for all guest CPUs.
The NPT entry for a vCPU's APIC backing page must always be present
when the vCPU is running, in order for Secure AVIC to function. A
VMEXIT_BUSY is returned on VMRUN and the vCPU cannot be resumed if
the NPT entry for the APIC backing page is not present. To handle this,
notify GPA of the vCPU's APIC backing page to the hypervisor by using the
SVM_VMGEXIT_SECURE_AVIC GHCB protocol event. Before executing VMRUN,
the hypervisor makes use of this information to make sure the APIC backing
page is mapped in NPT.
Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
- Use "struct secure_avic_page" instead of defining a common
"struct apic_page".
arch/x86/coco/sev/core.c | 22 ++++++++++++++++++
arch/x86/include/asm/apic.h | 1 +
arch/x86/include/asm/sev.h | 2 ++
arch/x86/include/uapi/asm/svm.h | 4 ++++
arch/x86/kernel/apic/apic.c | 3 +++
arch/x86/kernel/apic/x2apic_savic.c | 35 +++++++++++++++++++++++++++++
6 files changed, 67 insertions(+)
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index a19691436ea6..0c59ea82fa99 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -1085,6 +1085,28 @@ int __init sev_es_efi_map_ghcbs_cas(pgd_t *pgd)
return 0;
}
+enum es_result savic_register_gpa(u64 gpa)
+{
+ struct ghcb_state state;
+ struct es_em_ctxt ctxt;
+ enum es_result res;
+ struct ghcb *ghcb;
+
+ guard(irqsave)();
+
+ ghcb = __sev_get_ghcb(&state);
+ vc_ghcb_invalidate(ghcb);
+
+ ghcb_set_rax(ghcb, SVM_VMGEXIT_SAVIC_SELF_GPA);
+ ghcb_set_rbx(ghcb, gpa);
+ res = sev_es_ghcb_hv_call(ghcb, &ctxt, SVM_VMGEXIT_SAVIC,
+ SVM_VMGEXIT_SAVIC_REGISTER_GPA, 0);
+
+ __sev_put_ghcb(&state);
+
+ return res;
+}
+
static void snp_register_per_cpu_ghcb(void)
{
struct sev_es_runtime_data *data;
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 07ba4935e873..44b4080721a6 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -305,6 +305,7 @@ struct apic {
/* Probe, setup and smpboot functions */
int (*probe)(void);
+ void (*setup)(void);
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
void (*init_apic_ldr)(void);
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 89075ff19afa..8e5083b46607 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -533,6 +533,7 @@ int snp_svsm_vtpm_send_command(u8 *buffer);
void __init snp_secure_tsc_prepare(void);
void __init snp_secure_tsc_init(void);
+enum es_result savic_register_gpa(u64 gpa);
static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb)
{
@@ -605,6 +606,7 @@ static inline int snp_send_guest_request(struct snp_msg_desc *mdesc,
static inline int snp_svsm_vtpm_send_command(u8 *buffer) { return -ENODEV; }
static inline void __init snp_secure_tsc_prepare(void) { }
static inline void __init snp_secure_tsc_init(void) { }
+static inline enum es_result savic_register_gpa(u64 gpa) { return ES_UNSUPPORTED; }
#endif /* CONFIG_AMD_MEM_ENCRYPT */
diff --git a/arch/x86/include/uapi/asm/svm.h b/arch/x86/include/uapi/asm/svm.h
index 9c640a521a67..650e3256ea7d 100644
--- a/arch/x86/include/uapi/asm/svm.h
+++ b/arch/x86/include/uapi/asm/svm.h
@@ -118,6 +118,10 @@
#define SVM_VMGEXIT_AP_CREATE 1
#define SVM_VMGEXIT_AP_DESTROY 2
#define SVM_VMGEXIT_SNP_RUN_VMPL 0x80000018
+#define SVM_VMGEXIT_SAVIC 0x8000001a
+#define SVM_VMGEXIT_SAVIC_REGISTER_GPA 0
+#define SVM_VMGEXIT_SAVIC_UNREGISTER_GPA 1
+#define SVM_VMGEXIT_SAVIC_SELF_GPA ~0ULL
#define SVM_VMGEXIT_HV_FEATURES 0x8000fffd
#define SVM_VMGEXIT_TERM_REQUEST 0x8000fffe
#define SVM_VMGEXIT_TERM_REASON(reason_set, reason_code) \
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index d73ba5a7b623..36f1326fea2e 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1503,6 +1503,9 @@ static void setup_local_APIC(void)
return;
}
+ if (apic->setup)
+ apic->setup();
+
/*
* If this comes from kexec/kcrash the APIC might be enabled in
* SPIV. Soft disable it before doing further initialization.
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index bea844f28192..1c70b7c111f0 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -8,17 +8,47 @@
*/
#include <linux/cc_platform.h>
+#include <linux/percpu-defs.h>
#include <asm/apic.h>
#include <asm/sev.h>
#include "local.h"
+struct secure_avic_page {
+ u8 regs[PAGE_SIZE];
+} __aligned(PAGE_SIZE);
+
+static struct secure_avic_page __percpu *secure_avic_page __ro_after_init;
+
static int savic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
return x2apic_enabled() && cc_platform_has(CC_ATTR_SNP_SECURE_AVIC);
}
+static void savic_setup(void)
+{
+ void *ap = this_cpu_ptr(secure_avic_page);
+ enum es_result res;
+ unsigned long gpa;
+
+ gpa = __pa(ap);
+
+ /*
+ * The NPT entry for a vCPU's APIC backing page must always be
+ * present when the vCPU is running in order for Secure AVIC to
+ * function. A VMEXIT_BUSY is returned on VMRUN and the vCPU cannot
+ * be resumed if the NPT entry for the APIC backing page is not
+ * present. Notify GPA of the vCPU's APIC backing page to the
+ * hypervisor by calling savic_register_gpa(). Before executing
+ * VMRUN, the hypervisor makes use of this information to make sure
+ * the APIC backing page is mapped in NPT.
+ */
+ res = savic_register_gpa(gpa);
+ if (res != ES_OK)
+ snp_abort();
+}
+
static int savic_probe(void)
{
if (!cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
@@ -30,6 +60,10 @@ static int savic_probe(void)
/* unreachable */
}
+ secure_avic_page = alloc_percpu(struct secure_avic_page);
+ if (!secure_avic_page)
+ snp_abort();
+
return 1;
}
@@ -38,6 +72,7 @@ static struct apic apic_x2apic_savic __ro_after_init = {
.name = "secure avic x2apic",
.probe = savic_probe,
.acpi_madt_oem_check = savic_acpi_madt_oem_check,
+ .setup = savic_setup,
.dest_mode_logical = false,
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 02/18] x86/apic: Initialize Secure AVIC APIC backing page
2025-08-11 9:44 ` [PATCH v9 02/18] x86/apic: Initialize Secure AVIC APIC backing page Neeraj Upadhyay
@ 2025-08-15 10:25 ` Borislav Petkov
2025-08-15 13:16 ` Upadhyay, Neeraj
0 siblings, 1 reply; 45+ messages in thread
From: Borislav Petkov @ 2025-08-15 10:25 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:28PM +0530, Neeraj Upadhyay wrote:
> With Secure AVIC, the APIC backing page is owned and managed by guest.
Please use articles: "...and managed by the guest."
Check all your text pls.
> +enum es_result savic_register_gpa(u64 gpa)
> +{
> + struct ghcb_state state;
> + struct es_em_ctxt ctxt;
> + enum es_result res;
> + struct ghcb *ghcb;
> +
> + guard(irqsave)();
> +
> + ghcb = __sev_get_ghcb(&state);
> + vc_ghcb_invalidate(ghcb);
> +
> + ghcb_set_rax(ghcb, SVM_VMGEXIT_SAVIC_SELF_GPA);
> + ghcb_set_rbx(ghcb, gpa);
> + res = sev_es_ghcb_hv_call(ghcb, &ctxt, SVM_VMGEXIT_SAVIC,
> + SVM_VMGEXIT_SAVIC_REGISTER_GPA, 0);
> +
> + __sev_put_ghcb(&state);
> +
> + return res;
> +}
I was gonna say put this into a new arch/x86/coco/sev/savic.c but ok, you're
adding only two functions.
> +struct secure_avic_page {
> + u8 regs[PAGE_SIZE];
> +} __aligned(PAGE_SIZE);
> +
> +static struct secure_avic_page __percpu *secure_avic_page __ro_after_init;
static struct secure_avic_page __percpu *savic_page __ro_after_init;
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 02/18] x86/apic: Initialize Secure AVIC APIC backing page
2025-08-15 10:25 ` Borislav Petkov
@ 2025-08-15 13:16 ` Upadhyay, Neeraj
2025-08-15 21:05 ` Borislav Petkov
0 siblings, 1 reply; 45+ messages in thread
From: Upadhyay, Neeraj @ 2025-08-15 13:16 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On 8/15/2025 3:55 PM, Borislav Petkov wrote:
> On Mon, Aug 11, 2025 at 03:14:28PM +0530, Neeraj Upadhyay wrote:
>> With Secure AVIC, the APIC backing page is owned and managed by guest.
>
> Please use articles: "...and managed by the guest."
>
> Check all your text pls.
>
Ok
>> +enum es_result savic_register_gpa(u64 gpa)
>> +{
>> + struct ghcb_state state;
>> + struct es_em_ctxt ctxt;
>> + enum es_result res;
>> + struct ghcb *ghcb;
>> +
>> + guard(irqsave)();
>> +
>> + ghcb = __sev_get_ghcb(&state);
>> + vc_ghcb_invalidate(ghcb);
>> +
>> + ghcb_set_rax(ghcb, SVM_VMGEXIT_SAVIC_SELF_GPA);
>> + ghcb_set_rbx(ghcb, gpa);
>> + res = sev_es_ghcb_hv_call(ghcb, &ctxt, SVM_VMGEXIT_SAVIC,
>> + SVM_VMGEXIT_SAVIC_REGISTER_GPA, 0);
>> +
>> + __sev_put_ghcb(&state);
>> +
>> + return res;
>> +}
>
> I was gonna say put this into a new arch/x86/coco/sev/savic.c but ok, you're
> adding only two functions.
>
There are four new functions. So, do I need to put them in new
arch/x86/coco/sev/savic.c file?
savic_register_gpa()
savic_unregister_gpa()
savic_ghcb_msr_read()
savic_ghcb_msr_write()
>> +struct secure_avic_page {
>> + u8 regs[PAGE_SIZE];
>> +} __aligned(PAGE_SIZE);
>> +
>> +static struct secure_avic_page __percpu *secure_avic_page __ro_after_init;
>
>
> static struct secure_avic_page __percpu *savic_page __ro_after_init;
>
Ok
- Neeraj
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 02/18] x86/apic: Initialize Secure AVIC APIC backing page
2025-08-15 13:16 ` Upadhyay, Neeraj
@ 2025-08-15 21:05 ` Borislav Petkov
0 siblings, 0 replies; 45+ messages in thread
From: Borislav Petkov @ 2025-08-15 21:05 UTC (permalink / raw)
To: Upadhyay, Neeraj
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Fri, Aug 15, 2025 at 06:46:55PM +0530, Upadhyay, Neeraj wrote:
> There are four new functions. So, do I need to put them in new
> arch/x86/coco/sev/savic.c file?
>
> savic_register_gpa()
> savic_unregister_gpa()
> savic_ghcb_msr_read()
> savic_ghcb_msr_write()
Lemme go through the set first.
Those last two, for example: we're adding more MSR handling routines related
to SEV and this is slowly getting out of hand. But lemme look first.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 01/18] x86/apic: Add new driver for Secure AVIC Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 02/18] x86/apic: Initialize Secure AVIC APIC backing page Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-18 11:26 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 04/18] x86/apic: Initialize APIC ID for Secure AVIC Neeraj Upadhyay
` (15 subsequent siblings)
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Add read() and write() APIC callback functions to read and write x2APIC
registers directly from the guest APIC backing page of a vCPU.
The x2APIC registers are mapped at an offset within the guest APIC
backing page which is same as their x2APIC MMIO offset. Secure AVIC
adds new registers such as ALLOWED_IRRs (which are at 4-byte offset
within the IRR register offset range) and NMI_REQ to the APIC register
space.
When Secure AVIC is enabled, guest's rdmsr/wrmsr of APIC registers
result in VC exception (for non-accelerated register accesses) with
error code VMEXIT_AVIC_NOACCEL. The VC exception handler can read/write
the x2APIC register in the guest APIC backing page to complete the
rdmsr/wrmsr. Since doing this would increase the latency of accessing
x2APIC registers, instead of doing rdmsr/wrmsr based reg accesses
and handling reads/writes in VC exception, directly read/write APIC
registers from/to the guest APIC backing page of the vCPU in read()
and write() callbacks of the Secure AVIC APIC driver.
Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
- Code cleanup to use struct secure_avic_page pointer.
arch/x86/include/asm/apicdef.h | 2 +
arch/x86/kernel/apic/x2apic_savic.c | 113 +++++++++++++++++++++++++++-
2 files changed, 113 insertions(+), 2 deletions(-)
diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index 094106b6a538..be39a543fbe5 100644
--- a/arch/x86/include/asm/apicdef.h
+++ b/arch/x86/include/asm/apicdef.h
@@ -135,6 +135,8 @@
#define APIC_TDR_DIV_128 0xA
#define APIC_EFEAT 0x400
#define APIC_ECTRL 0x410
+#define APIC_SEOI 0x420
+#define APIC_IER 0x480
#define APIC_EILVTn(n) (0x500 + 0x10 * n)
#define APIC_EILVT_NR_AMD_K8 1 /* # of extended interrupts */
#define APIC_EILVT_NR_AMD_10H 4
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index 1c70b7c111f0..86a522685230 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -9,6 +9,7 @@
#include <linux/cc_platform.h>
#include <linux/percpu-defs.h>
+#include <linux/align.h>
#include <asm/apic.h>
#include <asm/sev.h>
@@ -26,6 +27,114 @@ static int savic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
return x2apic_enabled() && cc_platform_has(CC_ATTR_SNP_SECURE_AVIC);
}
+#define SAVIC_ALLOWED_IRR 0x204
+
+static u32 savic_read(u32 reg)
+{
+ void *ap = this_cpu_ptr(secure_avic_page);
+
+ /*
+ * When Secure AVIC is enabled, rdmsr/wrmsr of APIC registers
+ * result in VC exception (for non-accelerated register accesses)
+ * with VMEXIT_AVIC_NOACCEL error code. The VC exception handler
+ * can read/write the x2APIC register in the guest APIC backing page.
+ * Since doing this would increase the latency of accessing x2APIC
+ * registers, instead of doing rdmsr/wrmsr based accesses and
+ * handling apic register reads/writes in VC exception, the read()
+ * and write() callbacks directly read/write APIC register from/to
+ * the vCPU APIC backing page.
+ */
+ switch (reg) {
+ case APIC_LVTT:
+ case APIC_TMICT:
+ case APIC_TMCCT:
+ case APIC_TDCR:
+ case APIC_ID:
+ case APIC_LVR:
+ case APIC_TASKPRI:
+ case APIC_ARBPRI:
+ case APIC_PROCPRI:
+ case APIC_LDR:
+ case APIC_SPIV:
+ case APIC_ESR:
+ case APIC_LVTTHMR:
+ case APIC_LVTPC:
+ case APIC_LVT0:
+ case APIC_LVT1:
+ case APIC_LVTERR:
+ case APIC_EFEAT:
+ case APIC_ECTRL:
+ case APIC_SEOI:
+ case APIC_IER:
+ case APIC_EILVTn(0) ... APIC_EILVTn(3):
+ return apic_get_reg(ap, reg);
+ case APIC_ICR:
+ return (u32) apic_get_reg64(ap, reg);
+ case APIC_ISR ... APIC_ISR + 0x70:
+ case APIC_TMR ... APIC_TMR + 0x70:
+ if (WARN_ONCE(!IS_ALIGNED(reg, 16),
+ "APIC reg read offset 0x%x not aligned at 16 bytes", reg))
+ return 0;
+ return apic_get_reg(ap, reg);
+ /* IRR and ALLOWED_IRR offset range */
+ case APIC_IRR ... APIC_IRR + 0x74:
+ /*
+ * Either aligned at 16 bytes for valid IRR reg offset or a
+ * valid Secure AVIC ALLOWED_IRR offset.
+ */
+ if (WARN_ONCE(!(IS_ALIGNED(reg, 16) ||
+ IS_ALIGNED(reg - SAVIC_ALLOWED_IRR, 16)),
+ "Misaligned IRR/ALLOWED_IRR APIC reg read offset 0x%x", reg))
+ return 0;
+ return apic_get_reg(ap, reg);
+ default:
+ pr_err("Permission denied: read of Secure AVIC reg offset 0x%x\n", reg);
+ return 0;
+ }
+}
+
+#define SAVIC_NMI_REQ 0x278
+
+static void savic_write(u32 reg, u32 data)
+{
+ void *ap = this_cpu_ptr(secure_avic_page);
+
+ switch (reg) {
+ case APIC_LVTT:
+ case APIC_LVT0:
+ case APIC_LVT1:
+ case APIC_TMICT:
+ case APIC_TDCR:
+ case APIC_SELF_IPI:
+ case APIC_TASKPRI:
+ case APIC_EOI:
+ case APIC_SPIV:
+ case SAVIC_NMI_REQ:
+ case APIC_ESR:
+ case APIC_LVTTHMR:
+ case APIC_LVTPC:
+ case APIC_LVTERR:
+ case APIC_ECTRL:
+ case APIC_SEOI:
+ case APIC_IER:
+ case APIC_EILVTn(0) ... APIC_EILVTn(3):
+ apic_set_reg(ap, reg, data);
+ break;
+ case APIC_ICR:
+ apic_set_reg64(ap, reg, (u64) data);
+ break;
+ /* ALLOWED_IRR offsets are writable */
+ case SAVIC_ALLOWED_IRR ... SAVIC_ALLOWED_IRR + 0x70:
+ if (IS_ALIGNED(reg - SAVIC_ALLOWED_IRR, 16)) {
+ apic_set_reg(ap, reg, data);
+ break;
+ }
+ fallthrough;
+ default:
+ pr_err("Permission denied: write to Secure AVIC reg offset 0x%x\n", reg);
+ }
+}
+
static void savic_setup(void)
{
void *ap = this_cpu_ptr(secure_avic_page);
@@ -88,8 +197,8 @@ static struct apic apic_x2apic_savic __ro_after_init = {
.nmi_to_offline_cpu = true,
- .read = native_apic_msr_read,
- .write = native_apic_msr_write,
+ .read = savic_read,
+ .write = savic_write,
.eoi = native_apic_msr_eoi,
.icr_read = native_x2apic_icr_read,
.icr_write = native_x2apic_icr_write,
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver
2025-08-11 9:44 ` [PATCH v9 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver Neeraj Upadhyay
@ 2025-08-18 11:26 ` Borislav Petkov
2025-08-19 4:15 ` Upadhyay, Neeraj
0 siblings, 1 reply; 45+ messages in thread
From: Borislav Petkov @ 2025-08-18 11:26 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:29PM +0530, Neeraj Upadhyay wrote:
> Add read() and write() APIC callback functions to read and write x2APIC
> registers directly from the guest APIC backing page of a vCPU.
>
> The x2APIC registers are mapped at an offset within the guest APIC
> backing page which is same as their x2APIC MMIO offset. Secure AVIC
> adds new registers such as ALLOWED_IRRs (which are at 4-byte offset
> within the IRR register offset range) and NMI_REQ to the APIC register
> space.
>
> When Secure AVIC is enabled, guest's rdmsr/wrmsr of APIC registers
> result in VC exception (for non-accelerated register accesses) with
s/VC/#VC/g since you're talking about an exception vector.
> error code VMEXIT_AVIC_NOACCEL. The VC exception handler can read/write
> the x2APIC register in the guest APIC backing page to complete the
> rdmsr/wrmsr.
All x86 insns in caps pls: RDMSR/WRMSR.
> +static u32 savic_read(u32 reg)
> +{
> + void *ap = this_cpu_ptr(secure_avic_page);
> +
> + /*
> + * When Secure AVIC is enabled, rdmsr/wrmsr of APIC registers
> + * result in VC exception (for non-accelerated register accesses)
> + * with VMEXIT_AVIC_NOACCEL error code. The VC exception handler
> + * can read/write the x2APIC register in the guest APIC backing page.
> + * Since doing this would increase the latency of accessing x2APIC
> + * registers, instead of doing rdmsr/wrmsr based accesses and
> + * handling apic register reads/writes in VC exception, the read()
s/apic/APIC/g
Please be consistent across the whole set. Acronyms are in all caps. Insn
names too.
> + * and write() callbacks directly read/write APIC register from/to
> + * the vCPU APIC backing page.
> + */
Move that comment above the function. And also split it in paragraphs: when it
becomes more than 4-5 lines, split the next one with a new line.
> + switch (reg) {
> + case APIC_LVTT:
> + case APIC_TMICT:
> + case APIC_TMCCT:
> + case APIC_TDCR:
> + case APIC_ID:
> + case APIC_LVR:
> + case APIC_TASKPRI:
> + case APIC_ARBPRI:
> + case APIC_PROCPRI:
> + case APIC_LDR:
> + case APIC_SPIV:
> + case APIC_ESR:
> + case APIC_LVTTHMR:
> + case APIC_LVTPC:
> + case APIC_LVT0:
> + case APIC_LVT1:
> + case APIC_LVTERR:
> + case APIC_EFEAT:
> + case APIC_ECTRL:
> + case APIC_SEOI:
> + case APIC_IER:
> + case APIC_EILVTn(0) ... APIC_EILVTn(3):
> + return apic_get_reg(ap, reg);
> + case APIC_ICR:
> + return (u32) apic_get_reg64(ap, reg);
^
no need for that space.
> + case APIC_ISR ... APIC_ISR + 0x70:
> + case APIC_TMR ... APIC_TMR + 0x70:
> + if (WARN_ONCE(!IS_ALIGNED(reg, 16),
> + "APIC reg read offset 0x%x not aligned at 16 bytes", reg))
> + return 0;
> + return apic_get_reg(ap, reg);
> + /* IRR and ALLOWED_IRR offset range */
> + case APIC_IRR ... APIC_IRR + 0x74:
> + /*
> + * Either aligned at 16 bytes for valid IRR reg offset or a
> + * valid Secure AVIC ALLOWED_IRR offset.
> + */
> + if (WARN_ONCE(!(IS_ALIGNED(reg, 16) ||
> + IS_ALIGNED(reg - SAVIC_ALLOWED_IRR, 16)),
> + "Misaligned IRR/ALLOWED_IRR APIC reg read offset 0x%x", reg))
What is that second thing supposed to catch?
reg can be aligned to 16 but reg - SAVIC_ALLOWED_IRR cannot be?
I can't follow the comment... perhaps write it out and not try to be clever.
> + return 0;
> + return apic_get_reg(ap, reg);
> + default:
> + pr_err("Permission denied: read of Secure AVIC reg offset 0x%x\n", reg);
Permission denied?
"Error reading unknown Secure AVIC reg offset..."
I'd say.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver
2025-08-18 11:26 ` Borislav Petkov
@ 2025-08-19 4:15 ` Upadhyay, Neeraj
2025-08-19 14:32 ` Borislav Petkov
0 siblings, 1 reply; 45+ messages in thread
From: Upadhyay, Neeraj @ 2025-08-19 4:15 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On 8/18/2025 4:56 PM, Borislav Petkov wrote:
> On Mon, Aug 11, 2025 at 03:14:29PM +0530, Neeraj Upadhyay wrote:
>> Add read() and write() APIC callback functions to read and write x2APIC
>> registers directly from the guest APIC backing page of a vCPU.
>>
>> The x2APIC registers are mapped at an offset within the guest APIC
>> backing page which is same as their x2APIC MMIO offset. Secure AVIC
>> adds new registers such as ALLOWED_IRRs (which are at 4-byte offset
>> within the IRR register offset range) and NMI_REQ to the APIC register
>> space.
>>
>> When Secure AVIC is enabled, guest's rdmsr/wrmsr of APIC registers
>> result in VC exception (for non-accelerated register accesses) with
>
> s/VC/#VC/g since you're talking about an exception vector.
>
Ok
>> error code VMEXIT_AVIC_NOACCEL. The VC exception handler can read/write
>> the x2APIC register in the guest APIC backing page to complete the
>> rdmsr/wrmsr.
>
> All x86 insns in caps pls: RDMSR/WRMSR.
>
Ok
>> +static u32 savic_read(u32 reg)
>> +{
>> + void *ap = this_cpu_ptr(secure_avic_page);
>> +
>> + /*
>> + * When Secure AVIC is enabled, rdmsr/wrmsr of APIC registers
>> + * result in VC exception (for non-accelerated register accesses)
>> + * with VMEXIT_AVIC_NOACCEL error code. The VC exception handler
>> + * can read/write the x2APIC register in the guest APIC backing page.
>> + * Since doing this would increase the latency of accessing x2APIC
>> + * registers, instead of doing rdmsr/wrmsr based accesses and
>> + * handling apic register reads/writes in VC exception, the read()
>
> s/apic/APIC/g
>
> Please be consistent across the whole set. Acronyms are in all caps. Insn
> names too.
>
Ok
>> + * and write() callbacks directly read/write APIC register from/to
>> + * the vCPU APIC backing page.
>> + */
>
> Move that comment above the function. And also split it in paragraphs: when it
> becomes more than 4-5 lines, split the next one with a new line.
>
Ok
>> + switch (reg) {
>> + case APIC_LVTT:
>> + case APIC_TMICT:
>> + case APIC_TMCCT:
>> + case APIC_TDCR:
>> + case APIC_ID:
>> + case APIC_LVR:
>> + case APIC_TASKPRI:
>> + case APIC_ARBPRI:
>> + case APIC_PROCPRI:
>> + case APIC_LDR:
>> + case APIC_SPIV:
>> + case APIC_ESR:
>> + case APIC_LVTTHMR:
>> + case APIC_LVTPC:
>> + case APIC_LVT0:
>> + case APIC_LVT1:
>> + case APIC_LVTERR:
>> + case APIC_EFEAT:
>> + case APIC_ECTRL:
>> + case APIC_SEOI:
>> + case APIC_IER:
>> + case APIC_EILVTn(0) ... APIC_EILVTn(3):
>> + return apic_get_reg(ap, reg);
>> + case APIC_ICR:
>> + return (u32) apic_get_reg64(ap, reg);
> ^
>
> no need for that space.
>
Ok, will remove.
>> + case APIC_ISR ... APIC_ISR + 0x70:
>> + case APIC_TMR ... APIC_TMR + 0x70:
>> + if (WARN_ONCE(!IS_ALIGNED(reg, 16),
>> + "APIC reg read offset 0x%x not aligned at 16 bytes", reg))
>> + return 0;
>> + return apic_get_reg(ap, reg);
>> + /* IRR and ALLOWED_IRR offset range */
>> + case APIC_IRR ... APIC_IRR + 0x74:
>> + /*
>> + * Either aligned at 16 bytes for valid IRR reg offset or a
>> + * valid Secure AVIC ALLOWED_IRR offset.
>> + */
>> + if (WARN_ONCE(!(IS_ALIGNED(reg, 16) ||
>> + IS_ALIGNED(reg - SAVIC_ALLOWED_IRR, 16)),
>> + "Misaligned IRR/ALLOWED_IRR APIC reg read offset 0x%x", reg))
>
> What is that second thing supposed to catch?
>
> reg can be aligned to 16 but reg - SAVIC_ALLOWED_IRR cannot be?
>
APIC_IRR register offsets are:
#Offset #bits Description
0x200 31:0 vectors 0-31
0x210 31:0 vectors 32-63
...
0x270 31:0 vectors 224-255
ALLOWED_IRR register offsets are:
#Offset #bits Description
0x204 31:0 vectors 0-31
0x214 31:0 vectors 32-63
...
0x274 31:0 vectors 224-255
IS_ALIGNED(reg, 16) is when 'reg' is an APIC_IRR register, which are 16
byte aligned.
IS_ALIGNED(reg - SAVIC_ALLOWED_IRR, 16) is for the case when 'reg' is
a SAVIC_ALLOWED_IRR register. which are at 16 byte strides from the
SAVIC_ALLOWED_IRR base offset. Expected values of (reg -
SAVIC_ALLOWED_IRR) are 0, 0x10, 0x20, ..., 0x70.
If both checks fail, that is a invalid offset ('!' is on the final ORed
value).
!(IS_ALIGNED(reg, 16) || IS_ALIGNED(reg - SAVIC_ALLOWED_IRR, 16))
> I can't follow the comment... perhaps write it out and not try to be clever.
>
Maybe change it to below?
/*
* Valid APIC_IRR/SAVIC_ALLOWED_IRR registers are at 16 bytes strides
* from their respective base offset.
*/
if (WARN_ONCE(!(IS_ALIGNED(reg - APIC_IRR, 16) ||
IS_ALIGNED(reg - SAVIC_ALLOWED_IRR, 16)),
"Misaligned APIC_IRR/ALLOWED_IRR APIC register read
offset 0x%x",
reg))
>> + return 0;
>> + return apic_get_reg(ap, reg);
>> + default:
>> + pr_err("Permission denied: read of Secure AVIC reg offset 0x%x\n", reg);
>
> Permission denied?
>
> "Error reading unknown Secure AVIC reg offset..."
>
> I'd say.
>
Ok, yes it is clearer.
- Neeraj
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver
2025-08-19 4:15 ` Upadhyay, Neeraj
@ 2025-08-19 14:32 ` Borislav Petkov
2025-08-20 3:33 ` Upadhyay, Neeraj
0 siblings, 1 reply; 45+ messages in thread
From: Borislav Petkov @ 2025-08-19 14:32 UTC (permalink / raw)
To: Upadhyay, Neeraj
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Tue, Aug 19, 2025 at 09:45:02AM +0530, Upadhyay, Neeraj wrote:
> Maybe change it to below?
>
> /*
> * Valid APIC_IRR/SAVIC_ALLOWED_IRR registers are at 16 bytes strides
> * from their respective base offset.
> */
>
> if (WARN_ONCE(!(IS_ALIGNED(reg - APIC_IRR, 16) ||
> IS_ALIGNED(reg - SAVIC_ALLOWED_IRR, 16)),
> "Misaligned APIC_IRR/ALLOWED_IRR APIC register read offset
> 0x%x",
> reg))
Let's beef that up some more with a crystal-clear explanation what is going on
here so that readers don't have to stop and stare for 5 mins before they grok
what this is doing:
/*
* Valid APIC_IRR/SAVIC_ALLOWED_IRR registers are at 16 bytes strides from
* their respective base offset. APIC_IRRs are in the range
*
* (0x200, 0x210, ..., 0x270)
*
* while the SAVIC_ALLOWED_IRR range starts 4 bytes later, in the rangea
*
* (0x204, 0x214, ..., 0x274).
*
* Filter out everything else.
*/
if (WARN_ONCE(!(IS_ALIGNED(reg, 16) ||
IS_ALIGNED(reg - 4, 16)),
"Misaligned APIC_IRR/ALLOWED_IRR APIC register read offset 0x%x", reg));
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver
2025-08-19 14:32 ` Borislav Petkov
@ 2025-08-20 3:33 ` Upadhyay, Neeraj
0 siblings, 0 replies; 45+ messages in thread
From: Upadhyay, Neeraj @ 2025-08-20 3:33 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On 8/19/2025 8:02 PM, Borislav Petkov wrote:
> On Tue, Aug 19, 2025 at 09:45:02AM +0530, Upadhyay, Neeraj wrote:
>> Maybe change it to below?
>>
>> /*
>> * Valid APIC_IRR/SAVIC_ALLOWED_IRR registers are at 16 bytes strides
>> * from their respective base offset.
>> */
>>
>> if (WARN_ONCE(!(IS_ALIGNED(reg - APIC_IRR, 16) ||
>> IS_ALIGNED(reg - SAVIC_ALLOWED_IRR, 16)),
>> "Misaligned APIC_IRR/ALLOWED_IRR APIC register read offset
>> 0x%x",
>> reg))
>
> Let's beef that up some more with a crystal-clear explanation what is going on
> here so that readers don't have to stop and stare for 5 mins before they grok
> what this is doing:
>
> /*
> * Valid APIC_IRR/SAVIC_ALLOWED_IRR registers are at 16 bytes strides from
> * their respective base offset. APIC_IRRs are in the range
> *
> * (0x200, 0x210, ..., 0x270)
> *
> * while the SAVIC_ALLOWED_IRR range starts 4 bytes later, in the rangea
> *
> * (0x204, 0x214, ..., 0x274).
> *
> * Filter out everything else.
> */
> if (WARN_ONCE(!(IS_ALIGNED(reg, 16) ||
> IS_ALIGNED(reg - 4, 16)),
> "Misaligned APIC_IRR/ALLOWED_IRR APIC register read offset 0x%x", reg));
>
Ok, looks good. Thanks!
- Neeraj
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 04/18] x86/apic: Initialize APIC ID for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (2 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-19 21:53 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 05/18] x86/apic: Add update_vector() callback for apic drivers Neeraj Upadhyay
` (14 subsequent siblings)
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Initialize the APIC ID in the Secure AVIC APIC backing page with
the APIC_ID msr value read from Hypervisor. CPU topology evaluation
later during boot would catch and report any duplicate APIC ID for
two CPUs.
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
- Code cleanup.
arch/x86/kernel/apic/x2apic_savic.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index 86a522685230..55edc6c30ba4 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -141,6 +141,12 @@ static void savic_setup(void)
enum es_result res;
unsigned long gpa;
+ /*
+ * Before Secure AVIC is enabled, APIC msr reads are intercepted.
+ * APIC_ID msr read returns the value from the Hypervisor.
+ */
+ apic_set_reg(ap, APIC_ID, native_apic_msr_read(APIC_ID));
+
gpa = __pa(ap);
/*
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 04/18] x86/apic: Initialize APIC ID for Secure AVIC
2025-08-11 9:44 ` [PATCH v9 04/18] x86/apic: Initialize APIC ID for Secure AVIC Neeraj Upadhyay
@ 2025-08-19 21:53 ` Borislav Petkov
2025-08-20 3:34 ` Upadhyay, Neeraj
0 siblings, 1 reply; 45+ messages in thread
From: Borislav Petkov @ 2025-08-19 21:53 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:30PM +0530, Neeraj Upadhyay wrote:
> Initialize the APIC ID in the Secure AVIC APIC backing page with
> the APIC_ID msr value read from Hypervisor. CPU topology evaluation
> later during boot would catch and report any duplicate APIC ID for
> two CPUs.
>
> Reviewed-by: Tianyu Lan <tiala@microsoft.com>
> Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
> ---
> Changes since v8:
> - Added Tianyu's Reviewed-by.
> - Code cleanup.
>
> arch/x86/kernel/apic/x2apic_savic.c | 6 ++++++
> 1 file changed, 6 insertions(+)
>
> diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
> index 86a522685230..55edc6c30ba4 100644
> --- a/arch/x86/kernel/apic/x2apic_savic.c
> +++ b/arch/x86/kernel/apic/x2apic_savic.c
> @@ -141,6 +141,12 @@ static void savic_setup(void)
> enum es_result res;
> unsigned long gpa;
>
> + /*
> + * Before Secure AVIC is enabled, APIC msr reads are intercepted.
s/msr/MSR/g
Please check your whole text for such acronyms.
> + * APIC_ID msr read returns the value from the Hypervisor.
> + */
> + apic_set_reg(ap, APIC_ID, native_apic_msr_read(APIC_ID));
> +
> gpa = __pa(ap);
>
> /*
> --
> 2.34.1
>
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 04/18] x86/apic: Initialize APIC ID for Secure AVIC
2025-08-19 21:53 ` Borislav Petkov
@ 2025-08-20 3:34 ` Upadhyay, Neeraj
0 siblings, 0 replies; 45+ messages in thread
From: Upadhyay, Neeraj @ 2025-08-20 3:34 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On 8/20/2025 3:23 AM, Borislav Petkov wrote:
> On Mon, Aug 11, 2025 at 03:14:30PM +0530, Neeraj Upadhyay wrote:
>> Initialize the APIC ID in the Secure AVIC APIC backing page with
>> the APIC_ID msr value read from Hypervisor. CPU topology evaluation
>> later during boot would catch and report any duplicate APIC ID for
>> two CPUs.
>>
>> Reviewed-by: Tianyu Lan <tiala@microsoft.com>
>> Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
>> ---
>> Changes since v8:
>> - Added Tianyu's Reviewed-by.
>> - Code cleanup.
>>
>> arch/x86/kernel/apic/x2apic_savic.c | 6 ++++++
>> 1 file changed, 6 insertions(+)
>>
>> diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
>> index 86a522685230..55edc6c30ba4 100644
>> --- a/arch/x86/kernel/apic/x2apic_savic.c
>> +++ b/arch/x86/kernel/apic/x2apic_savic.c
>> @@ -141,6 +141,12 @@ static void savic_setup(void)
>> enum es_result res;
>> unsigned long gpa;
>>
>> + /*
>> + * Before Secure AVIC is enabled, APIC msr reads are intercepted.
>
> s/msr/MSR/g
>
> Please check your whole text for such acronyms.
>
Ok, will fix this in all patches.
- Neeraj
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 05/18] x86/apic: Add update_vector() callback for apic drivers
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (3 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 04/18] x86/apic: Initialize APIC ID for Secure AVIC Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-19 21:59 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 06/18] x86/apic: Add update_vector() callback for Secure AVIC Neeraj Upadhyay
` (13 subsequent siblings)
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Add an update_vector() callback to allow APIC drivers to perform
driver specific operations on external vector allocation/teardown
on a CPU. This callback will be used in subsequent commits by Secure
AVIC APIC driver to configure the vectors which a guest vCPU allows
the hypervisor to send to it.
As system vectors have fixed vector assignments and are not dynamically
allocated, add apic_update_vector() public api to facilitate
update_vector() callback invocation for them. This will be used for
Secure AVIC enabled guests to allow the hypervisor to inject system
vectors which are emulated by the hypervisor such as APIC timer vector
and HYPERVISOR_CALLBACK_VECTOR.
While at it, cleanup line break in apic_update_irq_cfg().
Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- No change.
arch/x86/include/asm/apic.h | 9 +++++++++
arch/x86/kernel/apic/vector.c | 29 ++++++++++++++++++-----------
2 files changed, 27 insertions(+), 11 deletions(-)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 44b4080721a6..0683318470be 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -318,6 +318,8 @@ struct apic {
/* wakeup secondary CPU using 64-bit wakeup point */
int (*wakeup_secondary_cpu_64)(u32 apicid, unsigned long start_eip, unsigned int cpu);
+ void (*update_vector)(unsigned int cpu, unsigned int vector, bool set);
+
char *name;
};
@@ -471,6 +473,12 @@ static __always_inline bool apic_id_valid(u32 apic_id)
return apic_id <= apic->max_apic_id;
}
+static __always_inline void apic_update_vector(unsigned int cpu, unsigned int vector, bool set)
+{
+ if (apic->update_vector)
+ apic->update_vector(cpu, vector, set);
+}
+
#else /* CONFIG_X86_LOCAL_APIC */
static inline u32 apic_read(u32 reg) { return 0; }
@@ -482,6 +490,7 @@ static inline void apic_wait_icr_idle(void) { }
static inline u32 safe_apic_wait_icr_idle(void) { return 0; }
static inline void apic_native_eoi(void) { WARN_ON_ONCE(1); }
static inline void apic_setup_apic_calls(void) { }
+static inline void apic_update_vector(unsigned int cpu, unsigned int vector, bool set) { }
#define apic_update_callback(_callback, _fn) do { } while (0)
diff --git a/arch/x86/kernel/apic/vector.c b/arch/x86/kernel/apic/vector.c
index a947b46a8b64..655eeb808ebc 100644
--- a/arch/x86/kernel/apic/vector.c
+++ b/arch/x86/kernel/apic/vector.c
@@ -134,13 +134,21 @@ static void apic_update_irq_cfg(struct irq_data *irqd, unsigned int vector,
apicd->hw_irq_cfg.vector = vector;
apicd->hw_irq_cfg.dest_apicid = apic->calc_dest_apicid(cpu);
+
+ apic_update_vector(cpu, vector, true);
+
irq_data_update_effective_affinity(irqd, cpumask_of(cpu));
- trace_vector_config(irqd->irq, vector, cpu,
- apicd->hw_irq_cfg.dest_apicid);
+ trace_vector_config(irqd->irq, vector, cpu, apicd->hw_irq_cfg.dest_apicid);
}
-static void apic_update_vector(struct irq_data *irqd, unsigned int newvec,
- unsigned int newcpu)
+static void apic_free_vector(unsigned int cpu, unsigned int vector, bool managed)
+{
+ apic_update_vector(cpu, vector, false);
+ irq_matrix_free(vector_matrix, cpu, vector, managed);
+}
+
+static void apic_chipd_update_vector(struct irq_data *irqd, unsigned int newvec,
+ unsigned int newcpu)
{
struct apic_chip_data *apicd = apic_chip_data(irqd);
struct irq_desc *desc = irq_data_to_desc(irqd);
@@ -174,8 +182,7 @@ static void apic_update_vector(struct irq_data *irqd, unsigned int newvec,
apicd->prev_cpu = apicd->cpu;
WARN_ON_ONCE(apicd->cpu == newcpu);
} else {
- irq_matrix_free(vector_matrix, apicd->cpu, apicd->vector,
- managed);
+ apic_free_vector(apicd->cpu, apicd->vector, managed);
}
setnew:
@@ -261,7 +268,7 @@ assign_vector_locked(struct irq_data *irqd, const struct cpumask *dest)
trace_vector_alloc(irqd->irq, vector, resvd, vector);
if (vector < 0)
return vector;
- apic_update_vector(irqd, vector, cpu);
+ apic_chipd_update_vector(irqd, vector, cpu);
return 0;
}
@@ -337,7 +344,7 @@ assign_managed_vector(struct irq_data *irqd, const struct cpumask *dest)
trace_vector_alloc_managed(irqd->irq, vector, vector);
if (vector < 0)
return vector;
- apic_update_vector(irqd, vector, cpu);
+ apic_chipd_update_vector(irqd, vector, cpu);
return 0;
}
@@ -357,7 +364,7 @@ static void clear_irq_vector(struct irq_data *irqd)
apicd->prev_cpu);
per_cpu(vector_irq, apicd->cpu)[vector] = VECTOR_SHUTDOWN;
- irq_matrix_free(vector_matrix, apicd->cpu, vector, managed);
+ apic_free_vector(apicd->cpu, vector, managed);
apicd->vector = 0;
/* Clean up move in progress */
@@ -366,7 +373,7 @@ static void clear_irq_vector(struct irq_data *irqd)
return;
per_cpu(vector_irq, apicd->prev_cpu)[vector] = VECTOR_SHUTDOWN;
- irq_matrix_free(vector_matrix, apicd->prev_cpu, vector, managed);
+ apic_free_vector(apicd->prev_cpu, vector, managed);
apicd->prev_vector = 0;
apicd->move_in_progress = 0;
hlist_del_init(&apicd->clist);
@@ -905,7 +912,7 @@ static void free_moved_vector(struct apic_chip_data *apicd)
* affinity mask comes online.
*/
trace_vector_free_moved(apicd->irq, cpu, vector, managed);
- irq_matrix_free(vector_matrix, cpu, vector, managed);
+ apic_free_vector(cpu, vector, managed);
per_cpu(vector_irq, cpu)[vector] = VECTOR_UNUSED;
hlist_del_init(&apicd->clist);
apicd->prev_vector = 0;
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 05/18] x86/apic: Add update_vector() callback for apic drivers
2025-08-11 9:44 ` [PATCH v9 05/18] x86/apic: Add update_vector() callback for apic drivers Neeraj Upadhyay
@ 2025-08-19 21:59 ` Borislav Petkov
2025-08-20 3:36 ` Upadhyay, Neeraj
0 siblings, 1 reply; 45+ messages in thread
From: Borislav Petkov @ 2025-08-19 21:59 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:31PM +0530, Neeraj Upadhyay wrote:
> +static void apic_chipd_update_vector(struct irq_data *irqd, unsigned int newvec,
What is "chipd" supposed to denote?
> + unsigned int newcpu)
> {
> struct apic_chip_data *apicd = apic_chip_data(irqd);
> struct irq_desc *desc = irq_data_to_desc(irqd);
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 05/18] x86/apic: Add update_vector() callback for apic drivers
2025-08-19 21:59 ` Borislav Petkov
@ 2025-08-20 3:36 ` Upadhyay, Neeraj
2025-08-25 14:49 ` Borislav Petkov
0 siblings, 1 reply; 45+ messages in thread
From: Upadhyay, Neeraj @ 2025-08-20 3:36 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On 8/20/2025 3:29 AM, Borislav Petkov wrote:
> On Mon, Aug 11, 2025 at 03:14:31PM +0530, Neeraj Upadhyay wrote:
>> +static void apic_chipd_update_vector(struct irq_data *irqd, unsigned int newvec,
>
> What is "chipd" supposed to denote?
>
chip data (struct apic_chip_data)
- Neeraj
>> + unsigned int newcpu)
>> {
>> struct apic_chip_data *apicd = apic_chip_data(irqd);
>> struct irq_desc *desc = irq_data_to_desc(irqd);
>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 05/18] x86/apic: Add update_vector() callback for apic drivers
2025-08-20 3:36 ` Upadhyay, Neeraj
@ 2025-08-25 14:49 ` Borislav Petkov
2025-08-26 4:06 ` Upadhyay, Neeraj
0 siblings, 1 reply; 45+ messages in thread
From: Borislav Petkov @ 2025-08-25 14:49 UTC (permalink / raw)
To: Upadhyay, Neeraj
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Wed, Aug 20, 2025 at 09:06:52AM +0530, Upadhyay, Neeraj wrote:
> > > +static void apic_chipd_update_vector(struct irq_data *irqd, unsigned int newvec,
> >
> > What is "chipd" supposed to denote?
>
> chip data (struct apic_chip_data)
So this function should be called chip_data_update() or so?
It is static so it doesn't need the "apic_" prefix and "chipd" doesn't make
a whole lotta of sense so let's call it as what it does.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 05/18] x86/apic: Add update_vector() callback for apic drivers
2025-08-25 14:49 ` Borislav Petkov
@ 2025-08-26 4:06 ` Upadhyay, Neeraj
2025-08-26 13:25 ` Borislav Petkov
0 siblings, 1 reply; 45+ messages in thread
From: Upadhyay, Neeraj @ 2025-08-26 4:06 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On 8/25/2025 8:19 PM, Borislav Petkov wrote:
> On Wed, Aug 20, 2025 at 09:06:52AM +0530, Upadhyay, Neeraj wrote:
>>>> +static void apic_chipd_update_vector(struct irq_data *irqd, unsigned int newvec,
>>>
>>> What is "chipd" supposed to denote?
>>
>> chip data (struct apic_chip_data)
>
> So this function should be called chip_data_update() or so?
>
or chip_data_update_vector() as the updates are specific for a new
vector assignment?
> It is static so it doesn't need the "apic_" prefix and "chipd" doesn't make
> a whole lotta of sense so let's call it as what it does.
>
Got it. However, I see other static functions in this file using "apic_"
prefix (in some cases, maybe to differentiate "apic_chip_data" from a
generic "chip_data" in common kernel/irq/ subys?).
- Neeraj
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 05/18] x86/apic: Add update_vector() callback for apic drivers
2025-08-26 4:06 ` Upadhyay, Neeraj
@ 2025-08-26 13:25 ` Borislav Petkov
0 siblings, 0 replies; 45+ messages in thread
From: Borislav Petkov @ 2025-08-26 13:25 UTC (permalink / raw)
To: Upadhyay, Neeraj
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Tue, Aug 26, 2025 at 09:36:56AM +0530, Upadhyay, Neeraj wrote:
> or chip_data_update_vector() as the updates are specific for a new vector
> assignment?
This function assigns a bunch of things to struct apic_chip_data - not only
vector.
If we had to be precise perhaps update_vector_chip_data() or so. Or
chip_data_update_for_vector(). To better describe what the function does.
> Got it. However, I see other static functions in this file using "apic_"
> prefix (in some cases, maybe to differentiate "apic_chip_data" from a
> generic "chip_data" in common kernel/irq/ subys?).
Looks like this file would need cleaning up wrt naming but that's not that
important at the moment I'd say. There are other functions which don't have
the apic_ prefix so it is kinda arbitrary.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 06/18] x86/apic: Add update_vector() callback for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (4 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 05/18] x86/apic: Add update_vector() callback for apic drivers Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 07/18] x86/apic: Add support to send IPI " Neeraj Upadhyay
` (12 subsequent siblings)
18 siblings, 0 replies; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Add update_vector() callback to set/clear ALLOWED_IRR field in
a vCPU's APIC backing page for vectors which are emulated by the
hypervisor.
The ALLOWED_IRR field indicates the interrupt vectors which the
guest allows the hypervisor to inject (typically for emulated devices).
Interrupt vectors used exclusively by the guest itself and the vectors
which are not emulated by the hypervisor, such as IPI vectors, should
not be set by the guest in the ALLOWED_IRR fields.
As clearing/setting state of a vector will also be used in subsequent
commits for other APIC regs (such as APIC_IRR update for sending IPI),
add a common update_vector() in Secure AVIC driver.
Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
- Updates to use struce secure_avic_page.
arch/x86/kernel/apic/x2apic_savic.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index 55edc6c30ba4..cfe72473f843 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -27,6 +27,22 @@ static int savic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
return x2apic_enabled() && cc_platform_has(CC_ATTR_SNP_SECURE_AVIC);
}
+static inline void *get_reg_bitmap(unsigned int cpu, unsigned int offset)
+{
+ return &per_cpu_ptr(secure_avic_page, cpu)->regs[offset];
+}
+
+static inline void update_vector(unsigned int cpu, unsigned int offset,
+ unsigned int vector, bool set)
+{
+ void *bitmap = get_reg_bitmap(cpu, offset);
+
+ if (set)
+ apic_set_vector(vector, bitmap);
+ else
+ apic_clear_vector(vector, bitmap);
+}
+
#define SAVIC_ALLOWED_IRR 0x204
static u32 savic_read(u32 reg)
@@ -135,6 +151,11 @@ static void savic_write(u32 reg, u32 data)
}
}
+static void savic_update_vector(unsigned int cpu, unsigned int vector, bool set)
+{
+ update_vector(cpu, SAVIC_ALLOWED_IRR, vector, set);
+}
+
static void savic_setup(void)
{
void *ap = this_cpu_ptr(secure_avic_page);
@@ -208,6 +229,8 @@ static struct apic apic_x2apic_savic __ro_after_init = {
.eoi = native_apic_msr_eoi,
.icr_read = native_x2apic_icr_read,
.icr_write = native_x2apic_icr_write,
+
+ .update_vector = savic_update_vector,
};
apic_driver(apic_x2apic_savic);
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v9 07/18] x86/apic: Add support to send IPI for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (5 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 06/18] x86/apic: Add update_vector() callback for Secure AVIC Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-20 15:46 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 08/18] x86/apic: Support LAPIC timer " Neeraj Upadhyay
` (11 subsequent siblings)
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
With Secure AVIC only Self-IPI is accelerated. To handle all the
other IPIs, add new callbacks for sending IPI. These callbacks write
to the IRR of the target guest vCPU's APIC backing page and issue
GHCB protocol MSR write event for the hypervisor to notify the
target vCPU about the new interrupt request.
For Secure AVIC GHCB APIC MSR writes, reuse GHCB msr handling code in
vc_handle_msr() by exposing a sev-internal sev_es_ghcb_handle_msr().
Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
- Use struct secure_avic_page.
arch/x86/coco/sev/core.c | 28 ++++++
arch/x86/coco/sev/vc-handle.c | 11 ++-
arch/x86/include/asm/sev-internal.h | 2 +
arch/x86/include/asm/sev.h | 2 +
arch/x86/kernel/apic/x2apic_savic.c | 138 +++++++++++++++++++++++++++-
5 files changed, 173 insertions(+), 8 deletions(-)
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index 0c59ea82fa99..221a0fc0c387 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -1085,6 +1085,34 @@ int __init sev_es_efi_map_ghcbs_cas(pgd_t *pgd)
return 0;
}
+void savic_ghcb_msr_write(u32 reg, u64 value)
+{
+ u64 msr = APIC_BASE_MSR + (reg >> 4);
+ struct pt_regs regs = {
+ .cx = msr,
+ .ax = lower_32_bits(value),
+ .dx = upper_32_bits(value)
+ };
+ struct es_em_ctxt ctxt = { .regs = ®s };
+ struct ghcb_state state;
+ enum es_result res;
+ struct ghcb *ghcb;
+
+ guard(irqsave)();
+
+ ghcb = __sev_get_ghcb(&state);
+ vc_ghcb_invalidate(ghcb);
+
+ res = sev_es_ghcb_handle_msr(ghcb, &ctxt, true);
+ if (res != ES_OK) {
+ pr_err("Secure AVIC msr (0x%llx) write returned error (%d)\n", msr, res);
+ /* MSR writes should never fail. Any failure is fatal error for SNP guest */
+ snp_abort();
+ }
+
+ __sev_put_ghcb(&state);
+}
+
enum es_result savic_register_gpa(u64 gpa)
{
struct ghcb_state state;
diff --git a/arch/x86/coco/sev/vc-handle.c b/arch/x86/coco/sev/vc-handle.c
index faf1fce89ed4..fc770cc9117d 100644
--- a/arch/x86/coco/sev/vc-handle.c
+++ b/arch/x86/coco/sev/vc-handle.c
@@ -401,14 +401,10 @@ static enum es_result __vc_handle_secure_tsc_msrs(struct pt_regs *regs, bool wri
return ES_OK;
}
-static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
+enum es_result sev_es_ghcb_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt, bool write)
{
struct pt_regs *regs = ctxt->regs;
enum es_result ret;
- bool write;
-
- /* Is it a WRMSR? */
- write = ctxt->insn.opcode.bytes[1] == 0x30;
switch (regs->cx) {
case MSR_SVSM_CAA:
@@ -438,6 +434,11 @@ static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
return ret;
}
+static enum es_result vc_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt)
+{
+ return sev_es_ghcb_handle_msr(ghcb, ctxt, ctxt->insn.opcode.bytes[1] == 0x30);
+}
+
static void __init vc_early_forward_exception(struct es_em_ctxt *ctxt)
{
int trapnr = ctxt->fi.vector;
diff --git a/arch/x86/include/asm/sev-internal.h b/arch/x86/include/asm/sev-internal.h
index 3dfd306d1c9e..6876655183a6 100644
--- a/arch/x86/include/asm/sev-internal.h
+++ b/arch/x86/include/asm/sev-internal.h
@@ -97,6 +97,8 @@ static __always_inline void sev_es_wr_ghcb_msr(u64 val)
native_wrmsr(MSR_AMD64_SEV_ES_GHCB, low, high);
}
+enum es_result sev_es_ghcb_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt, bool write);
+
void snp_register_ghcb_early(unsigned long paddr);
bool sev_es_negotiate_protocol(void);
bool sev_es_check_cpu_features(void);
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index 8e5083b46607..e849e616dd24 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -534,6 +534,7 @@ int snp_svsm_vtpm_send_command(u8 *buffer);
void __init snp_secure_tsc_prepare(void);
void __init snp_secure_tsc_init(void);
enum es_result savic_register_gpa(u64 gpa);
+void savic_ghcb_msr_write(u32 reg, u64 value);
static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb)
{
@@ -607,6 +608,7 @@ static inline int snp_svsm_vtpm_send_command(u8 *buffer) { return -ENODEV; }
static inline void __init snp_secure_tsc_prepare(void) { }
static inline void __init snp_secure_tsc_init(void) { }
static inline enum es_result savic_register_gpa(u64 gpa) { return ES_UNSUPPORTED; }
+static inline void savic_ghcb_msr_write(u32 reg, u64 value) { }
#endif /* CONFIG_AMD_MEM_ENCRYPT */
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index cfe72473f843..dbd488191a16 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -8,6 +8,7 @@
*/
#include <linux/cc_platform.h>
+#include <linux/cpumask.h>
#include <linux/percpu-defs.h>
#include <linux/align.h>
@@ -111,6 +112,73 @@ static u32 savic_read(u32 reg)
#define SAVIC_NMI_REQ 0x278
+static inline void self_ipi_reg_write(unsigned int vector)
+{
+ /*
+ * Secure AVIC hardware accelerates guest's MSR write to SELF_IPI
+ * register. It updates the IRR in the APIC backing page, evaluates
+ * the new IRR for interrupt injection and continues with guest
+ * code execution.
+ */
+ native_apic_msr_write(APIC_SELF_IPI, vector);
+}
+
+static void send_ipi_dest(unsigned int cpu, unsigned int vector)
+{
+ update_vector(cpu, APIC_IRR, vector, true);
+}
+
+static void send_ipi_allbut(unsigned int vector)
+{
+ unsigned int cpu, src_cpu;
+
+ guard(irqsave)();
+
+ src_cpu = raw_smp_processor_id();
+
+ for_each_cpu(cpu, cpu_online_mask) {
+ if (cpu == src_cpu)
+ continue;
+ send_ipi_dest(cpu, vector);
+ }
+}
+
+static inline void self_ipi(unsigned int vector)
+{
+ u32 icr_low = APIC_SELF_IPI | vector;
+
+ native_x2apic_icr_write(icr_low, 0);
+}
+
+static void savic_icr_write(u32 icr_low, u32 icr_high)
+{
+ unsigned int dsh, vector;
+ u64 icr_data;
+
+ dsh = icr_low & APIC_DEST_ALLBUT;
+ vector = icr_low & APIC_VECTOR_MASK;
+
+ switch (dsh) {
+ case APIC_DEST_SELF:
+ self_ipi(vector);
+ break;
+ case APIC_DEST_ALLINC:
+ self_ipi(vector);
+ fallthrough;
+ case APIC_DEST_ALLBUT:
+ send_ipi_allbut(vector);
+ break;
+ default:
+ send_ipi_dest(icr_high, vector);
+ break;
+ }
+
+ icr_data = ((u64)icr_high) << 32 | icr_low;
+ if (dsh != APIC_DEST_SELF)
+ savic_ghcb_msr_write(APIC_ICR, icr_data);
+ apic_set_reg64(this_cpu_ptr(secure_avic_page), APIC_ICR, icr_data);
+}
+
static void savic_write(u32 reg, u32 data)
{
void *ap = this_cpu_ptr(secure_avic_page);
@@ -121,7 +189,6 @@ static void savic_write(u32 reg, u32 data)
case APIC_LVT1:
case APIC_TMICT:
case APIC_TDCR:
- case APIC_SELF_IPI:
case APIC_TASKPRI:
case APIC_EOI:
case APIC_SPIV:
@@ -137,7 +204,10 @@ static void savic_write(u32 reg, u32 data)
apic_set_reg(ap, reg, data);
break;
case APIC_ICR:
- apic_set_reg64(ap, reg, (u64) data);
+ savic_icr_write(data, 0);
+ break;
+ case APIC_SELF_IPI:
+ self_ipi_reg_write(data);
break;
/* ALLOWED_IRR offsets are writable */
case SAVIC_ALLOWED_IRR ... SAVIC_ALLOWED_IRR + 0x70:
@@ -151,6 +221,61 @@ static void savic_write(u32 reg, u32 data)
}
}
+static void send_ipi(u32 dest, unsigned int vector, unsigned int dsh)
+{
+ unsigned int icr_low;
+
+ icr_low = __prepare_ICR(dsh, vector, APIC_DEST_PHYSICAL);
+ savic_icr_write(icr_low, dest);
+}
+
+static void savic_send_ipi(int cpu, int vector)
+{
+ u32 dest = per_cpu(x86_cpu_to_apicid, cpu);
+
+ send_ipi(dest, vector, 0);
+}
+
+static void send_ipi_mask(const struct cpumask *mask, unsigned int vector, bool excl_self)
+{
+ unsigned int cpu, this_cpu;
+
+ guard(irqsave)();
+
+ this_cpu = raw_smp_processor_id();
+
+ for_each_cpu(cpu, mask) {
+ if (excl_self && cpu == this_cpu)
+ continue;
+ send_ipi(per_cpu(x86_cpu_to_apicid, cpu), vector, 0);
+ }
+}
+
+static void savic_send_ipi_mask(const struct cpumask *mask, int vector)
+{
+ send_ipi_mask(mask, vector, false);
+}
+
+static void savic_send_ipi_mask_allbutself(const struct cpumask *mask, int vector)
+{
+ send_ipi_mask(mask, vector, true);
+}
+
+static void savic_send_ipi_allbutself(int vector)
+{
+ send_ipi(0, vector, APIC_DEST_ALLBUT);
+}
+
+static void savic_send_ipi_all(int vector)
+{
+ send_ipi(0, vector, APIC_DEST_ALLINC);
+}
+
+static void savic_send_ipi_self(int vector)
+{
+ self_ipi_reg_write(vector);
+}
+
static void savic_update_vector(unsigned int cpu, unsigned int vector, bool set)
{
update_vector(cpu, SAVIC_ALLOWED_IRR, vector, set);
@@ -222,13 +347,20 @@ static struct apic apic_x2apic_savic __ro_after_init = {
.calc_dest_apicid = apic_default_calc_apicid,
+ .send_IPI = savic_send_ipi,
+ .send_IPI_mask = savic_send_ipi_mask,
+ .send_IPI_mask_allbutself = savic_send_ipi_mask_allbutself,
+ .send_IPI_allbutself = savic_send_ipi_allbutself,
+ .send_IPI_all = savic_send_ipi_all,
+ .send_IPI_self = savic_send_ipi_self,
+
.nmi_to_offline_cpu = true,
.read = savic_read,
.write = savic_write,
.eoi = native_apic_msr_eoi,
.icr_read = native_x2apic_icr_read,
- .icr_write = native_x2apic_icr_write,
+ .icr_write = savic_icr_write,
.update_vector = savic_update_vector,
};
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 07/18] x86/apic: Add support to send IPI for Secure AVIC
2025-08-11 9:44 ` [PATCH v9 07/18] x86/apic: Add support to send IPI " Neeraj Upadhyay
@ 2025-08-20 15:46 ` Borislav Petkov
2025-08-21 5:27 ` Upadhyay, Neeraj
0 siblings, 1 reply; 45+ messages in thread
From: Borislav Petkov @ 2025-08-20 15:46 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:33PM +0530, Neeraj Upadhyay wrote:
> With Secure AVIC only Self-IPI is accelerated. To handle all the
> other IPIs, add new callbacks for sending IPI. These callbacks write
> to the IRR of the target guest vCPU's APIC backing page and issue
> GHCB protocol MSR write event for the hypervisor to notify the
> target vCPU about the new interrupt request.
>
> For Secure AVIC GHCB APIC MSR writes, reuse GHCB msr handling code in
^^^^^^^^^^^^^^^^^^
say what now?!
> +void savic_ghcb_msr_write(u32 reg, u64 value)
I guess this belongs into x2apic_savic.c.
> +{
> + u64 msr = APIC_BASE_MSR + (reg >> 4);
> + struct pt_regs regs = {
> + .cx = msr,
> + .ax = lower_32_bits(value),
> + .dx = upper_32_bits(value)
> + };
> + struct es_em_ctxt ctxt = { .regs = ®s };
> + struct ghcb_state state;
> + enum es_result res;
> + struct ghcb *ghcb;
> +
> + guard(irqsave)();
> +
> + ghcb = __sev_get_ghcb(&state);
> + vc_ghcb_invalidate(ghcb);
> +
> + res = sev_es_ghcb_handle_msr(ghcb, &ctxt, true);
> + if (res != ES_OK) {
> + pr_err("Secure AVIC msr (0x%llx) write returned error (%d)\n", msr, res);
> + /* MSR writes should never fail. Any failure is fatal error for SNP guest */
> + snp_abort();
> + }
> +
> + __sev_put_ghcb(&state);
> +}
...
> +static inline void self_ipi_reg_write(unsigned int vector)
> +{
> + /*
> + * Secure AVIC hardware accelerates guest's MSR write to SELF_IPI
> + * register. It updates the IRR in the APIC backing page, evaluates
> + * the new IRR for interrupt injection and continues with guest
> + * code execution.
> + */
Why is that comment here? It is above a WRMSR write. What acceleration is it
talking about?
> + native_apic_msr_write(APIC_SELF_IPI, vector);
> +}
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 07/18] x86/apic: Add support to send IPI for Secure AVIC
2025-08-20 15:46 ` Borislav Petkov
@ 2025-08-21 5:27 ` Upadhyay, Neeraj
2025-08-22 17:14 ` Borislav Petkov
0 siblings, 1 reply; 45+ messages in thread
From: Upadhyay, Neeraj @ 2025-08-21 5:27 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On 8/20/2025 9:16 PM, Borislav Petkov wrote:
> On Mon, Aug 11, 2025 at 03:14:33PM +0530, Neeraj Upadhyay wrote:
>> With Secure AVIC only Self-IPI is accelerated. To handle all the
>> other IPIs, add new callbacks for sending IPI. These callbacks write
>> to the IRR of the target guest vCPU's APIC backing page and issue
>> GHCB protocol MSR write event for the hypervisor to notify the
>> target vCPU about the new interrupt request.
>>
>> For Secure AVIC GHCB APIC MSR writes, reuse GHCB msr handling code in
> ^^^^^^^^^^^^^^^^^^
>
> say what now?!
>
Is below better?
x86/apic: Add support to send IPI for Secure AVIC
Secure AVIC hardware only accelerates Self-IPI, i.e. on WRMSR to
APIC_SELF_IPI and APIC_ICR (with destination shorthand equal to Self)
registers, hardware takes care of updating the APIC_IRR in the APIC
backing page of the vCPU. For other IPI types (cross-vCPU, broadcast
IPIs), software needs to take care of updating the APIC_IRR state of the
target CPUs and to ensure that the target vCPUs notice the new pending
interrupt.
Add new callbacks in the Secure AVIC driver for sending IPI requests.
These callbacks update the IRR in the target guest vCPU's APIC backing
page. To ensure that the remote vCPU notices the new pending interrupt,
reuse the GHCB MSR handling code in vc_handle_msr() to issue APIC_ICR
MSR-write GHCB protocol event to the hypervisor. For Secure AVIC guests,
on APIC_ICR write MSR exits, the hypervisor notifies the target vCPU by
either sending an AVIC doorbell (if target vCPU is running) or by waking
up the non-running target vCPU.
>> +void savic_ghcb_msr_write(u32 reg, u64 value)
>
> I guess this belongs into x2apic_savic.c.
>
Ok moving it to x2apic_savic.c requires below 4 sev-internal
declarations to be moved to arch/x86/include/asm/sev.h
struct ghcb_state;
struct ghcb *__sev_get_ghcb(struct ghcb_state *state);
void __sev_put_ghcb(struct ghcb_state *state);
enum es_result sev_es_ghcb_handle_msr(...);
>> +{
>> + u64 msr = APIC_BASE_MSR + (reg >> 4);
>> + struct pt_regs regs = {
>> + .cx = msr,
>> + .ax = lower_32_bits(value),
>> + .dx = upper_32_bits(value)
>> + };
>> + struct es_em_ctxt ctxt = { .regs = ®s };
>> + struct ghcb_state state;
>> + enum es_result res;
>> + struct ghcb *ghcb;
>> +
>> + guard(irqsave)();
>> +
>> + ghcb = __sev_get_ghcb(&state);
>> + vc_ghcb_invalidate(ghcb);
>> +
>> + res = sev_es_ghcb_handle_msr(ghcb, &ctxt, true);
>> + if (res != ES_OK) {
>> + pr_err("Secure AVIC msr (0x%llx) write returned error (%d)\n", msr, res);
>> + /* MSR writes should never fail. Any failure is fatal error for SNP guest */
>> + snp_abort();
>> + }
>> +
>> + __sev_put_ghcb(&state);
>> +}
>
> ...
>
>> +static inline void self_ipi_reg_write(unsigned int vector)
>> +{
>> + /*
>> + * Secure AVIC hardware accelerates guest's MSR write to SELF_IPI
>> + * register. It updates the IRR in the APIC backing page, evaluates
>> + * the new IRR for interrupt injection and continues with guest
>> + * code execution.
>> + */
>
> Why is that comment here? It is above a WRMSR write. What acceleration is it
> talking about?
>
This comment explains why WRMSR is sufficient for sending SELF_IPI. On
WRMSR by vCPU, Secure AVIC hardware takes care of updating APIC_IRR in
backing page. Hardware also ensures that new APIC_IRR state is evaluated
for new pending interrupts. So, WRMSR is hardware-accelerated.
For non-self-IPI case, software need to do APIC_IRR update and sending
of wakeup-request/doorbell to the target vCPU.
- Neeraj
>> + native_apic_msr_write(APIC_SELF_IPI, vector);
>> +}
>
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 07/18] x86/apic: Add support to send IPI for Secure AVIC
2025-08-21 5:27 ` Upadhyay, Neeraj
@ 2025-08-22 17:14 ` Borislav Petkov
2025-08-23 4:20 ` Upadhyay, Neeraj
0 siblings, 1 reply; 45+ messages in thread
From: Borislav Petkov @ 2025-08-22 17:14 UTC (permalink / raw)
To: Upadhyay, Neeraj
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Thu, Aug 21, 2025 at 10:57:24AM +0530, Upadhyay, Neeraj wrote:
> Is below better?
I was only reacting to that head-spinning, conglomerate of abbreviations "AVIC
GHCB APIC MSR".
> x86/apic: Add support to send IPI for Secure AVIC
>
> Secure AVIC hardware only accelerates Self-IPI, i.e. on WRMSR to
> APIC_SELF_IPI and APIC_ICR (with destination shorthand equal to Self)
> registers, hardware takes care of updating the APIC_IRR in the APIC
> backing page of the vCPU. For other IPI types (cross-vCPU, broadcast IPIs),
> software needs to take care of updating the APIC_IRR state of the target
> CPUs and to ensure that the target vCPUs notice the new pending interrupt.
>
> Add new callbacks in the Secure AVIC driver for sending IPI requests. These
> callbacks update the IRR in the target guest vCPU's APIC backing page. To
> ensure that the remote vCPU notices the new pending interrupt, reuse the
> GHCB MSR handling code in vc_handle_msr() to issue APIC_ICR MSR-write GHCB
> protocol event to the hypervisor. For Secure AVIC guests, on APIC_ICR write
> MSR exits, the hypervisor notifies the target vCPU by either sending an AVIC
> doorbell (if target vCPU is running) or by waking up the non-running target
> vCPU.
But I'll take a definitely better commit message too! :-)
> Ok moving it to x2apic_savic.c requires below 4 sev-internal declarations to
> be moved to arch/x86/include/asm/sev.h
>
> struct ghcb_state;
> struct ghcb *__sev_get_ghcb(struct ghcb_state *state);
> void __sev_put_ghcb(struct ghcb_state *state);
> enum es_result sev_es_ghcb_handle_msr(...);
Well, do you anticipate needing any more sev* facilities for SAVIC?
If so, you probably should carve them out into arch/x86/coco/sev/savic.c
If only 4 functions, I guess they're probably still ok in .../sev/core.c
> This comment explains why WRMSR is sufficient for sending SELF_IPI. On
> WRMSR by vCPU, Secure AVIC hardware takes care of updating APIC_IRR in
> backing page. Hardware also ensures that new APIC_IRR state is evaluated
> for new pending interrupts. So, WRMSR is hardware-accelerated.
>
> For non-self-IPI case, software need to do APIC_IRR update and sending of
> wakeup-request/doorbell to the target vCPU.
Yeah, you need to rewrite it like the commit message above - it needs to say
that upon the MSR write, hw does this and that and therefore accelerates this
type of IPI.
Then it is clear what you mean by "acceleration."
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 07/18] x86/apic: Add support to send IPI for Secure AVIC
2025-08-22 17:14 ` Borislav Petkov
@ 2025-08-23 4:20 ` Upadhyay, Neeraj
0 siblings, 0 replies; 45+ messages in thread
From: Upadhyay, Neeraj @ 2025-08-23 4:20 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On 8/22/2025 10:44 PM, Borislav Petkov wrote:
> On Thu, Aug 21, 2025 at 10:57:24AM +0530, Upadhyay, Neeraj wrote:
>> Is below better?
>
> I was only reacting to that head-spinning, conglomerate of abbreviations "AVIC
> GHCB APIC MSR".
>
Ah ok. I thought you were not happy with the commit message
wording/structure.
>> x86/apic: Add support to send IPI for Secure AVIC
>>
>> Secure AVIC hardware only accelerates Self-IPI, i.e. on WRMSR to
>> APIC_SELF_IPI and APIC_ICR (with destination shorthand equal to Self)
>> registers, hardware takes care of updating the APIC_IRR in the APIC
>> backing page of the vCPU. For other IPI types (cross-vCPU, broadcast IPIs),
>> software needs to take care of updating the APIC_IRR state of the target
>> CPUs and to ensure that the target vCPUs notice the new pending interrupt.
>>
>> Add new callbacks in the Secure AVIC driver for sending IPI requests. These
>> callbacks update the IRR in the target guest vCPU's APIC backing page. To
>> ensure that the remote vCPU notices the new pending interrupt, reuse the
>> GHCB MSR handling code in vc_handle_msr() to issue APIC_ICR MSR-write GHCB
>> protocol event to the hypervisor. For Secure AVIC guests, on APIC_ICR write
>> MSR exits, the hypervisor notifies the target vCPU by either sending an AVIC
>> doorbell (if target vCPU is running) or by waking up the non-running target
>> vCPU.
>
> But I'll take a definitely better commit message too! :-)
>
Cool!
>> Ok moving it to x2apic_savic.c requires below 4 sev-internal declarations to
>> be moved to arch/x86/include/asm/sev.h
>>
>> struct ghcb_state;
>> struct ghcb *__sev_get_ghcb(struct ghcb_state *state);
>> void __sev_put_ghcb(struct ghcb_state *state);
>> enum es_result sev_es_ghcb_handle_msr(...);
>
> Well, do you anticipate needing any more sev* facilities for SAVIC?
>
At this point I do not anticipate adding new functions for new SAVIC
features.
> If so, you probably should carve them out into arch/x86/coco/sev/savic.c
>
> If only 4 functions, I guess they're probably still ok in .../sev/core.c
>
Ok. I will keep them in sev/core.c for now and move to sev/savic.c if
anything new comes up in future.
>> This comment explains why WRMSR is sufficient for sending SELF_IPI. On
>> WRMSR by vCPU, Secure AVIC hardware takes care of updating APIC_IRR in
>> backing page. Hardware also ensures that new APIC_IRR state is evaluated
>> for new pending interrupts. So, WRMSR is hardware-accelerated.
>>
>> For non-self-IPI case, software need to do APIC_IRR update and sending of
>> wakeup-request/doorbell to the target vCPU.
>
> Yeah, you need to rewrite it like the commit message above - it needs to say
> that upon the MSR write, hw does this and that and therefore accelerates this
> type of IPI.
>
> Then it is clear what you mean by "acceleration."
>
Got it. Will update. Thanks!
- Neeraj
> Thx.
>
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 08/18] x86/apic: Support LAPIC timer for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (6 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 07/18] x86/apic: Add support to send IPI " Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 09/18] x86/sev: Initialize VGIF for secondary VCPUs " Neeraj Upadhyay
` (10 subsequent siblings)
18 siblings, 0 replies; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Secure AVIC requires LAPIC timer to be emulated by the hypervisor.
KVM already supports emulating LAPIC timer using hrtimers. In order
to emulate LAPIC timer, APIC_LVTT, APIC_TMICT and APIC_TDCR register
values need to be propagated to the hypervisor for arming the timer.
APIC_TMCCT register value has to be read from the hypervisor, which
is required for calibrating the APIC timer. So, read/write all APIC
timer registers from/to the hypervisor.
Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
arch/x86/coco/sev/core.c | 26 ++++++++++++++++++++++++++
arch/x86/include/asm/sev.h | 2 ++
arch/x86/kernel/apic/apic.c | 2 ++
arch/x86/kernel/apic/x2apic_savic.c | 7 +++++--
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index 221a0fc0c387..3f64ed6bd1e6 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -1085,6 +1085,32 @@ int __init sev_es_efi_map_ghcbs_cas(pgd_t *pgd)
return 0;
}
+u64 savic_ghcb_msr_read(u32 reg)
+{
+ u64 msr = APIC_BASE_MSR + (reg >> 4);
+ struct pt_regs regs = { .cx = msr };
+ struct es_em_ctxt ctxt = { .regs = ®s };
+ struct ghcb_state state;
+ enum es_result res;
+ struct ghcb *ghcb;
+
+ guard(irqsave)();
+
+ ghcb = __sev_get_ghcb(&state);
+ vc_ghcb_invalidate(ghcb);
+
+ res = sev_es_ghcb_handle_msr(ghcb, &ctxt, false);
+ if (res != ES_OK) {
+ pr_err("Secure AVIC msr (0x%llx) read returned error (%d)\n", msr, res);
+ /* MSR read failures are treated as fatal errors */
+ snp_abort();
+ }
+
+ __sev_put_ghcb(&state);
+
+ return regs.ax | regs.dx << 32;
+}
+
void savic_ghcb_msr_write(u32 reg, u64 value)
{
u64 msr = APIC_BASE_MSR + (reg >> 4);
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index e849e616dd24..d10ca66aa684 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -534,6 +534,7 @@ int snp_svsm_vtpm_send_command(u8 *buffer);
void __init snp_secure_tsc_prepare(void);
void __init snp_secure_tsc_init(void);
enum es_result savic_register_gpa(u64 gpa);
+u64 savic_ghcb_msr_read(u32 reg);
void savic_ghcb_msr_write(u32 reg, u64 value);
static __always_inline void vc_ghcb_invalidate(struct ghcb *ghcb)
@@ -609,6 +610,7 @@ static inline void __init snp_secure_tsc_prepare(void) { }
static inline void __init snp_secure_tsc_init(void) { }
static inline enum es_result savic_register_gpa(u64 gpa) { return ES_UNSUPPORTED; }
static inline void savic_ghcb_msr_write(u32 reg, u64 value) { }
+static inline u64 savic_ghcb_msr_read(u32 reg) { return 0; }
#endif /* CONFIG_AMD_MEM_ENCRYPT */
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 36f1326fea2e..69b1084da8f4 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -592,6 +592,8 @@ static void setup_APIC_timer(void)
0xF, ~0UL);
} else
clockevents_register_device(levt);
+
+ apic_update_vector(smp_processor_id(), LOCAL_TIMER_VECTOR, true);
}
/*
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index dbd488191a16..668912945d3b 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -66,6 +66,7 @@ static u32 savic_read(u32 reg)
case APIC_TMICT:
case APIC_TMCCT:
case APIC_TDCR:
+ return savic_ghcb_msr_read(reg);
case APIC_ID:
case APIC_LVR:
case APIC_TASKPRI:
@@ -185,10 +186,12 @@ static void savic_write(u32 reg, u32 data)
switch (reg) {
case APIC_LVTT:
- case APIC_LVT0:
- case APIC_LVT1:
case APIC_TMICT:
case APIC_TDCR:
+ savic_ghcb_msr_write(reg, data);
+ break;
+ case APIC_LVT0:
+ case APIC_LVT1:
case APIC_TASKPRI:
case APIC_EOI:
case APIC_SPIV:
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v9 09/18] x86/sev: Initialize VGIF for secondary VCPUs for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (7 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 08/18] x86/apic: Support LAPIC timer " Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-22 17:28 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 10/18] x86/apic: Add support to send NMI IPI " Neeraj Upadhyay
` (9 subsequent siblings)
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
From: Kishon Vijay Abraham I <kvijayab@amd.com>
Secure AVIC requires VGIF to be configured in VMSA. Configure
for secondary CPUs (the configuration for boot CPU is done by
the hypervisor).
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
arch/x86/coco/sev/core.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index 3f64ed6bd1e6..e341d6239326 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -951,6 +951,9 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip, unsigned
vmsa->x87_ftw = AP_INIT_X87_FTW_DEFAULT;
vmsa->x87_fcw = AP_INIT_X87_FCW_DEFAULT;
+ if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
+ vmsa->vintr_ctrl |= V_GIF_MASK;
+
/* SVME must be set. */
vmsa->efer = EFER_SVME;
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 09/18] x86/sev: Initialize VGIF for secondary VCPUs for Secure AVIC
2025-08-11 9:44 ` [PATCH v9 09/18] x86/sev: Initialize VGIF for secondary VCPUs " Neeraj Upadhyay
@ 2025-08-22 17:28 ` Borislav Petkov
2025-08-25 6:25 ` Upadhyay, Neeraj
0 siblings, 1 reply; 45+ messages in thread
From: Borislav Petkov @ 2025-08-22 17:28 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:35PM +0530, Neeraj Upadhyay wrote:
> Subject: Re: [PATCH v9 09/18] x86/sev: Initialize VGIF for secondary VCPUs for Secure AVIC
"vCPU"
> From: Kishon Vijay Abraham I <kvijayab@amd.com>
>
> Secure AVIC requires VGIF to be configured in VMSA. Configure
Please explain in one sentence here for the unenlightened among us what VGIF
is.
Also, I can't find anyhwere in the APM the requirement that SAVIC requires
VGIF. Do we need to document it?
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 09/18] x86/sev: Initialize VGIF for secondary VCPUs for Secure AVIC
2025-08-22 17:28 ` Borislav Petkov
@ 2025-08-25 6:25 ` Upadhyay, Neeraj
2025-08-25 14:53 ` Borislav Petkov
0 siblings, 1 reply; 45+ messages in thread
From: Upadhyay, Neeraj @ 2025-08-25 6:25 UTC (permalink / raw)
To: Borislav Petkov
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On 8/22/2025 10:58 PM, Borislav Petkov wrote:
> On Mon, Aug 11, 2025 at 03:14:35PM +0530, Neeraj Upadhyay wrote:
>> Subject: Re: [PATCH v9 09/18] x86/sev: Initialize VGIF for secondary VCPUs for Secure AVIC
>
> "vCPU"
>
Ok
>> From: Kishon Vijay Abraham I <kvijayab@amd.com>
>>
>> Secure AVIC requires VGIF to be configured in VMSA. Configure
>
> Please explain in one sentence here for the unenlightened among us what VGIF
> is.
>
Ok. Below is the updated description:
Virtual GIF (VGIF) providing masking capability for when virtual
interrupts (virtual maskable interrupts, virtual NMIs) can be taken by
the guest vCPU. Secure AVIC hardware reads VGIF state from the vCPU's
VMSA. So, set VGIF for secondary CPUs (the configuration for boot CPU is
done by the hypervisor), to unmask delivery of virtual interrupts to
the vCPU.
> Also, I can't find anyhwere in the APM the requirement that SAVIC requires
> VGIF. Do we need to document it?
>
I also don't see an explicit mention. I will check on documenting it in
the APM. However, there are references to virtual interrupts (V_NMI,
V_INTR) (which requires VGIF support) and VGIF in terms of functional
usage in below sections of volume 2. In addition, as event injection is
not supported (EventInjCtlr field in the VMCB is ignored), virtual NMI
is required for NMI injection from host to guest.
"15.36.21.2 VMRUN and #VMEXIT
...
The interrupt control information loaded from the VMCB and VMSA for
Secure AVIC mode operation is the same as the information loaded in
Alternate Injection mode. "
Alternate injection section talks about the interrupt controls:
"15.36.16 Interrupt Injection Restrictions
When Alternate Injection is enabled, the EventInjCtlr field in the VMCB
(offset A8h) is ignored on VMRUN. The VIntrCtrl field in the VMCB
(offset 60h) is processed, but only the V_INTR_MASKING, Virtual GIF
Mode, and AVIC Enable bits are used.
...
The remaining fields of VIntrCtrl (V_TPR, V_IRQ, VGIF, V_INTR_PRIO,
V_IGN_TPR, V_INTR_VECTOR, V_NMI, V_NMI_MASK, V_NMI_EN) are read from the
VMSA."
- Neeraj
^ permalink raw reply [flat|nested] 45+ messages in thread
* Re: [PATCH v9 09/18] x86/sev: Initialize VGIF for secondary VCPUs for Secure AVIC
2025-08-25 6:25 ` Upadhyay, Neeraj
@ 2025-08-25 14:53 ` Borislav Petkov
0 siblings, 0 replies; 45+ messages in thread
From: Borislav Petkov @ 2025-08-25 14:53 UTC (permalink / raw)
To: Upadhyay, Neeraj
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Mon, Aug 25, 2025 at 11:55:44AM +0530, Upadhyay, Neeraj wrote:
> Ok. Below is the updated description:
>
> Virtual GIF (VGIF) providing masking capability for when virtual interrupts
> (virtual maskable interrupts, virtual NMIs) can be taken by the guest vCPU.
> Secure AVIC hardware reads VGIF state from the vCPU's VMSA. So, set VGIF for
> secondary CPUs (the configuration for boot CPU is done by the hypervisor),
> to unmask delivery of virtual interrupts to the vCPU.
Yap.
> I also don't see an explicit mention. I will check on documenting it in the
> APM. However, there are references to virtual interrupts (V_NMI, V_INTR)
> (which requires VGIF support)
Oh, I don't doubt that SAVIC requires VGIF - I just spotted a documentation
hole here so let's start the process of documenting this internally.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 10/18] x86/apic: Add support to send NMI IPI for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (8 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 09/18] x86/sev: Initialize VGIF for secondary VCPUs " Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-25 15:06 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 11/18] x86/apic: Allow NMI to be injected from hypervisor " Neeraj Upadhyay
` (8 subsequent siblings)
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Secure AVIC has introduced a new field in the APIC backing page
"NmiReq" that has to be set by the guest to request a NMI IPI
through APIC_ICR write.
Add support to set NmiReq appropriately to send NMI IPI.
Sending NMI IPI also requires Virtual NMI feature to be enabled
in VINTRL_CTRL field in the VMSA. However, this would be added by
a later commit after adding support for injecting NMI from the
hypervisor.
Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
arch/x86/kernel/apic/x2apic_savic.c | 26 +++++++++++++++++---------
1 file changed, 17 insertions(+), 9 deletions(-)
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index 668912945d3b..62681fa4f1a5 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -124,12 +124,15 @@ static inline void self_ipi_reg_write(unsigned int vector)
native_apic_msr_write(APIC_SELF_IPI, vector);
}
-static void send_ipi_dest(unsigned int cpu, unsigned int vector)
+static void send_ipi_dest(unsigned int cpu, unsigned int vector, bool nmi)
{
- update_vector(cpu, APIC_IRR, vector, true);
+ if (nmi)
+ apic_set_reg(per_cpu_ptr(secure_avic_page, cpu), SAVIC_NMI_REQ, 1);
+ else
+ update_vector(cpu, APIC_IRR, vector, true);
}
-static void send_ipi_allbut(unsigned int vector)
+static void send_ipi_allbut(unsigned int vector, bool nmi)
{
unsigned int cpu, src_cpu;
@@ -140,14 +143,17 @@ static void send_ipi_allbut(unsigned int vector)
for_each_cpu(cpu, cpu_online_mask) {
if (cpu == src_cpu)
continue;
- send_ipi_dest(cpu, vector);
+ send_ipi_dest(cpu, vector, nmi);
}
}
-static inline void self_ipi(unsigned int vector)
+static inline void self_ipi(unsigned int vector, bool nmi)
{
u32 icr_low = APIC_SELF_IPI | vector;
+ if (nmi)
+ icr_low |= APIC_DM_NMI;
+
native_x2apic_icr_write(icr_low, 0);
}
@@ -155,22 +161,24 @@ static void savic_icr_write(u32 icr_low, u32 icr_high)
{
unsigned int dsh, vector;
u64 icr_data;
+ bool nmi;
dsh = icr_low & APIC_DEST_ALLBUT;
vector = icr_low & APIC_VECTOR_MASK;
+ nmi = ((icr_low & APIC_DM_FIXED_MASK) == APIC_DM_NMI);
switch (dsh) {
case APIC_DEST_SELF:
- self_ipi(vector);
+ self_ipi(vector, nmi);
break;
case APIC_DEST_ALLINC:
- self_ipi(vector);
+ self_ipi(vector, nmi);
fallthrough;
case APIC_DEST_ALLBUT:
- send_ipi_allbut(vector);
+ send_ipi_allbut(vector, nmi);
break;
default:
- send_ipi_dest(icr_high, vector);
+ send_ipi_dest(icr_high, vector, nmi);
break;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 10/18] x86/apic: Add support to send NMI IPI for Secure AVIC
2025-08-11 9:44 ` [PATCH v9 10/18] x86/apic: Add support to send NMI IPI " Neeraj Upadhyay
@ 2025-08-25 15:06 ` Borislav Petkov
0 siblings, 0 replies; 45+ messages in thread
From: Borislav Petkov @ 2025-08-25 15:06 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:36PM +0530, Neeraj Upadhyay wrote:
> Secure AVIC has introduced a new field in the APIC backing page
> "NmiReq" that has to be set by the guest to request a NMI IPI
> through APIC_ICR write.
>
> Add support to set NmiReq appropriately to send NMI IPI.
>
> Sending NMI IPI also requires Virtual NMI feature to be enabled
> in VINTRL_CTRL field in the VMSA. However, this would be added by
> a later commit after adding support for injecting NMI from the
> hypervisor.
So drop this whole paragraph. No need to mention that here.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 11/18] x86/apic: Allow NMI to be injected from hypervisor for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (9 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 10/18] x86/apic: Add support to send NMI IPI " Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-25 15:20 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 12/18] x86/sev: Enable NMI support " Neeraj Upadhyay
` (7 subsequent siblings)
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Secure AVIC requires "AllowedNmi" bit in the Secure AVIC Control MSR
to be set for NMI to be injected from hypervisor. Set "AllowedNmi"
bit in Secure AVIC Control MSR to allow NMI interrupts to be injected
from hypervisor.
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
arch/x86/include/asm/msr-index.h | 3 +++
arch/x86/kernel/apic/x2apic_savic.c | 6 ++++++
2 files changed, 9 insertions(+)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 2a6d4fd8659a..2efc03d324c0 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -703,6 +703,9 @@
#define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)
#define MSR_AMD64_SNP_RESV_BIT 19
#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
+#define MSR_AMD64_SECURE_AVIC_CONTROL 0xc0010138
+#define MSR_AMD64_SECURE_AVIC_ALLOWEDNMI_BIT 1
+#define MSR_AMD64_SECURE_AVIC_ALLOWEDNMI BIT_ULL(MSR_AMD64_SECURE_AVIC_ALLOWEDNMI_BIT)
#define MSR_AMD64_RMP_BASE 0xc0010132
#define MSR_AMD64_RMP_END 0xc0010133
#define MSR_AMD64_RMP_CFG 0xc0010136
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index 62681fa4f1a5..2bae2f711959 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -23,6 +23,11 @@ struct secure_avic_page {
static struct secure_avic_page __percpu *secure_avic_page __ro_after_init;
+static inline void savic_wr_control_msr(u64 val)
+{
+ native_wrmsr(MSR_AMD64_SECURE_AVIC_CONTROL, lower_32_bits(val), upper_32_bits(val));
+}
+
static int savic_acpi_madt_oem_check(char *oem_id, char *oem_table_id)
{
return x2apic_enabled() && cc_platform_has(CC_ATTR_SNP_SECURE_AVIC);
@@ -319,6 +324,7 @@ static void savic_setup(void)
res = savic_register_gpa(gpa);
if (res != ES_OK)
snp_abort();
+ savic_wr_control_msr(gpa | MSR_AMD64_SECURE_AVIC_ALLOWEDNMI);
}
static int savic_probe(void)
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 11/18] x86/apic: Allow NMI to be injected from hypervisor for Secure AVIC
2025-08-11 9:44 ` [PATCH v9 11/18] x86/apic: Allow NMI to be injected from hypervisor " Neeraj Upadhyay
@ 2025-08-25 15:20 ` Borislav Petkov
0 siblings, 0 replies; 45+ messages in thread
From: Borislav Petkov @ 2025-08-25 15:20 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, huibo.wang, naveen.rao,
francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:37PM +0530, Neeraj Upadhyay wrote:
> Secure AVIC requires "AllowedNmi" bit in the Secure AVIC Control MSR
> to be set for NMI to be injected from hypervisor.
"So set it."
And drop that sentence repeating the whole thing again.
> Set "AllowedNmi"
> bit in Secure AVIC Control MSR to allow NMI interrupts to be injected
> from hypervisor.
> diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
> index 2a6d4fd8659a..2efc03d324c0 100644
> --- a/arch/x86/include/asm/msr-index.h
> +++ b/arch/x86/include/asm/msr-index.h
> @@ -703,6 +703,9 @@
> #define MSR_AMD64_SNP_SECURE_AVIC BIT_ULL(MSR_AMD64_SNP_SECURE_AVIC_BIT)
> #define MSR_AMD64_SNP_RESV_BIT 19
> #define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
> +#define MSR_AMD64_SECURE_AVIC_CONTROL 0xc0010138
> +#define MSR_AMD64_SECURE_AVIC_ALLOWEDNMI_BIT 1
> +#define MSR_AMD64_SECURE_AVIC_ALLOWEDNMI BIT_ULL(MSR_AMD64_SECURE_AVIC_ALLOWEDNMI_BIT)
> #define MSR_AMD64_RMP_BASE 0xc0010132
> #define MSR_AMD64_RMP_END 0xc0010133
> #define MSR_AMD64_RMP_CFG 0xc0010136
s/_SECURE_AVIC_/_SAVIC_/g
and you'll have room again.
> diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
> index 62681fa4f1a5..2bae2f711959 100644
> --- a/arch/x86/kernel/apic/x2apic_savic.c
> +++ b/arch/x86/kernel/apic/x2apic_savic.c
> @@ -23,6 +23,11 @@ struct secure_avic_page {
>
> static struct secure_avic_page __percpu *secure_avic_page __ro_after_init;
>
> +static inline void savic_wr_control_msr(u64 val)
> +{
> + native_wrmsr(MSR_AMD64_SECURE_AVIC_CONTROL, lower_32_bits(val), upper_32_bits(val));
> +}
Zap that silly wrapper.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 12/18] x86/sev: Enable NMI support for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (10 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 11/18] x86/apic: Allow NMI to be injected from hypervisor " Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 13/18] x86/apic: Read and write LVT* APIC registers from HV for SAVIC guests Neeraj Upadhyay
` (6 subsequent siblings)
18 siblings, 0 replies; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
From: Kishon Vijay Abraham I <kvijayab@amd.com>
Now that support to send NMI IPI and support to inject NMI from
the hypervisor has been added, set V_NMI_ENABLE in VINTR_CTRL
field of VMSA to enable NMI for Secure AVIC guests.
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
arch/x86/coco/sev/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index e341d6239326..d7c53b3eeaa9 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -952,7 +952,7 @@ static int wakeup_cpu_via_vmgexit(u32 apic_id, unsigned long start_ip, unsigned
vmsa->x87_fcw = AP_INIT_X87_FCW_DEFAULT;
if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
- vmsa->vintr_ctrl |= V_GIF_MASK;
+ vmsa->vintr_ctrl |= (V_GIF_MASK | V_NMI_ENABLE_MASK);
/* SVME must be set. */
vmsa->efer = EFER_SVME;
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v9 13/18] x86/apic: Read and write LVT* APIC registers from HV for SAVIC guests
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (11 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 12/18] x86/sev: Enable NMI support " Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 14/18] x86/apic: Handle EOI writes for Secure AVIC guests Neeraj Upadhyay
` (5 subsequent siblings)
18 siblings, 0 replies; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Hypervisor need information about the current state of LVT registers
for device emulation and NMI. So, forward reads and write of these
registers to the hypervisor for Secure AVIC enabled guests.
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
arch/x86/kernel/apic/x2apic_savic.c | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index 2bae2f711959..6012c83cbf09 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -71,6 +71,11 @@ static u32 savic_read(u32 reg)
case APIC_TMICT:
case APIC_TMCCT:
case APIC_TDCR:
+ case APIC_LVTTHMR:
+ case APIC_LVTPC:
+ case APIC_LVT0:
+ case APIC_LVT1:
+ case APIC_LVTERR:
return savic_ghcb_msr_read(reg);
case APIC_ID:
case APIC_LVR:
@@ -80,11 +85,6 @@ static u32 savic_read(u32 reg)
case APIC_LDR:
case APIC_SPIV:
case APIC_ESR:
- case APIC_LVTTHMR:
- case APIC_LVTPC:
- case APIC_LVT0:
- case APIC_LVT1:
- case APIC_LVTERR:
case APIC_EFEAT:
case APIC_ECTRL:
case APIC_SEOI:
@@ -201,18 +201,18 @@ static void savic_write(u32 reg, u32 data)
case APIC_LVTT:
case APIC_TMICT:
case APIC_TDCR:
- savic_ghcb_msr_write(reg, data);
- break;
case APIC_LVT0:
case APIC_LVT1:
+ case APIC_LVTTHMR:
+ case APIC_LVTPC:
+ case APIC_LVTERR:
+ savic_ghcb_msr_write(reg, data);
+ break;
case APIC_TASKPRI:
case APIC_EOI:
case APIC_SPIV:
case SAVIC_NMI_REQ:
case APIC_ESR:
- case APIC_LVTTHMR:
- case APIC_LVTPC:
- case APIC_LVTERR:
case APIC_ECTRL:
case APIC_SEOI:
case APIC_IER:
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v9 14/18] x86/apic: Handle EOI writes for Secure AVIC guests
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (12 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 13/18] x86/apic: Read and write LVT* APIC registers from HV for SAVIC guests Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 15/18] x86/apic: Add kexec support for Secure AVIC Neeraj Upadhyay
` (4 subsequent siblings)
18 siblings, 0 replies; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Secure AVIC accelerates guest's EOI msr writes for edge-triggered
interrupts.
For level-triggered interrupts, EOI msr writes trigger VC exception
with SVM_EXIT_AVIC_UNACCELERATED_ACCESS error code. To complete EOI
handling, the VC exception handler would need to trigger a GHCB protocol
MSR write event to notify the hypervisor about completion of the
level-triggered interrupt. Hypervisor notification is required for
cases like emulated IOAPIC, to complete and clear interrupt in the
IOAPIC's interrupt state.
However, VC exception handling adds extra performance overhead for
APIC register writes. In addition, for Secure AVIC, some unaccelerated
APIC register msr writes are trapped, whereas others are faulted. This
results in additional complexity in VC exception handling for unacclerated
APIC msr accesses. So, directly do a GHCB protocol based APIC EOI msr write
from apic->eoi() callback for level-triggered interrupts.
Use wrmsr for edge-triggered interrupts, so that hardware re-evaluates
any pending interrupt which can be delivered to guest vCPU. For level-
triggered interrupts, re-evaluation happens on return from VMGEXIT
corresponding to the GHCB event for APIC EOI msr write.
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
- Refactored savic_eoi based on Sean's feedback.
arch/x86/kernel/apic/x2apic_savic.c | 31 ++++++++++++++++++++++++++++-
1 file changed, 30 insertions(+), 1 deletion(-)
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index 6012c83cbf09..bef77283dd43 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -297,6 +297,35 @@ static void savic_update_vector(unsigned int cpu, unsigned int vector, bool set)
update_vector(cpu, SAVIC_ALLOWED_IRR, vector, set);
}
+static void savic_eoi(void)
+{
+ unsigned int cpu;
+ int vec;
+
+ cpu = raw_smp_processor_id();
+ vec = apic_find_highest_vector(get_reg_bitmap(cpu, APIC_ISR));
+ if (WARN_ONCE(vec == -1, "EOI write while no active interrupt in APIC_ISR"))
+ return;
+
+ /* Is level-triggered interrupt? */
+ if (apic_test_vector(vec, get_reg_bitmap(cpu, APIC_TMR))) {
+ update_vector(cpu, APIC_ISR, vec, false);
+ /*
+ * Propagate the EOI write to hv for level-triggered interrupts.
+ * Return to guest from GHCB protocol event takes care of
+ * re-evaluating interrupt state.
+ */
+ savic_ghcb_msr_write(APIC_EOI, 0);
+ } else {
+ /*
+ * Hardware clears APIC_ISR and re-evaluates the interrupt state
+ * to determine if there is any pending interrupt which can be
+ * delivered to CPU.
+ */
+ native_apic_msr_eoi();
+ }
+}
+
static void savic_setup(void)
{
void *ap = this_cpu_ptr(secure_avic_page);
@@ -375,7 +404,7 @@ static struct apic apic_x2apic_savic __ro_after_init = {
.read = savic_read,
.write = savic_write,
- .eoi = native_apic_msr_eoi,
+ .eoi = savic_eoi,
.icr_read = native_x2apic_icr_read,
.icr_write = savic_icr_write,
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v9 15/18] x86/apic: Add kexec support for Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (13 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 14/18] x86/apic: Handle EOI writes for Secure AVIC guests Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-11 9:44 ` [PATCH v9 16/18] x86/apic: Enable Secure AVIC in Control MSR Neeraj Upadhyay
` (3 subsequent siblings)
18 siblings, 0 replies; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Add a apic->teardown() callback to disable Secure AVIC before
rebooting into the new kernel. This ensures that the new
kernel does not access the old APIC backing page which was
allocated by the previous kernel. Such accesses can happen
if there are any APIC accesses done during guest boot before
Secure AVIC driver probe is done by the new kernel (as Secure
AVIC would have remained enabled in the Secure AVIC control
msr).
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- No change.
arch/x86/coco/sev/core.c | 23 +++++++++++++++++++++++
arch/x86/include/asm/apic.h | 1 +
arch/x86/include/asm/sev.h | 2 ++
arch/x86/kernel/apic/apic.c | 3 +++
arch/x86/kernel/apic/x2apic_savic.c | 8 ++++++++
5 files changed, 37 insertions(+)
diff --git a/arch/x86/coco/sev/core.c b/arch/x86/coco/sev/core.c
index d7c53b3eeaa9..da7fc7913a00 100644
--- a/arch/x86/coco/sev/core.c
+++ b/arch/x86/coco/sev/core.c
@@ -1164,6 +1164,29 @@ enum es_result savic_register_gpa(u64 gpa)
return res;
}
+enum es_result savic_unregister_gpa(u64 *gpa)
+{
+ struct ghcb_state state;
+ struct es_em_ctxt ctxt;
+ enum es_result res;
+ struct ghcb *ghcb;
+
+ guard(irqsave)();
+
+ ghcb = __sev_get_ghcb(&state);
+ vc_ghcb_invalidate(ghcb);
+
+ ghcb_set_rax(ghcb, SVM_VMGEXIT_SAVIC_SELF_GPA);
+ res = sev_es_ghcb_hv_call(ghcb, &ctxt, SVM_VMGEXIT_SAVIC,
+ SVM_VMGEXIT_SAVIC_UNREGISTER_GPA, 0);
+ if (gpa && res == ES_OK)
+ *gpa = ghcb->save.rbx;
+
+ __sev_put_ghcb(&state);
+
+ return res;
+}
+
static void snp_register_per_cpu_ghcb(void)
{
struct sev_es_runtime_data *data;
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 0683318470be..a26e66d66444 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -306,6 +306,7 @@ struct apic {
/* Probe, setup and smpboot functions */
int (*probe)(void);
void (*setup)(void);
+ void (*teardown)(void);
int (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
void (*init_apic_ldr)(void);
diff --git a/arch/x86/include/asm/sev.h b/arch/x86/include/asm/sev.h
index d10ca66aa684..35877c32b528 100644
--- a/arch/x86/include/asm/sev.h
+++ b/arch/x86/include/asm/sev.h
@@ -534,6 +534,7 @@ int snp_svsm_vtpm_send_command(u8 *buffer);
void __init snp_secure_tsc_prepare(void);
void __init snp_secure_tsc_init(void);
enum es_result savic_register_gpa(u64 gpa);
+enum es_result savic_unregister_gpa(u64 *gpa);
u64 savic_ghcb_msr_read(u32 reg);
void savic_ghcb_msr_write(u32 reg, u64 value);
@@ -609,6 +610,7 @@ static inline int snp_svsm_vtpm_send_command(u8 *buffer) { return -ENODEV; }
static inline void __init snp_secure_tsc_prepare(void) { }
static inline void __init snp_secure_tsc_init(void) { }
static inline enum es_result savic_register_gpa(u64 gpa) { return ES_UNSUPPORTED; }
+static inline enum es_result savic_unregister_gpa(u64 *gpa) { return ES_UNSUPPORTED; }
static inline void savic_ghcb_msr_write(u32 reg, u64 value) { }
static inline u64 savic_ghcb_msr_read(u32 reg) { return 0; }
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index 69b1084da8f4..badd6a42bced 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -1170,6 +1170,9 @@ void disable_local_APIC(void)
if (!apic_accessible())
return;
+ if (apic->teardown)
+ apic->teardown();
+
apic_soft_disable();
#ifdef CONFIG_X86_32
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index bef77283dd43..71775d6d8fbe 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -326,6 +326,13 @@ static void savic_eoi(void)
}
}
+static void savic_teardown(void)
+{
+ /* Disable Secure AVIC */
+ native_wrmsr(MSR_AMD64_SECURE_AVIC_CONTROL, 0, 0);
+ savic_unregister_gpa(NULL);
+}
+
static void savic_setup(void)
{
void *ap = this_cpu_ptr(secure_avic_page);
@@ -380,6 +387,7 @@ static struct apic apic_x2apic_savic __ro_after_init = {
.probe = savic_probe,
.acpi_madt_oem_check = savic_acpi_madt_oem_check,
.setup = savic_setup,
+ .teardown = savic_teardown,
.dest_mode_logical = false,
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* [PATCH v9 16/18] x86/apic: Enable Secure AVIC in Control MSR
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (14 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 15/18] x86/apic: Add kexec support for Secure AVIC Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-25 15:54 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 17/18] x86/sev: Prevent SECURE_AVIC_CONTROL MSR interception for Secure AVIC guests Neeraj Upadhyay
` (2 subsequent siblings)
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
With all the pieces in place now, enable Secure AVIC in Secure
AVIC Control MSR. Any access to x2APIC MSRs are emulated by
the hypervisor before Secure AVIC is enabled in the control MSR.
Post Secure AVIC enablement, all x2APIC MSR accesses (whether
accelerated by AVIC hardware or trapped as VC exception) operate
on vCPU's APIC backing page.
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- Added Tianyu's Reviewed-by.
arch/x86/include/asm/msr-index.h | 2 ++
arch/x86/kernel/apic/x2apic_savic.c | 2 +-
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/x86/include/asm/msr-index.h b/arch/x86/include/asm/msr-index.h
index 2efc03d324c0..3d0688af2009 100644
--- a/arch/x86/include/asm/msr-index.h
+++ b/arch/x86/include/asm/msr-index.h
@@ -704,6 +704,8 @@
#define MSR_AMD64_SNP_RESV_BIT 19
#define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
#define MSR_AMD64_SECURE_AVIC_CONTROL 0xc0010138
+#define MSR_AMD64_SECURE_AVIC_EN_BIT 0
+#define MSR_AMD64_SECURE_AVIC_EN BIT_ULL(MSR_AMD64_SECURE_AVIC_EN_BIT)
#define MSR_AMD64_SECURE_AVIC_ALLOWEDNMI_BIT 1
#define MSR_AMD64_SECURE_AVIC_ALLOWEDNMI BIT_ULL(MSR_AMD64_SECURE_AVIC_ALLOWEDNMI_BIT)
#define MSR_AMD64_RMP_BASE 0xc0010132
diff --git a/arch/x86/kernel/apic/x2apic_savic.c b/arch/x86/kernel/apic/x2apic_savic.c
index 71775d6d8fbe..e3d8a4302522 100644
--- a/arch/x86/kernel/apic/x2apic_savic.c
+++ b/arch/x86/kernel/apic/x2apic_savic.c
@@ -360,7 +360,7 @@ static void savic_setup(void)
res = savic_register_gpa(gpa);
if (res != ES_OK)
snp_abort();
- savic_wr_control_msr(gpa | MSR_AMD64_SECURE_AVIC_ALLOWEDNMI);
+ savic_wr_control_msr(gpa | MSR_AMD64_SECURE_AVIC_EN | MSR_AMD64_SECURE_AVIC_ALLOWEDNMI);
}
static int savic_probe(void)
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 16/18] x86/apic: Enable Secure AVIC in Control MSR
2025-08-11 9:44 ` [PATCH v9 16/18] x86/apic: Enable Secure AVIC in Control MSR Neeraj Upadhyay
@ 2025-08-25 15:54 ` Borislav Petkov
0 siblings, 0 replies; 45+ messages in thread
From: Borislav Petkov @ 2025-08-25 15:54 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, huibo.wang, naveen.rao,
francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:42PM +0530, Neeraj Upadhyay wrote:
> #define MSR_AMD64_SNP_RESV_BIT 19
> #define MSR_AMD64_SNP_RESERVED_MASK GENMASK_ULL(63, MSR_AMD64_SNP_RESV_BIT)
> #define MSR_AMD64_SECURE_AVIC_CONTROL 0xc0010138
> +#define MSR_AMD64_SECURE_AVIC_EN_BIT 0
> +#define MSR_AMD64_SECURE_AVIC_EN BIT_ULL(MSR_AMD64_SECURE_AVIC_EN_BIT)
..._SAVIC_...
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 17/18] x86/sev: Prevent SECURE_AVIC_CONTROL MSR interception for Secure AVIC guests
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (15 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 16/18] x86/apic: Enable Secure AVIC in Control MSR Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-25 16:28 ` Borislav Petkov
2025-08-11 9:44 ` [PATCH v9 18/18] x86/sev: Indicate SEV-SNP guest supports Secure AVIC Neeraj Upadhyay
2025-08-25 16:02 ` [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Borislav Petkov
18 siblings, 1 reply; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
The SECURE_AVIC_CONTROL MSR holds the GPA of the guest APIC backing
page and bitfields to control enablement of Secure AVIC and NMI by
guest vCPUs. This MSR is populated by the guest and the hypervisor
should not intercept it. A #VC exception will be generated otherwise.
If this occurs and Secure AVIC is enabled, terminate guest execution.
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
- No change.
arch/x86/coco/sev/vc-handle.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/x86/coco/sev/vc-handle.c b/arch/x86/coco/sev/vc-handle.c
index fc770cc9117d..e856a5e18670 100644
--- a/arch/x86/coco/sev/vc-handle.c
+++ b/arch/x86/coco/sev/vc-handle.c
@@ -414,6 +414,15 @@ enum es_result sev_es_ghcb_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt
if (sev_status & MSR_AMD64_SNP_SECURE_TSC)
return __vc_handle_secure_tsc_msrs(regs, write);
break;
+ case MSR_AMD64_SECURE_AVIC_CONTROL:
+ /*
+ * AMD64_SECURE_AVIC_CONTROL should not be intercepted when
+ * Secure AVIC is enabled. Terminate the Secure AVIC guest
+ * if the interception is enabled.
+ */
+ if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
+ return ES_VMM_ERROR;
+ break;
default:
break;
}
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 17/18] x86/sev: Prevent SECURE_AVIC_CONTROL MSR interception for Secure AVIC guests
2025-08-11 9:44 ` [PATCH v9 17/18] x86/sev: Prevent SECURE_AVIC_CONTROL MSR interception for Secure AVIC guests Neeraj Upadhyay
@ 2025-08-25 16:28 ` Borislav Petkov
0 siblings, 0 replies; 45+ messages in thread
From: Borislav Petkov @ 2025-08-25 16:28 UTC (permalink / raw)
To: Neeraj Upadhyay, seanjc
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, pbonzini, kvm, huibo.wang, naveen.rao,
francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:43PM +0530, Neeraj Upadhyay wrote:
> The SECURE_AVIC_CONTROL MSR holds the GPA of the guest APIC backing
> page and bitfields to control enablement of Secure AVIC and NMI by
> guest vCPUs. This MSR is populated by the guest and the hypervisor
> should not intercept it. A #VC exception will be generated otherwise.
> If this occurs and Secure AVIC is enabled, terminate guest execution.
>
> Reviewed-by: Tianyu Lan <tiala@microsoft.com>
> Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
> ---
> Changes since v8:
> - No change.
>
> arch/x86/coco/sev/vc-handle.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/arch/x86/coco/sev/vc-handle.c b/arch/x86/coco/sev/vc-handle.c
> index fc770cc9117d..e856a5e18670 100644
> --- a/arch/x86/coco/sev/vc-handle.c
> +++ b/arch/x86/coco/sev/vc-handle.c
> @@ -414,6 +414,15 @@ enum es_result sev_es_ghcb_handle_msr(struct ghcb *ghcb, struct es_em_ctxt *ctxt
> if (sev_status & MSR_AMD64_SNP_SECURE_TSC)
> return __vc_handle_secure_tsc_msrs(regs, write);
> break;
> + case MSR_AMD64_SECURE_AVIC_CONTROL:
> + /*
> + * AMD64_SECURE_AVIC_CONTROL should not be intercepted when
> + * Secure AVIC is enabled. Terminate the Secure AVIC guest
> + * if the interception is enabled.
> + */
> + if (cc_platform_has(CC_ATTR_SNP_SECURE_AVIC))
> + return ES_VMM_ERROR;
> + break;
In light of the recent secure TSC MSR discussions, let's see if Sean really
wants to do two different things for reads and writes here too...
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread
* [PATCH v9 18/18] x86/sev: Indicate SEV-SNP guest supports Secure AVIC
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (16 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 17/18] x86/sev: Prevent SECURE_AVIC_CONTROL MSR interception for Secure AVIC guests Neeraj Upadhyay
@ 2025-08-11 9:44 ` Neeraj Upadhyay
2025-08-25 16:02 ` [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Borislav Petkov
18 siblings, 0 replies; 45+ messages in thread
From: Neeraj Upadhyay @ 2025-08-11 9:44 UTC (permalink / raw)
To: linux-kernel
Cc: bp, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
Now that Secure AVIC support is added in the guest, indicate SEV-SNP
guest supports Secure AVIC feature if AMD_SECURE_AVIC config is
enabled.
Co-developed-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Signed-off-by: Kishon Vijay Abraham I <kvijayab@amd.com>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Signed-off-by: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
---
Changes since v8:
Add Tianyu's Reviewed-by.
arch/x86/boot/compressed/sev.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/x86/boot/compressed/sev.c b/arch/x86/boot/compressed/sev.c
index 74e083feb2d9..048d3e8839c3 100644
--- a/arch/x86/boot/compressed/sev.c
+++ b/arch/x86/boot/compressed/sev.c
@@ -238,13 +238,20 @@ bool sev_es_check_ghcb_fault(unsigned long address)
MSR_AMD64_SNP_SECURE_AVIC | \
MSR_AMD64_SNP_RESERVED_MASK)
+#ifdef CONFIG_AMD_SECURE_AVIC
+#define SNP_FEATURE_SECURE_AVIC MSR_AMD64_SNP_SECURE_AVIC
+#else
+#define SNP_FEATURE_SECURE_AVIC 0
+#endif
+
/*
* SNP_FEATURES_PRESENT is the mask of SNP features that are implemented
* by the guest kernel. As and when a new feature is implemented in the
* guest kernel, a corresponding bit should be added to the mask.
*/
#define SNP_FEATURES_PRESENT (MSR_AMD64_SNP_DEBUG_SWAP | \
- MSR_AMD64_SNP_SECURE_TSC)
+ MSR_AMD64_SNP_SECURE_TSC | \
+ SNP_FEATURE_SECURE_AVIC)
u64 snp_get_unsupported_features(u64 status)
{
--
2.34.1
^ permalink raw reply related [flat|nested] 45+ messages in thread
* Re: [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support
2025-08-11 9:44 [PATCH v9 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
` (17 preceding siblings ...)
2025-08-11 9:44 ` [PATCH v9 18/18] x86/sev: Indicate SEV-SNP guest supports Secure AVIC Neeraj Upadhyay
@ 2025-08-25 16:02 ` Borislav Petkov
18 siblings, 0 replies; 45+ messages in thread
From: Borislav Petkov @ 2025-08-25 16:02 UTC (permalink / raw)
To: Neeraj Upadhyay
Cc: linux-kernel, tglx, mingo, dave.hansen, Thomas.Lendacky, nikunj,
Santosh.Shukla, Vasant.Hegde, Suravee.Suthikulpanit, David.Kaplan,
x86, hpa, peterz, seanjc, pbonzini, kvm, kirill.shutemov,
huibo.wang, naveen.rao, francescolavra.fl, tiala
On Mon, Aug 11, 2025 at 03:14:26PM +0530, Neeraj Upadhyay wrote:
> Kishon Vijay Abraham I (2):
> x86/sev: Initialize VGIF for secondary VCPUs for Secure AVIC
> x86/sev: Enable NMI support for Secure AVIC
>
> Neeraj Upadhyay (16):
> x86/apic: Add new driver for Secure AVIC
> x86/apic: Initialize Secure AVIC APIC backing page
> x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver
> x86/apic: Initialize APIC ID for Secure AVIC
> x86/apic: Add update_vector() callback for apic drivers
> x86/apic: Add update_vector() callback for Secure AVIC
> x86/apic: Add support to send IPI for Secure AVIC
> x86/apic: Support LAPIC timer for Secure AVIC
> x86/apic: Add support to send NMI IPI for Secure AVIC
> x86/apic: Allow NMI to be injected from hypervisor for Secure AVIC
> x86/apic: Read and write LVT* APIC registers from HV for SAVIC guests
> x86/apic: Handle EOI writes for Secure AVIC guests
> x86/apic: Add kexec support for Secure AVIC
> x86/apic: Enable Secure AVIC in Control MSR
> x86/sev: Prevent SECURE_AVIC_CONTROL MSR interception for Secure AVIC
> guests
> x86/sev: Indicate SEV-SNP guest supports Secure AVIC
Ok, you're all reviewed.
I don't see any big issues with the set anymore except nitpicks I've replied
with to each patch separately. You can work in all review feedback and send
the next revision which I'll queue unless someone objects.
Thx.
--
Regards/Gruss,
Boris.
https://people.kernel.org/tglx/notes-about-netiquette
^ permalink raw reply [flat|nested] 45+ messages in thread