diff options
author | gibbs <gibbs@FreeBSD.org> | 2013-09-20 05:06:03 +0000 |
---|---|---|
committer | gibbs <gibbs@FreeBSD.org> | 2013-09-20 05:06:03 +0000 |
commit | a9c07a6f6791cbf5f8350541942b0dab762b0423 (patch) | |
tree | 297f8425e6baa2d90b45079c46930ff9d40e9994 /sys/amd64 | |
parent | 45812e0f976ce4fd4915dda57316808d8bb5f23e (diff) | |
download | FreeBSD-src-a9c07a6f6791cbf5f8350541942b0dab762b0423.zip FreeBSD-src-a9c07a6f6791cbf5f8350541942b0dab762b0423.tar.gz |
Add support for suspend/resume/migration operations when running as a
Xen PVHVM guest.
Submitted by: Roger Pau Monné
Sponsored by: Citrix Systems R&D
Reviewed by: gibbs
Approved by: re (blanket Xen)
MFC after: 2 weeks
sys/amd64/amd64/mp_machdep.c:
sys/i386/i386/mp_machdep.c:
- Make sure that are no MMU related IPIs pending on migration.
- Reset pending IPI_BITMAP on resume.
- Init vcpu_info on resume.
sys/amd64/include/intr_machdep.h:
sys/i386/include/intr_machdep.h:
sys/x86/acpica/acpi_wakeup.c:
sys/x86/x86/intr_machdep.c:
sys/x86/isa/atpic.c:
sys/x86/x86/io_apic.c:
sys/x86/x86/local_apic.c:
- Add a "suspend_cancelled" parameter to pic_resume(). For the
Xen PIC, restoration of interrupt services differs between
the aborted suspend and normal resume cases, so we must provide
this information.
sys/dev/acpica/acpi_timer.c:
sys/dev/xen/timer/timer.c:
sys/timetc.h:
- Don't swap out "suspend safe" timers across a suspend/resume
cycle. This includes the Xen PV and ACPI timers.
sys/dev/xen/control/control.c:
- Perform proper suspend/resume process for PVHVM:
- Suspend all APs before going into suspension, this allows us
to reset the vcpu_info on resume for each AP.
- Reset shared info page and callback on resume.
sys/dev/xen/timer/timer.c:
- Implement suspend/resume support for the PV timer. Since FreeBSD
doesn't perform a per-cpu resume of the timer, we need to call
smp_rendezvous in order to correctly resume the timer on each CPU.
sys/dev/xen/xenpci/xenpci.c:
- Don't reset the PCI interrupt on each suspend/resume.
sys/kern/subr_smp.c:
- When suspending a PVHVM domain make sure there are no MMU IPIs
in-flight, or we will get a lockup on resume due to the fact that
pending event channels are not carried over on migration.
- Implement a generic version of restart_cpus that can be used by
suspended and stopped cpus.
sys/x86/xen/hvm.c:
- Implement resume support for the hypercall page and shared info.
- Clear vcpu_info so it can be reset by APs when resuming from
suspension.
sys/dev/xen/xenpci/xenpci.c:
sys/x86/xen/hvm.c:
sys/x86/xen/xen_intr.c:
- Support UP kernel configurations.
sys/x86/xen/xen_intr.c:
- Properly rebind per-cpus VIRQs and IPIs on resume.
Diffstat (limited to 'sys/amd64')
-rw-r--r-- | sys/amd64/amd64/mp_machdep.c | 16 | ||||
-rw-r--r-- | sys/amd64/include/intr_machdep.h | 4 |
2 files changed, 18 insertions, 2 deletions
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c index 0fdb668..1f02211 100644 --- a/sys/amd64/amd64/mp_machdep.c +++ b/sys/amd64/amd64/mp_machdep.c @@ -1468,6 +1468,10 @@ cpususpend_handler(void) cpu = PCPU_GET(cpuid); +#ifdef XENHVM + mtx_assert(&smp_ipi_mtx, MA_NOTOWNED); +#endif + if (savectx(susppcbs[cpu])) { ctx_fpusave(susppcbs[cpu]->pcb_fpususpend); wbinvd(); @@ -1486,11 +1490,23 @@ cpususpend_handler(void) while (!CPU_ISSET(cpu, &started_cpus)) ia32_pause(); +#ifdef XENHVM + /* + * Reset pending bitmap IPIs, because Xen doesn't preserve pending + * event channels on migration. + */ + cpu_ipi_pending[cpu] = 0; + /* register vcpu_info area */ + xen_hvm_init_cpu(); +#endif + /* Resume MCA and local APIC */ mca_resume(); lapic_setup(0); CPU_CLR_ATOMIC(cpu, &started_cpus); + /* Indicate that we are resumed */ + CPU_CLR_ATOMIC(cpu, &suspended_cpus); } /* diff --git a/sys/amd64/include/intr_machdep.h b/sys/amd64/include/intr_machdep.h index c8b454d..fb71b5a 100644 --- a/sys/amd64/include/intr_machdep.h +++ b/sys/amd64/include/intr_machdep.h @@ -102,7 +102,7 @@ struct pic { int (*pic_vector)(struct intsrc *); int (*pic_source_pending)(struct intsrc *); void (*pic_suspend)(struct pic *); - void (*pic_resume)(struct pic *); + void (*pic_resume)(struct pic *, bool suspend_cancelled); int (*pic_config_intr)(struct intsrc *, enum intr_trigger, enum intr_polarity); int (*pic_assign_cpu)(struct intsrc *, u_int apic_id); @@ -170,7 +170,7 @@ struct intsrc *intr_lookup_source(int vector); int intr_register_pic(struct pic *pic); int intr_register_source(struct intsrc *isrc); int intr_remove_handler(void *cookie); -void intr_resume(void); +void intr_resume(bool suspend_cancelled); void intr_suspend(void); void intrcnt_add(const char *name, u_long **countp); void nexus_add_irq(u_long irq); |