[PATCH kvm-unit-tests 03/18] x86: desc: change set_gdt_entry argument to selector

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

 



This interface, already used in taskswitch.c, is a bit easier to use.

Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx>
---
 lib/x86/desc.c    | 20 +++++++++++---------
 lib/x86/desc.h    |  8 +++++---
 x86/taskswitch2.c | 15 +++++++--------
 3 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/lib/x86/desc.c b/lib/x86/desc.c
index ac60686..b8b5452 100644
--- a/lib/x86/desc.c
+++ b/lib/x86/desc.c
@@ -228,10 +228,11 @@ unsigned exception_error_code(void)
  */
 
 static gdt_entry_t gdt[10];
-#define TSS_GDT_OFFSET 4
 
-void set_gdt_entry(int num, u32 base,  u32 limit, u8 access, u8 gran)
+void set_gdt_entry(int sel, u32 base,  u32 limit, u8 access, u8 gran)
 {
+	int num = sel >> 3;
+
 	/* Setup the descriptor base address */
 	gdt[num].base_low = (base & 0xFFFF);
 	gdt[num].base_middle = (base >> 16) & 0xFF;
@@ -261,15 +262,15 @@ void setup_gdt(void)
 	/* The second entry is our Code Segment. The base address
 	 *  is 0, the limit is 4GBytes, it uses 4KByte granularity,
 	 *  uses 32-bit opcodes, and is a Code Segment descriptor. */
-	set_gdt_entry(1, 0, 0xFFFFFFFF, 0x9A, 0xcf);
+	set_gdt_entry(KERNEL_CS, 0, 0xFFFFFFFF, 0x9A, 0xcf);
 
 	/* The third entry is our Data Segment. It's EXACTLY the
 	 *  same as our code segment, but the descriptor type in
 	 *  this entry's access byte says it's a Data Segment */
-	set_gdt_entry(2, 0, 0xFFFFFFFF, 0x92, 0xcf);
+	set_gdt_entry(KERNEL_DS, 0, 0xFFFFFFFF, 0x92, 0xcf);
 
 	/* Same as code register above but not present */
-	set_gdt_entry(3, 0, 0xFFFFFFFF, 0x1A, 0xcf);
+	set_gdt_entry(NP_SEL, 0, 0xFFFFFFFF, 0x1A, 0xcf);
 
 
 	/* Flush out the old GDT and install the new changes! */
@@ -280,7 +281,7 @@ void setup_gdt(void)
 		      "mov %0, %%fs\n\t"
 		      "mov %0, %%gs\n\t"
 		      "mov %0, %%ss\n\t"
-		      "jmp $0x08, $.Lflush2\n\t"
+		      "jmp $" xstr(KERNEL_CS), $.Lflush2\n\t"
 		      ".Lflush2: "::"r"(0x10));
 }
 
@@ -315,10 +316,11 @@ void setup_tss32(void)
 		tss[i].ss0 = tss[i].ss1 = tss[i].ss2 = 0x10;
 		tss[i].esp = tss[i].esp0 = tss[i].esp1 = tss[i].esp2 =
 			(u32)tss_stack[i] + 4096;
-		tss[i].cs = 0x08;
-		tss[i].ds = tss[i].es = tss[i].fs = tss[i].gs = tss[i].ss = 0x10;
+		tss[i].cs = KERNEL_CS;
+		tss[i].ds = tss[i].es = tss[i].fs = tss[i].gs =
+			tss[i].ss = KERNEL_DS;
 		tss[i].iomap_base = (u16)desc_size;
-		set_gdt_entry(TSS_GDT_OFFSET + i, (u32)&tss[i],
+		set_gdt_entry(TSS_MAIN + (i << 3), (u32)&tss[i],
 			     desc_size - 1, 0x89, 0x0f);
 	}
 
diff --git a/lib/x86/desc.h b/lib/x86/desc.h
index b795aad..e3f1ea0 100644
--- a/lib/x86/desc.h
+++ b/lib/x86/desc.h
@@ -71,16 +71,18 @@ typedef struct {
 #define UD_VECTOR   6
 #define GP_VECTOR   13
 
+#define KERNEL_CS 0x08
+#define KERNEL_DS 0x10
+#define NP_SEL 0x18
 #define TSS_MAIN 0x20
 #define TSS_INTR 0x28
-
-#define NP_SEL 0x18
+#define FIRST_SPARE_SEL 0x30
 
 unsigned exception_vector(void);
 unsigned exception_error_code(void);
 void set_idt_entry(int vec, void *addr, int dpl);
 void set_idt_sel(int vec, u16 sel);
-void set_gdt_entry(int num, u32 base,  u32 limit, u8 access, u8 gran);
+void set_gdt_entry(int sel, u32 base,  u32 limit, u8 access, u8 gran);
 void set_idt_task_gate(int vec, u16 sel);
 void set_intr_task_gate(int e, void *fn);
 void print_current_tss_info(void);
diff --git a/x86/taskswitch2.c b/x86/taskswitch2.c
index 08bcce9..de7e969 100644
--- a/x86/taskswitch2.c
+++ b/x86/taskswitch2.c
@@ -5,9 +5,8 @@
 #include "processor.h"
 #include "vm.h"
 
-#define FREE_GDT_INDEX 6
-#define MAIN_TSS_INDEX (FREE_GDT_INDEX + 0)
-#define VM86_TSS_INDEX (FREE_GDT_INDEX + 1)
+#define MAIN_TSS_SEL (FIRST_SPARE_SEL + 0)
+#define VM86_TSS_SEL (FIRST_SPARE_SEL + 8)
 
 static volatile int test_count;
 static volatile unsigned int test_divider;
@@ -217,15 +216,15 @@ void test_vm86_switch(void)
     vm86_start[1] = 0x0b;
 
     /* Main TSS */
-    set_gdt_entry(MAIN_TSS_INDEX, (u32)&main_tss, sizeof(tss32_t) - 1, 0x89, 0);
-    ltr(MAIN_TSS_INDEX << 3);
+    set_gdt_entry(MAIN_TSS_SEL, (u32)&main_tss, sizeof(tss32_t) - 1, 0x89, 0);
+    ltr(MAIN_TSS_SEL);
     main_tss = (tss32_t) {
-        .prev   = VM86_TSS_INDEX << 3,
+        .prev   = VM86_TSS_SEL,
         .cr3    = read_cr3(),
     };
 
     /* VM86 TSS (marked as busy, so we can iret to it) */
-    set_gdt_entry(VM86_TSS_INDEX, (u32)&vm86_tss, sizeof(tss32_t) - 1, 0x8b, 0);
+    set_gdt_entry(VM86_TSS_SEL, (u32)&vm86_tss, sizeof(tss32_t) - 1, 0x8b, 0);
     vm86_tss = (tss32_t) {
         .eflags = 0x20002,
         .cr3    = read_cr3(),
@@ -236,7 +235,7 @@ void test_vm86_switch(void)
     };
 
     /* Setup task gate to main TSS for #UD */
-    set_idt_task_gate(6, MAIN_TSS_INDEX << 3);
+    set_idt_task_gate(6, MAIN_TSS_SEL);
 
     /* Jump into VM86 task with iret, #UD lets it come back immediately */
     printf("Switch to VM86 task and back\n");
-- 
1.8.3.1


--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[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