Tweak memory allocation for amd64 suspend/resume CPU context.

This commit is contained in:
Jung-uk Kim 2009-11-04 22:39:18 +00:00
parent c2b1d5a3d6
commit 8fa0490a2e
2 changed files with 17 additions and 19 deletions

View File

@ -65,9 +65,9 @@ extern int acpi_resume_beep;
extern int acpi_reset_video;
#ifdef SMP
extern struct xpcb *stopxpcbs;
extern struct xpcb **stopxpcbs;
#else
static struct xpcb *stopxpcbs;
static struct xpcb **stopxpcbs;
#endif
int acpi_restorecpu(struct xpcb *, vm_offset_t);
@ -104,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_xpcb, struct xpcb *, stopxpcbs[cpu]);
WAKECODE_FIXUP(wakeup_gdt, uint16_t, stopxpcbs[cpu]->xpcb_gdt.rd_limit);
WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t,
stopxpcbs[cpu].xpcb_gdt.rd_base);
stopxpcbs[cpu]->xpcb_gdt.rd_base);
WAKECODE_FIXUP(wakeup_cpu, int, cpu);
/* do an INIT IPI: assert RESET */
@ -245,8 +245,8 @@ acpi_sleep_machdep(struct acpi_softc *sc, int state)
cr3 = rcr3();
load_cr3(KPML4phys);
stopfpu = &stopxpcbs[0].xpcb_pcb.pcb_save;
if (acpi_savecpu(&stopxpcbs[0])) {
stopfpu = &stopxpcbs[0]->xpcb_pcb.pcb_save;
if (acpi_savecpu(stopxpcbs[0])) {
fpugetregs(curthread, stopfpu);
#ifdef SMP
@ -261,11 +261,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_xpcb, struct xpcb *, stopxpcbs[0]);
WAKECODE_FIXUP(wakeup_gdt, uint16_t,
stopxpcbs[0].xpcb_gdt.rd_limit);
stopxpcbs[0]->xpcb_gdt.rd_limit);
WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t,
stopxpcbs[0].xpcb_gdt.rd_base);
stopxpcbs[0]->xpcb_gdt.rd_base);
WAKECODE_FIXUP(wakeup_cpu, int, 0);
/* Call ACPICA to enter the desired sleep state */
@ -320,6 +320,7 @@ static void *
acpi_alloc_wakeup_handler(void)
{
void *wakeaddr;
int i;
/*
* Specify the region for our wakeup code. We want it in the low 1 MB
@ -334,12 +335,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_NOWAIT);
if (stopxpcbs == NULL) {
contigfree(wakeaddr, 4 * PAGE_SIZE, M_DEVBUF);
printf("%s: can't alloc CPU state memory\n", __func__);
return (NULL);
}
stopxpcbs = malloc(mp_ncpus * sizeof(*stopxpcbs), M_DEVBUF, M_WAITOK);
for (i = 0; i < mp_ncpus; i++)
stopxpcbs[i] = malloc(sizeof(**stopxpcbs), M_DEVBUF, M_WAITOK);
return (wakeaddr);
}

View File

@ -105,7 +105,7 @@ extern pt_entry_t *KPTphys;
extern pt_entry_t *SMPpt;
struct pcb stoppcbs[MAXCPU];
struct xpcb *stopxpcbs = NULL;
struct xpcb **stopxpcbs = NULL;
/* Variables needed for SMP tlb shootdown. */
vm_offset_t smp_tlb_addr1;
@ -1256,8 +1256,8 @@ cpususpend_handler(void)
rf = intr_disable();
cr3 = rcr3();
stopfpu = &stopxpcbs[cpu].xpcb_pcb.pcb_save;
if (savectx2(&stopxpcbs[cpu])) {
stopfpu = &stopxpcbs[cpu]->xpcb_pcb.pcb_save;
if (savectx2(stopxpcbs[cpu])) {
fpugetregs(curthread, stopfpu);
wbinvd();
atomic_set_int(&stopped_cpus, cpumask);