[PATCH kvm-unit-tests] x86: clean up GDTs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



- Add a 16-bit code and data segment to cstart.S.
- Move ring 3 segment descriptors at the end of the GDT, and lay them out
  as required by syscall/sysret in cstart64.S.
- Only define TSS_INTR for 32-bit, and place it where cstart64.S puts the
  32-bit ring 0 segment.
- Document that the same data segment can be used for 32 and 64-bit code.
- Mark all descriptors as accessed.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 lib/x86/desc.c | 13 -------------
 lib/x86/desc.h | 59 ++++++++++++++++++++++++++++++++++++++++++++++------------
 x86/cstart.S   | 16 ++++++++--------
 x86/cstart64.S | 12 ++++++------
 4 files changed, 61 insertions(+), 39 deletions(-)

diff --git a/lib/x86/desc.c b/lib/x86/desc.c
index 4747b32..6144a3d 100644
--- a/lib/x86/desc.c
+++ b/lib/x86/desc.c
@@ -262,19 +262,6 @@ bool exception_rflags_rf(void)
 static char intr_alt_stack[4096];
 
 #ifndef __x86_64__
-/*
- * GDT, with 6 entries:
- * 0x00 - NULL descriptor
- * 0x08 - Code segment (ring 0)
- * 0x10 - Data segment (ring 0)
- * 0x18 - Not present code segment (ring 0)
- * 0x20 - Code segment (ring 3)
- * 0x28 - Data segment (ring 3)
- * 0x30 - Interrupt task
- * 0x38 to 0x78 - Free to use for test cases
- * 0x80 - Primary task (CPU 0)
- */
-
 void set_gdt_entry(int sel, u32 base,  u32 limit, u8 access, u8 gran)
 {
 	int num = sel >> 3;
diff --git a/lib/x86/desc.h b/lib/x86/desc.h
index be52fd4..e7edb4f 100644
--- a/lib/x86/desc.h
+++ b/lib/x86/desc.h
@@ -85,24 +85,59 @@ typedef struct  __attribute__((packed)) {
 #define UD_VECTOR   6
 #define GP_VECTOR   13
 
-#define KERNEL_CS 0x08
-#define KERNEL_DS 0x10
-#define NP_SEL 0x18
-#define USER_CS 0x23
-#define USER_DS 0x2b
+/*
+ * selector     32-bit                        64-bit
+ * 0x00         NULL descriptor               NULL descriptor
+ * 0x08         ring-0 code segment (32-bit)  ring-0 code segment (64-bit)
+ * 0x10         ring-0 data segment (32-bit)  ring-0 data segment (32/64-bit)
+ * 0x18         ring-0 code segment (P=0)     ring-0 code segment (64-bit, P=0)
+ * 0x20         intr_alt_stack TSS            ring-0 code segment (32-bit)
+ * 0x28         ring-0 code segment (16-bit)  same
+ * 0x30         ring-0 data segment (16-bit)  same
+ * 0x38 (0x3b)  ring-3 code segment (32-bit)  same
+ * 0x40 (0x43)  ring-3 data segment (32-bit)  ring-3 data segment (32/64-bit)
+ * 0x48 (0x4b)  **unused**                    ring-3 code segment (64-bit)
+ * 0x50--0x78   free to use for test cases    same
+ * 0x80         primary TSS (CPU 0)           same
+ *
+ * Note that the same segment can be used for 32-bit and 64-bit data segments
+ * (the L bit is only defined for code segments)
+ *
+ * Selectors 0x08-0x10 and 0x3b-0x4b are set up for use with the SYSCALL
+ * and SYSRET instructions.
+ */
+
+#define KERNEL_CS   0x08
+#define KERNEL_DS   0x10
+#define NP_SEL      0x18
+#ifdef __x86_64__
+#define KERNEL_CS32 0x20
+#else
+#define TSS_INTR    0x20
+#endif
+#define KERNEL_CS16 0x28
+#define KERNEL_DS16 0x30
+#define USER_CS32   0x3b
+#define USER_DS     0x43
+#ifdef __x86_64__
+#define USER_CS64   0x4b
+#endif
+
+/* Synonyms */
+#define KERNEL_DS32 KERNEL_DS
+#define USER_DS32   USER_DS
+
 #ifdef __x86_64__
 #define KERNEL_CS64 KERNEL_CS
+#define USER_CS     USER_CS64
 #define KERNEL_DS64 KERNEL_DS
-#define KERNEL_CS32 0x30
-#define KERNEL_DS32 0x38
-#define KERNEL_CS16 0x40
-#define KERNEL_DS16 0x48
+#define USER_DS64   USER_DS
 #else
 #define KERNEL_CS32 KERNEL_CS
-#define KERNEL_DS32 KERNEL_DS
+#define USER_CS     USER_CS32
 #endif
-#define TSS_INTR 0x50
-#define FIRST_SPARE_SEL 0x58
+
+#define FIRST_SPARE_SEL 0x50
 #define TSS_MAIN 0x80
 
 typedef struct {
diff --git a/x86/cstart.S b/x86/cstart.S
index 69b5c33..a3c26a4 100644
--- a/x86/cstart.S
+++ b/x86/cstart.S
@@ -34,14 +34,14 @@ gdt32:
 	.quad 0x00cf9b000000ffff // flat 32-bit code segment
 	.quad 0x00cf93000000ffff // flat 32-bit data segment
 	.quad 0x00cf1b000000ffff // flat 32-bit code segment, not present
-	.quad 0x00cffb000000ffff // 64-bit code segment (user)
-	.quad 0x00cff3000000ffff // 64-bit data segment (user)
-
-	.quad 0			 // 10 spare selectors
-	.quad 0
-	.quad 0
-	.quad 0
-	.quad 0
+	.quad 0                  // TSS for task gates
+	.quad 0x008f9b000000FFFF // 16-bit code segment
+	.quad 0x008f93000000FFFF // 16-bit data segment
+	.quad 0x00cffb000000ffff // 32-bit code segment (user)
+	.quad 0x00cff3000000ffff // 32-bit data segment (user)
+	.quad 0                  // unused
+
+	.quad 0			 // 6 spare selectors
 	.quad 0
 	.quad 0
 	.quad 0
diff --git a/x86/cstart64.S b/x86/cstart64.S
index 004c014..4c26fb2 100644
--- a/x86/cstart64.S
+++ b/x86/cstart64.S
@@ -53,14 +53,14 @@ gdt64_desc:
 gdt64:
 	.quad 0
 	.quad 0x00af9b000000ffff // 64-bit code segment
-	.quad 0x00cf93000000ffff // 64-bit data segment
+	.quad 0x00cf93000000ffff // 32/64-bit data segment
 	.quad 0x00af1b000000ffff // 64-bit code segment, not present
-	.quad 0x00affb000000ffff // 64-bit code segment (user)
-	.quad 0x00cff3000000ffff // 64-bit data segment (user)
 	.quad 0x00cf9b000000ffff // 32-bit code segment
-	.quad 0x00cf92000000ffff // 32-bit data segment
-	.quad 0x008F9A000000FFFF // 16-bit code segment
-	.quad 0x008F92000000FFFF // 16-bit data segment
+	.quad 0x008f9b000000FFFF // 16-bit code segment
+	.quad 0x008f93000000FFFF // 16-bit data segment
+	.quad 0x00cffb000000ffff // 32-bit code segment (user)
+	.quad 0x00cff3000000ffff // 32/64-bit data segment (user)
+	.quad 0x00affb000000ffff // 64-bit code segment (user)
 
 	.quad 0			 // 6 spare selectors
 	.quad 0
-- 
2.13.0




[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux