Skip to content

Commit ae359e8

Browse files
authored
Fix kernel pointer offset used by SYSCALL instruction (#90)
This PR fixes an issue introduced by #83 where the trap code for system calls that use the `SYSCALL` instruction do not use the correct offset in the per-CPU data structure when it retrieves the kernel stack pointer. This was caused by a change to the `percpu_t` structure that wasn't reflected in the offset the assembly language code uses.
1 parent 17dd38e commit ae359e8

File tree

6 files changed

+92
-9
lines changed

6 files changed

+92
-9
lines changed

include/kernel/infrastructure/i686/asm/descriptors.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@
6464
#define GDT_USER_TLS_DATA 7
6565

6666
/** number of descriptors in GDT */
67-
#define GDT_LENGTH 8
67+
#define GDT_NUM_ENTRIES 8
6868

6969
/** offset of descriptor type in descriptor */
7070
#define SEG_FLAGS_OFFSET 40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*
2+
* Copyright (C) 2024 Philippe Aubertin.
3+
* All rights reserved.
4+
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* 3. Neither the name of the author nor the names of other contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
21+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
24+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_PERCPU_H
33+
#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_PERCPU_H
34+
35+
#include <kernel/infrastructure/i686/asm/descriptors.h>
36+
37+
/* The PERCPU_OFFSET_... definitions here must match the offsets in the
38+
* percpu_t struct. They are used by assembly language code that can't use the
39+
* struct definition. */
40+
41+
#define PERCPU_OFFSET_GDT 8
42+
43+
#define PERCPU_OFFSET_TSS (PERCPU_OFFSET_GDT + 8 * GDT_NUM_ENTRIES)
44+
45+
#endif
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
/*
2+
* Copyright (C) 2024 Philippe Aubertin.
3+
* All rights reserved.
4+
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions
7+
* are met:
8+
*
9+
* 1. Redistributions of source code must retain the above copyright
10+
* notice, this list of conditions and the following disclaimer.
11+
*
12+
* 2. Redistributions in binary form must reproduce the above copyright
13+
* notice, this list of conditions and the following disclaimer in the
14+
* documentation and/or other materials provided with the distribution.
15+
*
16+
* 3. Neither the name of the author nor the names of other contributors
17+
* may be used to endorse or promote products derived from this software
18+
* without specific prior written permission.
19+
*
20+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
21+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23+
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
24+
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25+
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26+
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27+
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_TSS_H
33+
#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_TSS_H
34+
35+
#define TSS_OFFSET_ESP0 4
36+
37+
#endif

include/kernel/infrastructure/i686/types.h

+3-4
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,11 @@ typedef struct {
111111
} tss_t;
112112

113113
struct percpu_t {
114+
/* Assembly language code accesses members in this structure. Make sure to
115+
* update the PERCPU_OFFSET_... definitions when you change its layout. */
114116
struct percpu_t *self;
115117
addr_space_t *current_addr_space;
116-
seg_descriptor_t gdt[GDT_LENGTH];
117-
/* The assembly-language system call entry point for the SYSCALL instruction
118-
* (fast_amd_entry in trap.asm) makes assumptions regarding the location of
119-
* the TSS within this structure. */
118+
seg_descriptor_t gdt[GDT_NUM_ENTRIES];
120119
tss_t tss;
121120
};
122121

kernel/infrastructure/i686/init.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ static void load_selectors(percpu_t *cpu_data, boot_alloc_t *boot_alloc) {
164164

165165
/* load new GDT and TSS */
166166
pseudo->addr = (addr_t)&cpu_data->gdt;
167-
pseudo->limit = GDT_LENGTH * 8 - 1;
167+
pseudo->limit = GDT_NUM_ENTRIES * 8 - 1;
168168

169169
lgdt(pseudo);
170170

kernel/interface/i686/trap.asm

+5-3
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2929

3030
#include <kernel/infrastructure/i686/asm/descriptors.h>
31+
#include <kernel/infrastructure/i686/asm/percpu.h>
32+
#include <kernel/infrastructure/i686/asm/tss.h>
3133
#include <kernel/interface/i686/asm/irq.h>
3234
#include <kernel/machine/asm/machine.h>
3335

@@ -261,9 +263,9 @@ fast_amd_entry:
261263
; instruction.
262264
mov edx, SEG_SELECTOR(GDT_PER_CPU_DATA, RPL_KERNEL)
263265
mov gs, dx ; load gs with per-cpu data segment selector
264-
mov esp, [gs:GDT_LENGTH * 8 + 4] ; load kernel stack pointer from TSS
265-
; Stack pointer is at offset 4 in the TSS, and
266-
; the TSS follows the GDT (see percpu_t).
266+
267+
; load kernel stack pointer from TSS
268+
mov esp, [gs:PERCPU_OFFSET_TSS + TSS_OFFSET_ESP0]
267269
268270
; For details on the stack layout, see comments in interrupt_entry above and
269271
; the definition of the trapframe_t type.

0 commit comments

Comments
 (0)