mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: "tip-bot2 for Neeraj Upadhyay" <tip-bot2@linutronix.de>
To: linux-tip-commits@vger.kernel.org
Cc: Kishon Vijay Abraham I <kvijayab@amd.com>,
	Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>,
	"Borislav Petkov (AMD)" <bp@alien8.de>,
	Tianyu Lan <tiala@microsoft.com>,
	x86@kernel.org, linux-kernel@vger.kernel.org
Subject: [tip: x86/apic] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver
Date: Tue, 02 Sep 2025 10:36:48 -0000	[thread overview]
Message-ID: <175680940884.1920.2159466177340458638.tip-bot2@tip-bot2> (raw)
In-Reply-To: <20250828110255.208779-1-Neeraj.Upadhyay@amd.com>

The following commit has been merged into the x86/apic branch of tip:

Commit-ID:     c822f58a4fab25944ba66768c1d6c563aa6ac077
Gitweb:        https://git.kernel.org/tip/c822f58a4fab25944ba66768c1d6c563aa6ac077
Author:        Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
AuthorDate:    Thu, 28 Aug 2025 16:32:40 +05:30
Committer:     Borislav Petkov (AMD) <bp@alien8.de>
CommitterDate: Sun, 31 Aug 2025 22:07:35 +02:00

x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver

Add read() and write() APIC callback functions to read and write the 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 the 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, accessing the guest's APIC registers through
RD/WRMSR results in a #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 the x2APIC registers, instead of doing RDMSR/WRMSR based
register accesses and handling reads/writes in the #VC exception, directly
read/write the APIC registers from/to the guest APIC backing page of the vCPU
in read() and write() callbacks of the Secure AVIC APIC driver.

  [ bp: Massage commit message. ]

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>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Tianyu Lan <tiala@microsoft.com>
Link: https://lore.kernel.org/20250828110255.208779-1-Neeraj.Upadhyay@amd.com
---
 arch/x86/include/asm/apicdef.h      |   2 +-
 arch/x86/kernel/apic/x2apic_savic.c | 122 ++++++++++++++++++++++++++-
 2 files changed, 122 insertions(+), 2 deletions(-)

diff --git a/arch/x86/include/asm/apicdef.h b/arch/x86/include/asm/apicdef.h
index 094106b..be39a54 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 948d894..5479605 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,123 @@ 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
+
+/*
+ * When Secure AVIC is enabled, RDMSR/WRMSR of the 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 the APIC register reads/writes in the #VC exception handler,
+ * the read() and write() callbacks directly read/write the APIC register
+ * from/to the vCPU's APIC backing page.
+ */
+static u32 savic_read(u32 reg)
+{
+	void *ap = this_cpu_ptr(savic_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 register 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:
+		/*
+		 * 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 range
+		 *
+		 * (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))
+			return 0;
+		return apic_get_reg(ap, reg);
+	default:
+		pr_err("Error reading unknown 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(savic_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 - 4, 16)) {
+			apic_set_reg(ap, reg, data);
+			break;
+		}
+		fallthrough;
+	default:
+		pr_err("Error writing unknown Secure AVIC reg offset 0x%x\n", reg);
+	}
+}
+
 static void savic_setup(void)
 {
 	void *ap = this_cpu_ptr(savic_page);
@@ -88,8 +206,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,

  parent reply	other threads:[~2025-09-02 10:36 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-28  7:03 [PATCH v10 00/18] AMD: Add Secure AVIC Guest Support Neeraj Upadhyay
2025-08-28  7:03 ` [PATCH v10 01/18] x86/apic: Add new driver for Secure AVIC Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28  7:03 ` [PATCH v10 02/18] x86/apic: Initialize Secure AVIC APIC backing page Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:02 ` [PATCH v10 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver Neeraj Upadhyay
2025-08-28 11:02   ` [PATCH v10 04/18] x86/apic: Initialize APIC ID for Secure AVIC Neeraj Upadhyay
2025-09-02 10:36     ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:02   ` [PATCH v10 05/18] x86/apic: Add update_vector() callback for APIC drivers Neeraj Upadhyay
2025-09-02 10:36     ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:02   ` [PATCH v10 06/18] x86/apic: Add update_vector() callback for Secure AVIC Neeraj Upadhyay
2025-09-02 10:36     ` [tip: x86/apic] x86/apic: Add an " tip-bot2 for Neeraj Upadhyay
2025-09-02 10:36   ` tip-bot2 for Neeraj Upadhyay [this message]
2025-08-28 11:08 ` [PATCH v10 07/18] x86/apic: Add support to send IPI " Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:09 ` [PATCH v10 08/18] x86/apic: Support LAPIC timer " Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:11 ` [PATCH v10 09/18] x86/sev: Initialize VGIF for secondary vCPUs " Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Kishon Vijay Abraham I
2025-08-28 11:12 ` [PATCH v10 10/18] x86/apic: Add support to send NMI IPI " Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:12 ` [PATCH v10 11/18] x86/apic: Allow NMI to be injected from hypervisor " Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:13 ` [PATCH v10 12/18] x86/sev: Enable NMI support " Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Kishon Vijay Abraham I
2025-08-28 11:13 ` [PATCH v10 13/18] x86/apic: Read and write LVT* APIC registers from HV for SAVIC guests Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:16 ` [PATCH v10 14/18] x86/apic: Handle EOI writes for Secure AVIC guests Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:20 ` [PATCH v10 15/18] x86/apic: Add kexec support for Secure AVIC Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:21 ` [PATCH v10 16/18] x86/apic: Enable Secure AVIC in Control MSR Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] x86/apic: Enable Secure AVIC in the control MSR tip-bot2 for Neeraj Upadhyay
2025-08-28 11:31 ` [PATCH v10 17/18] x86/sev: Prevent SECURE_AVIC_CONTROL MSR interception for Secure AVIC guests Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] " tip-bot2 for Neeraj Upadhyay
2025-08-28 11:32 ` [PATCH v10 18/18] x86/sev: Indicate SEV-SNP guest supports Secure AVIC Neeraj Upadhyay
2025-09-02 10:36   ` [tip: x86/apic] x86/sev: Indicate the " tip-bot2 for Neeraj Upadhyay

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=175680940884.1920.2159466177340458638.tip-bot2@tip-bot2 \
    --to=tip-bot2@linutronix.de \
    --cc=Neeraj.Upadhyay@amd.com \
    --cc=bp@alien8.de \
    --cc=kvijayab@amd.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-tip-commits@vger.kernel.org \
    --cc=tiala@microsoft.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

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

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

all inboxes | Powered by JetHome®