Introduce a new API that replaces setup_tss32 and set_intr_task_gate in tests that run in both modes. This will enable three more tests in eventinj to run in 64-bit mode. Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- lib/x86/desc.c | 26 ++++++++++++++++++++++++-- lib/x86/desc.h | 34 ++++++++++++++++++++++++++-------- x86/cstart64.S | 1 + x86/eventinj.c | 6 +++--- 4 files changed, 54 insertions(+), 13 deletions(-) diff --git a/lib/x86/desc.c b/lib/x86/desc.c index ec1fda3..9a80f48 100644 --- a/lib/x86/desc.c +++ b/lib/x86/desc.c @@ -187,6 +187,8 @@ unsigned exception_error_code(void) return error_code; } +static char intr_alt_stack[4096]; + #ifndef __x86_64__ /* * GDT, with 6 entries: @@ -243,7 +245,6 @@ void set_idt_task_gate(int vec, u16 sel) */ tss32_t tss_intr; -static char tss_stack[4096]; void setup_tss32(void) { @@ -253,7 +254,7 @@ void setup_tss32(void) tss_intr.cr3 = read_cr3(); tss_intr.ss0 = tss_intr.ss1 = tss_intr.ss2 = 0x10; tss_intr.esp = tss_intr.esp0 = tss_intr.esp1 = tss_intr.esp2 = - (u32)tss_stack + 4096; + (u32)intr_alt_stack + 4096; tss_intr.cs = 0x08; tss_intr.ds = tss_intr.es = tss_intr.fs = tss_intr.gs = tss_intr.ss = 0x10; tss_intr.iomap_base = (u16)desc_size; @@ -266,6 +267,16 @@ void set_intr_task_gate(int e, void *fn) set_idt_task_gate(e, TSS_INTR); } +void setup_alt_stack(void) +{ + setup_tss32(); +} + +void set_intr_alt_stack(int e, void *fn) +{ + set_intr_task_gate(e, fn); +} + void print_current_tss_info(void) { u16 tr = str(); @@ -276,6 +287,17 @@ void print_current_tss_info(void) printf("TR=%x (%s) Main TSS back link %x. Intr TSS back link %x\n", tr, tr ? "interrupt" : "main", tss.prev, tss_intr.prev); } +#else +void set_intr_alt_stack(int e, void *addr) +{ + set_idt_entry(e, addr, 0); + boot_idt[e].ist = 1; +} + +void setup_alt_stack(void) +{ + tss.ist1 = (u64)intr_alt_stack + 4096; +} #endif static bool exception; diff --git a/lib/x86/desc.h b/lib/x86/desc.h index cd41a74..33e721c 100644 --- a/lib/x86/desc.h +++ b/lib/x86/desc.h @@ -2,11 +2,7 @@ #define __IDT_TEST__ void setup_idt(void); -#ifndef __x86_64__ -void setup_tss32(void); -#else -static inline void setup_tss32(void){} -#endif +void setup_alt_stack(void); struct ex_regs { unsigned long rax, rcx, rdx, rbx; @@ -57,6 +53,24 @@ typedef struct { u16 iomap_base; } tss32_t; +typedef struct __attribute__((packed)) { + u32 res1; + u64 rsp0; + u64 rsp1; + u64 rsp2; + u64 res2; + u64 ist1; + u64 ist2; + u64 ist3; + u64 ist4; + u64 ist5; + u64 ist6; + u64 ist7; + u64 res3; + u16 res4; + u16 iomap_base; +} tss64_t; + #define ASM_TRY(catch) \ "movl $0, %%gs:4 \n\t" \ ".pushsection .data.ex \n\t" \ @@ -109,6 +123,12 @@ extern idt_entry_t boot_idt[256]; extern gdt_entry_t gdt32[]; extern tss32_t tss; extern tss32_t tss_intr; +void set_gdt_task_gate(u16 tss_sel, u16 sel); +void set_idt_task_gate(int vec, u16 sel); +void set_intr_task_gate(int vec, void *fn); +void setup_tss32(void); +#else +extern tss64_t tss; #endif unsigned exception_vector(void); @@ -116,9 +136,7 @@ unsigned exception_error_code(void); void set_idt_entry(int vec, void *addr, int dpl); void set_idt_sel(int vec, u16 sel); void set_gdt_entry(int sel, u32 base, u32 limit, u8 access, u8 gran); -void set_gdt_task_gate(u16 tss_sel, u16 sel); -void set_idt_task_gate(int vec, u16 sel); -void set_intr_task_gate(int e, void *fn); +void set_intr_alt_stack(int e, void *fn); void print_current_tss_info(void); void handle_exception(u8 v, void (*func)(struct ex_regs *regs)); diff --git a/x86/cstart64.S b/x86/cstart64.S index 1a0c85e..7a1d79d 100644 --- a/x86/cstart64.S +++ b/x86/cstart64.S @@ -77,6 +77,7 @@ tss_descr: gdt64_end: i = 0 +.globl tss tss: .rept max_cpus .long 0 diff --git a/x86/eventinj.c b/x86/eventinj.c index 900cfda..2124bdf 100644 --- a/x86/eventinj.c +++ b/x86/eventinj.c @@ -183,7 +183,7 @@ int main() setup_vm(); setup_idt(); - setup_tss32(); + setup_alt_stack(); handle_irq(32, tirq0); handle_irq(33, tirq1); @@ -344,7 +344,7 @@ int main() /* Generate DE and PF exceptions serially */ test_divider = 0; - set_intr_task_gate(14, pf_tss); + set_intr_alt_stack(14, pf_tss); handle_exception(0, de_isr); printf("Try to divide by 0\n"); /* install read only pte */ @@ -363,7 +363,7 @@ int main() /* Generate NP and PF exceptions serially */ printf("Before NP test\n"); test_count = 0; - set_intr_task_gate(14, pf_tss); + set_intr_alt_stack(14, pf_tss); handle_exception(11, np_isr); set_idt_sel(33, NP_SEL); /* install read only pte */ -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html