- Merge savectx2() with savectx() and struct xpcb with struct pcb. [1]
savectx() is only used for panic dump (dumppcb) and kdb (stoppcbs). Thus, saving additional information does not hurt and it may be even beneficial. Unfortunately, struct pcb has grown larger to accommodate more data. Move 512-byte long pcb_user_save to the end of struct pcb while I am here. - savectx() now saves FPU state unconditionally and copy it to the PCB of FPU thread if necessary. This gives panic dump and kdb a chance to take a look at the current FPU state even if the FPU is "supposedly" not used. - Resuming CPU now unconditionally reinitializes FPU. If the saved FPU state was irrelevant, it could be in an unknown state. Suggested by: bde [1]
This commit is contained in:
parent
afba0b6e9e
commit
a2d2c83668
@ -1,7 +1,7 @@
|
||||
/*-
|
||||
* Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org>
|
||||
* Copyright (c) 2001 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
|
||||
* Copyright (c) 2008-2009 Jung-uk Kim <jkim@FreeBSD.org>
|
||||
* Copyright (c) 2008-2010 Jung-uk Kim <jkim@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -35,8 +35,6 @@
|
||||
#include "assym.s"
|
||||
|
||||
#define WAKEUP_CTX(member) wakeup_ ## member - wakeup_ctx(%rdi)
|
||||
#define WAKEUP_PCB(member) PCB_ ## member(%r11)
|
||||
#define WAKEUP_XPCB(member) XPCB_ ## member(%r11)
|
||||
|
||||
ENTRY(acpi_restorecpu)
|
||||
/* Switch to KPML4phys. */
|
||||
@ -49,7 +47,7 @@ ENTRY(acpi_restorecpu)
|
||||
1:
|
||||
|
||||
/* Fetch PCB. */
|
||||
movq WAKEUP_CTX(xpcb), %r11
|
||||
movq WAKEUP_CTX(pcb), %rsi
|
||||
|
||||
/* Force kernel segment registers. */
|
||||
movl $KDSEL, %eax
|
||||
@ -62,16 +60,16 @@ ENTRY(acpi_restorecpu)
|
||||
movw %ax, %gs
|
||||
|
||||
movl $MSR_FSBASE, %ecx
|
||||
movl WAKEUP_PCB(FSBASE), %eax
|
||||
movl 4 + WAKEUP_PCB(FSBASE), %edx
|
||||
movl PCB_FSBASE(%rsi), %eax
|
||||
movl 4 + PCB_FSBASE(%rsi), %edx
|
||||
wrmsr
|
||||
movl $MSR_GSBASE, %ecx
|
||||
movl WAKEUP_PCB(GSBASE), %eax
|
||||
movl 4 + WAKEUP_PCB(GSBASE), %edx
|
||||
movl PCB_GSBASE(%rsi), %eax
|
||||
movl 4 + PCB_GSBASE(%rsi), %edx
|
||||
wrmsr
|
||||
movl $MSR_KGSBASE, %ecx
|
||||
movl WAKEUP_XPCB(KGSBASE), %eax
|
||||
movl 4 + WAKEUP_XPCB(KGSBASE), %edx
|
||||
movl PCB_KGSBASE(%rsi), %eax
|
||||
movl 4 + PCB_KGSBASE(%rsi), %edx
|
||||
wrmsr
|
||||
|
||||
/* Restore EFER. */
|
||||
@ -103,19 +101,20 @@ ENTRY(acpi_restorecpu)
|
||||
wrmsr
|
||||
|
||||
/* Restore CR0 except for FPU mode. */
|
||||
movq WAKEUP_XPCB(CR0), %rax
|
||||
movq PCB_CR0(%rsi), %rax
|
||||
movq %rax, %rcx
|
||||
andq $~(CR0_EM | CR0_TS), %rax
|
||||
movq %rax, %cr0
|
||||
|
||||
/* Restore CR2 and CR4. */
|
||||
movq WAKEUP_XPCB(CR2), %rax
|
||||
movq PCB_CR2(%rsi), %rax
|
||||
movq %rax, %cr2
|
||||
movq WAKEUP_XPCB(CR4), %rax
|
||||
movq PCB_CR4(%rsi), %rax
|
||||
movq %rax, %cr4
|
||||
|
||||
/* Restore descriptor tables. */
|
||||
lidt WAKEUP_XPCB(IDT)
|
||||
lldt WAKEUP_XPCB(LDT)
|
||||
lidt PCB_IDT(%rsi)
|
||||
lldt PCB_LDT(%rsi)
|
||||
|
||||
#define SDT_SYSTSS 9
|
||||
#define SDT_SYSBSY 11
|
||||
@ -123,48 +122,58 @@ ENTRY(acpi_restorecpu)
|
||||
/* Clear "task busy" bit and reload TR. */
|
||||
movq PCPU(TSS), %rax
|
||||
andb $(~SDT_SYSBSY | SDT_SYSTSS), 5(%rax)
|
||||
movw WAKEUP_XPCB(TR), %ax
|
||||
movw PCB_TR(%rsi), %ax
|
||||
ltr %ax
|
||||
|
||||
#undef SDT_SYSTSS
|
||||
#undef SDT_SYSBSY
|
||||
|
||||
/* Restore other callee saved registers. */
|
||||
movq WAKEUP_PCB(R15), %r15
|
||||
movq WAKEUP_PCB(R14), %r14
|
||||
movq WAKEUP_PCB(R13), %r13
|
||||
movq WAKEUP_PCB(R12), %r12
|
||||
movq WAKEUP_PCB(RBP), %rbp
|
||||
movq WAKEUP_PCB(RSP), %rsp
|
||||
movq WAKEUP_PCB(RBX), %rbx
|
||||
movq PCB_R15(%rsi), %r15
|
||||
movq PCB_R14(%rsi), %r14
|
||||
movq PCB_R13(%rsi), %r13
|
||||
movq PCB_R12(%rsi), %r12
|
||||
movq PCB_RBP(%rsi), %rbp
|
||||
movq PCB_RSP(%rsi), %rsp
|
||||
movq PCB_RBX(%rsi), %rbx
|
||||
|
||||
/* Restore debug registers. */
|
||||
movq WAKEUP_PCB(DR0), %rax
|
||||
movq PCB_DR0(%rsi), %rax
|
||||
movq %rax, %dr0
|
||||
movq WAKEUP_PCB(DR1), %rax
|
||||
movq PCB_DR1(%rsi), %rax
|
||||
movq %rax, %dr1
|
||||
movq WAKEUP_PCB(DR2), %rax
|
||||
movq PCB_DR2(%rsi), %rax
|
||||
movq %rax, %dr2
|
||||
movq WAKEUP_PCB(DR3), %rax
|
||||
movq PCB_DR3(%rsi), %rax
|
||||
movq %rax, %dr3
|
||||
movq WAKEUP_PCB(DR6), %rax
|
||||
movq PCB_DR6(%rsi), %rax
|
||||
movq %rax, %dr6
|
||||
movq WAKEUP_PCB(DR7), %rax
|
||||
movq PCB_DR7(%rsi), %rax
|
||||
movq %rax, %dr7
|
||||
|
||||
/* Restore FPU state. */
|
||||
#define __INITIAL_FPUCW__ 0x037f
|
||||
#define __INITIAL_MXCSR__ 0x1f80
|
||||
|
||||
/* Initialize FPU and restore state if necessary. */
|
||||
fninit
|
||||
movw $__INITIAL_FPUCW__, -2(%rsp)
|
||||
fldcw -2(%rsp)
|
||||
movl $__INITIAL_MXCSR__, -4(%rsp)
|
||||
ldmxcsr -4(%rsp)
|
||||
movq PCPU(FPCURTHREAD), %rax
|
||||
testq %rax, %rax
|
||||
je 1f
|
||||
fxrstor WAKEUP_PCB(USERFPU)
|
||||
fxrstor PCB_USERFPU(%rsi)
|
||||
1:
|
||||
|
||||
/* Restore CR0 with FPU mode. */
|
||||
movq WAKEUP_XPCB(CR0), %rax
|
||||
movq %rax, %cr0
|
||||
#undef __INITIAL_FPUCW__
|
||||
#undef __INITIAL_MXCSR__
|
||||
|
||||
/* Reload CR0. */
|
||||
movq %rcx, %cr0
|
||||
|
||||
/* Restore return address. */
|
||||
movq WAKEUP_PCB(RIP), %rax
|
||||
movq PCB_RIP(%rsi), %rax
|
||||
movq %rax, (%rsp)
|
||||
|
||||
/* Indicate the CPU is resumed. */
|
||||
@ -173,19 +182,3 @@ ENTRY(acpi_restorecpu)
|
||||
|
||||
ret
|
||||
END(acpi_restorecpu)
|
||||
|
||||
ENTRY(acpi_savecpu)
|
||||
/* Fetch XPCB and save CPU context. */
|
||||
movq %rdi, %r10
|
||||
call savectx2
|
||||
movq %r10, %r11
|
||||
|
||||
/* Patch caller's return address and stack pointer. */
|
||||
movq (%rsp), %rax
|
||||
movq %rax, WAKEUP_PCB(RIP)
|
||||
movq %rsp, %rax
|
||||
movq %rax, WAKEUP_PCB(RSP)
|
||||
|
||||
movl $1, %eax
|
||||
ret
|
||||
END(acpi_savecpu)
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org>
|
||||
* Copyright (c) 2001 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
|
||||
* Copyright (c) 2003 Peter Wemm
|
||||
* Copyright (c) 2008-2009 Jung-uk Kim <jkim@FreeBSD.org>
|
||||
* Copyright (c) 2008-2010 Jung-uk Kim <jkim@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -265,7 +265,7 @@ wakeup_kpml4:
|
||||
|
||||
wakeup_ctx:
|
||||
.quad 0
|
||||
wakeup_xpcb:
|
||||
wakeup_pcb:
|
||||
.quad 0
|
||||
wakeup_gdt:
|
||||
.word 0
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Copyright (c) 2001 Takanori Watanabe <takawata@jp.freebsd.org>
|
||||
* Copyright (c) 2001 Mitsuru IWASAKI <iwasaki@jp.freebsd.org>
|
||||
* Copyright (c) 2003 Peter Wemm
|
||||
* Copyright (c) 2008-2009 Jung-uk Kim <jkim@FreeBSD.org>
|
||||
* Copyright (c) 2008-2010 Jung-uk Kim <jkim@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -66,13 +66,12 @@ extern int acpi_resume_beep;
|
||||
extern int acpi_reset_video;
|
||||
|
||||
#ifdef SMP
|
||||
extern struct xpcb **stopxpcbs;
|
||||
extern struct pcb **susppcbs;
|
||||
#else
|
||||
static struct xpcb **stopxpcbs;
|
||||
static struct pcb **susppcbs;
|
||||
#endif
|
||||
|
||||
int acpi_restorecpu(struct xpcb *, vm_offset_t);
|
||||
int acpi_savecpu(struct xpcb *);
|
||||
int acpi_restorecpu(struct pcb *, vm_offset_t);
|
||||
|
||||
static void *acpi_alloc_wakeup_handler(void);
|
||||
static void acpi_stop_beep(void *);
|
||||
@ -105,10 +104,10 @@ acpi_wakeup_ap(struct acpi_softc *sc, int cpu)
|
||||
int apic_id = cpu_apic_ids[cpu];
|
||||
int ms;
|
||||
|
||||
WAKECODE_FIXUP(wakeup_xpcb, struct xpcb *, stopxpcbs[cpu]);
|
||||
WAKECODE_FIXUP(wakeup_gdt, uint16_t, stopxpcbs[cpu]->xpcb_gdt.rd_limit);
|
||||
WAKECODE_FIXUP(wakeup_pcb, struct pcb *, susppcbs[cpu]);
|
||||
WAKECODE_FIXUP(wakeup_gdt, uint16_t, susppcbs[cpu]->pcb_gdt.rd_limit);
|
||||
WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t,
|
||||
stopxpcbs[cpu]->xpcb_gdt.rd_base);
|
||||
susppcbs[cpu]->pcb_gdt.rd_base);
|
||||
WAKECODE_FIXUP(wakeup_cpu, int, cpu);
|
||||
|
||||
/* do an INIT IPI: assert RESET */
|
||||
@ -245,7 +244,7 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
|
||||
cr3 = rcr3();
|
||||
load_cr3(KPML4phys);
|
||||
|
||||
if (acpi_savecpu(stopxpcbs[0])) {
|
||||
if (savectx(susppcbs[0])) {
|
||||
#ifdef SMP
|
||||
if (wakeup_cpus != 0 && suspend_cpus(wakeup_cpus) == 0) {
|
||||
device_printf(sc->acpi_dev,
|
||||
@ -258,11 +257,11 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
|
||||
WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0));
|
||||
WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0));
|
||||
|
||||
WAKECODE_FIXUP(wakeup_xpcb, struct xpcb *, stopxpcbs[0]);
|
||||
WAKECODE_FIXUP(wakeup_pcb, struct pcb *, susppcbs[0]);
|
||||
WAKECODE_FIXUP(wakeup_gdt, uint16_t,
|
||||
stopxpcbs[0]->xpcb_gdt.rd_limit);
|
||||
susppcbs[0]->pcb_gdt.rd_limit);
|
||||
WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t,
|
||||
stopxpcbs[0]->xpcb_gdt.rd_base);
|
||||
susppcbs[0]->pcb_gdt.rd_base);
|
||||
WAKECODE_FIXUP(wakeup_cpu, int, 0);
|
||||
|
||||
/* Call ACPICA to enter the desired sleep state */
|
||||
@ -332,9 +331,9 @@ acpi_alloc_wakeup_handler(void)
|
||||
printf("%s: can't alloc wake memory\n", __func__);
|
||||
return (NULL);
|
||||
}
|
||||
stopxpcbs = malloc(mp_ncpus * sizeof(*stopxpcbs), M_DEVBUF, M_WAITOK);
|
||||
susppcbs = malloc(mp_ncpus * sizeof(*susppcbs), M_DEVBUF, M_WAITOK);
|
||||
for (i = 0; i < mp_ncpus; i++)
|
||||
stopxpcbs[i] = malloc(sizeof(**stopxpcbs), M_DEVBUF, M_WAITOK);
|
||||
susppcbs[i] = malloc(sizeof(**susppcbs), M_DEVBUF, M_WAITOK);
|
||||
|
||||
return (wakeaddr);
|
||||
}
|
||||
|
@ -303,22 +303,69 @@ END(cpu_switch)
|
||||
*/
|
||||
ENTRY(savectx)
|
||||
/* Fetch PCB. */
|
||||
movq %rdi,%rcx
|
||||
movq %rdi,%rsi
|
||||
|
||||
/* Save caller's return address. */
|
||||
movq (%rsp),%rax
|
||||
movq %rax,PCB_RIP(%rcx)
|
||||
movq %rax,PCB_RIP(%rsi)
|
||||
|
||||
movq %rbx,PCB_RBX(%rsi)
|
||||
movq %rsp,PCB_RSP(%rsi)
|
||||
movq %rbp,PCB_RBP(%rsi)
|
||||
movq %r12,PCB_R12(%rsi)
|
||||
movq %r13,PCB_R13(%rsi)
|
||||
movq %r14,PCB_R14(%rsi)
|
||||
movq %r15,PCB_R15(%rsi)
|
||||
|
||||
movq %cr2,%rax
|
||||
movq %rax,PCB_CR2(%rsi)
|
||||
movq %cr3,%rax
|
||||
movq %rax,PCB_CR3(%rcx)
|
||||
movq %rax,PCB_CR3(%rsi)
|
||||
movq %cr4,%rax
|
||||
movq %rax,PCB_CR4(%rsi)
|
||||
|
||||
movq %rbx,PCB_RBX(%rcx)
|
||||
movq %rsp,PCB_RSP(%rcx)
|
||||
movq %rbp,PCB_RBP(%rcx)
|
||||
movq %r12,PCB_R12(%rcx)
|
||||
movq %r13,PCB_R13(%rcx)
|
||||
movq %r14,PCB_R14(%rcx)
|
||||
movq %r15,PCB_R15(%rcx)
|
||||
movq %dr0,%rax
|
||||
movq %rax,PCB_DR0(%rsi)
|
||||
movq %dr1,%rax
|
||||
movq %rax,PCB_DR1(%rsi)
|
||||
movq %dr2,%rax
|
||||
movq %rax,PCB_DR2(%rsi)
|
||||
movq %dr3,%rax
|
||||
movq %rax,PCB_DR3(%rsi)
|
||||
movq %dr6,%rax
|
||||
movq %rax,PCB_DR6(%rsi)
|
||||
movq %dr7,%rax
|
||||
movq %rax,PCB_DR7(%rsi)
|
||||
|
||||
movl $MSR_FSBASE,%ecx
|
||||
rdmsr
|
||||
shlq $32,%rdx
|
||||
leaq (%rax,%rdx),%rax
|
||||
movq %rax,PCB_FSBASE(%rsi)
|
||||
movl $MSR_GSBASE,%ecx
|
||||
rdmsr
|
||||
shlq $32,%rdx
|
||||
leaq (%rax,%rdx),%rax
|
||||
movq %rax,PCB_GSBASE(%rsi)
|
||||
movl $MSR_KGSBASE,%ecx
|
||||
rdmsr
|
||||
shlq $32,%rdx
|
||||
leaq (%rax,%rdx),%rax
|
||||
movq %rax,PCB_KGSBASE(%rsi)
|
||||
|
||||
sgdt PCB_GDT(%rsi)
|
||||
sidt PCB_IDT(%rsi)
|
||||
sldt PCB_LDT(%rsi)
|
||||
str PCB_TR(%rsi)
|
||||
|
||||
movq %cr0,%rax
|
||||
movq %rax,PCB_CR0(%rsi)
|
||||
leaq PCB_USERFPU(%rsi),%rdi
|
||||
pushfq
|
||||
cli
|
||||
clts
|
||||
fxsave (%rdi)
|
||||
movq %rax,%cr0
|
||||
|
||||
/*
|
||||
* If fpcurthread == NULL, then the fpu h/w state is irrelevant and the
|
||||
@ -326,104 +373,22 @@ ENTRY(savectx)
|
||||
* but not for dumps (the old book-keeping with FP flags in the pcb
|
||||
* always lost for dumps because the dump pcb has 0 flags).
|
||||
*
|
||||
* If fpcurthread != NULL, then we have to save the fpu h/w state to
|
||||
* fpcurthread's pcb and copy it to the requested pcb, or save to the
|
||||
* requested pcb and reload. Copying is easier because we would
|
||||
* have to handle h/w bugs for reloading. We used to lose the
|
||||
* parent's fpu state for forks by forgetting to reload.
|
||||
* If fpcurthread != NULL, then we have to copy the fpu h/w state to
|
||||
* fpcurthread's pcb, or reload from the requested pcb. Copying is
|
||||
* easier because we would have to handle h/w bugs for reloading.
|
||||
*/
|
||||
pushfq
|
||||
cli
|
||||
movq PCPU(FPCURTHREAD),%rax
|
||||
testq %rax,%rax
|
||||
je 1f
|
||||
|
||||
movq TD_PCB(%rax),%rdi
|
||||
movq PCB_SAVEFPU(%rdi),%rdi
|
||||
clts
|
||||
fxsave (%rdi)
|
||||
smsw %ax
|
||||
orb $CR0_TS,%al
|
||||
lmsw %ax
|
||||
|
||||
movq $PCB_SAVEFPU_SIZE,%rdx /* arg 3 */
|
||||
leaq PCB_USERFPU(%rcx),%rsi /* arg 2 */
|
||||
/* arg 1 (%rdi) already loaded */
|
||||
movq TD_PCB(%rax),%rax
|
||||
movq PCB_SAVEFPU(%rax),%rsi /* arg 2 */
|
||||
movq $PCB_SAVEFPU_SIZE,%rdx /* arg 3 */
|
||||
call bcopy
|
||||
1:
|
||||
popfq
|
||||
movl $1,%eax
|
||||
|
||||
ret
|
||||
END(savectx)
|
||||
|
||||
/*
|
||||
* savectx2(xpcb)
|
||||
* Update xpcb, saving current processor state.
|
||||
*/
|
||||
ENTRY(savectx2)
|
||||
/* Fetch XPCB. */
|
||||
movq %rdi,%r8
|
||||
|
||||
/* Save caller's return address. */
|
||||
movq (%rsp),%rax
|
||||
movq %rax,PCB_RIP(%r8)
|
||||
|
||||
movq %rbx,PCB_RBX(%r8)
|
||||
movq %rsp,PCB_RSP(%r8)
|
||||
movq %rbp,PCB_RBP(%r8)
|
||||
movq %r12,PCB_R12(%r8)
|
||||
movq %r13,PCB_R13(%r8)
|
||||
movq %r14,PCB_R14(%r8)
|
||||
movq %r15,PCB_R15(%r8)
|
||||
|
||||
movq %cr0,%rax
|
||||
movq %rax,XPCB_CR0(%r8)
|
||||
movq %cr2,%rax
|
||||
movq %rax,XPCB_CR2(%r8)
|
||||
movq %cr4,%rax
|
||||
movq %rax,XPCB_CR4(%r8)
|
||||
|
||||
movq %dr0,%rax
|
||||
movq %rax,PCB_DR0(%r8)
|
||||
movq %dr1,%rax
|
||||
movq %rax,PCB_DR1(%r8)
|
||||
movq %dr2,%rax
|
||||
movq %rax,PCB_DR2(%r8)
|
||||
movq %dr3,%rax
|
||||
movq %rax,PCB_DR3(%r8)
|
||||
movq %dr6,%rax
|
||||
movq %rax,PCB_DR6(%r8)
|
||||
movq %dr7,%rax
|
||||
movq %rax,PCB_DR7(%r8)
|
||||
|
||||
sgdt XPCB_GDT(%r8)
|
||||
sidt XPCB_IDT(%r8)
|
||||
sldt XPCB_LDT(%r8)
|
||||
str XPCB_TR(%r8)
|
||||
|
||||
movl $MSR_FSBASE,%ecx
|
||||
rdmsr
|
||||
shlq $32,%rdx
|
||||
leaq (%rax,%rdx),%rax
|
||||
movq %rax,PCB_FSBASE(%r8)
|
||||
movl $MSR_GSBASE,%ecx
|
||||
rdmsr
|
||||
shlq $32,%rdx
|
||||
leaq (%rax,%rdx),%rax
|
||||
movq %rax,PCB_GSBASE(%r8)
|
||||
movl $MSR_KGSBASE,%ecx
|
||||
rdmsr
|
||||
shlq $32,%rdx
|
||||
leaq (%rax,%rdx),%rax
|
||||
movq %rax,XPCB_KGSBASE(%r8)
|
||||
|
||||
movq PCPU(FPCURTHREAD),%rax
|
||||
testq %rax,%rax
|
||||
je 1f
|
||||
clts
|
||||
fxsave PCB_USERFPU(%r8)
|
||||
1:
|
||||
|
||||
movl $1, %eax
|
||||
ret
|
||||
END(savectx2)
|
||||
|
@ -123,7 +123,7 @@ ASSYM(KERNBASE, KERNBASE);
|
||||
ASSYM(DMAP_MIN_ADDRESS, DMAP_MIN_ADDRESS);
|
||||
ASSYM(DMAP_MAX_ADDRESS, DMAP_MAX_ADDRESS);
|
||||
ASSYM(MCLBYTES, MCLBYTES);
|
||||
ASSYM(PCB_CR3, offsetof(struct pcb, pcb_cr3));
|
||||
|
||||
ASSYM(PCB_R15, offsetof(struct pcb, pcb_r15));
|
||||
ASSYM(PCB_R14, offsetof(struct pcb, pcb_r14));
|
||||
ASSYM(PCB_R13, offsetof(struct pcb, pcb_r13));
|
||||
@ -134,40 +134,35 @@ ASSYM(PCB_RBX, offsetof(struct pcb, pcb_rbx));
|
||||
ASSYM(PCB_RIP, offsetof(struct pcb, pcb_rip));
|
||||
ASSYM(PCB_FSBASE, offsetof(struct pcb, pcb_fsbase));
|
||||
ASSYM(PCB_GSBASE, offsetof(struct pcb, pcb_gsbase));
|
||||
ASSYM(PCB_KGSBASE, offsetof(struct pcb, pcb_kgsbase));
|
||||
ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
|
||||
ASSYM(PCB_CR0, offsetof(struct pcb, pcb_cr0));
|
||||
ASSYM(PCB_CR2, offsetof(struct pcb, pcb_cr2));
|
||||
ASSYM(PCB_CR3, offsetof(struct pcb, pcb_cr3));
|
||||
ASSYM(PCB_CR4, offsetof(struct pcb, pcb_cr4));
|
||||
ASSYM(PCB_DR0, offsetof(struct pcb, pcb_dr0));
|
||||
ASSYM(PCB_DR1, offsetof(struct pcb, pcb_dr1));
|
||||
ASSYM(PCB_DR2, offsetof(struct pcb, pcb_dr2));
|
||||
ASSYM(PCB_DR3, offsetof(struct pcb, pcb_dr3));
|
||||
ASSYM(PCB_DR6, offsetof(struct pcb, pcb_dr6));
|
||||
ASSYM(PCB_DR7, offsetof(struct pcb, pcb_dr7));
|
||||
ASSYM(PCB_USERFPU, offsetof(struct pcb, pcb_user_save));
|
||||
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
|
||||
ASSYM(PCB_GS32SD, offsetof(struct pcb, pcb_gs32sd));
|
||||
ASSYM(PCB_TSSP, offsetof(struct pcb, pcb_tssp));
|
||||
ASSYM(PCB_SAVEFPU, offsetof(struct pcb, pcb_save));
|
||||
ASSYM(PCB_SAVEFPU_SIZE, sizeof(struct savefpu));
|
||||
ASSYM(PCB_FULL_IRET, offsetof(struct pcb, pcb_full_iret));
|
||||
ASSYM(PCB_GDT, offsetof(struct pcb, pcb_gdt));
|
||||
ASSYM(PCB_IDT, offsetof(struct pcb, pcb_idt));
|
||||
ASSYM(PCB_LDT, offsetof(struct pcb, pcb_ldt));
|
||||
ASSYM(PCB_TR, offsetof(struct pcb, pcb_tr));
|
||||
ASSYM(PCB_USERFPU, offsetof(struct pcb, pcb_user_save));
|
||||
ASSYM(PCB_SIZE, sizeof(struct pcb));
|
||||
ASSYM(PCB_DBREGS, PCB_DBREGS);
|
||||
ASSYM(PCB_32BIT, PCB_32BIT);
|
||||
ASSYM(PCB_GS32BIT, PCB_GS32BIT);
|
||||
ASSYM(PCB_FULLCTX, PCB_FULLCTX);
|
||||
|
||||
ASSYM(PCB_FLAGS, offsetof(struct pcb, pcb_flags));
|
||||
ASSYM(PCB_SAVEFPU, offsetof(struct pcb, pcb_save));
|
||||
ASSYM(PCB_SAVEFPU_SIZE, sizeof(struct savefpu));
|
||||
ASSYM(PCB_ONFAULT, offsetof(struct pcb, pcb_onfault));
|
||||
ASSYM(PCB_GS32SD, offsetof(struct pcb, pcb_gs32sd));
|
||||
|
||||
ASSYM(PCB_SIZE, sizeof(struct pcb));
|
||||
|
||||
ASSYM(XPCB_PCB, offsetof(struct xpcb, xpcb_pcb));
|
||||
ASSYM(XPCB_CR0, offsetof(struct xpcb, xpcb_cr0));
|
||||
ASSYM(XPCB_CR2, offsetof(struct xpcb, xpcb_cr2));
|
||||
ASSYM(XPCB_CR4, offsetof(struct xpcb, xpcb_cr4));
|
||||
ASSYM(XPCB_KGSBASE, offsetof(struct xpcb, xpcb_kgsbase));
|
||||
ASSYM(XPCB_GDT, offsetof(struct xpcb, xpcb_gdt));
|
||||
ASSYM(XPCB_IDT, offsetof(struct xpcb, xpcb_idt));
|
||||
ASSYM(XPCB_LDT, offsetof(struct xpcb, xpcb_ldt));
|
||||
ASSYM(XPCB_TR, offsetof(struct xpcb, xpcb_tr));
|
||||
|
||||
ASSYM(XPCB_SIZE, sizeof(struct xpcb));
|
||||
|
||||
ASSYM(COMMON_TSS_RSP0, offsetof(struct amd64tss, tss_rsp0));
|
||||
|
||||
ASSYM(TF_R15, offsetof(struct trapframe, tf_r15));
|
||||
|
@ -100,7 +100,7 @@ char *nmi_stack;
|
||||
void *dpcpu;
|
||||
|
||||
struct pcb stoppcbs[MAXCPU];
|
||||
struct xpcb **stopxpcbs = NULL;
|
||||
struct pcb **susppcbs = NULL;
|
||||
|
||||
/* Variables needed for SMP tlb shootdown. */
|
||||
vm_offset_t smp_tlb_addr1;
|
||||
@ -1336,7 +1336,7 @@ cpususpend_handler(void)
|
||||
rf = intr_disable();
|
||||
cr3 = rcr3();
|
||||
|
||||
if (savectx2(stopxpcbs[cpu])) {
|
||||
if (savectx(susppcbs[cpu])) {
|
||||
wbinvd();
|
||||
atomic_set_int(&stopped_cpus, cpumask);
|
||||
}
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include <machine/segments.h>
|
||||
|
||||
struct pcb {
|
||||
register_t pcb_cr3;
|
||||
register_t pcb_r15;
|
||||
register_t pcb_r14;
|
||||
register_t pcb_r13;
|
||||
@ -55,6 +54,7 @@ struct pcb {
|
||||
register_t pcb_rip;
|
||||
register_t pcb_fsbase;
|
||||
register_t pcb_gsbase;
|
||||
register_t pcb_kgsbase;
|
||||
u_long pcb_flags;
|
||||
#define PCB_DBREGS 0x02 /* process using debug registers */
|
||||
#define PCB_KERNFPU 0x04 /* kernel uses fpu */
|
||||
@ -64,44 +64,41 @@ struct pcb {
|
||||
#define PCB_32BIT 0x40 /* process has 32 bit context (segs etc) */
|
||||
#define PCB_FULLCTX 0x80 /* full context restore on sysret */
|
||||
|
||||
u_int64_t pcb_dr0;
|
||||
u_int64_t pcb_dr1;
|
||||
u_int64_t pcb_dr2;
|
||||
u_int64_t pcb_dr3;
|
||||
u_int64_t pcb_dr6;
|
||||
u_int64_t pcb_dr7;
|
||||
register_t pcb_cr0;
|
||||
register_t pcb_cr2;
|
||||
register_t pcb_cr3;
|
||||
register_t pcb_cr4;
|
||||
register_t pcb_dr0;
|
||||
register_t pcb_dr1;
|
||||
register_t pcb_dr2;
|
||||
register_t pcb_dr3;
|
||||
register_t pcb_dr6;
|
||||
register_t pcb_dr7;
|
||||
|
||||
struct savefpu pcb_user_save;
|
||||
uint16_t pcb_initial_fpucw;
|
||||
|
||||
caddr_t pcb_onfault; /* copyin/out fault recovery */
|
||||
|
||||
/* 32-bit segment descriptor */
|
||||
struct user_segment_descriptor pcb_gs32sd;
|
||||
struct user_segment_descriptor pcb_gs32sd;
|
||||
/* local tss, with i/o bitmap; NULL for common */
|
||||
struct amd64tss *pcb_tssp;
|
||||
struct savefpu *pcb_save;
|
||||
char pcb_full_iret;
|
||||
};
|
||||
|
||||
struct xpcb {
|
||||
struct pcb xpcb_pcb;
|
||||
register_t xpcb_cr0;
|
||||
register_t xpcb_cr2;
|
||||
register_t xpcb_cr4;
|
||||
register_t xpcb_kgsbase;
|
||||
struct region_descriptor xpcb_gdt;
|
||||
struct region_descriptor xpcb_idt;
|
||||
struct region_descriptor xpcb_ldt;
|
||||
uint16_t xpcb_tr;
|
||||
struct region_descriptor pcb_gdt;
|
||||
struct region_descriptor pcb_idt;
|
||||
struct region_descriptor pcb_ldt;
|
||||
uint16_t pcb_tr;
|
||||
|
||||
struct savefpu pcb_user_save;
|
||||
};
|
||||
|
||||
#ifdef _KERNEL
|
||||
struct trapframe;
|
||||
|
||||
void makectx(struct trapframe *, struct pcb *);
|
||||
void savectx(struct pcb *);
|
||||
int savectx2(struct xpcb *);
|
||||
int savectx(struct pcb *);
|
||||
#endif
|
||||
|
||||
#endif /* _AMD64_PCB_H_ */
|
||||
|
Loading…
Reference in New Issue
Block a user