Linux Test Project
 help / color / mirror / Atom feed
* [LTP] [PATCH 0/5] KVM test for Intel VMX vAPIC
@ 2025-04-07 14:23 Martin Doucha
  2025-04-07 14:23 ` [LTP] [PATCH 1/5] kvm_vmx01: Fix 32bit compiler warnings Martin Doucha
                   ` (4 more replies)
  0 siblings, 5 replies; 12+ messages in thread
From: Martin Doucha @ 2025-04-07 14:23 UTC (permalink / raw)
  To: ltp

We already have a CVE test for AMD SVM which checks that access to virtual
APIC in nested VMs is correctly redirected to the backing page allocated
by the parent VM. Add a similar test for Intel VMX.

Martin Doucha (5):
  kvm_vmx01: Fix 32bit compiler warnings
  KVM: Add kvm_vmx01 to the runtest file
  KVM: Simplify reading VMX control field masks
  KVM: Add constants for Intel VMX vAPIC control
  Add test for Intel VMX virtualized APIC

 runtest/kvm                                |   2 +
 testcases/kernel/kvm/.gitignore            |   1 +
 testcases/kernel/kvm/include/kvm_x86_vmx.h |  22 ++-
 testcases/kernel/kvm/kvm_vmx01.c           |  15 +-
 testcases/kernel/kvm/kvm_vmx02.c           | 193 +++++++++++++++++++++
 testcases/kernel/kvm/lib_x86.c             |  48 +++--
 6 files changed, 260 insertions(+), 21 deletions(-)
 create mode 100644 testcases/kernel/kvm/kvm_vmx02.c

-- 
2.49.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 1/5] kvm_vmx01: Fix 32bit compiler warnings
  2025-04-07 14:23 [LTP] [PATCH 0/5] KVM test for Intel VMX vAPIC Martin Doucha
@ 2025-04-07 14:23 ` Martin Doucha
  2025-04-07 14:23 ` [LTP] [PATCH 2/5] KVM: Add kvm_vmx01 to the runtest file Martin Doucha
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 12+ messages in thread
From: Martin Doucha @ 2025-04-07 14:23 UTC (permalink / raw)
  To: ltp

Fix printf formatting warnings due to type mismatch during 32bit
compilation.

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
 testcases/kernel/kvm/kvm_vmx01.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/testcases/kernel/kvm/kvm_vmx01.c b/testcases/kernel/kvm/kvm_vmx01.c
index c413b4148..31ad75137 100644
--- a/testcases/kernel/kvm/kvm_vmx01.c
+++ b/testcases/kernel/kvm/kvm_vmx01.c
@@ -25,7 +25,7 @@
 struct vmcs_field_table {
 	unsigned long field_id;
 	const char *name;
-	uint64_t value;
+	unsigned long value;
 };
 
 /* Data written into shadow VMCS by the parent VM and read by the nested VM */
@@ -110,7 +110,7 @@ static struct vmcs_field_table guest_data[SHADOW_DATA_LENGTH] = {
 	{VMCS_FIELD(VMX_VMCS_GUEST_LDTR_BASE), 0xb1d72}
 };
 
-static uint64_t vmread_buffer[SHADOW_DATA_LENGTH];
+static unsigned long vmread_buffer[SHADOW_DATA_LENGTH];
 
 int guest_main(void)
 {
@@ -221,7 +221,7 @@ void main(void)
 			continue;
 
 		errors++;
-		tst_res(TFAIL, "Shadow %s guest mismatch: %llx != %llx",
+		tst_res(TFAIL, "Shadow %s guest mismatch: %lx != %lx",
 			host_data[i].name, vmread_buffer[i],
 			host_data[i].value);
 	}
@@ -239,7 +239,7 @@ void main(void)
 			continue;
 
 		errors++;
-		tst_res(TFAIL, "Shadow %s parent mismatch: %llx != %llx",
+		tst_res(TFAIL, "Shadow %s parent mismatch: %llx != %lx",
 			guest_data[i].name, val, guest_data[i].value);
 	}
 
-- 
2.49.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 2/5] KVM: Add kvm_vmx01 to the runtest file
  2025-04-07 14:23 [LTP] [PATCH 0/5] KVM test for Intel VMX vAPIC Martin Doucha
  2025-04-07 14:23 ` [LTP] [PATCH 1/5] kvm_vmx01: Fix 32bit compiler warnings Martin Doucha
@ 2025-04-07 14:23 ` Martin Doucha
  2025-04-16  6:19   ` Petr Vorel
  2025-04-07 14:23 ` [LTP] [PATCH 3/5] KVM: Simplify reading VMX control field masks Martin Doucha
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 12+ messages in thread
From: Martin Doucha @ 2025-04-07 14:23 UTC (permalink / raw)
  To: ltp

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
 runtest/kvm | 1 +
 1 file changed, 1 insertion(+)

diff --git a/runtest/kvm b/runtest/kvm
index 74a517add..091bcd43e 100644
--- a/runtest/kvm
+++ b/runtest/kvm
@@ -2,5 +2,6 @@ kvm_svm01 kvm_svm01
 kvm_svm02 kvm_svm02
 kvm_svm03 kvm_svm03
 kvm_svm04 kvm_svm04
+kvm_vmx01 kvm_vmx01
 # Tests below may interfere with bug reproducibility
 kvm_pagefault01 kvm_pagefault01
-- 
2.49.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 3/5] KVM: Simplify reading VMX control field masks
  2025-04-07 14:23 [LTP] [PATCH 0/5] KVM test for Intel VMX vAPIC Martin Doucha
  2025-04-07 14:23 ` [LTP] [PATCH 1/5] kvm_vmx01: Fix 32bit compiler warnings Martin Doucha
  2025-04-07 14:23 ` [LTP] [PATCH 2/5] KVM: Add kvm_vmx01 to the runtest file Martin Doucha
@ 2025-04-07 14:23 ` Martin Doucha
  2025-04-16  6:22   ` Petr Vorel
  2025-04-07 14:23 ` [LTP] [PATCH 4/5] KVM: Add constants for Intel VMX vAPIC control Martin Doucha
  2025-04-07 14:23 ` [LTP] [PATCH 5/5] Add test for Intel VMX virtualized APIC Martin Doucha
  4 siblings, 1 reply; 12+ messages in thread
From: Martin Doucha @ 2025-04-07 14:23 UTC (permalink / raw)
  To: ltp

Some VMX control fields have two different MSRs holding supported bit
masks. Add a helper function to read the correct MSR.

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
 testcases/kernel/kvm/include/kvm_x86_vmx.h | 10 +++++
 testcases/kernel/kvm/kvm_vmx01.c           |  7 +---
 testcases/kernel/kvm/lib_x86.c             | 48 +++++++++++++++++-----
 3 files changed, 49 insertions(+), 16 deletions(-)

diff --git a/testcases/kernel/kvm/include/kvm_x86_vmx.h b/testcases/kernel/kvm/include/kvm_x86_vmx.h
index 180a114e7..92e3c683e 100644
--- a/testcases/kernel/kvm/include/kvm_x86_vmx.h
+++ b/testcases/kernel/kvm/include/kvm_x86_vmx.h
@@ -28,6 +28,15 @@
 #define MSR_IA32_VMX_EXECCTL_MASK2 0x48e
 #define MSR_IA32_VMX_EXITCTL_MASK2 0x48f
 #define MSR_IA32_VMX_ENTRYCTL_MASK2 0x490
+#define MSR_IA32_VMX_EXECCTL3_MASK 0x492
+
+#define VMX_CTLMASK_PINX 0
+#define VMX_CTLMASK_EXECCTL 1
+#define VMX_CTLMASK_EXECCTL2 2
+#define VMX_CTLMASK_EXECCTL3 3
+#define VMX_CTLMASK_EXITCTL 4
+#define VMX_CTLMASK_ENTRYCTL 5
+#define VMX_CTLMASK_MAX 6
 
 #define IA32FC_LOCK (1 << 0)
 #define IA32FC_VMXON_SMX (1 << 1)
@@ -174,6 +183,7 @@ struct kvm_vmcs *kvm_alloc_vmcs(void);
 void kvm_vmcs_copy_gdt_descriptor(unsigned int gdt_id,
 	unsigned long vmcs_selector, unsigned long vmcs_flags,
 	unsigned long vmcs_limit, unsigned long vmcs_baseaddr);
+uint64_t kvm_vmx_read_vmctl_mask(unsigned int ctl_id);
 void kvm_init_vmx_vcpu(struct kvm_vmx_vcpu *cpu, uint16_t ss, void *rsp,
 	int (*guest_main)(void));
 struct kvm_vmx_vcpu *kvm_create_vmx_vcpu(int (*guest_main)(void),
diff --git a/testcases/kernel/kvm/kvm_vmx01.c b/testcases/kernel/kvm/kvm_vmx01.c
index 31ad75137..5bffbe946 100644
--- a/testcases/kernel/kvm/kvm_vmx01.c
+++ b/testcases/kernel/kvm/kvm_vmx01.c
@@ -152,10 +152,7 @@ void main(void)
 	kvm_set_vmx_state(1);
 
 	/* Check secondary VMCS execctl support */
-	if (kvm_rdmsr(MSR_IA32_VMX_BASIC) & IA32_VMXBASIC_USELESS_CTL_MASKS)
-		val = kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK2);
-	else
-		val = kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK);
+	val = kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXECCTL);
 
 	if (!((val >> 32) & VMX_EXECCTL_ENABLE_CTL2))
 		tst_brk(TCONF, "CPU does not support shadow VMCS");
@@ -169,7 +166,7 @@ void main(void)
 	val = kvm_vmx_vmread(VMX_VMCS_VMEXEC_CTL);
 	val |= VMX_EXECCTL_ENABLE_CTL2;
 	kvm_vmx_vmwrite(VMX_VMCS_VMEXEC_CTL, val);
-	val = kvm_rdmsr(MSR_IA32_VMX_EXECCTL2_MASK);
+	val = kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXECCTL2);
 
 	if (!((val >> 32) & VMX_EXECCTL2_SHADOW_VMCS))
 		tst_brk(TCONF, "CPU does not support shadow VMCS");
diff --git a/testcases/kernel/kvm/lib_x86.c b/testcases/kernel/kvm/lib_x86.c
index e6acc0797..c3363e033 100644
--- a/testcases/kernel/kvm/lib_x86.c
+++ b/testcases/kernel/kvm/lib_x86.c
@@ -119,6 +119,24 @@ static const char *vmx_error_description[VMX_VMINST_ERR_COUNT] = {
 	"Invalid operand to INVEPT/INVVPID"
 };
 
+static const unsigned int vmx_ctl_masks_old[VMX_CTLMASK_MAX] = {
+	MSR_IA32_VMX_PINX_MASK,
+	MSR_IA32_VMX_EXECCTL_MASK,
+	MSR_IA32_VMX_EXECCTL2_MASK,
+	MSR_IA32_VMX_EXECCTL3_MASK,
+	MSR_IA32_VMX_EXITCTL_MASK,
+	MSR_IA32_VMX_ENTRYCTL_MASK
+};
+
+static const unsigned int vmx_ctl_masks_new[VMX_CTLMASK_MAX] = {
+	MSR_IA32_VMX_PINX_MASK2,
+	MSR_IA32_VMX_EXECCTL_MASK2,
+	MSR_IA32_VMX_EXECCTL2_MASK,
+	MSR_IA32_VMX_EXECCTL3_MASK,
+	MSR_IA32_VMX_EXITCTL_MASK2,
+	MSR_IA32_VMX_ENTRYCTL_MASK2
+};
+
 static void kvm_set_intr_handler(unsigned int id, uintptr_t func)
 {
 	memset(kvm_idt + id, 0, sizeof(kvm_idt[0]));
@@ -711,6 +729,21 @@ void kvm_vmcs_copy_gdt_descriptor(unsigned int gdt_id,
 	kvm_vmx_vmwrite(vmcs_baseaddr, baseaddr);
 }
 
+uint64_t kvm_vmx_read_vmctl_mask(unsigned int ctl_id)
+{
+	unsigned int msr;
+
+	if (ctl_id >= VMX_CTLMASK_MAX)
+		tst_brk(TBROK, "Invalid VMX control ID %u", ctl_id);
+
+	if (kvm_rdmsr(MSR_IA32_VMX_BASIC) & IA32_VMXBASIC_USELESS_CTL_MASKS)
+		msr = vmx_ctl_masks_new[ctl_id];
+	else
+		msr = vmx_ctl_masks_old[ctl_id];
+
+	return kvm_rdmsr(msr);
+}
+
 void kvm_init_vmx_vcpu(struct kvm_vmx_vcpu *cpu, uint16_t ss, void *rsp,
 	int (*guest_main)(void))
 {
@@ -730,17 +763,10 @@ void kvm_init_vmx_vcpu(struct kvm_vmx_vcpu *cpu, uint16_t ss, void *rsp,
 	kvm_vmx_vmptrld(cpu->vmcs);
 
 	/* Configure VM execution control fields */
-	if (kvm_rdmsr(MSR_IA32_VMX_BASIC) & IA32_VMXBASIC_USELESS_CTL_MASKS) {
-		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK2);
-		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK2);
-		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK2);
-		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK2);
-	} else {
-		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK);
-		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK);
-		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK);
-		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK);
-	}
+	pinxctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_PINX);
+	execctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXECCTL);
+	exitctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXITCTL);
+	entryctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_ENTRYCTL);
 
 	execctl |= VMX_INTERCEPT_HLT;
 
-- 
2.49.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 4/5] KVM: Add constants for Intel VMX vAPIC control
  2025-04-07 14:23 [LTP] [PATCH 0/5] KVM test for Intel VMX vAPIC Martin Doucha
                   ` (2 preceding siblings ...)
  2025-04-07 14:23 ` [LTP] [PATCH 3/5] KVM: Simplify reading VMX control field masks Martin Doucha
@ 2025-04-07 14:23 ` Martin Doucha
  2025-04-16  6:24   ` Petr Vorel
  2025-04-07 14:23 ` [LTP] [PATCH 5/5] Add test for Intel VMX virtualized APIC Martin Doucha
  4 siblings, 1 reply; 12+ messages in thread
From: Martin Doucha @ 2025-04-07 14:23 UTC (permalink / raw)
  To: ltp

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
 testcases/kernel/kvm/include/kvm_x86_vmx.h | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/testcases/kernel/kvm/include/kvm_x86_vmx.h b/testcases/kernel/kvm/include/kvm_x86_vmx.h
index 92e3c683e..672c1b932 100644
--- a/testcases/kernel/kvm/include/kvm_x86_vmx.h
+++ b/testcases/kernel/kvm/include/kvm_x86_vmx.h
@@ -61,7 +61,10 @@
 #define VMX_VMCS_HOST_GS	0xc0a
 #define VMX_VMCS_HOST_TR	0xc0c
 
-#define VMX_VMCS_LINK_POINTER	0x2800
+#define VMX_VMCS_MSR_BITMAP_POINTER	0x2004
+#define VMX_VMCS_VIRT_APIC_POINTER	0x2012
+#define VMX_VMCS_VIRT_APIC_BASE		0x2014
+#define VMX_VMCS_LINK_POINTER		0x2800
 
 #define VMX_VMCS_GUEST_ES_LIMIT		0x4800
 #define VMX_VMCS_GUEST_CS_LIMIT		0x4802
@@ -143,8 +146,14 @@
 #define VMX_VMCS_EXIT_QUALIFICATION	0x6400
 
 #define VMX_INTERCEPT_HLT (1 << 7)
+#define VMX_EXECCTL_TPR_SHADOW (1 << 21)
+#define VMX_EXECCTL_MSR_BITMAP (1 << 28)
 #define VMX_EXECCTL_ENABLE_CTL2 (1 << 31)
 
+#define VMX_EXECCTL2_VIRT_APIC (1 << 0)
+#define VMX_EXECCTL2_VIRT_X2APIC (1 << 4)
+#define VMX_EXECCTL2_VIRT_APIC_REG (1 << 8)
+#define VMX_EXECCTL2_VIRT_INTR (1 << 9)
 #define VMX_EXECCTL2_SHADOW_VMCS (1 << 14)
 
 #define VMX_EXITCTL_SAVE_DR (1 << 2)
@@ -160,6 +169,7 @@
 #define VMX_INVALID_VMCS 0xffffffffffffffffULL
 
 #define VMX_EXIT_HLT 12
+#define VMX_EXIT_RDMSR 31
 #define VMX_EXIT_FAILED_ENTRY 0x80000000
 
 struct kvm_vmcs {
-- 
2.49.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [LTP] [PATCH 5/5] Add test for Intel VMX virtualized APIC
  2025-04-07 14:23 [LTP] [PATCH 0/5] KVM test for Intel VMX vAPIC Martin Doucha
                   ` (3 preceding siblings ...)
  2025-04-07 14:23 ` [LTP] [PATCH 4/5] KVM: Add constants for Intel VMX vAPIC control Martin Doucha
@ 2025-04-07 14:23 ` Martin Doucha
  4 siblings, 0 replies; 12+ messages in thread
From: Martin Doucha @ 2025-04-07 14:23 UTC (permalink / raw)
  To: ltp

Signed-off-by: Martin Doucha <mdoucha@suse.cz>
---
 runtest/kvm                      |   1 +
 testcases/kernel/kvm/.gitignore  |   1 +
 testcases/kernel/kvm/kvm_vmx02.c | 193 +++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+)
 create mode 100644 testcases/kernel/kvm/kvm_vmx02.c

diff --git a/runtest/kvm b/runtest/kvm
index 091bcd43e..5c285e656 100644
--- a/runtest/kvm
+++ b/runtest/kvm
@@ -3,5 +3,6 @@ kvm_svm02 kvm_svm02
 kvm_svm03 kvm_svm03
 kvm_svm04 kvm_svm04
 kvm_vmx01 kvm_vmx01
+kvm_vmx02 kvm_vmx02
 # Tests below may interfere with bug reproducibility
 kvm_pagefault01 kvm_pagefault01
diff --git a/testcases/kernel/kvm/.gitignore b/testcases/kernel/kvm/.gitignore
index c18a31792..f6935c17a 100644
--- a/testcases/kernel/kvm/.gitignore
+++ b/testcases/kernel/kvm/.gitignore
@@ -4,3 +4,4 @@
 /kvm_svm03
 /kvm_svm04
 /kvm_vmx01
+/kvm_vmx02
diff --git a/testcases/kernel/kvm/kvm_vmx02.c b/testcases/kernel/kvm/kvm_vmx02.c
new file mode 100644
index 000000000..3fcfebb3b
--- /dev/null
+++ b/testcases/kernel/kvm/kvm_vmx02.c
@@ -0,0 +1,193 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2024 SUSE LLC <mdoucha@suse.cz>
+ */
+
+/*\
+ * Verify that reads and writes to virtualized APIC in nested VM get
+ * redirected to the memory page selected by parent VM.
+ */
+
+#include "kvm_test.h"
+
+#ifdef COMPILE_PAYLOAD
+#if defined(__i386__) || defined(__x86_64__)
+
+#include "kvm_x86_vmx.h"
+
+#define TPR_OFFSET 0x80
+#define TPR_VALUE 0x7
+#define TPR_OLD_VALUE 0x9
+#define MSR_TPR 0x808
+
+static void *apic_base;
+
+int memapic_guest_main(void)
+{
+	int ret;
+	uint32_t *ptr;
+
+	ptr = apic_base + TPR_OFFSET;
+	ret = *ptr;
+	*ptr = TPR_VALUE;
+	return ret;
+}
+
+int msrapic_guest_main(void)
+{
+	int ret;
+
+	ret = kvm_rdmsr(MSR_TPR);
+	kvm_wrmsr(MSR_TPR, TPR_VALUE);
+	return ret;
+}
+
+int setup_vmcs(void *apic_ptr, void *msr_mask, uint64_t ec2_flags)
+{
+	uint32_t *tpr;
+	uint64_t val, mask, flags;
+
+	/* Check secondary VMCS execctl support */
+	mask = kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXECCTL);
+
+	if (!((mask >> 32) & VMX_EXECCTL_ENABLE_CTL2))
+		return 0;
+
+	/* Create and configure guest VMCS */
+	tpr = apic_ptr + TPR_OFFSET;
+	memset(apic_ptr, 0xa9, PAGESIZE);
+	memset(apic_base, 0xab, PAGESIZE);
+	*tpr = TPR_OLD_VALUE;
+	val = kvm_vmx_vmread(VMX_VMCS_VMEXEC_CTL);
+	flags = VMX_EXECCTL_TPR_SHADOW | VMX_EXECCTL_ENABLE_CTL2;
+	flags |= VMX_EXECCTL_MSR_BITMAP;
+	flags &= mask >> 32;
+	kvm_vmx_vmwrite(VMX_VMCS_VMEXEC_CTL, val | flags);
+
+	if (flags & VMX_EXECCTL_MSR_BITMAP) {
+		kvm_vmx_vmwrite(VMX_VMCS_MSR_BITMAP_POINTER,
+			(uintptr_t)msr_mask);
+	}
+
+	mask = kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXECCTL2);
+	ec2_flags &= mask >> 32;
+
+	if (!ec2_flags)
+		return 0;
+
+	val = ec2_flags | (uint32_t)mask;
+	kvm_vmx_vmwrite(VMX_VMCS_VMEXEC_CTL2, val);
+	kvm_vmx_vmwrite(VMX_VMCS_VIRT_APIC_POINTER, (uintptr_t)apic_ptr);
+	kvm_vmx_vmwrite(VMX_VMCS_VIRT_APIC_BASE, (uintptr_t)apic_base);
+	return 1;
+}
+
+void check_result(struct kvm_vmx_vcpu *vcpu, unsigned int tpr,
+	unsigned int tpr_b)
+{
+	/* Cast RAX value to int. The upper 32 bits may contain garbage. */
+	int tpr_orig = vcpu->regs.rax;
+
+	if (tpr_orig == TPR_OLD_VALUE)
+		tst_res(TPASS, "vTPR has correct value");
+	else
+		tst_res(TFAIL, "Unexpected vTPR value: %x", tpr_orig);
+
+	if (tpr == TPR_VALUE)
+		tst_res(TPASS, "vAPIC write was handled correctly");
+	else if (tpr_b == TPR_VALUE)
+		tst_res(TFAIL, "vAPIC write was stored to literal address");
+	else
+		tst_res(TFAIL, "vAPIC write may have overwritten host memory!");
+}
+
+void main(void)
+{
+	void *apic_ptr, *msr_mask;
+	struct kvm_vmx_vcpu *vcpu;
+	uintptr_t rsp;
+	uint32_t *tpr, *tpr_b;
+	uint64_t reason;
+	uint16_t ss;
+
+	kvm_set_vmx_state(1);
+
+	apic_ptr = tst_heap_alloc_aligned(2 * PAGESIZE, PAGESIZE);
+	apic_base = apic_ptr + PAGESIZE;
+	tpr = apic_ptr + TPR_OFFSET;
+	tpr_b = apic_base + TPR_OFFSET;
+	msr_mask = tst_heap_alloc_aligned(PAGESIZE, PAGESIZE);
+	memset(msr_mask, 0, PAGESIZE);
+	vcpu = kvm_create_vmx_vcpu(memapic_guest_main, 1);
+	kvm_vmx_vmptrld(vcpu->vmcs);
+	ss = kvm_vmx_vmread(VMX_VMCS_GUEST_SS) >> 3;
+	rsp = kvm_vmx_vmread(VMX_VMCS_GUEST_RSP);
+	tst_res(TINFO, "Testing memory-mapped APIC");
+
+	if (setup_vmcs(apic_ptr, msr_mask, VMX_EXECCTL2_VIRT_APIC)) {
+		kvm_vmx_vmrun(vcpu);
+		reason = kvm_vmx_vmread(VMX_VMCS_EXIT_REASON);
+
+		if (reason != VMX_EXIT_HLT) {
+			tst_res(TFAIL, "Unexpected guest exit reason %llx",
+				reason);
+		} else {
+			check_result(vcpu, *tpr, *tpr_b);
+		}
+	} else {
+		tst_res(TCONF, "CPU does not support memory mapped vAPIC");
+	}
+
+	tst_res(TINFO, "Testing MSR-based APIC");
+	kvm_init_vmx_vcpu(vcpu, ss, (void *)rsp, msrapic_guest_main);
+
+	if (setup_vmcs(apic_ptr, msr_mask, VMX_EXECCTL2_VIRT_X2APIC)) {
+		kvm_vmx_vmrun(vcpu);
+		reason = kvm_vmx_vmread(VMX_VMCS_EXIT_REASON);
+
+		if (reason == VMX_EXIT_RDMSR) {
+			tst_res(TCONF, "CPU does not support MSR bitmaps");
+		} else if (reason != VMX_EXIT_HLT) {
+			tst_res(TFAIL, "Unexpected guest exit reason %llx",
+				reason);
+		} else {
+			check_result(vcpu, *tpr, *tpr_b);
+		}
+	} else {
+		tst_res(TCONF, "CPU does not support MSR-based vAPIC");
+	}
+}
+
+#else /* defined(__i386__) || defined(__x86_64__) */
+TST_TEST_TCONF("Test supported only on x86");
+#endif /* defined(__i386__) || defined(__x86_64__) */
+
+#else /* COMPILE_PAYLOAD */
+
+#include "tst_module.h"
+
+#define NESTED_INTEL_SYSFILE "/sys/module/kvm_intel/parameters/nested"
+
+static void setup(void)
+{
+	if (!tst_read_bool_sys_param(NESTED_INTEL_SYSFILE)) {
+		tst_module_reload("kvm_intel",
+			(char *const[]){"nested=1", NULL});
+	}
+
+	tst_kvm_setup();
+}
+
+static struct tst_test test = {
+	.test_all = tst_kvm_run,
+	.setup = setup,
+	.cleanup = tst_kvm_cleanup,
+	.needs_root = 1,
+	.supported_archs = (const char *const []) {
+		"x86_64",
+		"x86",
+		NULL
+	},
+};
+
+#endif /* COMPILE_PAYLOAD */
-- 
2.49.0


-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [LTP] [PATCH 2/5] KVM: Add kvm_vmx01 to the runtest file
  2025-04-07 14:23 ` [LTP] [PATCH 2/5] KVM: Add kvm_vmx01 to the runtest file Martin Doucha
@ 2025-04-16  6:19   ` Petr Vorel
  0 siblings, 0 replies; 12+ messages in thread
From: Petr Vorel @ 2025-04-16  6:19 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp

Hi Martin,

This and previous patch as obvious fixes merged.
Thanks!

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [LTP] [PATCH 3/5] KVM: Simplify reading VMX control field masks
  2025-04-07 14:23 ` [LTP] [PATCH 3/5] KVM: Simplify reading VMX control field masks Martin Doucha
@ 2025-04-16  6:22   ` Petr Vorel
  2025-04-16  7:16     ` Petr Vorel
  0 siblings, 1 reply; 12+ messages in thread
From: Petr Vorel @ 2025-04-16  6:22 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp

Hi Martin,

...
>  	/* Configure VM execution control fields */
> -	if (kvm_rdmsr(MSR_IA32_VMX_BASIC) & IA32_VMXBASIC_USELESS_CTL_MASKS) {
> -		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK2);
> -		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK2);
> -		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK2);
> -		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK2);
> -	} else {
> -		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK);
> -		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK);
> -		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK);
> -		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK);

I guess you're going to use in the future MSR_IA32_VMX_PINX_MASK2 and other
deleted masks (because now they are IMHO only in the structs).

Acked-by: Petr Vorel <pvorel@suse.cz>

Kind regards,
Petr

> -	}
> +	pinxctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_PINX);
> +	execctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXECCTL);
> +	exitctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXITCTL);
> +	entryctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_ENTRYCTL);

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [LTP] [PATCH 4/5] KVM: Add constants for Intel VMX vAPIC control
  2025-04-07 14:23 ` [LTP] [PATCH 4/5] KVM: Add constants for Intel VMX vAPIC control Martin Doucha
@ 2025-04-16  6:24   ` Petr Vorel
  0 siblings, 0 replies; 12+ messages in thread
From: Petr Vorel @ 2025-04-16  6:24 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp

Hi Martin,

Acked-by: Petr Vorel <pvorel@suse.cz>

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [LTP] [PATCH 3/5] KVM: Simplify reading VMX control field masks
  2025-04-16  6:22   ` Petr Vorel
@ 2025-04-16  7:16     ` Petr Vorel
  2025-04-28 10:38       ` Martin Doucha
  0 siblings, 1 reply; 12+ messages in thread
From: Petr Vorel @ 2025-04-16  7:16 UTC (permalink / raw)
  To: Martin Doucha, ltp

Hi Martin,

> Hi Martin,

> ...
> >  	/* Configure VM execution control fields */
> > -	if (kvm_rdmsr(MSR_IA32_VMX_BASIC) & IA32_VMXBASIC_USELESS_CTL_MASKS) {
> > -		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK2);
> > -		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK2);
> > -		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK2);
> > -		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK2);
> > -	} else {
> > -		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK);
> > -		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK);
> > -		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK);
> > -		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK);

The rest of the patchset merged, thank you!

> I guess you're going to use in the future MSR_IA32_VMX_PINX_MASK2 and other
> deleted masks (because now they are IMHO only in the structs).

If you don't need the constants in the future, please remove it in a subsequent
patch.

Kind regards,
Petr

> Acked-by: Petr Vorel <pvorel@suse.cz>

> Kind regards,
> Petr

> > -	}
> > +	pinxctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_PINX);
> > +	execctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXECCTL);
> > +	exitctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_EXITCTL);
> > +	entryctl = (uint32_t)kvm_vmx_read_vmctl_mask(VMX_CTLMASK_ENTRYCTL);

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [LTP] [PATCH 3/5] KVM: Simplify reading VMX control field masks
  2025-04-16  7:16     ` Petr Vorel
@ 2025-04-28 10:38       ` Martin Doucha
  2025-04-28 12:29         ` Petr Vorel
  0 siblings, 1 reply; 12+ messages in thread
From: Martin Doucha @ 2025-04-28 10:38 UTC (permalink / raw)
  To: Petr Vorel, ltp

Hi!

On 16. 04. 25 9:16, Petr Vorel wrote:
> Hi Martin,
> 
>> Hi Martin,
> 
>> ...
>>>   	/* Configure VM execution control fields */
>>> -	if (kvm_rdmsr(MSR_IA32_VMX_BASIC) & IA32_VMXBASIC_USELESS_CTL_MASKS) {
>>> -		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK2);
>>> -		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK2);
>>> -		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK2);
>>> -		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK2);
>>> -	} else {
>>> -		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK);
>>> -		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK);
>>> -		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK);
>>> -		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK);
> 
> The rest of the patchset merged, thank you!
> 
>> I guess you're going to use in the future MSR_IA32_VMX_PINX_MASK2 and other
>> deleted masks (because now they are IMHO only in the structs).
> 
> If you don't need the constants in the future, please remove it in a subsequent
> patch.

Those constants are still used in kvm_vmx_read_vmctl_mask() via the 
static lookup table in lib_x86.c. We can't remove them because the tests 
would break on old CPUs.

-- 
Martin Doucha   mdoucha@suse.cz
SW Quality Engineer
SUSE LINUX, s.r.o.
CORSO IIa
Krizikova 148/34
186 00 Prague 8
Czech Republic

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [LTP] [PATCH 3/5] KVM: Simplify reading VMX control field masks
  2025-04-28 10:38       ` Martin Doucha
@ 2025-04-28 12:29         ` Petr Vorel
  0 siblings, 0 replies; 12+ messages in thread
From: Petr Vorel @ 2025-04-28 12:29 UTC (permalink / raw)
  To: Martin Doucha; +Cc: ltp

Hi Martin,

> Hi!

> On 16. 04. 25 9:16, Petr Vorel wrote:
> > Hi Martin,

> > > Hi Martin,

> > > ...
> > > >   	/* Configure VM execution control fields */
> > > > -	if (kvm_rdmsr(MSR_IA32_VMX_BASIC) & IA32_VMXBASIC_USELESS_CTL_MASKS) {
> > > > -		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK2);
> > > > -		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK2);
> > > > -		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK2);
> > > > -		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK2);
> > > > -	} else {
> > > > -		pinxctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_PINX_MASK);
> > > > -		execctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXECCTL_MASK);
> > > > -		exitctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_EXITCTL_MASK);
> > > > -		entryctl = (uint32_t)kvm_rdmsr(MSR_IA32_VMX_ENTRYCTL_MASK);

> > The rest of the patchset merged, thank you!

> > > I guess you're going to use in the future MSR_IA32_VMX_PINX_MASK2 and other
> > > deleted masks (because now they are IMHO only in the structs).

> > If you don't need the constants in the future, please remove it in a subsequent
> > patch.

> Those constants are still used in kvm_vmx_read_vmctl_mask() via the static
> lookup table in lib_x86.c. We can't remove them because the tests would
> break on old CPUs.

Good to know, thanks for info!

Kind regards,
Petr

-- 
Mailing list info: https://lists.linux.it/listinfo/ltp

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2025-04-28 12:29 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-07 14:23 [LTP] [PATCH 0/5] KVM test for Intel VMX vAPIC Martin Doucha
2025-04-07 14:23 ` [LTP] [PATCH 1/5] kvm_vmx01: Fix 32bit compiler warnings Martin Doucha
2025-04-07 14:23 ` [LTP] [PATCH 2/5] KVM: Add kvm_vmx01 to the runtest file Martin Doucha
2025-04-16  6:19   ` Petr Vorel
2025-04-07 14:23 ` [LTP] [PATCH 3/5] KVM: Simplify reading VMX control field masks Martin Doucha
2025-04-16  6:22   ` Petr Vorel
2025-04-16  7:16     ` Petr Vorel
2025-04-28 10:38       ` Martin Doucha
2025-04-28 12:29         ` Petr Vorel
2025-04-07 14:23 ` [LTP] [PATCH 4/5] KVM: Add constants for Intel VMX vAPIC control Martin Doucha
2025-04-16  6:24   ` Petr Vorel
2025-04-07 14:23 ` [LTP] [PATCH 5/5] Add test for Intel VMX virtualized APIC Martin Doucha

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox