Skip to content

Commit

Permalink
Fix kernel pointer offset used by SYSCALL instruction (#90)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
phaubertin authored Nov 21, 2024
1 parent 17dd38e commit ae359e8
Show file tree
Hide file tree
Showing 6 changed files with 92 additions and 9 deletions.
2 changes: 1 addition & 1 deletion include/kernel/infrastructure/i686/asm/descriptors.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
#define GDT_USER_TLS_DATA 7

/** number of descriptors in GDT */
#define GDT_LENGTH 8
#define GDT_NUM_ENTRIES 8

/** offset of descriptor type in descriptor */
#define SEG_FLAGS_OFFSET 40
Expand Down
45 changes: 45 additions & 0 deletions include/kernel/infrastructure/i686/asm/percpu.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (C) 2024 Philippe Aubertin.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the author nor the names of other contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_PERCPU_H
#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_PERCPU_H

#include <kernel/infrastructure/i686/asm/descriptors.h>

/* The PERCPU_OFFSET_... definitions here must match the offsets in the
* percpu_t struct. They are used by assembly language code that can't use the
* struct definition. */

#define PERCPU_OFFSET_GDT 8

#define PERCPU_OFFSET_TSS (PERCPU_OFFSET_GDT + 8 * GDT_NUM_ENTRIES)

#endif
37 changes: 37 additions & 0 deletions include/kernel/infrastructure/i686/asm/tss.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (C) 2024 Philippe Aubertin.
* All rights reserved.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 3. Neither the name of the author nor the names of other contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

#ifndef JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_TSS_H
#define JINUE_KERNEL_INFRASTRUCTURE_I686_ASM_TSS_H

#define TSS_OFFSET_ESP0 4

#endif
7 changes: 3 additions & 4 deletions include/kernel/infrastructure/i686/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,12 +111,11 @@ typedef struct {
} tss_t;

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

Expand Down
2 changes: 1 addition & 1 deletion kernel/infrastructure/i686/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ static void load_selectors(percpu_t *cpu_data, boot_alloc_t *boot_alloc) {

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

lgdt(pseudo);

Expand Down
8 changes: 5 additions & 3 deletions kernel/interface/i686/trap.asm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include <kernel/infrastructure/i686/asm/descriptors.h>
#include <kernel/infrastructure/i686/asm/percpu.h>
#include <kernel/infrastructure/i686/asm/tss.h>
#include <kernel/interface/i686/asm/irq.h>
#include <kernel/machine/asm/machine.h>

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

0 comments on commit ae359e8

Please sign in to comment.