Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions BM/apx/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
apx_cpuid
apx_xstate
apx_egpr
apx_instructions
*.o
50 changes: 50 additions & 0 deletions BM/apx/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2024 Intel Corporation.

cmake_minimum_required(VERSION 3.12)
project(apx)

# Set the build output directory
set(BUILD_OUTPUT ${CMAKE_CURRENT_BINARY_DIR})

# Set the installation prefix
set(CMAKE_INSTALL_PREFIX /usr/local/bin)

# Set common compilation flags
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2 -g -std=gnu99 -Wall -no-pie")

# APX requires GCC 14+ with -mapxf or compatible assembler
# Check for APX assembler support
include(CheckCCompilerFlag)
check_c_compiler_flag("-mapxf" HAS_MAPXF)

if(HAS_MAPXF)
set(APX_FLAGS "-mapxf")
else()
message(WARNING "Compiler does not support -mapxf, using raw .byte encoding")
set(APX_FLAGS "")
endif()

# Build apx_cpuid
add_executable(apx_cpuid apx_cpuid.c)

# Build apx_xstate_helpers as object library (needs special flags)
add_library(apx_xstate_helpers OBJECT apx_xstate_helpers.c)
target_compile_options(apx_xstate_helpers PRIVATE
-mno-sse -mno-mmx -mno-sse2 -mno-avx -mno-pku ${APX_FLAGS})

# Build apx_xstate
add_executable(apx_xstate apx_xstate.c)
target_link_libraries(apx_xstate PRIVATE apx_xstate_helpers)

# Build apx_egpr
add_executable(apx_egpr apx_egpr.c)
target_compile_options(apx_egpr PRIVATE ${APX_FLAGS})

# Build apx_instructions
add_executable(apx_instructions apx_instructions.c)
target_compile_options(apx_instructions PRIVATE ${APX_FLAGS})

# Install targets
install(TARGETS apx_cpuid apx_xstate apx_egpr apx_instructions
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX})
28 changes: 28 additions & 0 deletions BM/apx/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# SPDX-License-Identifier: GPL-2.0-only
# Copyright (c) 2024 Intel Corporation.

BIN := apx_cpuid apx_xstate apx_egpr apx_instructions

CFLAGS += -O2 -g -std=gnu99 -Wall -no-pie
NO_FPU_FLAG += -mno-sse -mno-mmx -mno-sse2 -mno-avx -mno-pku

# Check if GCC supports -mapxf
APX_FLAG := $(shell echo 'int main(){}' | gcc -mapxf -x c - -o /dev/null 2>/dev/null && echo -mapxf)

all: $(BIN)

apx_cpuid: apx_cpuid.c
gcc $(CFLAGS) -o $@ $^

apx_xstate: apx_xstate.c apx_xstate_helpers.c
gcc $(CFLAGS) $(NO_FPU_FLAG) $(APX_FLAG) -c -o apx_xstate_helpers.o apx_xstate_helpers.c
gcc $(CFLAGS) -o $@ apx_xstate.c apx_xstate_helpers.o

apx_egpr: apx_egpr.c
gcc $(CFLAGS) $(APX_FLAG) -o $@ $^

apx_instructions: apx_instructions.c
gcc $(CFLAGS) $(APX_FLAG) -o $@ $^

clean:
rm -rf $(BIN) *.o
47 changes: 47 additions & 0 deletions BM/apx/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Intel APX (Advanced Performance Extensions) Tests

## Overview

Intel APX extends the x86-64 ISA with:
- **Extended General Purpose Registers (EGPRs)**: 16 additional 64-bit registers (R16-R31)
- **REX2 prefix**: New 2-byte prefix encoding (0xD5) enabling access to EGPRs
- **Extended EVEX**: Promotes legacy instructions to use EGPRs via EVEX encoding
- **NDD (New Data Destination)**: Non-destructive destination forms of instructions
- **NF (No Flags)**: Suppress flag updates for certain instructions
- **CFCMOV**: Conditional flag-based CMOVcc with memory destination support

## Kernel Support Tested

1. **CPUID enumeration**: CPUID.(EAX=7, ECX=1):EDX[21] for APX feature
2. **XSAVE/XRSTOR**: XFEATURE_APX (state component 19) - saves/restores EGPR state
3. **XSTATE size**: 128 bytes (16 x 8-byte registers)
4. **Signal handling**: EGPR state preserved across signal delivery and return
5. **Context switch**: EGPR state preserved across fork and context switches
6. **Instruction decoder**: REX2 prefix (0xD5) parsing in kernel oops decoder
7. **APX/MPX mutual exclusion**: Kernel rejects CPUs advertising both APX and MPX

## Platform Support

- **DMR** (Diamond Rapids) and later

## Test Structure

```
apx/
├── CMakeLists.txt # Build system
├── Makefile # Legacy make support
├── README.md # This file
├── tests # Test case list for runtests framework
├── apx_xstate.c # XSAVE/XRSTOR EGPR tests (signal, fork, context switch)
├── apx_xstate_helpers.c # Assembly helpers for EGPR manipulation
├── apx_xstate_helpers.h # Helper declarations
├── apx_egpr.c # EGPR basic functionality tests
└── apx_instructions.c # APX instruction encoding tests (NDD, NF, CFCMOV)
```

## Dependencies

- CPU with APX support (CPUID.7.1:EDX[21])
- Kernel with CONFIG_X86_64=y and XSAVE support
- GCC 14+ or Clang 19+ with `-mapxf` flag for APX instruction encoding
- Binutils 2.43+ for APX assembler support
75 changes: 75 additions & 0 deletions BM/apx/apx_cpuid.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// SPDX-License-Identifier: GPL-2.0-only
// Copyright (c) 2024 Intel Corporation.

/*
* apx_cpuid.c - Validate APX CPUID enumeration.
*
* Checks:
* 1. CPUID.(EAX=7, ECX=1):EDX[21] - APX feature flag
* 2. CPUID.(EAX=0Dh, ECX=19) - APX XSAVE state info (size=128, offset, alignment)
* 3. XCR0[19] - OS has enabled APX state saving
*/

#define _GNU_SOURCE
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <cpuid.h>

typedef uint32_t u32;
typedef uint64_t u64;

#include "../common/kselftest.h"

#define NUM_TESTS 4

static inline u64 xgetbv(u32 index)
{
u32 eax, edx;

asm volatile("xgetbv" : "=a"(eax), "=d"(edx) : "c"(index));
return ((u64)edx << 32) | eax;
}

int main(void)
{
u32 eax, ebx, ecx, edx;
u64 xcr0;

ksft_print_header();
ksft_set_plan(NUM_TESTS);

/* Test 1: APX feature bit in CPUID */
__cpuid_count(7, 1, eax, ebx, ecx, edx);
if (edx & (1U << 21))
ksft_test_result_pass("CPUID.7.1:EDX[21] APX feature present\n");
else
ksft_test_result_fail("CPUID.7.1:EDX[21] APX feature NOT present\n");

/* Test 2: XSAVE support prerequisite */
__cpuid_count(1, 0, eax, ebx, ecx, edx);
if ((ecx & (1U << 26)) && (ecx & (1U << 27)))
ksft_test_result_pass("XSAVE/OSXSAVE supported and enabled\n");
else
ksft_test_result_skip("XSAVE/OSXSAVE not available\n");

/* Test 3: XCR0 bit 19 - OS enabled APX state */
xcr0 = xgetbv(0);
if (xcr0 & (1ULL << 19))
ksft_test_result_pass("XCR0[19] APX state enabled by OS\n");
else
ksft_test_result_fail("XCR0[19] APX state NOT enabled (xcr0=0x%llx)\n",
(unsigned long long)xcr0);

/* Test 4: APX XSAVE area properties via CPUID.(0Dh, 19) */
__cpuid_count(0xD, 19, eax, ebx, ecx, edx);
if (eax == 128 && ebx > 0)
ksft_test_result_pass("CPUID.0D.19: size=%u offset=%u (expected 128B)\n",
eax, ebx);
else
ksft_test_result_fail("CPUID.0D.19: size=%u offset=%u (expected size=128)\n",
eax, ebx);

ksft_finished();
return 0;
}
Loading
Loading