Skip to content

Commit

Permalink
traps, entry: split cpu_regs into cpu_exc and cpu_regs
Browse files Browse the repository at this point in the history
Splitting cpu_regs_t into cpu_exc_t and cpu_regs_t using cpu_exc_t
allows to create asm-offset entries for the struct members to be
used directly in entry.S (allows to use different structure offsets
when in exception handler and when in syscall).

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>
  • Loading branch information
wipawel committed Aug 22, 2023
1 parent 98c43fb commit 6cd9db5
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 27 deletions.
33 changes: 33 additions & 0 deletions arch/x86/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,37 @@

void __asm_offset_header(void) {
OFFSETOF(usermode_private, percpu_t, usermode_private);

OFFSETOF(cpu_exc_error_code, cpu_exc_t, error_code);
OFFSETOF(cpu_exc_vector, cpu_exc_t, vector);
OFFSETOF(cpu_exc_ip, cpu_exc_t, _ASM_IP);
OFFSETOF(cpu_exc_cs, cpu_exc_t, cs);
OFFSETOF(cpu_exc_flags, cpu_exc_t, _ASM_FLAGS);
OFFSETOF(cpu_exc_sp, cpu_exc_t, _ASM_SP);
OFFSETOF(cpu_exc_ss, cpu_exc_t, ss);

OFFSETOF(cpu_regs_ax, cpu_regs_t, _ASM_AX);
OFFSETOF(cpu_regs_bx, cpu_regs_t, _ASM_BX);
OFFSETOF(cpu_regs_cx, cpu_regs_t, _ASM_CX);
OFFSETOF(cpu_regs_dx, cpu_regs_t, _ASM_DX);
OFFSETOF(cpu_regs_si, cpu_regs_t, _ASM_SI);
OFFSETOF(cpu_regs_di, cpu_regs_t, _ASM_DI);
OFFSETOF(cpu_regs_bp, cpu_regs_t, _ASM_BP);
OFFSETOF(cpu_regs_r8, cpu_regs_t, r8);
OFFSETOF(cpu_regs_r9, cpu_regs_t, r9);
OFFSETOF(cpu_regs_r10, cpu_regs_t, r10);
OFFSETOF(cpu_regs_r11, cpu_regs_t, r11);
OFFSETOF(cpu_regs_r12, cpu_regs_t, r12);
OFFSETOF(cpu_regs_r13, cpu_regs_t, r13);
OFFSETOF(cpu_regs_r14, cpu_regs_t, r14);
OFFSETOF(cpu_regs_r15, cpu_regs_t, r15);
OFFSETOF(cpu_regs_bx, cpu_regs_t, _ASM_BX);

OFFSETOF(cpu_regs_error_code, cpu_regs_t, exc.error_code);
OFFSETOF(cpu_regs_vector, cpu_regs_t, exc.vector);
OFFSETOF(cpu_regs_ip, cpu_regs_t, exc._ASM_IP);
OFFSETOF(cpu_regs_cs, cpu_regs_t, exc.cs);
OFFSETOF(cpu_regs_flags, cpu_regs_t, exc._ASM_FLAGS);
OFFSETOF(cpu_regs_sp, cpu_regs_t, exc._ASM_SP);
OFFSETOF(cpu_regs_ss, cpu_regs_t, exc.ss);
}
4 changes: 2 additions & 2 deletions arch/x86/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
#include <traps.h>

.macro _handle_usermode cr3
testb $0x3, 8(%_ASM_SP)
testb $0x3, cpu_exc_cs(%_ASM_SP)
jz 1f /* skip if from kernel mode */
SET_CR3 \cr3
swapgs
Expand All @@ -54,7 +54,7 @@ ENTRY(entry_\sym)
push $0
.endif

movl $\vec, 0x4(%_ASM_SP)
movl $\vec, cpu_exc_vector(%_ASM_SP)
jmp handle_exception
END_FUNC(entry_\sym)
.endm
Expand Down
28 changes: 14 additions & 14 deletions arch/x86/traps.c
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ static void dump_general_regs(const struct cpu_regs *regs) {
"\nRIP=0x%016lx\n\n",
regs->_ASM_AX, regs->r8, regs->_ASM_BX, regs->r9, regs->_ASM_CX, regs->r10,
regs->_ASM_DX, regs->r11, regs->_ASM_SI, regs->r12, regs->_ASM_DI, regs->r13,
regs->_ASM_BP, regs->r14, regs->_ASM_SP, regs->r15, regs->_ASM_IP);
regs->_ASM_BP, regs->r14, regs->exc._ASM_SP, regs->r15, regs->exc._ASM_IP);
}

static void dump_control_regs(const struct cpu_regs *regs) {
Expand All @@ -197,17 +197,17 @@ static void dump_segment_regs(const struct cpu_regs *regs) {
"ES=0x%04lx FS=0x%04lx GS=0x%04lx\n"
"EXCEPTION:\n"
"CS=0x%04x SS=0x%04x\n\n",
read_cs(), read_ds(), read_ss(), read_es(), read_fs(), read_gs(), regs->cs,
regs->ss);
read_cs(), read_ds(), read_ss(), read_es(), read_fs(), read_gs(), regs->exc.cs,
regs->exc.ss);
}

static void dump_flags(const struct cpu_regs *regs) {
printk("RFLAGS=0x%016lx\n\n", regs->_ASM_FLAGS);
printk("RFLAGS=0x%016lx\n\n", regs->exc._ASM_FLAGS);
}

#define DUMP_STACK_LINES 32
static void dump_stack(const struct cpu_regs *regs, unsigned words) {
unsigned long *sp = (unsigned long *) regs->_ASM_SP;
unsigned long *sp = (unsigned long *) regs->exc._ASM_SP;
unsigned lines = DUMP_STACK_LINES;

printk("STACK[%p]:", sp);
Expand Down Expand Up @@ -282,11 +282,11 @@ void print_callstack(const void *sp, const void *ip) {

static bool extables_fixup(struct cpu_regs *regs) {
for (extable_entry_t *cur = __start_extables; cur < __stop_extables; ++cur) {
if (regs->_ASM_IP != cur->fault_addr)
if (regs->exc._ASM_IP != cur->fault_addr)
continue;

if (cur->fixup)
regs->_ASM_IP = cur->fixup;
regs->exc._ASM_IP = cur->fixup;
else if (cur->cb)
cur->cb(regs);

Expand All @@ -299,22 +299,22 @@ static bool extables_fixup(struct cpu_regs *regs) {
void do_exception(struct cpu_regs *regs) {
static char ec_str[32], panic_str[128];

if (!enter_from_usermode(regs->cs) && extables_fixup(regs))
if (!enter_from_usermode(regs->exc.cs) && extables_fixup(regs))
return;

dump_regs(regs);
print_callstack(_ptr(regs->_ASM_SP), _ptr(regs->_ASM_IP));
print_callstack(_ptr(regs->exc._ASM_SP), _ptr(regs->exc._ASM_IP));

if (has_error_code(regs->vector))
x86_ex_decode_error_code(ec_str, sizeof(ec_str), regs->vector, regs->error_code);
if (has_error_code(regs->exc.vector))
x86_ex_decode_error_code(ec_str, sizeof(ec_str), regs->exc.vector, regs->exc.error_code);

snprintf(panic_str, sizeof(panic_str),
"#%s %sat IP: 0x%02x:0x%016lx SP: 0x%02x:0x%016lx\n",
exception_names[regs->vector], ec_str, regs->cs, regs->_ASM_IP, regs->ss,
regs->_ASM_SP);
exception_names[regs->exc.vector], ec_str, regs->exc.cs, regs->exc._ASM_IP, regs->exc.ss,
regs->exc._ASM_SP);

/* Handle user tasks' exceptions */
if (enter_from_usermode(regs->cs)) {
if (enter_from_usermode(regs->exc.cs)) {
printk("Task exception: %s\n", panic_str);
goto_syscall_exit(-EFAULT);
}
Expand Down
27 changes: 16 additions & 11 deletions include/arch/x86/processor.h
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,21 @@ typedef uint64_t x86_reg_t;
typedef uint32_t x86_reg_t;
#endif

struct cpu_regs {
struct __packed cpu_exc {
x86_ex_error_code_t error_code;
/* Populated by exception entry */
uint32_t vector;

/* Hardware exception */
x86_reg_t _ASM_IP;
uint16_t cs, _pad_cs[3];
x86_reg_t _ASM_FLAGS;
x86_reg_t _ASM_SP;
uint16_t ss, _pad_ss[3];
};
typedef struct cpu_exc cpu_exc_t;

struct __packed cpu_regs {
x86_reg_t r15;
x86_reg_t r14;
x86_reg_t r13;
Expand All @@ -258,16 +272,7 @@ struct cpu_regs {
x86_reg_t _ASM_BX;
x86_reg_t _ASM_AX;

x86_ex_error_code_t error_code;
/* Populated by exception entry */
uint32_t vector;

/* Hardware exception */
x86_reg_t _ASM_IP;
uint16_t cs, _pad_cs[3];
x86_reg_t _ASM_FLAGS;
x86_reg_t _ASM_SP;
uint16_t ss, _pad_ss[3];
cpu_exc_t exc;
};
typedef struct cpu_regs cpu_regs_t;

Expand Down

0 comments on commit 6cd9db5

Please sign in to comment.