[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v2 0/1] evtchn: make EVTCHNOP_reset suitable for kexec
With the help from David Vrabel (thanks!) I was able to make event channel rebinding work in both kexec/kdump cases. A guest should do the following on kexec/kdump: 1) Figure out store/console interdomain mapping 2) Call PHYSDEVOP_unmap_pirq if needed 3) Call EVTCHNOP_reset 4) Rebind store/console channels with EVTCHNOP_bind_interdomain 5) Update HVM_PARAM_CONSOLE_EVTCHN/HVM_PARAM_STORE_EVTCHN Here is an example of guest code (to be called from kexec/kdump handlers): void xen_hvm_reset_eventchannels(void) { struct evtchn_status status; struct physdev_unmap_pirq unmap_irq; struct evtchn_close close; struct evtchn_reset reset; struct evtchn_bind_interdomain int_bind; struct xen_hvm_param xhv; uint64_t store_evtchn = 0, console_evtchn = 0; domid_t store_domain = 0, console_domain = 0; evtchn_port_t store_rem_port = 0, console_rem_port = 0; int port, rc = -ENOENT; memset(&status, 0, sizeof(status)); status.dom = DOMID_SELF; if (hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &store_evtchn) == 0) { pr_debug("xen: need to rebind store evtchn %d\n", (uint32_t)store_evtchn); status.port = store_evtchn; rc = HYPERVISOR_event_channel_op(EVTCHNOP_status, &status); if (!rc && status.status == EVTCHNSTAT_interdomain) { pr_debug("xen: store port: %d, interdomain %d:%d", status.port, status.u.interdomain.dom, status.u.interdomain.port); store_domain = status.u.interdomain.dom; store_rem_port = status.u.interdomain.port; } } if (hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &console_evtchn) == 0) { pr_debug("xen: need to rebind console evtchn %d\n", (uint32_t)console_evtchn); status.port = console_evtchn; rc = HYPERVISOR_event_channel_op(EVTCHNOP_status, &status); if (!rc && status.status == EVTCHNSTAT_interdomain) { pr_debug("xen: console port: %d, interdomain %d:%d", status.port, status.u.interdomain.dom, status.u.interdomain.port); console_domain = status.u.interdomain.dom; console_rem_port = status.u.interdomain.port; } } for (port = 0; port < xen_evtchn_max_channels(); port++) { status.dom = DOMID_SELF; status.port = port; rc = HYPERVISOR_event_channel_op(EVTCHNOP_status, &status); if (rc < 0) continue; if (status.status != EVTCHNSTAT_closed) { close.port = port; if (HYPERVISOR_event_channel_op(EVTCHNOP_close, &close) != 0) pr_warn("xen: failed to close evtchn %d\n", port); } if (status.status == EVTCHNSTAT_pirq) { unmap_irq.pirq = status.u.pirq; unmap_irq.domid = DOMID_SELF; pr_warn("xen: unmapping previously mapped pirq %d\n", unmap_irq.pirq); if (HYPERVISOR_physdev_op(PHYSDEVOP_unmap_pirq, &unmap_irq) != 0) pr_warn("xen: failed to unmap pirq %d\n", unmap_irq.pirq); } } reset.dom = DOMID_SELF; if (HYPERVISOR_event_channel_op(EVTCHNOP_reset, &reset)) pr_warn("failed to reset all event channels!\n"); if (store_rem_port > 0) { int_bind.remote_dom = store_domain; int_bind.remote_port = store_rem_port; pr_debug("rebinding store: %d -> %d:%d\n", int_bind.local_port, int_bind.remote_port, int_bind.remote_dom); if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &int_bind)) pr_warn("failed to rebind store!\n"); if (int_bind.local_port != store_evtchn) { xhv.domid = DOMID_SELF; xhv.index = HVM_PARAM_STORE_EVTCHN; xhv.value = int_bind.local_port; if (HYPERVISOR_hvm_op(HVMOP_set_param, &xhv)) { pr_warn("Cannot set HVM_PARAM_STORE_EVTCHN!\n"); } } } if (console_rem_port > 0) { int_bind.remote_dom = console_domain; int_bind.remote_port = console_rem_port; pr_debug("rebinding console: %d -> %d:%d\n", int_bind.local_port, int_bind.remote_port, int_bind.remote_dom); if (HYPERVISOR_event_channel_op(EVTCHNOP_bind_interdomain, &int_bind)) pr_warn("failed to rebind console!\n"); if (int_bind.local_port != console_evtchn) { xhv.domid = DOMID_SELF; xhv.index = HVM_PARAM_CONSOLE_EVTCHN; xhv.value = int_bind.local_port; if (HYPERVISOR_hvm_op(HVMOP_set_param, &xhv)) { pr_warn("Cannot set HVM_PARAM_CONSOLE_EVTCHN!\n"); } } } } Vitaly Kuznetsov (1): evtchn: make EVTCHNOP_reset suitable for kexec xen/common/event_channel.c | 11 +++++++++++ xen/common/event_fifo.c | 1 + 2 files changed, 12 insertions(+) -- 1.9.3 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |