All of lore.kernel.org
 help / color / mirror / Atom feed
From: Manali Shukla <manali.shukla@amd.com>
To: <seanjc@google.com>, <pbonzini@redhat.com>
Cc: <mingo@redhat.com>, <bp@alien8.de>, <dave.hansen@linux.intel.com>,
	<kvm@vger.kernel.org>, <x86@kernel.org>, <santosh.shukla@amd.com>,
	<nikunj.dadhania@amd.com>, <Naveen.Rao@amd.com>,
	<dapeng1.mi@linux.intel.com>, <manali.shukla@amd.com>
Subject: [PATCH v1 4/9] KVM: x86: Introduce KVM_CAP_LAPIC2 for 4KB APIC register space support
Date: Wed, 4 Feb 2026 07:44:47 +0000	[thread overview]
Message-ID: <20260204074452.55453-5-manali.shukla@amd.com> (raw)
In-Reply-To: <20260204074452.55453-1-manali.shukla@amd.com>

Add KVM_CAP_LAPIC2 to allow userspace to opt into extended APIC register
space, i.e. to expose the full 4KB APIC page to the guest.  Extended LVT
registers are part of the 4KB APIC page and are AMD-specific. Extended
APIC registers provide additional interrupt vectors for hardware features
like Instruction Based Sampling (IBS).

Use a capability negotiation model to allow for future extensibility.
KVM_CHECK_EXTENSION returns a bitmask of supported capabilities, and
userspace enables the intersection of KVM and VMM support via
KVM_ENABLE_CAP.  This allows KVM and userspace to independently add
support for new APIC configurations without breaking compatibility.

Define two capability flags:
  - KVM_LAPIC2_DEFAULT: full 4KB APIC page support
  - KVM_LAPIC2_AMD_DEFAULT: extended LVT registers are supported

Require that the capability be enabled before vCPUs are created to avoid
the need to handle runtime changes to the APIC page size.

When KVM_LAPIC2_AMD_DEFAULT is enabled, set kvm->arch.nr_extlvt to
KVM_X86_NR_EXTLVT_DEFAULT (4) to track the number of extended LVT
registers available to the guest.  Future patches will use nr_extlvt to
emulate guest accesses to extended LVT registers at APIC offset 0x500.

Suggested-by: Naveen N Rao (AMD) <naveen@kernel.org>
Signed-off-by: Manali Shukla <manali.shukla@amd.com>
---
 Documentation/virt/kvm/api.rst  | 31 +++++++++++++++++++++++++++++++
 arch/x86/include/asm/kvm_host.h |  1 +
 arch/x86/kvm/x86.c              | 30 ++++++++++++++++++++++++++++++
 include/uapi/linux/kvm.h        |  5 +++++
 4 files changed, 67 insertions(+)

diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst
index 01a3abef8abb..71b4d24f009a 100644
--- a/Documentation/virt/kvm/api.rst
+++ b/Documentation/virt/kvm/api.rst
@@ -9291,6 +9291,37 @@ KVM exits with the register state of either the L1 or L2 guest
 depending on which executed at the time of an exit. Userspace must
 take care to differentiate between these cases.
 
+8.46 KVM_CAP_LAPIC2
+---------------------------
+
+:Architectures: x86
+:Target: VM
+:Parameters: args[0] is a bitmask of LAPIC2 capabilities
+:Returns: 0 on success, -EINVAL when arg[0] contains invalid bits
+
+This capability indicates that KVM supports extended APIC register space of the
+whole 4KB page.
+
+Calling KVM_CHECK_EXTENSION for this capability returns a bitmask of LAPIC2
+capabilities that can be enabled on a VM.
+
+The argument to KVM_ENABLE_CAP is also a bitmask that selects which LAPIC2
+capabilities to enable for the VM.  Userspace should enable the intersection
+of capabilities supported by KVM (from KVM_CHECK_EXTENSION) and capabilities
+supported by the VMM.  This must be called before creating any VCPUs.
+
+At this time, KVM_LAPIC2_DEFAULT and KVM_LAPIC2_AMD_DEFAULT are the supported
+capabilities:
+
+  - KVM_LAPIC2_DEFAULT: Full 4KB APIC page support
+  - KVM_LAPIC2_AMD_DEFAULT: Extended LVT registers are supported (they are part
+    of 4KB APIC page)
+
+KVM_LAPIC2_AMD_DEFAULT is available on AMD processors with ExtApicSpace feature
+(CPUID 8000_0001h.ECX[3]). Extended APIC registers start at APIC offset 400h.
+Currently 4 extended LVT registers are supported, used for features like
+Instruction Based Sampling (IBS), but future processors may support more.
+
 9. Known KVM API problems
 =========================
 
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h
index df642723cea6..5a659982aebd 100644
--- a/arch/x86/include/asm/kvm_host.h
+++ b/arch/x86/include/asm/kvm_host.h
@@ -1460,6 +1460,7 @@ struct kvm_arch {
 	u32 default_tsc_khz;
 	bool user_set_tsc;
 	u64 apic_bus_cycle_ns;
+	u8 nr_extlvt;
 
 	seqcount_raw_spinlock_t pvclock_sc;
 	bool use_master_clock;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 8acfdfc583a1..368ee9276366 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4990,6 +4990,18 @@ int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext)
 	case KVM_CAP_READONLY_MEM:
 		r = kvm ? kvm_arch_has_readonly_mem(kvm) : 1;
 		break;
+	case KVM_CAP_LAPIC2: {
+		u8 max_extlvt;
+
+		r = KVM_LAPIC2_DEFAULT;
+		if (!kvm_caps.has_extapic)
+			break;
+
+		max_extlvt = kvm_cpu_get_max_extlvt();
+		if (max_extlvt == KVM_X86_NR_EXTLVT_DEFAULT)
+			r |= KVM_LAPIC2_AMD_DEFAULT;
+		break;
+	}
 	default:
 		break;
 	}
@@ -6966,6 +6978,24 @@ int kvm_vm_ioctl_enable_cap(struct kvm *kvm,
 		mutex_unlock(&kvm->lock);
 		break;
 	}
+	case KVM_CAP_LAPIC2: {
+		r = -EINVAL;
+
+		mutex_lock(&kvm->lock);
+
+		kvm->arch.nr_extlvt = 0;
+
+		if (!kvm->created_vcpus) {
+			if (cap->args[0] & KVM_LAPIC2_DEFAULT) {
+				r = 0;
+				if (cap->args[0] & KVM_LAPIC2_AMD_DEFAULT)
+					kvm->arch.nr_extlvt = KVM_X86_NR_EXTLVT_DEFAULT;
+			}
+		}
+
+		mutex_unlock(&kvm->lock);
+		break;
+	}
 	default:
 		r = -EINVAL;
 		break;
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index 76bd54848b11..cb27eeb09bdb 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -659,6 +659,10 @@ struct kvm_ioeventfd {
 #define KVM_X86_DISABLE_EXITS_CSTATE         (1 << 3)
 #define KVM_X86_DISABLE_EXITS_APERFMPERF     (1 << 4)
 
+#define KVM_X86_NR_EXTLVT_DEFAULT		4
+#define KVM_LAPIC2_DEFAULT			(1 << 0)
+#define KVM_LAPIC2_AMD_DEFAULT			(1 << 1)
+
 /* for KVM_ENABLE_CAP */
 struct kvm_enable_cap {
 	/* in */
@@ -978,6 +982,7 @@ struct kvm_enable_cap {
 #define KVM_CAP_GUEST_MEMFD_FLAGS 244
 #define KVM_CAP_ARM_SEA_TO_USER 245
 #define KVM_CAP_S390_USER_OPEREXEC 246
+#define KVM_CAP_LAPIC2 247
 
 struct kvm_irq_routing_irqchip {
 	__u32 irqchip;
-- 
2.43.0


  parent reply	other threads:[~2026-02-04  7:45 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-02-04  7:44 [PATCH v1 0/9] KVM: x86: Add support for AMD Extended APIC registers Manali Shukla
2026-02-04  7:44 ` [PATCH v1 1/9] KVM: x86: Refactor APIC register mask handling to support extended " Manali Shukla
2026-05-14 12:48   ` Naveen N Rao
2026-02-04  7:44 ` [PATCH v1 2/9] x86/apic: Add helper to get maximum number of Extended LVT registers Manali Shukla
2026-05-06 11:22   ` Borislav Petkov
2026-05-14 12:50   ` Naveen N Rao
2026-02-04  7:44 ` [PATCH v1 3/9] KVM: SVM: Set kvm_caps.has_extapic when CPU supports Extended APIC Manali Shukla
2026-05-14 12:58   ` Naveen N Rao
2026-02-04  7:44 ` Manali Shukla [this message]
2026-05-14 13:08   ` [PATCH v1 4/9] KVM: x86: Introduce KVM_CAP_LAPIC2 for 4KB APIC register space support Naveen N Rao
2026-02-04  7:44 ` [PATCH v1 5/9] KVM: x86: Refactor APIC state get/set to accept variable-sized buffers Manali Shukla
2026-05-14 14:20   ` Naveen N Rao
2026-02-04  7:44 ` [PATCH v1 6/9] KVM: Add KVM_GET_LAPIC2 and KVM_SET_LAPIC2 for extended APIC Manali Shukla
2026-03-16 13:00   ` Nikunj A. Dadhania
2026-03-23 11:15     ` Manali Shukla
2026-05-14 14:36       ` Naveen N Rao
2026-05-14 14:41   ` Naveen N Rao
2026-02-04  7:44 ` [PATCH v1 7/9] KVM: x86: Emulate Extended LVT registers for AMD guests Manali Shukla
2026-05-14 14:48   ` Naveen N Rao
2026-02-04  7:44 ` [PATCH v1 8/9] x86/cpufeatures: Add CPUID feature bit for Extended LVT AVIC acceleration Manali Shukla
2026-02-04  7:44 ` [PATCH v1 9/9] KVM: SVM: Add AVIC support for extended LVT MSRs Manali Shukla
2026-05-14 15:10   ` Naveen N Rao
2026-03-10  6:17 ` [PATCH v1 0/9] KVM: x86: Add support for AMD Extended APIC registers Manali Shukla
2026-04-27  4:34   ` Shukla, Manali

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=20260204074452.55453-5-manali.shukla@amd.com \
    --to=manali.shukla@amd.com \
    --cc=Naveen.Rao@amd.com \
    --cc=bp@alien8.de \
    --cc=dapeng1.mi@linux.intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=nikunj.dadhania@amd.com \
    --cc=pbonzini@redhat.com \
    --cc=santosh.shukla@amd.com \
    --cc=seanjc@google.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.