Commit 67961d18 authored by Paolo Bonzini's avatar Paolo Bonzini
Browse files

x86: desc: change set_gdt_entry argument to selector



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

Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent a3d1fb55
......@@ -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);
}
......
......@@ -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);
......
......@@ -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");
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment