aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authorkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-08-28 13:23:40 +0000
committerkaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk>2003-08-28 13:23:40 +0000
commitd916b7f1fa0b74c9f1b358793949423c3a6ef844 (patch)
tree6d9ef0482253555fb4bbe6b650f806ef9cbdd0ef /xen
parentde0dff07cc4d4130b4bd28f4102bb9a62e2fc792 (diff)
downloadxen-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.S20
-rw-r--r--xen/arch/i386/mm.c13
-rw-r--r--xen/arch/i386/trampoline.S5
-rw-r--r--xen/include/asm-i386/desc.h18
-rw-r--r--xen/include/hypervisor-ifs/hypervisor-if.h28
-rw-r--r--xen/include/xeno/config.h4
-rw-r--r--xen/include/xeno/mm.h2
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__ */