mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Neeraj Upadhyay <Neeraj.Upadhyay@amd.com>
To: <linux-kernel@vger.kernel.org>
Cc: <bp@alien8.de>, <tglx@linutronix.de>, <mingo@redhat.com>,
	<dave.hansen@linux.intel.com>, <Thomas.Lendacky@amd.com>,
	<nikunj@amd.com>, <Santosh.Shukla@amd.com>,
	<Vasant.Hegde@amd.com>, <Suravee.Suthikulpanit@amd.com>,
	<David.Kaplan@amd.com>, <x86@kernel.org>, <hpa@zytor.com>,
	<peterz@infradead.org>, <seanjc@google.com>,
	<pbonzini@redhat.com>, <kvm@vger.kernel.org>,
	<kirill.shutemov@linux.intel.com>, <huibo.wang@amd.com>,
	<naveen.rao@amd.com>, <francescolavra.fl@gmail.com>,
	<tiala@microsoft.com>
Subject: [PATCH v10 03/18] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver
Date: Thu, 28 Aug 2025 16:32:40 +0530	[thread overview]
Message-ID: <20250828110255.208779-1-Neeraj.Upadhyay@amd.com> (raw)
In-Reply-To: <20250828070334.208401-1-Neeraj.Upadhyay@amd.com>

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 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 the 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
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.

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 v9:
 - Clean up the ALLOWED_IRR alignment condition check.
 - Update comments describing the alignment of APIC_IRR and
   ALLOWED_IRR.
 - Commit log updates.

 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 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 948d89497baa..5479605429c1 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,
-- 
2.34.1


  parent reply	other threads:[~2025-08-28 11:03 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 ` Neeraj Upadhyay [this message]
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: x86/apic] x86/apic: Populate .read()/.write() callbacks of Secure AVIC driver tip-bot2 for Neeraj Upadhyay
2025-08-28 11:08 ` [PATCH v10 07/18] x86/apic: Add support to send IPI for Secure AVIC 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=20250828110255.208779-1-Neeraj.Upadhyay@amd.com \
    --to=neeraj.upadhyay@amd.com \
    --cc=David.Kaplan@amd.com \
    --cc=Santosh.Shukla@amd.com \
    --cc=Suravee.Suthikulpanit@amd.com \
    --cc=Thomas.Lendacky@amd.com \
    --cc=Vasant.Hegde@amd.com \
    --cc=bp@alien8.de \
    --cc=dave.hansen@linux.intel.com \
    --cc=francescolavra.fl@gmail.com \
    --cc=hpa@zytor.com \
    --cc=huibo.wang@amd.com \
    --cc=kirill.shutemov@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=naveen.rao@amd.com \
    --cc=nikunj@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=seanjc@google.com \
    --cc=tglx@linutronix.de \
    --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®