From patchwork Wed Dec 22 15:06:18 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gleb Natapov X-Patchwork-Id: 427911 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 oBMF6qIa013964 for ; Wed, 22 Dec 2010 15:06:53 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753517Ab0LVPGm (ORCPT ); Wed, 22 Dec 2010 10:06:42 -0500 Received: from mx1.redhat.com ([209.132.183.28]:15913 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753414Ab0LVPGc (ORCPT ); Wed, 22 Dec 2010 10:06:32 -0500 Received: from int-mx12.intmail.prod.int.phx2.redhat.com (int-mx12.intmail.prod.int.phx2.redhat.com [10.5.11.25]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id oBMF6WYU011488 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Wed, 22 Dec 2010 10:06:32 -0500 Received: from dhcp-1-237.tlv.redhat.com (dhcp-1-237.tlv.redhat.com [10.35.1.237]) by int-mx12.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id oBMF6VCv022601; Wed, 22 Dec 2010 10:06:31 -0500 Received: by dhcp-1-237.tlv.redhat.com (Postfix, from userid 13519) id 8D3AE18D3EE; Wed, 22 Dec 2010 17:06:29 +0200 (IST) From: Gleb Natapov To: avi@redhat.com, mtosatti@redhat.com Cc: kvm@vger.kernel.org Subject: [PATCH unit-tests 05/16] Rename idt.[ch] into desc.[ch] Date: Wed, 22 Dec 2010 17:06:18 +0200 Message-Id: <1293030389-1143-6-git-send-email-gleb@redhat.com> In-Reply-To: <1293030389-1143-1-git-send-email-gleb@redhat.com> References: <1293030389-1143-1-git-send-email-gleb@redhat.com> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.25 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]); Wed, 22 Dec 2010 15:06:53 +0000 (UTC) diff --git a/config-x86-common.mak b/config-x86-common.mak index 2269c4a..367c0be 100644 --- a/config-x86-common.mak +++ b/config-x86-common.mak @@ -11,7 +11,7 @@ cflatobjs += \ cflatobjs += lib/x86/fwcfg.o cflatobjs += lib/x86/apic.o cflatobjs += lib/x86/atomic.o -cflatobjs += lib/x86/idt.o +cflatobjs += lib/x86/desc.o $(libcflat): LDFLAGS += -nostdlib $(libcflat): CFLAGS += -ffreestanding -I lib diff --git a/lib/x86/desc.c b/lib/x86/desc.c new file mode 100644 index 0000000..25a25bc --- /dev/null +++ b/lib/x86/desc.c @@ -0,0 +1,159 @@ +#include "libcflat.h" +#include "desc.h" +#include "processor.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; +#ifdef __x86_64__ + unsigned offset2; + unsigned reserved; +#endif +} idt_entry_t; + +static idt_entry_t idt[256]; + +void load_lidt(idt_entry_t *idt, int nentries) +{ + struct descriptor_table_ptr dt; + + dt.limit = nentries * sizeof(*idt) - 1; + dt.base = (unsigned long)idt; + lidt(&dt); + asm volatile ("lidt %0" : : "m"(dt)); +} + +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(); + e->ist = 0; + e->type = 14; + 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; + 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); +} + +#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" + "push"W" $0 \n\t" + "push"W" $6 \n\t" + "jmp handle_exception \n\t" + + "gp_fault: \n\t" + "push"W" $13 \n\t" + "jmp handle_exception \n\t" + + "de_fault: \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" +#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 %"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" +#endif + "add $"S", %"R"sp \n\t" + "add $"S", %"R"sp \n\t" + "iret"W" \n\t" + ".popsection"); + + +void setup_idt(void) +{ + extern char ud_fault, gp_fault, de_fault; + + 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) +{ + 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; +} diff --git a/lib/x86/desc.h b/lib/x86/desc.h new file mode 100644 index 0000000..81b8944 --- /dev/null +++ b/lib/x86/desc.h @@ -0,0 +1,20 @@ +#ifndef __IDT_TEST__ +#define __IDT_TEST__ + +void setup_idt(void); + +#define ASM_TRY(catch) \ + "movl $0, %%gs:4 \n\t" \ + ".pushsection .data.ex \n\t" \ + ".quad 1111f, " catch "\n\t" \ + ".popsection \n\t" \ + "1111:" + +#define UD_VECTOR 6 +#define GP_VECTOR 13 + +unsigned exception_vector(void); +unsigned exception_error_code(void); +void set_idt_entry(int vec, void *addr, int dpl); + +#endif diff --git a/lib/x86/idt.c b/lib/x86/idt.c deleted file mode 100644 index b3e47d4..0000000 --- a/lib/x86/idt.c +++ /dev/null @@ -1,159 +0,0 @@ -#include "idt.h" -#include "libcflat.h" -#include "processor.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; -#ifdef __x86_64__ - unsigned offset2; - unsigned reserved; -#endif -} idt_entry_t; - -static idt_entry_t idt[256]; - -void load_lidt(idt_entry_t *idt, int nentries) -{ - struct descriptor_table_ptr dt; - - dt.limit = nentries * sizeof(*idt) - 1; - dt.base = (unsigned long)idt; - lidt(&dt); - asm volatile ("lidt %0" : : "m"(dt)); -} - -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(); - e->ist = 0; - e->type = 14; - 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; - 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); -} - -#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" - "push"W" $0 \n\t" - "push"W" $6 \n\t" - "jmp handle_exception \n\t" - - "gp_fault: \n\t" - "push"W" $13 \n\t" - "jmp handle_exception \n\t" - - "de_fault: \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" -#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 %"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" -#endif - "add $"S", %"R"sp \n\t" - "add $"S", %"R"sp \n\t" - "iret"W" \n\t" - ".popsection"); - - -void setup_idt(void) -{ - extern char ud_fault, gp_fault, de_fault; - - 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) -{ - 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; -} diff --git a/lib/x86/idt.h b/lib/x86/idt.h deleted file mode 100644 index 81b8944..0000000 --- a/lib/x86/idt.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef __IDT_TEST__ -#define __IDT_TEST__ - -void setup_idt(void); - -#define ASM_TRY(catch) \ - "movl $0, %%gs:4 \n\t" \ - ".pushsection .data.ex \n\t" \ - ".quad 1111f, " catch "\n\t" \ - ".popsection \n\t" \ - "1111:" - -#define UD_VECTOR 6 -#define GP_VECTOR 13 - -unsigned exception_vector(void); -unsigned exception_error_code(void); -void set_idt_entry(int vec, void *addr, int dpl); - -#endif diff --git a/x86/access.c b/x86/access.c index df943d9..120682d 100644 --- a/x86/access.c +++ b/x86/access.c @@ -1,6 +1,6 @@ #include "libcflat.h" -#include "idt.h" +#include "desc.h" #include "processor.h" #define smp_id() 0 diff --git a/x86/apic.c b/x86/apic.c index bcb9fc1..4f05b02 100644 --- a/x86/apic.c +++ b/x86/apic.c @@ -2,7 +2,7 @@ #include "apic.h" #include "vm.h" #include "smp.h" -#include "idt.h" +#include "desc.h" typedef struct { ulong regs[sizeof(ulong)*2]; diff --git a/x86/emulator.c b/x86/emulator.c index 845e7a0..0486d38 100644 --- a/x86/emulator.c +++ b/x86/emulator.c @@ -1,7 +1,7 @@ #include "ioram.h" #include "vm.h" #include "libcflat.h" -#include "idt.h" +#include "desc.h" #define memset __builtin_memset #define TESTDEV_IO_PORT 0xe0 diff --git a/x86/idt_test.c b/x86/idt_test.c index 59256d4..2d2e0c2 100644 --- a/x86/idt_test.c +++ b/x86/idt_test.c @@ -1,5 +1,5 @@ #include "libcflat.h" -#include "idt.h" +#include "desc.h" int test_ud2(void) { diff --git a/x86/xsave.c b/x86/xsave.c index a22b44c..057b0ff 100644 --- a/x86/xsave.c +++ b/x86/xsave.c @@ -1,5 +1,5 @@ #include "libcflat.h" -#include "idt.h" +#include "desc.h" #ifdef __x86_64__ #define uint64_t unsigned long