Commit 309ca07b authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

x86: desc: support ISTs for alternate stacks in 64-bit mode



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: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent b6a0ff03
......@@ -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;
......
......@@ -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));
......
......@@ -77,6 +77,7 @@ tss_descr:
gdt64_end:
i = 0
.globl tss
tss:
.rept max_cpus
.long 0
......
......@@ -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 */
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment