From 26518e8dc4e8be0e0fe0bbb2161918d7744ed168 Mon Sep 17 00:00:00 2001 From: Jo Van Bulck Date: Tue, 17 Sep 2024 18:30:12 +0000 Subject: [PATCH] selftest: support x2apic and tsc_deadline MSRs All selftests should now be compatible with both legacy xapic MMIO and x2apic MSR addressing modes via libsgxstep support for privileged rdmsr/wrmsr call gates. cf issue #72 --- app/selftest/README.md | 9 +- app/selftest/apic-ipi/asm.S | 10 ++ app/selftest/apic-ipi/main.c | 11 ++- app/selftest/apic/Makefile | 2 +- app/selftest/apic/config.h | 7 +- app/selftest/apic/irq_entry.S | 58 ------------ app/selftest/apic/main.c | 31 +++--- app/selftest/cpl/README.md | 60 ++++++------ app/selftest/cpl/asm.S | 10 +- app/selftest/cpl/main.c | 11 +-- app/selftest/idt/README.md | 174 ++++++++++++++++++++++++---------- app/selftest/idt/main.c | 62 +++++++----- 12 files changed, 240 insertions(+), 205 deletions(-) delete mode 100644 app/selftest/apic/irq_entry.S diff --git a/app/selftest/README.md b/app/selftest/README.md index 6fdafbb..4f6907b 100644 --- a/app/selftest/README.md +++ b/app/selftest/README.md @@ -6,11 +6,11 @@ This directory contains bare-metal applications designed to test various functio | Directory | Description | |------------|-----------------------------------------------------------------------------------------------------------| -| `apic` | Microbenchmarks for timer interrupts via various Advanced Programmable Interrupt Controller (APIC) modes. | -| `apic-ipi` | Microbenchmarks for APIC inter-processor interrupts. | -| `cpl` | Changing the Current Privilege Level (CPL) through calland interrupt GDT/IDT gates. | +| `cpl` | Changing the Current Privilege Level (CPL) through call and interrupt GDT/IDT gates. | | `idt` | Custom handlers for software and timer interrupts via the Interrupt Descriptor Table (IDT). | | `idt_isr_map` | Stresstest to demonstrate custom IDT handlers can be called across processes. | +| `apic` | Microbenchmarks for timer interrupts via various Advanced Programmable Interrupt Controller (APIC) modes. | +| `apic-ipi` | Microbenchmarks for APIC inter-processor interrupts. | ## Usage @@ -28,4 +28,5 @@ To run the selftest applications: Reference output is available in the respective README files within each subdirectory. -**Note:** Any crashes during execution may indicate that your machine is not set up correctly for using SGX-Step. +**Note:** For troubleshooting, recommended is to execute the selftests in the order specified in the table above. Any crashes or assertion errors during execution may indicate that your machine is not set up correctly for using SGX-Step. + diff --git a/app/selftest/apic-ipi/asm.S b/app/selftest/apic-ipi/asm.S index 6781a01..8113ebe 100644 --- a/app/selftest/apic-ipi/asm.S +++ b/app/selftest/apic-ipi/asm.S @@ -1,11 +1,21 @@ #define APIC_ICR_LOW 0x300 #define APIC_ICR_HIGH 0x310 +#define APIC_ICR_MSR 0x830 +#include "libsgxstep/config.h" .macro apic_write_icr +#if !X2APIC mov apic_base(%rip), %rax movl %esi, APIC_ICR_HIGH(%rax) /* SDM: The act of writing to the low doubleword of the ICR causes the IPI to be sent. */ movl %edi, APIC_ICR_LOW(%rax) +#else /* X2APIC */ + /* SDM: A single MSR write to the Interrupt Command Register is required for dispatching an interrupt in x2APIC mode. */ + shl $32, %rsi + or %rdi, %rsi + mov $APIC_ICR_MSR, %rdi + int $WRMSR_GATE_VECTOR +#endif /* X2APIC */ .endm .text diff --git a/app/selftest/apic-ipi/main.c b/app/selftest/apic-ipi/main.c index ad93053..b12a714 100644 --- a/app/selftest/apic-ipi/main.c +++ b/app/selftest/apic-ipi/main.c @@ -15,8 +15,8 @@ #define SELF_IPI 0 #define MY_VICTIM_CPU 1 -//#define MY_SPY_CPU 3 // no hyperthreading -#define MY_SPY_CPU 37 // hyperthreading +#define MY_SPY_CPU 3 // no hyperthreading +//#define MY_SPY_CPU 37 // hyperthreading #if SELF_IPI #define DUMP_FILE "ipi-self.csv" @@ -63,7 +63,12 @@ void spy_func(int eid) apic_write_icr_ret(APIC_ICR_VECTOR(IRQ_VECTOR) | APIC_ICR_DELIVERY_FIXED | APIC_ICR_LEVEL_ASSERT | APIC_ICR_DEST_PHYSICAL, - (apic_id_victim << APIC_ID_SHIFT) & APIC_ICR_DEST_MASK); + #if !X2APIC + (apic_id_victim << APIC_ID_SHIFT) & APIC_ICR_DEST_MASK + #else + apic_id_victim + #endif + ); spy_ready = 0; while( !__ss_irq_fired ); diff --git a/app/selftest/apic/Makefile b/app/selftest/apic/Makefile index 1877f64..aef4d4b 100644 --- a/app/selftest/apic/Makefile +++ b/app/selftest/apic/Makefile @@ -71,7 +71,7 @@ run: clean all cat out.txt parse: run - SGX_STEP_PLATFORM=$(SGX_STEP_PLATFORM) ./parse_$(PARSE).py $(NUM) + ./parse.py $(OUTPUT): $(BUILDDIRS) $(OBJECTS) echo "$(INDENT)[LD]" $(OBJECTS) $(LIBS) -o $(OUTPUT) diff --git a/app/selftest/apic/config.h b/app/selftest/apic/config.h index a82b8d5..2fc7312 100644 --- a/app/selftest/apic/config.h +++ b/app/selftest/apic/config.h @@ -5,13 +5,10 @@ #define TEST_ITERATIONS 100001 #define APIC_ONESHOT_TICKS 30*2 // NOTE: sgx-step uses APIC timer divide 2(!) -#define APIC_TSC_INTERVAL 5750 +#define CPU_TSC_CLOCK_RATIO 256 // as reported by CPUID +#define APIC_TSC_INTERVAL (APIC_ONESHOT_TICKS * CPU_TSC_CLOCK_RATIO) #define USE_IRQ_GATE 1 #define WRMSR_ON_CPU_LATENCY 0 // is about 8000 -#ifndef IA32_TSC_DEADLINE_MSR - #define IA32_TSC_DEADLINE_MSR 0x6e0 -#endif - #endif diff --git a/app/selftest/apic/irq_entry.S b/app/selftest/apic/irq_entry.S deleted file mode 100644 index 8ab3c38..0000000 --- a/app/selftest/apic/irq_entry.S +++ /dev/null @@ -1,58 +0,0 @@ -#include "config.h" - -/* ********************************************************************** */ - .section isr_section,"awx",@progbits - .global __apic_irq_tsc, __apic_irq_rax, __apic_deadline_tsc -__apic_irq_tsc: - .quad 0x0 -__apic_deadline_tsc: - .quad 0x0 -__apic_irq_rax: - .quad 0x0 -__apic_irq_rcx: - .quad 0x0 -__apic_irq_rdx: - .quad 0x0 - -/* ********************************************************************** */ - .section isr_section,"awx",@progbits - .global __apic_irq_handler_timer -__apic_irq_handler_timer: - mov %rax, __apic_irq_rax(%rip) - mov %rdx, __apic_irq_rdx(%rip) - rdtsc - mov %eax, __apic_irq_tsc(%rip) - mov %edx, __apic_irq_tsc+4(%rip) - - /* IRQ bookkeeping */ - incl __ss_irq_fired(%rip) - - /* apic_write(APIC_EOI, 0x0); */ - lea apic_base(%rip), %rax - mov (%rax),%rax - test %rax, %rax - jz 1f - add $0xb0, %rax - movl $0x0, (%rax) -1: - mov __apic_irq_rax(%rip), %rax - mov __apic_irq_rdx(%rip), %rdx - iretq - - .section isr_section,"awx",@progbits - .global __apic_priv_irq_gate -__apic_priv_irq_gate: - push %rax - push %rcx - push %rdx - - /* wrmsr(IA32_TSC_DEADLINE_MSR, __apic_deadline_tsc) */ - mov __apic_deadline_tsc(%rip), %eax - mov __apic_deadline_tsc+4(%rip), %edx - mov $IA32_TSC_DEADLINE_MSR, %ecx - wrmsr - - pop %rdx - pop %rcx - pop %rax - iretq diff --git a/app/selftest/apic/main.c b/app/selftest/apic/main.c index 3ddfb2f..a03770a 100644 --- a/app/selftest/apic/main.c +++ b/app/selftest/apic/main.c @@ -36,12 +36,8 @@ unsigned long long test_tsc_results[TEST_ITERATIONS]; unsigned long long test_inc_results[TEST_ITERATIONS]; unsigned long long test_deadline_results[TEST_ITERATIONS]; +extern uint64_t __ss_irq_rax; void incs(void); -void __apic_irq_handler_timer(void); -void __apic_priv_irq_gate(void); -extern unsigned long long __apic_irq_tsc; -extern unsigned long long __apic_deadline_tsc; -extern unsigned long long __apic_irq_rax; /* ================== ATTACKER INIT/SETUP ================= */ @@ -68,15 +64,11 @@ int main( int argc, char **argv ) idt_t idt = {0}; attacker_config_runtime(); map_idt(&idt); - install_kernel_irq_handler(&idt, __apic_irq_handler_timer, IRQ_VECTOR); + install_kernel_irq_handler(&idt, __ss_irq_handler, IRQ_VECTOR); #if TSC_DEADLINE const char *filename = "deadline_results.txt"; apic_timer_deadline(IRQ_VECTOR); - - #if USE_IRQ_GATE - install_kernel_irq_handler(&idt, __apic_priv_irq_gate, IRQ_PRIV_VECTOR); - #endif #else const char *filename = "oneshot_results.txt"; apic_timer_oneshot(IRQ_VECTOR); @@ -85,32 +77,31 @@ int main( int argc, char **argv ) for (int i = 0; i < TEST_ITERATIONS; ++i) { __ss_irq_fired = 0; - unsigned long long begin_time = __rdtsc(); + g_apic_deadline_tsc_begin = rdtsc_begin(); #if TSC_DEADLINE && USE_IRQ_GATE - __apic_deadline_tsc = begin_time + APIC_TSC_INTERVAL; - asm("int %0\n\t" ::"i"(IRQ_PRIV_VECTOR):); + apic_timer_deadline_irq(APIC_TSC_INTERVAL); #elif TSC_DEADLINE - __apic_deadline_tsc = begin_time + APIC_TSC_INTERVAL + WRMSR_ON_CPU_LATENCY; - wrmsr_on_cpu(IA32_TSC_DEADLINE_MSR, get_cpu(), __apic_deadline_tsc); + wrmsr_on_cpu(IA32_TSC_DEADLINE_MSR, get_cpu(), + g_apic_deadline_tsc_begin + APIC_TSC_INTERVAL + WRMSR_ON_CPU_LATENCY); //unsigned long long wrmsr_time = __rdtsc(); #else apic_timer_irq(APIC_ONESHOT_TICKS); #endif incs(); - ASSERT(__ss_irq_fired); + ASSERT(__ss_irq_fired == 1); - test_tsc_results[i] = __apic_irq_tsc - begin_time; - test_inc_results[i] = __apic_irq_rax; - test_deadline_results[i] = __apic_irq_tsc - __apic_deadline_tsc; + test_tsc_results[i] = nemesis_tsc_aex - g_apic_deadline_tsc_begin ; + test_inc_results[i] = __ss_irq_rax; + test_deadline_results[i] = nemesis_tsc_aex - (g_apic_deadline_tsc_begin + APIC_TSC_INTERVAL); } // record results FILE *fp = fopen(filename, "w"); fprintf(fp, "#tsc_diff,inc_count,tsc_deadline_drift\n"); for (int i = 1; i < TEST_ITERATIONS; ++i) { - fprintf(fp, "%llu,%llu,%llu\n", test_tsc_results[i], test_inc_results[i], test_deadline_results[i]); + fprintf(fp, "%llu,%llu,%lld\n", test_tsc_results[i], test_inc_results[i], test_deadline_results[i]); } fclose(fp); diff --git a/app/selftest/cpl/README.md b/app/selftest/cpl/README.md index 6c8af56..296b05f 100644 --- a/app/selftest/cpl/README.md +++ b/app/selftest/cpl/README.md @@ -1,67 +1,67 @@ Sample output: ``` -[idt.c] locking IRQ handlers.. [sched.c] continuing on CPU 1 -------------------------------------------------------------------------------- [main.c] Establishing user space GDT mapping -------------------------------------------------------------------------------- -[gdt.c] DTR.base=0xfffffe0000034000/size=127 (16 entries) +[gdt.c] DTR.base=0xfffffe45202b3000/size=127 (16 entries) [pt.c] /dev/sgx-step opened! [pt.c] /dev/mem opened! -[gdt.c] established user space GDT mapping at 0x7faee1a13000 +[gdt.c] established user space GDT mapping at 0x7f1924083000 [gdt.c] -------------------------------------------------------------------------------- -[gdt.c] GDT[ 0] @0x7faee1a13000=0x00000000 / 0x00000 (seg sel 0x00); p=0; dpl=0; type= 0; g=0 -[gdt.c] GDT[ 1] @0x7faee1a13008=0x00000000 / 0xfffff (seg sel 0x08); p=1; dpl=0; type=11; g=1 -[gdt.c] GDT[ 2] @0x7faee1a13010=0x00000000 / 0xfffff (seg sel 0x10); p=1; dpl=0; type=11; g=1 -[gdt.c] GDT[ 3] @0x7faee1a13018=0x00000000 / 0xfffff (seg sel 0x18); p=1; dpl=0; type= 3; g=1 -[gdt.c] GDT[ 4] @0x7faee1a13020=0x00000000 / 0xfffff (seg sel 0x23); p=1; dpl=3; type=11; g=1 -[gdt.c] GDT[ 5] @0x7faee1a13028=0x00000000 / 0xfffff (seg sel 0x2b); p=1; dpl=3; type= 3; g=1 -[gdt.c] GDT[ 6] @0x7faee1a13030=0x00000000 / 0xfffff (seg sel 0x33); p=1; dpl=3; type=11; g=1 -[gdt.c] GDT[ 7] @0x7faee1a13038=0x00000000 / 0x00000 (seg sel 0x38); p=0; dpl=0; type= 0; g=0 -[gdt.c] GDT[ 8] @0x7faee1a13040=0x00036000 / 0x0206f (seg sel 0x40); p=1; dpl=0; type=11; g=0 -[gdt.c] GDT[ 9] @0x7faee1a13048=0x0000ffff / 0x0fe00 (seg sel 0x48); p=0; dpl=0; type= 0; g=0 -[gdt.c] GDT[ 10] @0x7faee1a13050=0x00000000 / 0x00000 (seg sel 0x50); p=0; dpl=0; type= 0; g=0 -[gdt.c] GDT[ 11] @0x7faee1a13058=0x00000000 / 0x00000 (seg sel 0x58); p=0; dpl=0; type= 0; g=0 -[gdt.c] GDT[ 12] @0x7faee1a13060=0x00000000 / 0x00000 (seg sel 0x60); p=0; dpl=0; type= 0; g=0 -[gdt.c] GDT[ 13] @0x7faee1a13068=0x00000000 / 0x00000 (seg sel 0x68); p=0; dpl=0; type= 0; g=0 -[gdt.c] GDT[ 14] @0x7faee1a13070=0x00000000 / 0x00000 (seg sel 0x70); p=0; dpl=0; type= 0; g=0 -[gdt.c] GDT[ 15] @0x7faee1a13078=0x00000000 / 0x00001 (seg sel 0x7b); p=1; dpl=3; type= 5; g=0 +[gdt.c] GDT[ 0] @0x7f1924083000=0x00000000 / 0x00000 (seg sel 0x00); p=0; dpl=0; type= 0; g=0 +[gdt.c] GDT[ 1] @0x7f1924083008=0x00000000 / 0xfffff (seg sel 0x08); p=1; dpl=0; type=11; g=1 +[gdt.c] GDT[ 2] @0x7f1924083010=0x00000000 / 0xfffff (seg sel 0x10); p=1; dpl=0; type=11; g=1 +[gdt.c] GDT[ 3] @0x7f1924083018=0x00000000 / 0xfffff (seg sel 0x18); p=1; dpl=0; type= 3; g=1 +[gdt.c] GDT[ 4] @0x7f1924083020=0x00000000 / 0xfffff (seg sel 0x23); p=1; dpl=3; type=11; g=1 +[gdt.c] GDT[ 5] @0x7f1924083028=0x00000000 / 0xfffff (seg sel 0x2b); p=1; dpl=3; type= 3; g=1 +[gdt.c] GDT[ 6] @0x7f1924083030=0x00000000 / 0xfffff (seg sel 0x33); p=1; dpl=3; type=11; g=1 +[gdt.c] GDT[ 7] @0x7f1924083038=0x00000000 / 0x00000 (seg sel 0x38); p=0; dpl=0; type= 0; g=0 +[gdt.c] GDT[ 8] @0x7f1924083040=0x202b5000 / 0x04087 (seg sel 0x40); p=1; dpl=0; type=11; g=0 +[gdt.c] GDT[ 9] @0x7f1924083048=0x0000ffff / 0x0fe45 (seg sel 0x48); p=0; dpl=0; type= 0; g=0 +[gdt.c] GDT[ 10] @0x7f1924083050=0x00000000 / 0x00000 (seg sel 0x50); p=0; dpl=0; type= 0; g=0 +[gdt.c] GDT[ 11] @0x7f1924083058=0x00000000 / 0x00000 (seg sel 0x58); p=0; dpl=0; type= 0; g=0 +[gdt.c] GDT[ 12] @0x7f1924083060=0x00000000 / 0x00000 (seg sel 0x60); p=0; dpl=0; type= 0; g=0 +[gdt.c] GDT[ 13] @0x7f1924083068=0x00000000 / 0x00000 (seg sel 0x68); p=0; dpl=0; type= 0; g=0 +[gdt.c] GDT[ 14] @0x7f1924083070=0x00000000 / 0x00000 (seg sel 0x70); p=0; dpl=0; type= 0; g=0 +[gdt.c] GDT[ 15] @0x7f1924083078=0x00000000 / 0x00001 (seg sel 0x7b); p=1; dpl=3; type= 5; g=0 [gdt.c] -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- [main.c] Installing and calling ring0 call gate -------------------------------------------------------------------------------- -[idt.c] IDT[ 13] @0x7faee1a13068 = 0x55f1625064d7 (seg sel 0x10); p=1; dpl=3; type=12; ist=0 -[main.c] back from call gate w CPL prev/cur=0/3; RDMSR=0xfee00800 +[idt.c] IDT[ 13] @0x7f1924083068 = 0x557a76cc84bc (seg sel 0x10); p=1; dpl=3; type=12; ist=0 +[main.c] back from call gate w CPL prev/cur=0/3; RDMSR=0x2 -------------------------------------------------------------------------------- [main.c] Establishing user space IDT mapping -------------------------------------------------------------------------------- [idt.c] DTR.base=0xfffffe0000000000/size=4095 (256 entries) -[idt.c] established user space IDT mapping at 0x7faee1a12000 +[idt.c] established user space IDT mapping at 0x7f1924082000 -------------------------------------------------------------------------------- [main.c] Installing and calling ring0 irq gate -------------------------------------------------------------------------------- -[idt.c] installed asm IRQ handler at 10:0x55f1625064de -[idt.c] IDT[ 45] @0x7faee1a122d0 = 0x55f1625064de (seg sel 0x10); p=1; dpl=3; type=14; ist=0 -[main.c] back from irq gate w CPL prev/cur=0/3; RDMSR=0xfee00800 +[idt.c] installed asm IRQ handler at 10:0x557a76cc84c3 +[idt.c] IDT[ 45] @0x7f19240822d0 = 0x557a76cc84c3 (seg sel 0x10); p=1; dpl=3; type=14; ist=0 +[main.c] back from irq gate w CPL prev/cur=0/3; RDMSR=0x2 -------------------------------------------------------------------------------- [main.c] Calling ring0 function on user page with `exec_priv()` -------------------------------------------------------------------------------- -[idt.c] installing and calling ring0 irq gate +[idt.c] locking user-space IRQ gate handler page at 0x557a76ccb000 +[idt.c] installing ring-0 IRQ gate [sched.c] continuing on CPU 1 [idt.c] DTR.base=0xfffffe0000000000/size=4095 (256 entries) -[idt.c] established user space IDT mapping at 0x7faee1a11000 -[idt.c] installed asm IRQ handler at 10:0x55f16250905a -[idt.c] IDT[ 49] @0x7faee1a11310 = 0x55f16250905a (seg sel 0x10); p=1; dpl=3; type=15; ist=0 -[main.c] back from my_ring0_func w CPL=0 and IA32_TIME_STAMP_COUNTER=0x9e6bb6308a6/0x9e6bb630a8e/488 +[idt.c] established user space IDT mapping at 0x7f1924081000 +[idt.c] installed asm IRQ handler at 10:0x557a76ccb000 +[idt.c] IDT[ 49] @0x7f1924081310 = 0x557a76ccb000 (seg sel 0x10); p=1; dpl=3; type=14; ist=0 +[main.c] back from my_ring0_func w CPL prev/cur=0/3; RDMSR=0x2 ``` diff --git a/app/selftest/cpl/asm.S b/app/selftest/cpl/asm.S index aa75091..1f06399 100644 --- a/app/selftest/cpl/asm.S +++ b/app/selftest/cpl/asm.S @@ -1,17 +1,19 @@ #define IA32_TIME_STAMP_COUNTER 0x10 -#define IA32_APIC_BASE 0x1b +#define IA32_APIC_ID 0x802 .text + .global do_rdmsr do_rdmsr: # store CPL (i.e., ring 0) call get_cpl mov %rax, gate_cpl(%rip) # store privileged RDMSR result - mov $IA32_APIC_BASE, %rdi - call rdmsr + mov $IA32_APIC_ID, %ecx + rdmsr + shl $32, %rdx + or %rdx, %rax mov %rax, gate_msr(%rip) - ret .global call_gate_func diff --git a/app/selftest/cpl/main.c b/app/selftest/cpl/main.c index 6006855..83cbb1a 100644 --- a/app/selftest/cpl/main.c +++ b/app/selftest/cpl/main.c @@ -30,20 +30,19 @@ int gate_cpl = -1; uint64_t gate_msr = -1; +uint64_t my_msr = -1; void call_gate_func(void); void irq_gate_func(void); +uint64_t do_rdmsr(void); int my_cpl = -1; -uint64_t my_tsc1 = -1; -uint64_t my_tsc2 = -1; /* ------------------------------------------------------------ */ /* This code will execute with ring0 privileges :) */ void my_ring0_func(void) { - my_tsc1 = rdmsr(IA32_TIME_STAMP_COUNTER); my_cpl = get_cpl(); - my_tsc2 = rdmsr(IA32_TIME_STAMP_COUNTER); + my_msr = do_rdmsr(); } /* ------------------------------------------------------------ */ @@ -85,8 +84,8 @@ int main( int argc, char **argv ) info_event("Calling ring0 function on user page with `exec_priv()`"); exec_priv(my_ring0_func); - info("back from my_ring0_func w CPL=%d and IA32_TIME_STAMP_COUNTER=%p/%p/%d", - my_cpl, my_tsc1, my_tsc2, (int) my_tsc2-my_tsc1); + info("back from my_ring0_func w CPL prev/cur=%d/%d; RDMSR=%p", + my_cpl, get_cpl(), my_msr); #endif return 0; diff --git a/app/selftest/idt/README.md b/app/selftest/idt/README.md index 3f1d79d..0ff362a 100644 --- a/app/selftest/idt/README.md +++ b/app/selftest/idt/README.md @@ -1,71 +1,141 @@ Sample output: ``` -[idt.c] locking IRQ handlers.. [sched.c] continuing on CPU 1 - --------------------------------------------------------------------------------- -[main.c] Installing and testing ring3 IDT handler --------------------------------------------------------------------------------- - [idt.c] DTR.base=0xfffffe0000000000/size=4095 (256 entries) [pt.c] /dev/sgx-step opened! [pt.c] /dev/mem opened! -[idt.c] established user space IDT mapping at 0x7fd245142000 -[idt.c] installed asm IRQ handler at 33:0x55ffaccea000 -[idt.c] IDT[ 45] @0x7fd2451422d0 = 0x55ffaccea000 (seg sel 0x33); p=1; dpl=3; type=15; ist=0 - -[main.c] Triggering ring3 software interrupts.. -[main.c] returned from IRQ: my_cpl=3; irq_cpl=3; count=01; flags=0x246 -[main.c] returned from IRQ: my_cpl=3; irq_cpl=3; count=02; flags=0x246 -[main.c] returned from IRQ: my_cpl=3; irq_cpl=3; count=03; flags=0x246 - -[main.c] Triggering ring3 APIC timer interrupts.. -[file.c] reading buffer from '/dev/cpu/1/msr' (size=8) -[apic.c] established local memory mapping for APIC_BASE=0xfee00000 at 0x7fd245141000 -[apic.c] APIC_ID=2000000; LVTT=400ec; TDCR=0 -[apic.c] APIC timer one-shot mode with division 2 (lvtt=2d/tdcr=0) -[main.c] returned from IRQ: my_cpl=3; irq_cpl=3; count=04; flags=0x246 -[main.c] returned from IRQ: my_cpl=3; irq_cpl=3; count=05; flags=0x246 -[main.c] returned from IRQ: my_cpl=3; irq_cpl=3; count=06; flags=0x246 -[apic.c] Restored APIC_LVTT=400ec/TDCR=0) -[file.c] writing buffer to '/dev/cpu/1/msr' (size=8) +[idt.c] established user space IDT mapping at 0x7f9a3aa22000 -------------------------------------------------------------------------------- -[main.c] Installing and testing ring0 IDT handler +[main.c] Installing and testing ring-0 IDT handler -------------------------------------------------------------------------------- -[idt.c] installed asm IRQ handler at 10:0x55ffaccea000 -[idt.c] IDT[ 45] @0x7fd2451422d0 = 0x55ffaccea000 (seg sel 0x10); p=1; dpl=3; type=14; ist=0 -[idt.c] installing and calling ring0 irq gate +[idt.c] setting up ISR kernel mapping: 0x55d35036b000-0x55d35036c06a +[idt.c] received kernel base address 0xff7e259b00368000 with offset 0xff7dcfc7afffd000 +[idt.c] using kernel-mapped ISR handler: 0x55d35036c000 -> 0xff7e259b00369000 +[idt.c] installed asm IRQ handler at 10:0xff7e259b00369000 +[idt.c] IDT[ 45] @0x7f9a3aa222d0 = 0xff7e259b00369000 (seg sel 0x10); p=1; dpl=3; type=14; ist=0 +[idt.c] locking user-space IRQ gate handler page at 0x55d350364000 +[idt.c] installing ring-0 IRQ gate [sched.c] continuing on CPU 1 [idt.c] DTR.base=0xfffffe0000000000/size=4095 (256 entries) -[idt.c] established user space IDT mapping at 0x7fd245140000 -[idt.c] installed asm IRQ handler at 10:0x55ffaccea05a -[idt.c] IDT[ 49] @0x7fd245140310 = 0x55ffaccea05a (seg sel 0x10); p=1; dpl=3; type=15; ist=0 +[idt.c] established user space IDT mapping at 0x7f9a3aa1f000 +[idt.c] installed asm IRQ handler at 10:0x55d350364000 +[idt.c] IDT[ 49] @0x7f9a3aa1f310 = 0x55d350364000 (seg sel 0x10); p=1; dpl=3; type=14; ist=0 [main.c] back from exec_priv(pre_irq) with CPL=0 -[main.c] Triggering ring3 software interrupts.. -[main.c] returned from IRQ: my_cpl=3; irq_cpl=0; count=07; flags=0x246 -[main.c] returned from IRQ: my_cpl=3; irq_cpl=0; count=08; flags=0x246 -[main.c] returned from IRQ: my_cpl=3; irq_cpl=0; count=09; flags=0x246 -[main.c] Triggering ring0 software interrupts.. -[main.c] returned from IRQ: my_cpl=0; irq_cpl=0; count=10; flags=0x246 -[main.c] returned from IRQ: my_cpl=0; irq_cpl=0; count=11; flags=0x246 -[main.c] returned from IRQ: my_cpl=0; irq_cpl=0; count=12; flags=0x246 +-------------------------------------------------------------------------------- +[main.c] Triggering ring-3 software interrupts.. +-------------------------------------------------------------------------------- + +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=01; nemesis=2692 +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=02; nemesis=400 +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=03; nemesis=416 +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=04; nemesis=414 +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=05; nemesis=418 +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=06; nemesis=416 +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=07; nemesis=418 +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=08; nemesis=414 +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=09; nemesis=418 +[main.c] returned from software IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=10; nemesis=410 + -[main.c] Triggering ring3 APIC timer interrupts.. +-------------------------------------------------------------------------------- +[main.c] Triggering ring-0 software interrupts.. +-------------------------------------------------------------------------------- + +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=11; nemesis=350 +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=12; nemesis=352 +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=13; nemesis=354 +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=14; nemesis=352 +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=15; nemesis=352 +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=16; nemesis=348 +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=17; nemesis=350 +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=18; nemesis=352 +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=19; nemesis=350 +[main.c] returned from software IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=20; nemesis=352 +[idt.c] locking user-space IRQ gate handler page at 0x55d350364000 +[idt.c] installing ring-0 IRQ gate +[sched.c] continuing on CPU 1 +[idt.c] DTR.base=0xfffffe0000000000/size=4095 (256 entries) +[idt.c] established user space IDT mapping at 0x7f9a3aa1f000 +[idt.c] installed asm IRQ handler at 10:0x55d35036400e +[idt.c] IDT[ 51] @0x7f9a3aa1f330 = 0x55d35036400e (seg sel 0x10); p=1; dpl=3; type=14; ist=0 +[idt.c] locking user-space IRQ gate handler page at 0x55d350364000 +[idt.c] installing ring-0 IRQ gate +[sched.c] continuing on CPU 1 +[idt.c] DTR.base=0xfffffe0000000000/size=4095 (256 entries) +[idt.c] established user space IDT mapping at 0x7f9a3aa1f000 +[idt.c] installed asm IRQ handler at 10:0x55d35036401f +[idt.c] IDT[ 50] @0x7f9a3aa1f320 = 0x55d35036401f (seg sel 0x10); p=1; dpl=3; type=14; ist=0 +[apic.c] APIC_ID=0; LVTT=0x400ec; TDCR=0 [apic.c] APIC timer one-shot mode with division 2 (lvtt=2d/tdcr=0) -[main.c] returned from IRQ: my_cpl=3; irq_cpl=0; count=13; flags=0x246 -[main.c] returned from IRQ: my_cpl=3; irq_cpl=0; count=14; flags=0x246 -[main.c] returned from IRQ: my_cpl=3; irq_cpl=0; count=15; flags=0x246 - -[main.c] Triggering ring0 APIC timer interrupts.. -[main.c] returned from IRQ: my_cpl=0; irq_cpl=0; count=16; flags=0x246 -[main.c] returned from IRQ: my_cpl=0; irq_cpl=0; count=17; flags=0x246 -[main.c] returned from IRQ: my_cpl=0; irq_cpl=0; count=18; flags=0x246 -[apic.c] Restored APIC_LVTT=400ec/TDCR=0) -[file.c] writing buffer to '/dev/cpu/1/msr' (size=8) -[main.c] all is well; irq_count=18; exiting.. + + +-------------------------------------------------------------------------------- +[main.c] Triggering ring-3 APIC timer oneshot interrupts.. +-------------------------------------------------------------------------------- + +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=21; nemesis=3670 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=22; nemesis=3494 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=23; nemesis=3486 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=24; nemesis=3602 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=25; nemesis=3496 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=26; nemesis=3462 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=27; nemesis=3416 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=28; nemesis=3292 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=29; nemesis=3490 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=30; nemesis=3636 + + +-------------------------------------------------------------------------------- +[main.c] Triggering ring-0 APIC timer oneshot interrupts.. +-------------------------------------------------------------------------------- + +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=31; nemesis=3276 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=32; nemesis=3338 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=33; nemesis=3212 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=34; nemesis=3152 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=35; nemesis=3386 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=36; nemesis=3338 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=37; nemesis=3360 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=38; nemesis=3186 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=39; nemesis=3344 +[main.c] returned from APIC timer oneshot IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=40; nemesis=3318 +[apic.c] APIC timer tsc-deadline mode (lvtt=4002d/tdcr=0) + + +-------------------------------------------------------------------------------- +[main.c] Triggering ring-3 APIC timer tsc_deadline interrupts.. +-------------------------------------------------------------------------------- + +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=41; nemesis=1386 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=42; nemesis=1340 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=43; nemesis=1326 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=44; nemesis=1324 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=45; nemesis=1304 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=46; nemesis=1320 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=47; nemesis=1302 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=48; nemesis=1314 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=49; nemesis=1402 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=3; irq_cpl=0; my_flags=0x246; count=50; nemesis=1416 + + +-------------------------------------------------------------------------------- +[main.c] Triggering ring-0 APIC timer tsc_deadline interrupts.. +-------------------------------------------------------------------------------- + +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=51; nemesis=1928 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=52; nemesis=1808 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=53; nemesis=2138 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=54; nemesis=2030 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=55; nemesis=1866 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=56; nemesis=1898 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=57; nemesis=1956 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=58; nemesis=1882 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=59; nemesis=2058 +[main.c] returned from APIC timer tsc_deadline IRQ: my_cpl=0; irq_cpl=0; my_flags=0x46; count=60; nemesis=1998 +[main.c] all is well; irq_count=60; exiting.. ``` diff --git a/app/selftest/idt/main.c b/app/selftest/idt/main.c index 54fd5af..d47b6bf 100644 --- a/app/selftest/idt/main.c +++ b/app/selftest/idt/main.c @@ -29,7 +29,7 @@ #define DO_APIC_TMR_IRQ 1 #define DO_EXEC_PRIV 1 #define NUM 10 -#define INFINITE_LOOP 1 +#define INFINITE_LOOP 0 #define NEMESIS_HIGH 1 /* ------------------------------------------------------------ */ @@ -37,6 +37,7 @@ int my_cpl = -1; uint64_t my_flags = 0; extern uint64_t nemesis_tsc_aex, nemesis_tsc_eresume; +int apic_oneshot = 1; void pre_irq(void) { @@ -55,7 +56,15 @@ void do_irq_sw(void) void do_irq_tmr(void) { pre_irq(); - apic_timer_irq(10); + + if (apic_oneshot) + { + apic_timer_irq(10); + } + else + { + apic_timer_deadline_irq(100); + } /* * Ring-0 `exec_priv` handler executes with interrupts disabled FLAGS.IF=0 @@ -84,6 +93,30 @@ void post_irq(char *s) my_cpl, __ss_irq_cpl, my_flags, __ss_irq_count, nemesis_tsc_aex - nemesis_tsc_eresume); } +void do_irq_apic_tmr_test(char *tmr_desc, int do_exec_priv) +{ + printf("\n"); + info_event("Triggering ring-3 %s interrupts..", tmr_desc); + for (int i=0; i < NUM; i++) + { + do_irq_tmr(); + post_irq(tmr_desc); + } + + if (do_exec_priv) + { + printf("\n"); + info_event("Triggering ring-0 %s interrupts..", tmr_desc); + for (int i=0; i < NUM; i++) + { + my_cpl = -1; + exec_priv(do_irq_tmr); + while (!__ss_irq_fired); + post_irq(tmr_desc); + } + } +} + void do_irq_test(int do_exec_priv) { #if DO_APIC_SW_IRQ @@ -109,28 +142,13 @@ void do_irq_test(int do_exec_priv) #endif #if DO_APIC_TMR_IRQ - printf("\n"); - info_event("Triggering ring-3 APIC timer interrupts.."); apic_timer_oneshot(IRQ_VECTOR); + apic_oneshot = 1; + do_irq_apic_tmr_test("APIC timer oneshot", do_exec_priv); - for (int i=0; i < NUM; i++) - { - do_irq_tmr(); - post_irq("APIC timer"); - } - - if (do_exec_priv) - { - printf("\n"); - info_event("Triggering ring-0 APIC timer interrupts.."); - for (int i=0; i < NUM; i++) - { - my_cpl = -1; - exec_priv(do_irq_tmr); - while (!__ss_irq_fired); - post_irq("APIC timer"); - } - } + apic_timer_deadline(IRQ_VECTOR); + apic_oneshot = 0; + do_irq_apic_tmr_test("APIC timer tsc_deadline", do_exec_priv); #endif }