[kvm-unit-tests PATCH v3 04/17] x86: cet: Directly check for #CP exception in run_in_user()

Sean Christopherson
2025-11-14T00:13:08Z

From: Chao Gao <chao.gao@intel.com>

Current CET tests validate if a #CP exception is raised by registering
a #CP handler. This handler counts the #CP exceptions and raises a #GP
exception, which is then caught by the run_in_user() infrastructure to
switch back to the kernel. This is convoluted.

Catch the #CP exception directly by run_in_user() to avoid the manual
counting of #CP exceptions and the #CP->#GP dance.

Signed-off-by: Chao Gao <chao.gao@intel.com>
Signed-off-by: Mathias Krause <minipli@grsecurity.net>
Signed-off-by: Sean Christopherson <seanjc@google.com>
---
x86/cet.c | 23 ++++-------------------
1 file changed, 4 insertions(+), 19 deletions(-)

diff --git a/x86/cet.c b/x86/cet.c
index e2681886..7635fe34 100644
--- a/x86/cet.c
+++ b/x86/cet.c
@@ -8,9 +8,6 @@
#include "alloc_page.h"
#include "fault_test.h"

-static int cp_count;
-static unsigned long invalid_offset = 0xffffffffffffff;
-
static u64 cet_shstk_func(void)
{
unsigned long *ret_addr, *ssp;
@@ -54,15 +51,6 @@ static u64 cet_ibt_func(void)
#define ENABLE_SHSTK_BIT 0x1
#define ENABLE_IBT_BIT 0x4

-static void handle_cp(struct ex_regs *regs)
-{
- cp_count++;
- printf("In #CP exception handler, error_code = 0x%lx\n",
- regs->error_code);
- /* Below jmp is expected to trigger #GP */
- asm("jmpq *%0": :"m"(invalid_offset));
-}
-
int main(int ac, char **av)
{
char *shstk_virt;
@@ -70,7 +58,6 @@ int main(int ac, char **av)
pteval_t pte = 0;
bool rvc;

- cp_count = 0;
if (!this_cpu_has(X86_FEATURE_SHSTK)) {
printf("SHSTK not enabled\n");
return report_summary();
@@ -82,7 +69,6 @@ int main(int ac, char **av)
}

setup_vm();
- handle_exception(CP_VECTOR, handle_cp);

/* Allocate one page for shadow-stack. */
shstk_virt = alloc_vpage();
@@ -107,15 +93,14 @@ int main(int ac, char **av)
write_cr4(read_cr4() | X86_CR4_CET);

printf("Unit test for CET user mode...\n");
- run_in_user((usermode_func)cet_shstk_func, GP_VECTOR, 0, 0, 0, 0, &rvc);
- report(cp_count == 1, "Completed shadow-stack protection test successfully.");
- cp_count = 0;
+ run_in_user((usermode_func)cet_shstk_func, CP_VECTOR, 0, 0, 0, 0, &rvc);
+ report(rvc, "Shadow-stack protection test.");

/* Enable indirect-branch tracking */
wrmsr(MSR_IA32_U_CET, ENABLE_IBT_BIT);

- run_in_user((usermode_func)cet_ibt_func, GP_VECTOR, 0, 0, 0, 0, &rvc);
- report(cp_count == 1, "Completed Indirect-branch tracking test successfully.");
+ run_in_user((usermode_func)cet_ibt_func, CP_VECTOR, 0, 0, 0, 0, &rvc);
+ report(rvc, "Indirect-branch tracking test.");

write_cr4(read_cr4() & ~X86_CR4_CET);
wrmsr(MSR_IA32_U_CET, 0);
--
2.52.0.rc1.455.g30608eb744-goog