diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-08-28 13:23:40 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-08-28 13:23:40 +0000 |
commit | d916b7f1fa0b74c9f1b358793949423c3a6ef844 (patch) | |
tree | 6d9ef0482253555fb4bbe6b650f806ef9cbdd0ef /xen | |
parent | de0dff07cc4d4130b4bd28f4102bb9a62e2fc792 (diff) | |
download | xen-d916b7f1fa0b74c9f1b358793949423c3a6ef844.tar.gz xen-d916b7f1fa0b74c9f1b358793949423c3a6ef844.tar.bz2 xen-d916b7f1fa0b74c9f1b358793949423c3a6ef844.zip |
bitkeeper revision 1.397 (3f4e025cTStPJGtnPMTvJ95GFn4NAg)
mm.h, config.h, hypervisor-if.h, desc.h, trampoline.S, mm.c, boot.S:
Move reserved GDT entries to later in the GDT, allowing support for hard-coded small selector values in brain-dead OSes.
Diffstat (limited to 'xen')
-rw-r--r-- | xen/arch/i386/boot/boot.S | 20 | ||||
-rw-r--r-- | xen/arch/i386/mm.c | 13 | ||||
-rw-r--r-- | xen/arch/i386/trampoline.S | 5 | ||||
-rw-r--r-- | xen/include/asm-i386/desc.h | 18 | ||||
-rw-r--r-- | xen/include/hypervisor-ifs/hypervisor-if.h | 28 | ||||
-rw-r--r-- | xen/include/xeno/config.h | 4 | ||||
-rw-r--r-- | xen/include/xeno/mm.h | 2 |
7 files changed, 56 insertions, 34 deletions
diff --git a/xen/arch/i386/boot/boot.S b/xen/arch/i386/boot/boot.S index 64658d6aa8..b27ff6c0f2 100644 --- a/xen/arch/i386/boot/boot.S +++ b/xen/arch/i386/boot/boot.S @@ -1,4 +1,5 @@ #include <xeno/config.h> +#include <hypervisor-ifs/hypervisor-if.h> #include <asm/page.h> #define SECONDARY_CPU_FLAG 0xA5A5A5A5 @@ -229,26 +230,27 @@ SYMBOL_NAME(idt): .word 0 gdt_descr: - .word (2*NR_CPUS+8)*8-1 + .word (LAST_RESERVED_GDT_ENTRY*8)+7 SYMBOL_NAME(gdt): .long SYMBOL_NAME(gdt_table) /* gdt base */ .word 0 nopaging_gdt_descr: - .word (2*NR_CPUS+8)*8-1 + .word (LAST_RESERVED_GDT_ENTRY*8)+7 .long SYMBOL_NAME(gdt_table)-__PAGE_OFFSET ALIGN /* NB. Rings != 0 get access up to 0xFC400000. This allows access to the */ /* machine->physical mapping table. Ring 0 can access all memory. */ ENTRY(gdt_table) - .quad 0x0000000000000000 /* 0x0000 NULL descriptor */ - .quad 0x00cf9a000000ffff /* 0x0008 ring 0 4.00GB code at 0x0 */ - .quad 0x00cf92000000ffff /* 0x0010 ring 0 4.00GB data at 0x0 */ - .quad 0x00cfba000000c3ff /* 0x0019 ring 1 3.95GB code at 0x0 */ - .quad 0x00cfb2000000c3ff /* 0x0021 ring 1 3.95GB data at 0x0 */ - .quad 0x00cffa000000c3ff /* 0x002b ring 3 3.95GB code at 0x0 */ - .quad 0x00cff2000000c3ff /* 0x0033 ring 3 3.95GB data at 0x0 */ + .fill FIRST_RESERVED_GDT_ENTRY,8,0 + .quad 0x0000000000000000 /* unused */ + .quad 0x00cf9a000000ffff /* 0x0808 ring 0 4.00GB code at 0x0 */ + .quad 0x00cf92000000ffff /* 0x0810 ring 0 4.00GB data at 0x0 */ + .quad 0x00cfba000000c3ff /* 0x0819 ring 1 3.95GB code at 0x0 */ + .quad 0x00cfb2000000c3ff /* 0x0821 ring 1 3.95GB data at 0x0 */ + .quad 0x00cffa000000c3ff /* 0x082b ring 3 3.95GB code at 0x0 */ + .quad 0x00cff2000000c3ff /* 0x0833 ring 3 3.95GB data at 0x0 */ .quad 0x0000000000000000 /* unused */ .fill 2*NR_CPUS,8,0 /* space for TSS and LDT per CPU */ diff --git a/xen/arch/i386/mm.c b/xen/arch/i386/mm.c index b32650c614..2ccb1bda1f 100644 --- a/xen/arch/i386/mm.c +++ b/xen/arch/i386/mm.c @@ -188,7 +188,7 @@ long do_set_gdt(unsigned long *frame_list, unsigned int entries) long ret = -EINVAL; struct pfn_info *page; - if ( (entries < FIRST_DOMAIN_GDT_ENTRY) || (entries > 8192) ) + if ( (entries <= LAST_RESERVED_GDT_ENTRY) || (entries > 8192) ) return -EINVAL; if ( copy_from_user(frames, frame_list, nr_pages * sizeof(unsigned long)) ) @@ -249,8 +249,10 @@ long do_set_gdt(unsigned long *frame_list, unsigned int entries) local_flush_tlb(); - /* Copy over first entries of the new GDT. */ - memcpy((void *)GDT_VIRT_START, gdt_table, FIRST_DOMAIN_GDT_ENTRY*8); + /* Copy reserved GDT entries to the new GDT. */ + memcpy((struct desc_struct *)GDT_VIRT_START + FIRST_RESERVED_GDT_ENTRY, + gdt_table + FIRST_RESERVED_GDT_ENTRY, + NR_RESERVED_GDT_ENTRIES*8); SET_GDT_ADDRESS(current, GDT_VIRT_START); SET_GDT_ENTRIES(current, (entries*8)-1); @@ -284,9 +286,10 @@ long do_update_descriptor( switch ( (page->flags & PG_type_mask) ) { case PGT_gdt_page: - /* Disallow updates of Xen-private descriptors in the current GDT. */ + /* Disallow updates of Xen-reserved descriptors in the current GDT. */ if ( (l1_pgentry_to_pagenr(current->mm.perdomain_pt[0]) == pfn) && - (((pa&(PAGE_SIZE-1))>>3) < FIRST_DOMAIN_GDT_ENTRY) ) + (((pa&(PAGE_SIZE-1))>>3) >= FIRST_RESERVED_GDT_ENTRY) && + (((pa&(PAGE_SIZE-1))>>3) <= LAST_RESERVED_GDT_ENTRY) ) goto out; case PGT_ldt_page: case PGT_writeable_page: diff --git a/xen/arch/i386/trampoline.S b/xen/arch/i386/trampoline.S index 79f58d746c..9fdea7d679 100644 --- a/xen/arch/i386/trampoline.S +++ b/xen/arch/i386/trampoline.S @@ -16,6 +16,7 @@ */ #include <xeno/config.h> +#include <hypervisor-ifs/hypervisor-if.h> #include <asm/page.h> #ifdef CONFIG_SMP @@ -49,8 +50,8 @@ idt_48: .word 0, 0 # idt base = 0L gdt_48: - .word 0x0800 # gdt limit = 2048, 256 GDT entries - .long gdt_table-__PAGE_OFFSET # gdt base = gdt (first SMP CPU) + .word (LAST_RESERVED_GDT_ENTRY*8)+7 + .long gdt_table-__PAGE_OFFSET .globl SYMBOL_NAME(trampoline_end) SYMBOL_NAME_LABEL(trampoline_end) diff --git a/xen/include/asm-i386/desc.h b/xen/include/asm-i386/desc.h index 3155af3268..facb3a6452 100644 --- a/xen/include/asm-i386/desc.h +++ b/xen/include/asm-i386/desc.h @@ -3,8 +3,8 @@ #define LDT_ENTRY_SIZE 8 -#define __FIRST_TSS_ENTRY 8 -#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY+1) +#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) +#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1) #define __TSS(n) (((n)<<1) + __FIRST_TSS_ENTRY) #define __LDT(n) (((n)<<1) + __FIRST_LDT_ENTRY) @@ -14,15 +14,19 @@ /* * Guest OS must provide its own code selectors, or use the one we provide. * The RPL must be 1, as we only create bounce frames to ring 1. + * Any LDT selector value is okay. */ -#define VALID_CODESEL(_s) \ - (((((_s)>>2) >= FIRST_DOMAIN_GDT_ENTRY) || ((_s) == FLAT_RING1_CS)) && \ - (((_s)&3) == 1)) -#define VALID_DATASEL(_s) \ - (((((_s)>>2) >= FIRST_DOMAIN_GDT_ENTRY) || ((_s) == FLAT_RING1_DS)) && \ +#define VALID_SEL(_s) \ + (((((_s)>>3) < FIRST_RESERVED_GDT_ENTRY) || \ + (((_s)>>3) > LAST_RESERVED_GDT_ENTRY) || \ + ((_s)&4)) && \ (((_s)&3) == 1)) +#define VALID_CODESEL(_s) ((_s) == FLAT_RING1_CS || VALID_SEL(_s)) + +#define VALID_DATASEL(_s) ((_s) == FLAT_RING1_DS || VALID_SEL(_s)) + /* These are bitmasks for the first 32 bits of a descriptor table entry. */ #define _SEGMENT_TYPE (15<< 8) #define _SEGMENT_S ( 1<<12) /* System descriptor (yes iff S==0) */ diff --git a/xen/include/hypervisor-ifs/hypervisor-if.h b/xen/include/hypervisor-ifs/hypervisor-if.h index 64c5bc040a..97eebaa014 100644 --- a/xen/include/hypervisor-ifs/hypervisor-if.h +++ b/xen/include/hypervisor-ifs/hypervisor-if.h @@ -10,17 +10,29 @@ /* * SEGMENT DESCRIPTOR TABLES */ -/* The first few GDT entries are reserved by Xen. */ -#define FIRST_DOMAIN_GDT_ENTRY 40 /* - * These flat segments are in the Xen-private section of every GDT. Since - * these are also present in the initial GDT, many OSes will be able to avoid + * A number of GDT entries are reserved by Xen. These are not situated at the + * start of the GDT because some stupid OSes export hard-coded selector values + * in their ABI. These hard-coded values are always near the start of the GDT, + * so Xen places itself out of the way. + * + * NB. The reserved range is inclusive (that is, both FIRST_RESERVED_GDT_ENTRY + * and LAST_RESERVED_GDT_ENTRY are reserved). + */ +#define NR_RESERVED_GDT_ENTRIES 40 +#define FIRST_RESERVED_GDT_ENTRY 256 +#define LAST_RESERVED_GDT_ENTRY \ + (FIRST_RESERVED_GDT_ENTRY + NR_RESERVED_GDT_ENTRIES - 1) + +/* + * These flat segments are in the Xen-private section of every GDT. Since these + * are also present in the initial GDT, many OSes will be able to avoid * installing their own GDT. */ -#define FLAT_RING1_CS 0x0019 -#define FLAT_RING1_DS 0x0021 -#define FLAT_RING3_CS 0x002b -#define FLAT_RING3_DS 0x0033 +#define FLAT_RING1_CS 0x0819 +#define FLAT_RING1_DS 0x0821 +#define FLAT_RING3_CS 0x082b +#define FLAT_RING3_DS 0x0833 /* diff --git a/xen/include/xeno/config.h b/xen/include/xeno/config.h index f1bc4c2000..b4935f706f 100644 --- a/xen/include/xeno/config.h +++ b/xen/include/xeno/config.h @@ -127,8 +127,8 @@ #define barrier() __asm__ __volatile__("": : :"memory") -#define __HYPERVISOR_CS 0x0008 -#define __HYPERVISOR_DS 0x0010 +#define __HYPERVISOR_CS 0x0808 +#define __HYPERVISOR_DS 0x0810 #define NR_syscalls 256 diff --git a/xen/include/xeno/mm.h b/xen/include/xeno/mm.h index 6f7eaa89b7..2570cfafec 100644 --- a/xen/include/xeno/mm.h +++ b/xen/include/xeno/mm.h @@ -149,7 +149,7 @@ int check_descriptor(unsigned long a, unsigned long b); /* Part of the domain API. */ int do_process_page_updates(page_update_request_t *updates, int count); -#define DEFAULT_GDT_ENTRIES ((FIRST_DOMAIN_GDT_ENTRY*8)-1) +#define DEFAULT_GDT_ENTRIES ((LAST_RESERVED_GDT_ENTRY*8)+7) #define DEFAULT_GDT_ADDRESS ((unsigned long)gdt_table) #endif /* __XENO_MM_H__ */ |