1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0
20d1edf46SJeremy Fitzhardinge #include <linux/hardirq.h>
30d1edf46SJeremy Fitzhardinge
466bcaf0bSThomas Gleixner #include <asm/x86_init.h>
566bcaf0bSThomas Gleixner
60d1edf46SJeremy Fitzhardinge #include <xen/interface/xen.h>
70d1edf46SJeremy Fitzhardinge #include <xen/interface/sched.h>
80d1edf46SJeremy Fitzhardinge #include <xen/interface/vcpu.h>
92771374dSMukesh Rathor #include <xen/features.h>
100ec53ecfSStefano Stabellini #include <xen/events.h>
110d1edf46SJeremy Fitzhardinge
120d1edf46SJeremy Fitzhardinge #include <asm/xen/hypercall.h>
130d1edf46SJeremy Fitzhardinge #include <asm/xen/hypervisor.h>
140d1edf46SJeremy Fitzhardinge
150d1edf46SJeremy Fitzhardinge #include "xen-ops.h"
160d1edf46SJeremy Fitzhardinge
170d1edf46SJeremy Fitzhardinge /*
180d1edf46SJeremy Fitzhardinge * Force a proper event-channel callback from Xen after clearing the
190d1edf46SJeremy Fitzhardinge * callback mask. We do this in a very simple manner, by making a call
200d1edf46SJeremy Fitzhardinge * down into Xen. The pending flag will be checked by Xen on return.
210d1edf46SJeremy Fitzhardinge */
xen_force_evtchn_callback(void)22847d9317SPeter Zijlstra noinstr void xen_force_evtchn_callback(void)
230d1edf46SJeremy Fitzhardinge {
240d1edf46SJeremy Fitzhardinge (void)HYPERVISOR_xen_version(0, NULL);
250d1edf46SJeremy Fitzhardinge }
260d1edf46SJeremy Fitzhardinge
xen_safe_halt(void)27*10a09940SPeter Zijlstra static noinstr void xen_safe_halt(void)
280d1edf46SJeremy Fitzhardinge {
290d1edf46SJeremy Fitzhardinge /* Blocking includes an implicit local_irq_enable(). */
300d1edf46SJeremy Fitzhardinge if (HYPERVISOR_sched_op(SCHEDOP_block, NULL) != 0)
310d1edf46SJeremy Fitzhardinge BUG();
320d1edf46SJeremy Fitzhardinge }
330d1edf46SJeremy Fitzhardinge
xen_halt(void)340d1edf46SJeremy Fitzhardinge static void xen_halt(void)
350d1edf46SJeremy Fitzhardinge {
360d1edf46SJeremy Fitzhardinge if (irqs_disabled())
37ad5475f9SVitaly Kuznetsov HYPERVISOR_vcpu_op(VCPUOP_down,
38ad5475f9SVitaly Kuznetsov xen_vcpu_nr(smp_processor_id()), NULL);
390d1edf46SJeremy Fitzhardinge else
400d1edf46SJeremy Fitzhardinge xen_safe_halt();
410d1edf46SJeremy Fitzhardinge }
420d1edf46SJeremy Fitzhardinge
431462eb38SPeter Zijlstra static const typeof(pv_ops) xen_irq_ops __initconst = {
441462eb38SPeter Zijlstra .irq = {
45e453f872SJuergen Gross /* Initial interrupt flag handling only called while interrupts off. */
46e453f872SJuergen Gross .save_fl = __PV_IS_CALLEE_SAVE(paravirt_ret0),
47e453f872SJuergen Gross .irq_disable = __PV_IS_CALLEE_SAVE(paravirt_nop),
48e453f872SJuergen Gross .irq_enable = __PV_IS_CALLEE_SAVE(paravirt_BUG),
49ecb93d1cSJeremy Fitzhardinge
500d1edf46SJeremy Fitzhardinge .safe_halt = xen_safe_halt,
510d1edf46SJeremy Fitzhardinge .halt = xen_halt,
521462eb38SPeter Zijlstra },
530d1edf46SJeremy Fitzhardinge };
540d1edf46SJeremy Fitzhardinge
xen_init_irq_ops(void)557d81c3b9SRandy Dunlap void __init xen_init_irq_ops(void)
560d1edf46SJeremy Fitzhardinge {
571462eb38SPeter Zijlstra pv_ops.irq = xen_irq_ops.irq;
5866bcaf0bSThomas Gleixner x86_init.irqs.intr_init = xen_init_IRQ;
590d1edf46SJeremy Fitzhardinge }
60