1
0
Fork 0
mirror of https://github.com/hermitcore/libhermit.git synced 2025-03-09 00:00:03 +01:00

save /restore only MXCSR & the x87 status word

- reduce overhead for a "user-level" context switch
This commit is contained in:
Stefan Lankes 2016-09-10 16:55:33 +02:00
parent e4ecf36a39
commit 0001229827
5 changed files with 30 additions and 11 deletions

View file

@ -144,6 +144,8 @@ typedef struct mregs {
uint64_t rsp;
/// RIP
uint64_t rip;
/// MSXCSR
uint32_t mxcsr;
} mregs_t;
/// This defines what the stack looks like after the task context is saved

View file

@ -108,6 +108,22 @@ union fpu_state {
xsave_t xsave;
};
typedef struct {
uint16_t control_word;
uint16_t unused1;
uint16_t status_word;
uint16_t unused2;
uint16_t tags;
uint16_t unused3;
uint32_t eip;
uint16_t cs_selector;
uint32_t opcode:11;
uint32_t unused4:5;
uint32_t data_offset;
uint16_t data_selector;
uint16_t unused5;
} fenv_t;
typedef void (*handle_fpu_state)(union fpu_state* state);
extern handle_fpu_state save_fpu_state;

View file

@ -493,7 +493,6 @@ isrsyscall:
o64 sysret
%endif
extern save_fpu_state
global getcontext
align 64
getcontext:
@ -515,23 +514,23 @@ getcontext:
mov QWORD [rdi + 0x60], rax
mov rax, QWORD [rsp]
mov QWORD [rdi + 0x68], rax
; restore FPU state
add rdi, 0x80
call [save_fpu_state]
sub rdi, 0x80
; save FPU state
fnstenv [rdi + 0x74]
fldenv [rdi + 0x74]
lea rax, [rdi + 0x70]
stmxcsr [rax]
xor rax, rax
sti
ret
extern restore_fpu_state
global setcontext
align 64
setcontext:
cli
; restore FPU state
add rdi, 0x80
call [restore_fpu_state]
sub rdi, 0x80
fldenv [rdi + 0x74]
lea rax, [rdi + 0x70]
ldmxcsr [rax]
; restore general purpose registers
mov r15, QWORD [rdi + 0x00]
mov r14, QWORD [rdi + 0x08]

View file

@ -95,13 +95,15 @@ int sys_signal(signal_handler_t handler);
typedef struct ucontext {
mregs_t uc_mregs;
union fpu_state uc_fpu;
fenv_t uc_fenv;
struct ucontext *uc_link;
stack_t uc_stack;
} ucontext_t;
void makecontext(ucontext_t *ucp, void (*func)(), int argc, ...);
int swapcontext(ucontext_t *oucp, const ucontext_t *ucp);
int getcontext(ucontext_t *ucp);
int setcontext(ucontext_t *ucp);
#define __NR_exit 0
#define __NR_write 1

@ -1 +1 @@
Subproject commit ba4dae88bdc2fda079fc96cf70e7b238282229ca
Subproject commit 30a3e67a8641c3a6884ad3d18e1fc8752652e89c