From: Gleb Natapov <gleb@xxxxxxxxxx> Make it compilable in 32 and 64 bit mode. Signed-off-by: Gleb Natapov <gleb@xxxxxxxxxx> Signed-off-by: Avi Kivity <avi@xxxxxxxxxx> diff --git a/config-x86-common.mak b/config-x86-common.mak index b5c49f4..4d50e51 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -11,6 +11,7 @@ cflatobjs += \ cflatobjs += lib/x86/fwcfg.o cflatobjs += lib/x86/apic.o cflatobjs += lib/x86/atomic.o +cflatobjs += lib/x86/idt.o $(libcflat): LDFLAGS += -nostdlib $(libcflat): CFLAGS += -ffreestanding -I lib @@ -53,7 +54,7 @@ $(TEST_DIR)/vmexit.elf: $(cstart.o) $(TEST_DIR)/vmexit.o $(TEST_DIR)/smptest.elf: $(cstart.o) $(TEST_DIR)/smptest.o $(TEST_DIR)/emulator.elf: $(cstart.o) $(TEST_DIR)/emulator.o \ - $(TEST_DIR)/vm.o $(TEST_DIR)/idt.o + $(TEST_DIR)/vm.o $(TEST_DIR)/port80.elf: $(cstart.o) $(TEST_DIR)/port80.o @@ -68,9 +69,9 @@ $(TEST_DIR)/realmode.o: bits = 32 $(TEST_DIR)/msr.elf: $(cstart.o) $(TEST_DIR)/msr.o -$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/idt_test.o +$(TEST_DIR)/idt_test.elf: $(cstart.o) $(TEST_DIR)/idt_test.o -$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/idt.o $(TEST_DIR)/xsave.o +$(TEST_DIR)/xsave.elf: $(cstart.o) $(TEST_DIR)/xsave.o $(TEST_DIR)/rmap_chain.elf: $(cstart.o) $(TEST_DIR)/rmap_chain.o \ $(TEST_DIR)/vm.o diff --git a/x86/idt.c b/lib/x86/idt.c similarity index 69% rename from x86/idt.c rename to lib/x86/idt.c index 4480833..b3e47d4 100644 --- a/x86/idt.c +++ b/lib/x86/idt.c @@ -1,5 +1,6 @@ #include "idt.h" #include "libcflat.h" +#include "processor.h" typedef struct { unsigned short offset0; @@ -11,36 +12,27 @@ typedef struct { unsigned short dpl : 2; unsigned short p : 1; unsigned short offset1; +#ifdef __x86_64__ unsigned offset2; unsigned reserved; +#endif } idt_entry_t; static idt_entry_t idt[256]; -typedef struct { - unsigned short limit; - unsigned long linear_addr; -} __attribute__((packed)) descriptor_table_t; - -void lidt(idt_entry_t *idt, int nentries) +void load_lidt(idt_entry_t *idt, int nentries) { - descriptor_table_t dt; + struct descriptor_table_ptr dt; dt.limit = nentries * sizeof(*idt) - 1; - dt.linear_addr = (unsigned long)idt; + dt.base = (unsigned long)idt; + lidt(&dt); asm volatile ("lidt %0" : : "m"(dt)); } -unsigned short read_cs() -{ - unsigned short r; - - asm volatile ("mov %%cs, %0" : "=r"(r)); - return r; -} - -void set_idt_entry(idt_entry_t *e, void *addr, int dpl) +void set_idt_entry(int vec, void *addr, int dpl) { + idt_entry_t *e = &idt[vec]; memset(e, 0, sizeof *e); e->offset0 = (unsigned long)addr; e->selector = read_cs(); @@ -49,14 +41,18 @@ void set_idt_entry(idt_entry_t *e, void *addr, int dpl) e->dpl = dpl; e->p = 1; e->offset1 = (unsigned long)addr >> 16; +#ifdef __x86_64__ e->offset2 = (unsigned long)addr >> 32; +#endif } struct ex_regs { unsigned long rax, rcx, rdx, rbx; unsigned long dummy, rbp, rsi, rdi; +#ifdef __x86_64__ unsigned long r8, r9, r10, r11; unsigned long r12, r13, r14, r15; +#endif unsigned long vector; unsigned long error_code; unsigned long rip; @@ -90,34 +86,49 @@ void do_handle_exception(struct ex_regs *regs) exit(7); } +#ifdef __x86_64__ +# define R "r" +# define W "q" +# define S "8" +#else +# define R "e" +# define W "l" +# define S "4" +#endif + asm (".pushsection .text \n\t" "ud_fault: \n\t" - "pushq $0 \n\t" - "pushq $6 \n\t" + "push"W" $0 \n\t" + "push"W" $6 \n\t" "jmp handle_exception \n\t" "gp_fault: \n\t" - "pushq $13 \n\t" + "push"W" $13 \n\t" "jmp handle_exception \n\t" "de_fault: \n\t" - "pushq $0 \n\t" - "pushq $0 \n\t" + "push"W" $0 \n\t" + "push"W" $0 \n\t" "jmp handle_exception \n\t" "handle_exception: \n\t" +#ifdef __x86_64__ "push %r15; push %r14; push %r13; push %r12 \n\t" "push %r11; push %r10; push %r9; push %r8 \n\t" - "push %rdi; push %rsi; push %rbp; sub $8, %rsp \n\t" - "push %rbx; push %rdx; push %rcx; push %rax \n\t" - "mov %rsp, %rdi \n\t" +#endif + "push %"R"di; push %"R"si; push %"R"bp; sub $"S", %"R"sp \n\t" + "push %"R"bx; push %"R"dx; push %"R"cx; push %"R"ax \n\t" + "mov %"R"sp, %"R"di \n\t" "call do_handle_exception \n\t" - "pop %rax; pop %rcx; pop %rdx; pop %rbx \n\t" - "add $8, %rsp; pop %rbp; pop %rsi; pop %rdi \n\t" + "pop %"R"ax; pop %"R"cx; pop %"R"dx; pop %"R"bx \n\t" + "add $"S", %"R"sp; pop %"R"bp; pop %"R"si; pop %"R"di \n\t" +#ifdef __x86_64__ "pop %r8; pop %r9; pop %r10; pop %r11 \n\t" "pop %r12; pop %r13; pop %r14; pop %r15 \n\t" - "add $16, %rsp \n\t" - "iretq \n\t" +#endif + "add $"S", %"R"sp \n\t" + "add $"S", %"R"sp \n\t" + "iret"W" \n\t" ".popsection"); @@ -125,10 +136,10 @@ void setup_idt(void) { extern char ud_fault, gp_fault, de_fault; - lidt(idt, 256); - set_idt_entry(&idt[0], &de_fault, 0); - set_idt_entry(&idt[6], &ud_fault, 0); - set_idt_entry(&idt[13], &gp_fault, 0); + load_lidt(idt, 256); + set_idt_entry(0, &de_fault, 0); + set_idt_entry(6, &ud_fault, 0); + set_idt_entry(13, &gp_fault, 0); } unsigned exception_vector(void) diff --git a/lib/x86/idt.h b/lib/x86/idt.h index 6babcb4..81b8944 100644 --- a/lib/x86/idt.h +++ b/lib/x86/idt.h @@ -15,5 +15,6 @@ void setup_idt(void); unsigned exception_vector(void); unsigned exception_error_code(void); +void set_idt_entry(int vec, void *addr, int dpl); #endif -- To unsubscribe from this list: send the line "unsubscribe kvm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html