summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2009-04-01 12:53:01 +0000
committerkib <kib@FreeBSD.org>2009-04-01 12:53:01 +0000
commitd2c67f9684a76233c58b569abc3a56c24f6a64db (patch)
treea85cf0bbb16ef5df509627582d65c573b28ebf49
parente81c32aa375c3dc4b0c34a23684314b46616d249 (diff)
downloadFreeBSD-src-d2c67f9684a76233c58b569abc3a56c24f6a64db.zip
FreeBSD-src-d2c67f9684a76233c58b569abc3a56c24f6a64db.tar.gz
Add separate gdt descriptors for %fs and %gs on amd64.
Reorder amd64 gdt descriptors so that user-accessible selectors are the same as on i386. At least Wine hard-codes this into the binary. In collaboration with: pho Reviewed by: jhb
-rw-r--r--sys/amd64/amd64/machdep.c71
-rw-r--r--sys/amd64/include/segments.h22
2 files changed, 69 insertions, 24 deletions
diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index f34e815..cd86789 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -826,7 +826,12 @@ CTASSERT(sizeof(struct nmi_pcpu) == 16);
struct amd64tss common_tss[MAXCPU];
-/* software prototypes -- in more palatable form */
+/*
+ * Software prototypes -- in more palatable form.
+ *
+ * Keep GUFS32, GUGS32, GUCODE32 and GUDATA at the same
+ * slots as corresponding segments for i386 kernel.
+ */
struct soft_segment_descriptor gdt_segs[] = {
/* GNULL_SEL 0 Null Descriptor */
{ .ssd_base = 0x0,
@@ -837,7 +842,34 @@ struct soft_segment_descriptor gdt_segs[] = {
.ssd_long = 0,
.ssd_def32 = 0,
.ssd_gran = 0 },
-/* GCODE_SEL 1 Code Descriptor for kernel */
+/* GNULL2_SEL 1 Null Descriptor */
+{ .ssd_base = 0x0,
+ .ssd_limit = 0x0,
+ .ssd_type = 0,
+ .ssd_dpl = 0,
+ .ssd_p = 0,
+ .ssd_long = 0,
+ .ssd_def32 = 0,
+ .ssd_gran = 0 },
+/* GUFS32_SEL 2 32 bit %gs Descriptor for user */
+{ .ssd_base = 0x0,
+ .ssd_limit = 0xfffff,
+ .ssd_type = SDT_MEMRWA,
+ .ssd_dpl = SEL_UPL,
+ .ssd_p = 1,
+ .ssd_long = 0,
+ .ssd_def32 = 1,
+ .ssd_gran = 1 },
+/* GUGS32_SEL 3 32 bit %fs Descriptor for user */
+{ .ssd_base = 0x0,
+ .ssd_limit = 0xfffff,
+ .ssd_type = SDT_MEMRWA,
+ .ssd_dpl = SEL_UPL,
+ .ssd_p = 1,
+ .ssd_long = 0,
+ .ssd_def32 = 1,
+ .ssd_gran = 1 },
+/* GCODE_SEL 4 Code Descriptor for kernel */
{ .ssd_base = 0x0,
.ssd_limit = 0xfffff,
.ssd_type = SDT_MEMERA,
@@ -846,7 +878,7 @@ struct soft_segment_descriptor gdt_segs[] = {
.ssd_long = 1,
.ssd_def32 = 0,
.ssd_gran = 1 },
-/* GDATA_SEL 2 Data Descriptor for kernel */
+/* GDATA_SEL 5 Data Descriptor for kernel */
{ .ssd_base = 0x0,
.ssd_limit = 0xfffff,
.ssd_type = SDT_MEMRWA,
@@ -855,7 +887,7 @@ struct soft_segment_descriptor gdt_segs[] = {
.ssd_long = 1,
.ssd_def32 = 0,
.ssd_gran = 1 },
-/* GUCODE32_SEL 3 32 bit Code Descriptor for user */
+/* GUCODE32_SEL 6 32 bit Code Descriptor for user */
{ .ssd_base = 0x0,
.ssd_limit = 0xfffff,
.ssd_type = SDT_MEMERA,
@@ -864,7 +896,7 @@ struct soft_segment_descriptor gdt_segs[] = {
.ssd_long = 0,
.ssd_def32 = 1,
.ssd_gran = 1 },
-/* GUDATA_SEL 4 32/64 bit Data Descriptor for user */
+/* GUDATA_SEL 7 32/64 bit Data Descriptor for user */
{ .ssd_base = 0x0,
.ssd_limit = 0xfffff,
.ssd_type = SDT_MEMRWA,
@@ -873,7 +905,7 @@ struct soft_segment_descriptor gdt_segs[] = {
.ssd_long = 0,
.ssd_def32 = 1,
.ssd_gran = 1 },
-/* GUCODE_SEL 5 64 bit Code Descriptor for user */
+/* GUCODE_SEL 8 64 bit Code Descriptor for user */
{ .ssd_base = 0x0,
.ssd_limit = 0xfffff,
.ssd_type = SDT_MEMERA,
@@ -882,9 +914,9 @@ struct soft_segment_descriptor gdt_segs[] = {
.ssd_long = 1,
.ssd_def32 = 0,
.ssd_gran = 1 },
-/* GPROC0_SEL 6 Proc 0 Tss Descriptor */
+/* GPROC0_SEL 9 Proc 0 Tss Descriptor */
{ .ssd_base = 0x0,
- .ssd_limit = sizeof(struct amd64tss)-1,
+ .ssd_limit = sizeof(struct amd64tss) + IOPAGES * PAGE_SIZE - 1,
.ssd_type = SDT_SYSTSS,
.ssd_dpl = SEL_KPL,
.ssd_p = 1,
@@ -900,15 +932,24 @@ struct soft_segment_descriptor gdt_segs[] = {
.ssd_long = 0,
.ssd_def32 = 0,
.ssd_gran = 0 },
-/* GUGS32_SEL 8 32 bit GS Descriptor for user */
+/* GUSERLDT_SEL 11 LDT Descriptor */
{ .ssd_base = 0x0,
- .ssd_limit = 0xfffff,
- .ssd_type = SDT_MEMRWA,
- .ssd_dpl = SEL_UPL,
- .ssd_p = 1,
+ .ssd_limit = 0x0,
+ .ssd_type = 0,
+ .ssd_dpl = 0,
+ .ssd_p = 0,
.ssd_long = 0,
- .ssd_def32 = 1,
- .ssd_gran = 1 },
+ .ssd_def32 = 0,
+ .ssd_gran = 0 },
+/* GUSERLDT_SEL 12 LDT Descriptor, double size */
+{ .ssd_base = 0x0,
+ .ssd_limit = 0x0,
+ .ssd_type = 0,
+ .ssd_dpl = 0,
+ .ssd_p = 0,
+ .ssd_long = 0,
+ .ssd_def32 = 0,
+ .ssd_gran = 0 },
};
void
diff --git a/sys/amd64/include/segments.h b/sys/amd64/include/segments.h
index 8ff3a0f..cab7554 100644
--- a/sys/amd64/include/segments.h
+++ b/sys/amd64/include/segments.h
@@ -212,15 +212,19 @@ struct region_descriptor {
* Entries in the Global Descriptor Table (GDT)
*/
#define GNULL_SEL 0 /* Null Descriptor */
-#define GCODE_SEL 1 /* Kernel Code Descriptor */
-#define GDATA_SEL 2 /* Kernel Data Descriptor */
-#define GUCODE32_SEL 3 /* User 32 bit code Descriptor */
-#define GUDATA_SEL 4 /* User 32/64 bit Data Descriptor */
-#define GUCODE_SEL 5 /* User 64 bit Code Descriptor */
-#define GPROC0_SEL 6 /* TSS for entering kernel etc */
-/* slot 7 is second half of GPROC0_SEL */
-#define GUGS32_SEL 8 /* User 32 bit GS Descriptor */
-#define NGDT 9
+#define GNULL2_SEL 1 /* Null Descriptor */
+#define GUFS32_SEL 2 /* User 32 bit %fs Descriptor */
+#define GUGS32_SEL 3 /* User 32 bit %gs Descriptor */
+#define GCODE_SEL 4 /* Kernel Code Descriptor */
+#define GDATA_SEL 5 /* Kernel Data Descriptor */
+#define GUCODE32_SEL 6 /* User 32 bit code Descriptor */
+#define GUDATA_SEL 7 /* User 32/64 bit Data Descriptor */
+#define GUCODE_SEL 8 /* User 64 bit Code Descriptor */
+#define GPROC0_SEL 9 /* TSS for entering kernel etc */
+/* slot 10 is second half of GPROC0_SEL */
+#define GUSERLDT_SEL 11 /* LDT */
+/* slot 11 is second half of GUSERLDT_SEL */
+#define NGDT 13
#ifdef _KERNEL
extern struct user_segment_descriptor gdt[];
OpenPOWER on IntegriCloud