From patchwork Tue Dec 14 15:48:46 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gleb Natapov X-Patchwork-Id: 410521 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oBEFmtL2007091 for ; Tue, 14 Dec 2010 15:49:23 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759410Ab0LNPsy (ORCPT ); Tue, 14 Dec 2010 10:48:54 -0500 Received: from mx1.redhat.com ([209.132.183.28]:8524 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758320Ab0LNPsv (ORCPT ); Tue, 14 Dec 2010 10:48:51 -0500 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oBEFmpuU026822 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 14 Dec 2010 10:48:51 -0500 Received: from dhcp-1-237.tlv.redhat.com (dhcp-1-237.tlv.redhat.com [10.35.1.237]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id oBEFmopO013544; Tue, 14 Dec 2010 10:48:50 -0500 Received: by dhcp-1-237.tlv.redhat.com (Postfix, from userid 13519) id 67A8B133F76; Tue, 14 Dec 2010 17:48:49 +0200 (IST) From: Gleb Natapov To: kvm@vger.kernel.org Cc: avi@redhat.com Subject: [PATCH unit-tests 1/4] Move idt.c into lib code. Date: Tue, 14 Dec 2010 17:48:46 +0200 Message-Id: <1292341729-20680-1-git-send-email-gleb@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Tue, 14 Dec 2010 15:49:23 +0000 (UTC) diff --git a/config-x86-common.mak b/config-x86-common.mak index c5508b3..2269c4a 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 @@ -50,7 +51,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 @@ -65,9 +66,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/lib/x86/idt.c b/lib/x86/idt.c index ed2f4b0..b3e47d4 100644 --- a/lib/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; @@ -19,30 +20,19 @@ typedef struct { 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(); @@ -146,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 diff --git a/x86/idt.c b/x86/idt.c deleted file mode 100644 index 4480833..0000000 --- a/x86/idt.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "idt.h" -#include "libcflat.h" - -typedef struct { - unsigned short offset0; - unsigned short selector; - unsigned short ist : 3; - unsigned short : 5; - unsigned short type : 4; - unsigned short : 1; - unsigned short dpl : 2; - unsigned short p : 1; - unsigned short offset1; - unsigned offset2; - unsigned reserved; -} 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) -{ - descriptor_table_t dt; - - dt.limit = nentries * sizeof(*idt) - 1; - dt.linear_addr = (unsigned long)idt; - 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) -{ - memset(e, 0, sizeof *e); - e->offset0 = (unsigned long)addr; - e->selector = read_cs(); - e->ist = 0; - e->type = 14; - e->dpl = dpl; - e->p = 1; - e->offset1 = (unsigned long)addr >> 16; - e->offset2 = (unsigned long)addr >> 32; -} - -struct ex_regs { - unsigned long rax, rcx, rdx, rbx; - unsigned long dummy, rbp, rsi, rdi; - unsigned long r8, r9, r10, r11; - unsigned long r12, r13, r14, r15; - unsigned long vector; - unsigned long error_code; - unsigned long rip; - unsigned long cs; - unsigned long rflags; -}; - -struct ex_record { - unsigned long rip; - unsigned long handler; -}; - -extern struct ex_record exception_table_start, exception_table_end; - -void do_handle_exception(struct ex_regs *regs) -{ - struct ex_record *ex; - unsigned ex_val; - - ex_val = regs->vector | (regs->error_code << 16); - - asm("mov %0, %%gs:4" : : "r"(ex_val)); - - for (ex = &exception_table_start; ex != &exception_table_end; ++ex) { - if (ex->rip == regs->rip) { - regs->rip = ex->handler; - return; - } - } - printf("unhandled excecption\n"); - exit(7); -} - -asm (".pushsection .text \n\t" - "ud_fault: \n\t" - "pushq $0 \n\t" - "pushq $6 \n\t" - "jmp handle_exception \n\t" - - "gp_fault: \n\t" - "pushq $13 \n\t" - "jmp handle_exception \n\t" - - "de_fault: \n\t" - "pushq $0 \n\t" - "pushq $0 \n\t" - "jmp handle_exception \n\t" - - "handle_exception: \n\t" - "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" - "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 %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" - ".popsection"); - - -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); -} - -unsigned exception_vector(void) -{ - unsigned short vector; - - asm("mov %%gs:4, %0" : "=rm"(vector)); - return vector; -} - -unsigned exception_error_code(void) -{ - unsigned short error_code; - - asm("mov %%gs:6, %0" : "=rm"(error_code)); - return error_code; -}