Commit b1c3497e authored by Jane Malalane's avatar Jane Malalane Committed by Juergen Gross
Browse files

x86/xen: Add support for HVMOP_set_evtchn_upcall_vector



Implement support for the HVMOP_set_evtchn_upcall_vector hypercall in
order to set the per-vCPU event channel vector callback on Linux and
use it in preference of HVM_PARAM_CALLBACK_IRQ.

If the per-VCPU vector setup is successful on BSP, use this method
for the APs. If not, fallback to the global vector-type callback.

Also register callback_irq at per-vCPU event channel setup to trick
toolstack to think the domain is enlightened.

Suggested-by: default avatar"Roger Pau Monné" <roger.pau@citrix.com>
Signed-off-by: default avatarJane Malalane <jane.malalane@citrix.com>
Reviewed-by: default avatarBoris Ostrovsky <boris.ostrovsky@oracle.com>
Link: https://lore.kernel.org/r/20220729070416.23306-1-jane.malalane@citrix.com


Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
parent 251e90e7
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -107,6 +107,8 @@
 * ID field from 8 to 15 bits, allowing to target APIC IDs up 32768.
 */
#define XEN_HVM_CPUID_EXT_DEST_ID      (1u << 5)
/* Per-vCPU event channel upcalls */
#define XEN_HVM_CPUID_UPCALL_VECTOR    (1u << 6)

/*
 * Leaf 6 (0x40000x05)
+2 −1
Original line number Diff line number Diff line
@@ -23,7 +23,7 @@ static inline int xen_irqs_disabled(struct pt_regs *regs)
/* No need for a barrier -- XCHG is a barrier on x86. */
#define xchg_xen_ulong(ptr, val) xchg((ptr), (val))

extern int xen_have_vector_callback;
extern bool xen_have_vector_callback;

/*
 * Events delivered via platform PCI interrupts are always
@@ -34,4 +34,5 @@ static inline bool xen_support_evtchn_rebind(void)
	return (!xen_hvm_domain() || xen_have_vector_callback);
}

extern bool xen_percpu_upcall;
#endif /* _ASM_X86_XEN_EVENTS_H */
+1 −1
Original line number Diff line number Diff line
@@ -51,7 +51,7 @@ EXPORT_SYMBOL_GPL(xen_start_info);

struct shared_info xen_dummy_shared_info;

__read_mostly int xen_have_vector_callback;
__read_mostly bool xen_have_vector_callback = true;
EXPORT_SYMBOL_GPL(xen_have_vector_callback);

/*
+18 −6
Original line number Diff line number Diff line
@@ -8,6 +8,8 @@

#include <xen/features.h>
#include <xen/events.h>
#include <xen/hvm.h>
#include <xen/interface/hvm/hvm_op.h>
#include <xen/interface/memory.h>

#include <asm/apic.h>
@@ -31,6 +33,9 @@

static unsigned long shared_info_pfn;

__ro_after_init bool xen_percpu_upcall;
EXPORT_SYMBOL_GPL(xen_percpu_upcall);

void xen_hvm_init_shared_info(void)
{
	struct xen_add_to_physmap xatp;
@@ -126,6 +131,9 @@ DEFINE_IDTENTRY_SYSVEC(sysvec_xen_hvm_callback)
{
	struct pt_regs *old_regs = set_irq_regs(regs);

	if (xen_percpu_upcall)
		ack_APIC_irq();

	inc_irq_stat(irq_hv_callback_count);

	xen_hvm_evtchn_do_upcall();
@@ -169,6 +177,15 @@ static int xen_cpu_up_prepare_hvm(unsigned int cpu)
	if (!xen_have_vector_callback)
		return 0;

	if (xen_percpu_upcall) {
		rc = xen_set_upcall_vector(cpu);
		if (rc) {
			WARN(1, "HVMOP_set_evtchn_upcall_vector"
			     " for CPU %d failed: %d\n", cpu, rc);
			return rc;
		}
	}

	if (xen_feature(XENFEAT_hvm_safe_pvclock))
		xen_setup_timer(cpu);

@@ -189,8 +206,6 @@ static int xen_cpu_dead_hvm(unsigned int cpu)
	return 0;
}

static bool no_vector_callback __initdata;

static void __init xen_hvm_guest_init(void)
{
	if (xen_pv_domain())
@@ -213,9 +228,6 @@ static void __init xen_hvm_guest_init(void)

	xen_panic_handler_init();

	if (!no_vector_callback && xen_feature(XENFEAT_hvm_callback_vector))
		xen_have_vector_callback = 1;

	xen_hvm_smp_init();
	WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_hvm, xen_cpu_dead_hvm));
	xen_unplug_emulated_devices();
@@ -241,7 +253,7 @@ early_param("xen_nopv", xen_parse_nopv);

static __init int xen_parse_no_vector_callback(char *arg)
{
	no_vector_callback = true;
	xen_have_vector_callback = false;
	return 0;
}
early_param("xen_no_vector_callback", xen_parse_no_vector_callback);
+9 −1
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <xen/hvm.h>
#include <xen/features.h>
#include <xen/interface/features.h>
#include <xen/events.h>

#include "xen-ops.h"

@@ -14,6 +15,13 @@ void xen_hvm_post_suspend(int suspend_cancelled)
		xen_hvm_init_shared_info();
		xen_vcpu_restore();
	}
	if (xen_percpu_upcall) {
		unsigned int cpu;

		for_each_online_cpu(cpu)
			BUG_ON(xen_set_upcall_vector(cpu));
	} else {
		xen_setup_callback_vector();
	}
	xen_unplug_emulated_devices();
}
Loading