Linux Documentation
 help / color / mirror / Atom feed
From: David Woodhouse <dwmw2@infradead.org>
To: "Xin Li (Intel)" <xin@zytor.com>,
	linux-kernel@vger.kernel.org,  kvm@vger.kernel.org,
	linux-doc@vger.kernel.org,
	Andrew Cooper <andrew.cooper3@citrix.com>,
	"Saenz Julienne, Nicolas" <nsaenz@amazon.es>
Cc: pbonzini@redhat.com, seanjc@google.com, corbet@lwn.net,
	tglx@linutronix.de,  mingo@redhat.com, bp@alien8.de,
	dave.hansen@linux.intel.com, x86@kernel.org,  hpa@zytor.com,
	luto@kernel.org, peterz@infradead.org, andrew.cooper3@citrix.com,
	 chao.gao@intel.com, hch@infradead.org, sohil.mehta@intel.com
Subject: Re: [PATCH v9 00/22] Enable FRED with KVM VMX
Date: Thu, 23 Apr 2026 15:35:38 +0100	[thread overview]
Message-ID: <7f93eb25874ddd13a1ad6e3c75785f11041c8b7f.camel@infradead.org> (raw)
In-Reply-To: <20251026201911.505204-1-xin@zytor.com>

[-- Attachment #1: Type: text/plain, Size: 9444 bytes --]

On Sun, 2025-10-26 at 13:18 -0700, Xin Li (Intel) wrote:
> This patch set enables the Intel flexible return and event delivery
> (FRED) architecture with KVM VMX to allow guests to utilize FRED.

This could do with having a *lot* of KVM selftests.

Here's one to get you started (untested as I haven't found suitable
hardware to test it on).

From bd465aabebcb124e09a26fe9f4c861354febabe4 Mon Sep 17 00:00:00 2001
From: David Woodhouse <dwmw@amazon.co.uk>
Date: Thu, 23 Apr 2026 15:20:11 +0100
Subject: [PATCH] KVM: selftests: Add FRED event type classification test

Test that software-generated events deliver the correct FRED event
type in the FRED stack frame.

In FRED mode, the CPU pushes event metadata including the event type
into the FRED stack frame. Different instruction types should produce
different event types:
  - ICEBP (INT1): EVENT_TYPE_PRIV_SWEVT (5)
  - INT3:         EVENT_TYPE_SWEXC (6)
  - INT n:        EVENT_TYPE_SWINT (4)

The test sets up a guest in FRED mode by enabling CR4.FRED and
configuring the FRED MSRs, with a hand-written FRED entry point that
extracts the event type from the FRED SS field. It exercises each
software event type and verifies the classification is correct.

Requires KVM guest FRED support (the FRED KVM VMX series) and
hardware FRED support. Skips if either is unavailable.

Signed-off-by: David Woodhouse <dwmw@amazon.co.uk>
---
 tools/testing/selftests/kvm/Makefile.kvm      |   1 +
 .../selftests/kvm/x86/int1_fred_test.c        | 225 ++++++++++++++++++
 2 files changed, 226 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/x86/int1_fred_test.c

diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm
index 148d427ff24b..62e76617f82f 100644
--- a/tools/testing/selftests/kvm/Makefile.kvm
+++ b/tools/testing/selftests/kvm/Makefile.kvm
@@ -74,6 +74,7 @@ TEST_GEN_PROGS_x86 += x86/feature_msrs_test
 TEST_GEN_PROGS_x86 += x86/exit_on_emulation_failure_test
 TEST_GEN_PROGS_x86 += x86/fastops_test
 TEST_GEN_PROGS_x86 += x86/fix_hypercall_test
+TEST_GEN_PROGS_x86 += x86/int1_fred_test
 TEST_GEN_PROGS_x86 += x86/hwcr_msr_test
 TEST_GEN_PROGS_x86 += x86/hyperv_clock
 TEST_GEN_PROGS_x86 += x86/hyperv_cpuid
diff --git a/tools/testing/selftests/kvm/x86/int1_fred_test.c b/tools/testing/selftests/kvm/x86/int1_fred_test.c
new file mode 100644
index 000000000000..7ffb54b56047
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86/int1_fred_test.c
@@ -0,0 +1,225 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Test FRED event type classification for software-generated events.
+ *
+ * In FRED mode, the CPU pushes event metadata including the event type
+ * into the FRED stack frame SS field. This test verifies the correct
+ * event type for:
+ *   - ICEBP (INT1, opcode 0xF1): EVENT_TYPE_PRIV_SWEXC (5)
+ *   - INT3 (opcode 0xCC):        EVENT_TYPE_SWEXC (6)
+ *   - INT n (opcode 0xCD nn):    EVENT_TYPE_SWINT (4)
+ *
+ * The FRED stack page is evicted via MADV_DONTNEED before each test
+ * to also exercise EPT/NPT fault handling during FRED frame push.
+ *
+ * This test requires KVM guest FRED support and hardware FRED support.
+ * It will skip if either is unavailable.
+ */
+#include <stdint.h>
+#include <string.h>
+#include <sys/mman.h>
+
+#include "test_util.h"
+#include "kvm_util.h"
+#include "processor.h"
+
+/* FRED: CPUID.(EAX=7,ECX=1):EAX bit 17 */
+#define X86_FEATURE_FRED	KVM_X86_CPU_FEATURE(7, 1, EAX, 17)
+
+/* FRED MSRs */
+#define MSR_IA32_FRED_RSP0	0x1cc
+#define MSR_IA32_FRED_STKLVLS	0x1d0
+#define MSR_IA32_FRED_CONFIG	0x1d4
+
+/* FRED event types (from arch/x86/include/asm/trapnr.h) */
+#define EVENT_TYPE_SWINT	4	/* INT n */
+#define EVENT_TYPE_PRIV_SWEXC	5	/* INT1 (ICEBP) */
+#define EVENT_TYPE_SWEXC	6	/* INTO, INT3 */
+
+/* FRED SS field layout */
+#define FRED_SS_TYPE_SHIFT	48
+#define FRED_SS_TYPE_MASK	(0xfULL << FRED_SS_TYPE_SHIFT)
+#define FRED_SS_VECTOR_SHIFT	32
+#define FRED_SS_VECTOR_MASK	(0xffULL << FRED_SS_VECTOR_SHIFT)
+
+/* CR4.FRED (bit 32) */
+#define X86_CR4_FRED		(1ULL << 32)
+
+/* Guest memory layout */
+#define FRED_STACK_GPA		0xc0000000ULL
+#define FRED_STACK_SIZE		PAGE_SIZE
+
+/*
+ * FRED stack frame as pushed by the CPU on event delivery.
+ * Layout from low address (RSP) to high address:
+ *
+ *   RSP+0x00: error code
+ *   RSP+0x08: RIP (return address)
+ *   RSP+0x10: CS (with auxiliary info in upper bits)
+ *   RSP+0x18: RFLAGS
+ *   RSP+0x20: RSP (original)
+ *   RSP+0x28: SS (with event type/vector in upper bits)
+ */
+struct fred_stack_frame {
+	uint64_t error_code;
+	uint64_t rip;
+	uint64_t cs;
+	uint64_t rflags;
+	uint64_t rsp;
+	uint64_t ss;
+};
+
+/* Shared result area */
+static volatile uint64_t fred_ss_value;
+static volatile uint64_t fred_saved_rip;
+static volatile bool fred_handler_called;
+
+static void __used fred_handler(struct fred_stack_frame *frame)
+{
+	fred_ss_value = frame->ss;
+	fred_saved_rip = frame->rip;
+	fred_handler_called = true;
+}
+
+/*
+ * FRED entry points. MSR_IA32_FRED_CONFIG points to the page-aligned
+ * base. Ring 3 events enter at base+0, ring 0 events at base+0x100.
+ * Since ICEBP executes in ring 0, the CPU enters at fred_entrypoint
+ * + 256 = fred_entrypoint_kernel.
+ */
+extern void fred_entrypoint(void);
+
+asm(
+	".pushsection .text\n"
+	".global fred_entrypoint\n"
+	".balign 4096\n"
+"fred_entrypoint:\n"
+	/* Ring 3 entry — unused, no userspace in this test */
+	"ud2\n"
+	/* Pad to +256 for ring 0 entry */
+	".org fred_entrypoint + 256, 0xcc\n"
+"fred_entrypoint_kernel:\n"
+	"movq %rsp, %rdi\n"
+	"call fred_handler\n"
+	".byte 0xf2, 0x0f, 0x01, 0xca\n"	/* ERETS */
+	".popsection\n"
+);
+
+static void check_fred_event(uint64_t expected_rip, uint8_t expected_vector,
+			     uint8_t expected_type, const char *name)
+{
+	uint64_t event_type, event_vector;
+
+	GUEST_ASSERT(fred_handler_called);
+	GUEST_ASSERT_EQ(fred_saved_rip, expected_rip);
+
+	event_type = (fred_ss_value & FRED_SS_TYPE_MASK) >> FRED_SS_TYPE_SHIFT;
+	event_vector = (fred_ss_value & FRED_SS_VECTOR_MASK) >> FRED_SS_VECTOR_SHIFT;
+
+	GUEST_ASSERT_EQ(event_vector, expected_vector);
+	GUEST_ASSERT_EQ(event_type, expected_type);
+}
+
+static void guest_code(void)
+{
+	uint64_t expected_rip;
+
+	/*
+	 * Enable FRED:
+	 *  1. Set MSR_IA32_FRED_CONFIG to our entry point
+	 *  2. Set MSR_IA32_FRED_RSP0 to our FRED stack
+	 *  3. Set MSR_IA32_FRED_STKLVLS (all events use stack level 0)
+	 *  4. Set CR4.FRED
+	 */
+	wrmsr(MSR_IA32_FRED_CONFIG, (uint64_t)fred_entrypoint);
+	wrmsr(MSR_IA32_FRED_RSP0, FRED_STACK_GPA + FRED_STACK_SIZE);
+	wrmsr(MSR_IA32_FRED_STKLVLS, 0);
+
+	{
+		uint64_t cr4;
+		asm volatile("mov %%cr4, %0" : "=r"(cr4));
+		cr4 |= X86_CR4_FRED;
+		asm volatile("mov %0, %%cr4" :: "r"(cr4));
+	}
+
+	/* Test 1: ICEBP (INT1) — should be EVENT_TYPE_PRIV_SWEXC (5) */
+	fred_handler_called = false;
+	asm volatile("lea 1f(%%rip), %0\n\t"
+		     ".byte 0xf1\n\t"
+		     "1:" : "=r"(expected_rip) :: "memory");
+	check_fred_event(expected_rip, DB_VECTOR, EVENT_TYPE_PRIV_SWEXC,
+			 "ICEBP");
+	GUEST_SYNC(0);
+
+	/* Test 2: INT3 — should be EVENT_TYPE_SWEXC (6) */
+	fred_handler_called = false;
+	asm volatile("lea 1f(%%rip), %0\n\t"
+		     "int3\n\t"
+		     "1:" : "=r"(expected_rip) :: "memory");
+	check_fred_event(expected_rip, BP_VECTOR, EVENT_TYPE_SWEXC, "INT3");
+	GUEST_SYNC(1);
+
+	/* Test 3: INT $0x20 — should be EVENT_TYPE_SWINT (4) */
+	fred_handler_called = false;
+	asm volatile("lea 1f(%%rip), %0\n\t"
+		     "int $0x20\n\t"
+		     "1:" : "=r"(expected_rip) :: "memory");
+	check_fred_event(expected_rip, 0x20, EVENT_TYPE_SWINT, "INT $0x20");
+	GUEST_SYNC(2);
+}
+
+static const char * const test_names[] = {
+	[0] = "ICEBP (EVENT_TYPE_PRIV_SWEXC)",
+	[1] = "INT3 (EVENT_TYPE_SWEXC)",
+	[2] = "INT $0x20 (EVENT_TYPE_SWINT)",
+};
+
+int main(int argc, char *argv[])
+{
+	struct kvm_vcpu *vcpu;
+	struct kvm_vm *vm;
+	struct ucall uc;
+	unsigned int nr_pages;
+	void *fred_stack_hva;
+	int test;
+
+	TEST_REQUIRE(kvm_cpu_has(X86_FEATURE_FRED));
+
+	pr_info("Testing FRED event types with EPT fault on stack\n");
+
+	vm = vm_create_with_one_vcpu(&vcpu, guest_code);
+
+	/* Map the FRED stack page */
+	nr_pages = vm_calc_num_guest_pages(VM_MODE_DEFAULT, FRED_STACK_SIZE);
+	vm_userspace_mem_region_add(vm, VM_MEM_SRC_ANONYMOUS,
+				    FRED_STACK_GPA, 1, nr_pages, 0);
+	virt_map(vm, FRED_STACK_GPA, FRED_STACK_GPA, nr_pages);
+	fred_stack_hva = addr_gpa2hva(vm, FRED_STACK_GPA);
+
+	for (test = 0; test < ARRAY_SIZE(test_names); test++) {
+		/*
+		 * Evict the FRED stack page so the CPU takes an EPT/NPT
+		 * violation when pushing the FRED frame. KVM must handle
+		 * the fault, map the page, and reinject the event.
+		 */
+		madvise(fred_stack_hva, FRED_STACK_SIZE, MADV_DONTNEED);
+
+		vcpu_run(vcpu);
+		TEST_ASSERT_KVM_EXIT_REASON(vcpu, KVM_EXIT_IO);
+
+		switch (get_ucall(vcpu, &uc)) {
+		case UCALL_ABORT:
+			REPORT_GUEST_ASSERT(uc);
+			break;
+		case UCALL_SYNC:
+			TEST_ASSERT_EQ(uc.args[1], test);
+			pr_info("  %s: PASSED\n", test_names[test]);
+			break;
+		default:
+			TEST_FAIL("Unexpected ucall");
+		}
+	}
+
+	kvm_vm_free(vm);
+	return 0;
+}
-- 
2.43.0





[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 5069 bytes --]

  parent reply	other threads:[~2026-04-23 14:35 UTC|newest]

Thread overview: 123+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-26 20:18 [PATCH v9 00/22] Enable FRED with KVM VMX Xin Li (Intel)
2025-10-26 20:18 ` [PATCH v9 01/22] KVM: VMX: Enable support for secondary VM exit controls Xin Li (Intel)
2025-10-26 20:18 ` [PATCH v9 02/22] KVM: VMX: Initialize VM entry/exit FRED controls in vmcs_config Xin Li (Intel)
2026-01-20  9:24   ` Binbin Wu
2026-01-22 17:57     ` Xin Li
2025-10-26 20:18 ` [PATCH v9 03/22] KVM: VMX: Disable FRED if FRED consistency checks fail Xin Li (Intel)
2026-03-05  0:25   ` Sean Christopherson
2025-10-26 20:18 ` [PATCH v9 04/22] x86/cea: Prefix event stack names with ESTACK_ Xin Li (Intel)
2025-10-26 20:18 ` [PATCH v9 05/22] x86/cea: Use array indexing to simplify exception stack access Xin Li (Intel)
2025-10-27 15:49   ` Dave Hansen
2025-10-28  2:31     ` Xin Li
2026-01-30 13:42   ` Borislav Petkov
2025-10-26 20:18 ` [PATCH v9 06/22] x86/cea: Export __this_cpu_ist_top_va() to KVM Xin Li (Intel)
2025-10-27 15:50   ` Dave Hansen
2026-01-30 13:46   ` Borislav Petkov
2026-01-30 16:35     ` Xin Li
2026-01-30 17:56       ` Borislav Petkov
2026-03-07  7:38     ` Xin Li
2026-03-09 15:24       ` Sean Christopherson
2026-03-09 22:57         ` Xin Li
2025-10-26 20:18 ` [PATCH v9 07/22] KVM: VMX: Initialize VMCS FRED fields Xin Li (Intel)
2025-11-19  2:44   ` Chao Gao
2026-01-21  6:44   ` Binbin Wu
2026-01-21 18:14     ` Xin Li
2026-01-22  0:45       ` Xin Li
2026-01-22  1:56         ` Binbin Wu
2026-01-22 17:22           ` Xin Li
2026-03-04 16:23     ` Sean Christopherson
2026-03-05  5:27       ` Xin Li
2026-03-05 15:21         ` Sean Christopherson
2026-03-05 17:25           ` Xin Li
2025-10-26 20:18 ` [PATCH v9 08/22] KVM: VMX: Set FRED MSR intercepts Xin Li (Intel)
2025-11-12  5:49   ` Chao Gao
2026-03-05  0:48     ` Sean Christopherson
2026-03-05  5:56       ` Xin Li
2026-03-06  2:30       ` Chao Gao
2026-03-06 15:54         ` Sean Christopherson
2026-01-16 19:49   ` Dave Hansen
2026-01-17  0:43     ` H. Peter Anvin
2025-10-26 20:18 ` [PATCH v9 09/22] KVM: VMX: Save/restore guest FRED RSP0 Xin Li (Intel)
2025-11-12  5:59   ` Chao Gao
2026-01-21  7:23   ` Binbin Wu
2025-10-26 20:18 ` [PATCH v9 10/22] KVM: VMX: Add support for saving and restoring FRED MSRs Xin Li (Intel)
2025-11-12  6:16   ` Chao Gao
2025-12-01  6:20     ` Xin Li
2025-10-26 20:18 ` [PATCH v9 11/22] KVM: x86: Add a helper to detect if FRED is enabled for a vCPU Xin Li (Intel)
2025-11-12  6:19   ` Chao Gao
2026-01-21  8:05   ` Binbin Wu
2026-01-21 16:46     ` Xin Li
2026-01-21 20:24       ` Sean Christopherson
2026-01-21 22:38         ` Xin Li
2025-10-26 20:19 ` [PATCH v9 12/22] KVM: VMX: Virtualize FRED event_data Xin Li (Intel)
2025-11-19  3:24   ` Chao Gao
2026-01-29 17:12     ` Xin Li
2026-01-29 17:21       ` H. Peter Anvin
2026-01-29 22:50         ` Xin Li
2026-03-04 16:42           ` Sean Christopherson
2025-10-26 20:19 ` [PATCH v9 13/22] KVM: VMX: Virtualize FRED nested exception tracking Xin Li (Intel)
2025-11-19  6:54   ` Chao Gao
2026-03-07  2:07   ` Sean Christopherson
2026-03-07  3:05     ` Xin Li
2025-10-26 20:19 ` [PATCH v9 14/22] KVM: x86: Save/restore the nested flag of an exception Xin Li (Intel)
2025-11-19  6:13   ` Chao Gao
2025-10-26 20:19 ` [PATCH v9 15/22] KVM: x86: Mark CR4.FRED as not reserved Xin Li (Intel)
2025-11-19  7:26   ` Chao Gao
2026-03-05  0:58     ` Sean Christopherson
2026-03-05  7:20       ` Xin Li
2026-03-05 15:35         ` Sean Christopherson
2026-03-05 17:09           ` Xin Li
2026-03-05 17:46             ` Xin Li
2026-03-06  5:33       ` Chao Gao
2025-10-26 20:19 ` [PATCH v9 16/22] KVM: VMX: Dump FRED context in dump_vmcs() Xin Li (Intel)
2025-11-19  7:40   ` Chao Gao
2025-11-30 18:42     ` Xin Li
2025-10-26 20:19 ` [PATCH v9 17/22] KVM: x86: Advertise support for FRED Xin Li (Intel)
2025-11-12  7:30   ` Chao Gao
2026-01-20  6:56     ` Xin Li
2026-01-20  8:07       ` Chao Gao
2026-01-20  9:09         ` Xin Li
2026-01-20  9:46           ` Binbin Wu
2026-01-20 15:25             ` Sean Christopherson
2026-01-20 18:04               ` Xin Li
2026-01-20 17:58             ` Xin Li
2025-10-26 20:19 ` [PATCH v9 18/22] KVM: nVMX: Enable support for secondary VM exit controls Xin Li (Intel)
2025-11-12 13:42   ` Chao Gao
2025-10-26 20:19 ` [PATCH v9 19/22] KVM: nVMX: Handle FRED VMCS fields in nested VMX context Xin Li (Intel)
2025-12-02  6:32   ` Chao Gao
2026-01-20  6:30     ` Xin Li
2026-01-20 16:07       ` Dave Hansen
2026-01-20 18:10         ` Xin Li
2026-01-21  0:44       ` Chao Gao
2026-01-22 16:52         ` Xin Li
2025-12-08 22:37   ` Sean Christopherson
2025-10-26 20:19 ` [PATCH v9 20/22] KVM: nVMX: Validate FRED-related VMCS fields Xin Li (Intel)
2025-11-13  3:00   ` Chao Gao
2026-01-20  9:19     ` Xin Li
2026-01-21  2:33       ` Chao Gao
2025-10-26 20:19 ` [PATCH v9 21/22] KVM: nVMX: Guard SHADOW_FIELD_R[OW] macros with VMX feature checks Xin Li (Intel)
2025-12-02  6:35   ` Chao Gao
2025-12-08 22:49   ` Sean Christopherson
2025-10-26 20:19 ` [PATCH v9 22/22] KVM: nVMX: Enable VMX FRED controls Xin Li (Intel)
2025-11-13  3:20   ` Chao Gao
2025-11-06 17:35 ` [PATCH v9 00/22] Enable FRED with KVM VMX Xin Li
2025-11-13 22:20   ` Sean Christopherson
2025-12-08 22:51 ` Sean Christopherson
2025-12-09 17:08   ` Xin Li
2026-04-23 14:35 ` David Woodhouse [this message]
2026-04-23 22:56   ` Xin Li
2026-05-05 18:04     ` Maciej Wieczor-Retman
2026-05-05 18:30       ` Andrew Cooper
2026-05-05 19:29         ` H. Peter Anvin
2026-05-05 20:20         ` Maciej Wieczor-Retman
2026-05-05 20:27           ` Andrew Cooper
2026-05-06 14:05             ` Maciej Wieczor-Retman
2026-05-07  7:49           ` David Woodhouse
2026-05-07 12:59             ` Maciej Wieczor-Retman
2026-05-07 13:35               ` David Woodhouse
2026-05-07 13:53                 ` Maciej Wieczor-Retman
2026-05-07 14:01                   ` David Woodhouse
2026-05-07 23:00                   ` David Woodhouse
2026-05-08 14:25                     ` Maciej Wieczor-Retman
2026-05-08 14:46                       ` David Woodhouse
2026-05-08 18:06                         ` Maciej Wieczor-Retman

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=7f93eb25874ddd13a1ad6e3c75785f11041c8b7f.camel@infradead.org \
    --to=dwmw2@infradead.org \
    --cc=andrew.cooper3@citrix.com \
    --cc=bp@alien8.de \
    --cc=chao.gao@intel.com \
    --cc=corbet@lwn.net \
    --cc=dave.hansen@linux.intel.com \
    --cc=hch@infradead.org \
    --cc=hpa@zytor.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-doc@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=luto@kernel.org \
    --cc=mingo@redhat.com \
    --cc=nsaenz@amazon.es \
    --cc=pbonzini@redhat.com \
    --cc=peterz@infradead.org \
    --cc=seanjc@google.com \
    --cc=sohil.mehta@intel.com \
    --cc=tglx@linutronix.de \
    --cc=x86@kernel.org \
    --cc=xin@zytor.com \
    /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