Tweak memory allocation for amd64 suspend/resume CPU context.
This commit is contained in:
parent
c2b1d5a3d6
commit
8fa0490a2e
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user