diff --git a/arch/x86/kernel/include/ihk/context.h b/arch/x86/kernel/include/ihk/context.h index 22448e66..2aebc038 100644 --- a/arch/x86/kernel/include/ihk/context.h +++ b/arch/x86/kernel/include/ihk/context.h @@ -25,7 +25,19 @@ typedef struct x86_kregs ihk_mc_kernel_context_t; /* XXX: User context should contain floating point registers */ struct x86_user_context { - struct x86_basic_regs gpr; + struct x86_sregs sr; + + /* 16-byte boundary here */ + uint8_t is_gpr_valid; + uint8_t is_sr_valid; + uint8_t spare_flags6; + uint8_t spare_flags5; + uint8_t spare_flags4; + uint8_t spare_flags3; + uint8_t spare_flags2; + uint8_t spare_flags1; + struct x86_basic_regs gpr; /* must be last */ + /* 16-byte boundary here */ }; typedef struct x86_user_context ihk_mc_user_context_t; diff --git a/arch/x86/kernel/include/registers.h b/arch/x86/kernel/include/registers.h index a016865b..a70a8489 100644 --- a/arch/x86/kernel/include/registers.h +++ b/arch/x86/kernel/include/registers.h @@ -184,6 +184,15 @@ struct x86_basic_regs { unsigned long rip, cs, rflags, rsp, ss; }; +struct x86_sregs { + unsigned long fs_base; + unsigned long gs_base; + unsigned long ds; + unsigned long es; + unsigned long fs; + unsigned long gs; +}; + #define REGS_GET_STACK_POINTER(regs) (((struct x86_regs *)regs)->rsp) /* diff --git a/arch/x86/kernel/interrupt.S b/arch/x86/kernel/interrupt.S index d8f9abbf..4cdf496b 100644 --- a/arch/x86/kernel/interrupt.S +++ b/arch/x86/kernel/interrupt.S @@ -25,9 +25,16 @@ #define USER_DS (56 + 3) /* struct x86_user_context */ -#define RAX_OFFSET 80 -#define ERROR_OFFSET 120 -#define RSP_OFFSET 152 +#define X86_SREGS_BASE (0) +#define X86_SREGS_SIZE 48 + +#define X86_FLAGS_BASE (X86_SREGS_BASE + X86_SREGS_SIZE) +#define X86_FLAGS_SIZE 8 + +#define X86_REGS_BASE (X86_FLAGS_BASE + X86_FLAGS_SIZE) +#define RAX_OFFSET (X86_REGS_BASE + 80) +#define ERROR_OFFSET (X86_REGS_BASE + 120) +#define RSP_OFFSET (X86_REGS_BASE + 152) #define PUSH_ALL_REGS \ pushq %rdi; \ @@ -44,9 +51,13 @@ pushq %r12; \ pushq %r13; \ pushq %r14; \ - pushq %r15 + pushq %r15; \ + pushq $1; /* is_gpr_valid is set, and others are cleared */ \ + subq $X86_FLAGS_BASE,%rsp /* for x86_sregs, etc. */ #define POP_ALL_REGS \ + movq $0,X86_FLAGS_BASE(%rsp); /* clear all flags */ \ + addq $X86_REGS_BASE,%rsp; /* discard x86_sregs, flags, etc. */ \ popq %r15; \ popq %r14; \ popq %r13; \