From: Aaron Lewis <aaronlewis@google.com>
To: kvm@vger.kernel.org
Cc: pbonzini@redhat.com, jmattson@google.com, seanjc@google.com,
Aaron Lewis <aaronlewis@google.com>
Subject: [kvm-unit-tests PATCH 09/14] x86: Move 32-bit GDT and TSS to desc.c
Date: Wed, 10 Nov 2021 21:19:56 +0000 [thread overview]
Message-ID: <20211110212001.3745914-10-aaronlewis@google.com> (raw)
In-Reply-To: <20211110212001.3745914-1-aaronlewis@google.com>
Move the GDT and TSS data structures from x86/cstart.S to
lib/x86/desc.c, for consistency with the 64-bit version.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
lib/x86/asm/setup.h | 2 +-
lib/x86/desc.c | 22 ++++++++--
lib/x86/desc.h | 2 +-
lib/x86/setup.c | 26 +++++++++++-
x86/cstart.S | 98 +++++++--------------------------------------
x86/cstart64.S | 1 +
x86/smap.c | 2 +-
x86/taskswitch.c | 2 +-
x86/umip.c | 2 +-
9 files changed, 63 insertions(+), 94 deletions(-)
diff --git a/lib/x86/asm/setup.h b/lib/x86/asm/setup.h
index e3c3bfb..4310132 100644
--- a/lib/x86/asm/setup.h
+++ b/lib/x86/asm/setup.h
@@ -1,6 +1,6 @@
#ifndef _X86_ASM_SETUP_H_
#define _X86_ASM_SETUP_H_
-unsigned long setup_tss(void);
+unsigned long setup_tss(u8 *stacktop);
#endif /* _X86_ASM_SETUP_H_ */
diff --git a/lib/x86/desc.c b/lib/x86/desc.c
index c185c01..16b7256 100644
--- a/lib/x86/desc.c
+++ b/lib/x86/desc.c
@@ -14,8 +14,22 @@ struct descriptor_table_ptr idt_descr = {
.base = (unsigned long)boot_idt,
};
-#ifdef __x86_64__
+#ifndef __x86_64__
/* GDT, TSS and descriptors */
+gdt_entry_t gdt[TSS_MAIN / 8 + MAX_TEST_CPUS * 2] = {
+ { 0, 0, 0, .type_limit_flags = 0x0000}, /* 0x00 null */
+ {0xffff, 0, 0, .type_limit_flags = 0xcf9b}, /* flat 32-bit code segment */
+ {0xffff, 0, 0, .type_limit_flags = 0xcf93}, /* flat 32-bit data segment */
+ {0xffff, 0, 0, .type_limit_flags = 0xcf1b}, /* flat 32-bit code segment, not present */
+ { 0, 0, 0, .type_limit_flags = 0x0000}, /* TSS for task gates */
+ {0xffff, 0, 0, .type_limit_flags = 0x8f9b}, /* 16-bit code segment */
+ {0xffff, 0, 0, .type_limit_flags = 0x8f93}, /* 16-bit data segment */
+ {0xffff, 0, 0, .type_limit_flags = 0xcffb}, /* 32-bit code segment (user) */
+ {0xffff, 0, 0, .type_limit_flags = 0xcff3}, /* 32-bit data segment (user) */
+};
+
+tss32_t tss[MAX_TEST_CPUS] = {0};
+#else
gdt_entry_t gdt[TSS_MAIN / 8 + MAX_TEST_CPUS * 2] = {
{ 0, 0, 0, .type_limit_flags = 0x0000}, /* 0x00 null */
{0xffff, 0, 0, .type_limit_flags = 0xaf9b}, /* 0x08 64-bit code segment */
@@ -30,12 +44,12 @@ gdt_entry_t gdt[TSS_MAIN / 8 + MAX_TEST_CPUS * 2] = {
};
tss64_t tss[MAX_TEST_CPUS] = {0};
+#endif
struct descriptor_table_ptr gdt_descr = {
.limit = sizeof(gdt) - 1,
.base = (unsigned long)gdt,
};
-#endif
#ifndef __x86_64__
__attribute__((regparm(1)))
@@ -365,7 +379,7 @@ void setup_tss32(void)
{
u16 desc_size = sizeof(tss32_t);
- tss.cr3 = read_cr3();
+ tss[0].cr3 = read_cr3();
tss_intr.cr3 = read_cr3();
tss_intr.ss0 = tss_intr.ss1 = tss_intr.ss2 = 0x10;
tss_intr.esp = tss_intr.esp0 = tss_intr.esp1 = tss_intr.esp2 =
@@ -401,7 +415,7 @@ void print_current_tss_info(void)
printf("Unknown TSS %x\n", tr);
else
printf("TR=%x (%s) Main TSS back link %x. Intr TSS back link %x\n",
- tr, tr ? "interrupt" : "main", tss.prev, tss_intr.prev);
+ tr, tr ? "interrupt" : "main", tss[0].prev, tss_intr.prev);
}
#else
void set_intr_alt_stack(int e, void *addr)
diff --git a/lib/x86/desc.h b/lib/x86/desc.h
index ddfae04..b65539e 100644
--- a/lib/x86/desc.h
+++ b/lib/x86/desc.h
@@ -197,7 +197,7 @@ struct system_desc64 {
extern idt_entry_t boot_idt[256];
#ifndef __x86_64__
-extern tss32_t tss;
+extern tss32_t tss[];
extern tss32_t tss_intr;
void set_gdt_task_gate(u16 tss_sel, u16 sel);
void set_idt_task_gate(int vec, u16 sel);
diff --git a/lib/x86/setup.c b/lib/x86/setup.c
index ec005b5..9c4393f 100644
--- a/lib/x86/setup.c
+++ b/lib/x86/setup.c
@@ -104,7 +104,7 @@ void find_highmem(void)
}
/* Setup TSS for the current processor, and return TSS offset within GDT */
-unsigned long setup_tss(void)
+unsigned long setup_tss(u8 *stacktop)
{
u32 id;
tss64_t *tss_entry;
@@ -122,6 +122,30 @@ unsigned long setup_tss(void)
return TSS_MAIN + id * 16;
}
+#else
+/* Setup TSS for the current processor, and return TSS offset within GDT */
+unsigned long setup_tss(u8 *stacktop)
+{
+ u32 id;
+ tss32_t *tss_entry;
+
+ id = apic_id();
+
+ /* Runtime address of current TSS */
+ tss_entry = &tss[id];
+
+ /* Update TSS */
+ memset((void *)tss_entry, 0, sizeof(tss32_t));
+ tss_entry->ss0 = KERNEL_DS;
+
+ /* Update descriptors for TSS and percpu data segment. */
+ set_gdt_entry(TSS_MAIN + id * 8,
+ (unsigned long)tss_entry, 0xffff, 0x89, 0);
+ set_gdt_entry(TSS_MAIN + MAX_TEST_CPUS * 8 + id * 8,
+ (unsigned long)stacktop - 4096, 0xfffff, 0x93, 0xc0);
+
+ return TSS_MAIN + id * 8;
+}
#endif
void setup_multiboot(struct mbi_bootinfo *bi)
diff --git a/x86/cstart.S b/x86/cstart.S
index e9100a4..2c0eec7 100644
--- a/x86/cstart.S
+++ b/x86/cstart.S
@@ -23,50 +23,6 @@ i = 0
i = i + 1
.endr
-.globl gdt
-gdt:
- .quad 0
- .quad 0x00cf9b000000ffff // flat 32-bit code segment
- .quad 0x00cf93000000ffff // flat 32-bit data segment
- .quad 0x00cf1b000000ffff // flat 32-bit code segment, not present
- .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
- .quad 0
- .quad 0
-
-tss_descr:
- .rept max_cpus
- .quad 0x000089000000ffff // 32-bit avail tss
- .endr
-percpu_descr:
- .rept max_cpus
- .quad 0x00cf93000000ffff // 32-bit data segment for perCPU area
- .endr
-gdt_end:
-
-i = 0
-.globl tss
-tss:
- .rept max_cpus
- .long 0
- .long 0
- .long 16
- .quad 0, 0
- .quad 0, 0, 0, 0, 0, 0, 0, 0
- .long 0, 0, 0
- i = i + 1
- .endr
-tss_end:
-
.section .init
.code32
@@ -78,21 +34,14 @@ mb_flags = 0x0
.long mb_magic, mb_flags, 0 - (mb_magic + mb_flags)
mb_cmdline = 16
-.macro setup_percpu_area
- lea -4096(%esp), %eax
-
- /* fill GS_BASE in the GDT, do not clobber %ebx (multiboot info) */
- mov (APIC_DEFAULT_PHYS_BASE + APIC_ID), %ecx
- shr $24, %ecx
- mov %ax, percpu_descr+2(,%ecx,8)
-
- shr $16, %eax
- mov %al, percpu_descr+4(,%ecx,8)
- mov %ah, percpu_descr+7(,%ecx,8)
-
- lea percpu_descr-gdt(,%ecx,8), %eax
+.macro setup_tr_and_percpu
+ lidt idt_descr
+ push %esp
+ call setup_tss
+ addl $4, %esp
+ ltr %ax
+ add $(max_cpus * 8), %ax
mov %ax, %gs
-
.endm
.macro setup_segments
@@ -109,7 +58,6 @@ start:
lgdtl gdt_descr
setup_segments
mov $stacktop, %esp
- setup_percpu_area
push %ebx
call setup_multiboot
@@ -147,11 +95,10 @@ ap_start32:
setup_segments
mov $-4096, %esp
lock xaddl %esp, smp_stacktop
- setup_percpu_area
+ setup_tr_and_percpu
call prepare_32
call reset_apic
call save_id
- call load_tss
call enable_apic
call enable_x2apic
sti
@@ -162,9 +109,9 @@ ap_start32:
jmp 1b
start32:
+ setup_tr_and_percpu
call reset_apic
call save_id
- call load_tss
call mask_pic_interrupts
call enable_apic
call ap_init
@@ -177,26 +124,9 @@ start32:
push %eax
call exit
-load_tss:
- lidt idt_descr
- mov $16, %eax
- mov %ax, %ss
- mov (APIC_DEFAULT_PHYS_BASE + APIC_ID), %eax
- shr $24, %eax
- mov %eax, %ebx
- mov $((tss_end - tss) / max_cpus), %edx
- imul %edx
- add $tss, %eax
- mov %ax, tss_descr+2(,%ebx,8)
- shr $16, %eax
- mov %al, tss_descr+4(,%ebx,8)
- mov %ah, tss_descr+7(,%ebx,8)
- lea tss_descr-gdt(,%ebx,8), %eax
- ltr %ax
- ret
-
ap_init:
cld
+ sgdtl ap_gdt_descr // must be close to sipi_entry for real mode access to work
lea sipi_entry, %esi
xor %edi, %edi
mov $(sipi_end - sipi_entry), %ecx
@@ -220,11 +150,11 @@ sipi_entry:
mov %cr0, %eax
or $1, %eax
mov %eax, %cr0
- lgdtl gdt_descr - sipi_entry
+ lgdtl ap_gdt_descr - sipi_entry
ljmpl $8, $ap_start32
-gdt_descr:
- .word gdt_end - gdt - 1
- .long gdt
+ap_gdt_descr:
+ .word 0
+ .long 0
sipi_end:
diff --git a/x86/cstart64.S b/x86/cstart64.S
index c6daa34..ddb83a0 100644
--- a/x86/cstart64.S
+++ b/x86/cstart64.S
@@ -68,6 +68,7 @@ MSR_GS_BASE = 0xc0000101
.macro load_tss
lidtq idt_descr
+ movq %rsp, %rdi
call setup_tss
ltr %ax
.endm
diff --git a/x86/smap.c b/x86/smap.c
index ac2c8d5..c6ddf38 100644
--- a/x86/smap.c
+++ b/x86/smap.c
@@ -20,7 +20,7 @@ void do_pf_tss(unsigned long error_code)
save = test;
#ifndef __x86_64__
- tss.eflags |= X86_EFLAGS_AC;
+ tss[0].eflags |= X86_EFLAGS_AC;
#endif
}
diff --git a/x86/taskswitch.c b/x86/taskswitch.c
index 1d6e6e2..0d31149 100644
--- a/x86/taskswitch.c
+++ b/x86/taskswitch.c
@@ -19,7 +19,7 @@ fault_handler(unsigned long error_code)
print_current_tss_info();
printf("error code %lx\n", error_code);
- tss.eip += 2;
+ tss[0].eip += 2;
gdt[TSS_MAIN / 8].type &= ~DESC_BUSY;
diff --git a/x86/umip.c b/x86/umip.c
index 0a52342..af8db59 100644
--- a/x86/umip.c
+++ b/x86/umip.c
@@ -161,7 +161,7 @@ static noinline int do_ring3(void (*fn)(const char *), const char *arg)
#ifdef __x86_64__
[sp0] "=m" (tss[0].rsp0)
#else
- [sp0] "=m" (tss.esp0)
+ [sp0] "=m" (tss[0].esp0)
#endif
: [user_ds] "i" (USER_DS),
[user_cs] "i" (USER_CS),
--
2.34.0.rc1.387.gb447b232ab-goog
next prev parent reply other threads:[~2021-11-10 21:20 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-10 21:19 [kvm-unit-tests PATCH 00/14] Run access test in an L2 guest Aaron Lewis
2021-11-10 21:19 ` [kvm-unit-tests PATCH 01/14] x86: cleanup handling of 16-byte GDT descriptors Aaron Lewis
2021-11-10 21:19 ` [kvm-unit-tests PATCH 02/14] x86: fix call to set_gdt_entry Aaron Lewis
2021-11-10 21:19 ` [kvm-unit-tests PATCH 03/14] unify field names and definitions for GDT descriptors Aaron Lewis
2021-11-10 21:19 ` [kvm-unit-tests PATCH 04/14] replace tss_descr global with a function Aaron Lewis
2021-11-10 21:19 ` [kvm-unit-tests PATCH 05/14] x86: Move IDT to desc.c Aaron Lewis
2021-11-10 21:19 ` [kvm-unit-tests PATCH 06/14] x86: unify name of 32-bit and 64-bit GDT Aaron Lewis
2021-11-10 21:19 ` [kvm-unit-tests PATCH 07/14] x86: get rid of ring0stacktop Aaron Lewis
2021-11-10 21:19 ` [kvm-unit-tests PATCH 08/14] x86: Move 64-bit GDT and TSS to desc.c Aaron Lewis
2021-11-10 21:19 ` Aaron Lewis [this message]
2021-11-10 21:19 ` [kvm-unit-tests PATCH 10/14] x86: Look up the PTEs rather than assuming them Aaron Lewis
2021-11-29 19:43 ` Babu Moger
2021-11-29 20:43 ` Sean Christopherson
2021-11-29 21:04 ` Babu Moger
2021-11-29 21:30 ` Babu Moger
2021-11-10 21:19 ` [kvm-unit-tests PATCH 11/14] x86: Prepare access test for running in L2 Aaron Lewis
2021-11-10 21:19 ` [kvm-unit-tests PATCH 12/14] x86: Fix tabs in access.c Aaron Lewis
2021-11-10 21:20 ` [kvm-unit-tests PATCH 13/14] x86: Clean up the global, page_table_levels, " Aaron Lewis
2021-11-10 21:20 ` [kvm-unit-tests PATCH 14/14] x86: Add tests that run ac_test_run() in an L2 guest Aaron Lewis
2021-11-11 17:51 ` [kvm-unit-tests PATCH 00/14] Run access test " Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20211110212001.3745914-10-aaronlewis@google.com \
--to=aaronlewis@google.com \
--cc=jmattson@google.com \
--cc=kvm@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=seanjc@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.