Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0991d22d authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Juergen Gross
Browse files

x86/xen: separate PV and HVM hypervisors



As a preparation to splitting the code we need to untangle it:

x86_hyper_xen -> x86_hyper_xen_hvm and x86_hyper_xen_pv
xen_platform() -> xen_platform_hvm() and xen_platform_pv()
xen_cpu_up_prepare() -> xen_cpu_up_prepare_pv() and xen_cpu_up_prepare_hvm()
xen_cpu_dead() -> xen_cpu_dead_pv() and xen_cpu_dead_pv_hvm()

Add two parameters to xen_cpuhp_setup() to pass proper cpu_up_prepare and
cpu_dead hooks. xen_set_cpu_features() is now PV-only so the redundant
xen_pv_domain() check can be dropped.

Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Reviewed-by: default avatarJuergen Gross <jgross@suse.com>
Signed-off-by: default avatarJuergen Gross <jgross@suse.com>
parent d3b5d352
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -53,7 +53,8 @@ extern const struct hypervisor_x86 *x86_hyper;
/* Recognized hypervisors */
extern const struct hypervisor_x86 x86_hyper_vmware;
extern const struct hypervisor_x86 x86_hyper_ms_hyperv;
extern const struct hypervisor_x86 x86_hyper_xen;
extern const struct hypervisor_x86 x86_hyper_xen_pv;
extern const struct hypervisor_x86 x86_hyper_xen_hvm;
extern const struct hypervisor_x86 x86_hyper_kvm;

extern void init_hypervisor(struct cpuinfo_x86 *c);
+2 −1
Original line number Diff line number Diff line
@@ -29,7 +29,8 @@
static const __initconst struct hypervisor_x86 * const hypervisors[] =
{
#ifdef CONFIG_XEN
	&x86_hyper_xen,
	&x86_hyper_xen_pv,
	&x86_hyper_xen_hvm,
#endif
	&x86_hyper_vmware,
	&x86_hyper_ms_hyperv,
+75 −39
Original line number Diff line number Diff line
@@ -140,9 +140,11 @@ void *xen_initial_gdt;

RESERVE_BRK(shared_info_page_brk, PAGE_SIZE);

static int xen_cpu_up_prepare(unsigned int cpu);
static int xen_cpu_up_prepare_pv(unsigned int cpu);
static int xen_cpu_up_prepare_hvm(unsigned int cpu);
static int xen_cpu_up_online(unsigned int cpu);
static int xen_cpu_dead(unsigned int cpu);
static int xen_cpu_dead_pv(unsigned int cpu);
static int xen_cpu_dead_hvm(unsigned int cpu);

/*
 * Point at some empty memory to start with. We map the real shared_info
@@ -1448,13 +1450,14 @@ static void __init xen_dom0_set_legacy_features(void)
	x86_platform.legacy.rtc = 1;
}

static int xen_cpuhp_setup(void)
static int xen_cpuhp_setup(int (*cpu_up_prepare_cb)(unsigned int),
			   int (*cpu_dead_cb)(unsigned int))
{
	int rc;

	rc = cpuhp_setup_state_nocalls(CPUHP_XEN_PREPARE,
				       "x86/xen/hvm_guest:prepare",
				       xen_cpu_up_prepare, xen_cpu_dead);
				       cpu_up_prepare_cb, cpu_dead_cb);
	if (rc >= 0) {
		rc = cpuhp_setup_state_nocalls(CPUHP_AP_ONLINE_DYN,
					       "x86/xen/hvm_guest:online",
@@ -1560,7 +1563,7 @@ asmlinkage __visible void __init xen_start_kernel(void)
	   possible map and a non-dummy shared_info. */
	per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0];

	WARN_ON(xen_cpuhp_setup());
	WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_pv, xen_cpu_dead_pv));

	local_irq_disable();
	early_boot_irqs_disabled = true;
@@ -1838,11 +1841,25 @@ static void __init init_hvm_pv_info(void)
}
#endif

static int xen_cpu_up_prepare(unsigned int cpu)
static int xen_cpu_up_prepare_pv(unsigned int cpu)
{
	int rc;

	xen_setup_timer(cpu);

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

static int xen_cpu_up_prepare_hvm(unsigned int cpu)
{
	int rc;

	if (xen_hvm_domain()) {
	/*
	 * This can happen if CPU was offlined earlier and
	 * offlining timed out in common_cpu_die().
@@ -1857,9 +1874,8 @@ static int xen_cpu_up_prepare(unsigned int cpu)
	else
		per_cpu(xen_vcpu_id, cpu) = cpu;
	xen_vcpu_setup(cpu);
	}

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

	rc = xen_smp_intr_init(cpu);
@@ -1871,11 +1887,20 @@ static int xen_cpu_up_prepare(unsigned int cpu)
	return 0;
}

static int xen_cpu_dead(unsigned int cpu)
static int xen_cpu_dead_pv(unsigned int cpu)
{
	xen_smp_intr_free(cpu);

	if (xen_pv_domain() || xen_feature(XENFEAT_hvm_safe_pvclock))
	xen_teardown_timer(cpu);

	return 0;
}

static int xen_cpu_dead_hvm(unsigned int cpu)
{
	xen_smp_intr_free(cpu);

	if (xen_feature(XENFEAT_hvm_safe_pvclock))
		xen_teardown_timer(cpu);

       return 0;
@@ -1917,7 +1942,7 @@ static void __init xen_hvm_guest_init(void)
	BUG_ON(!xen_feature(XENFEAT_hvm_callback_vector));

	xen_hvm_smp_init();
	WARN_ON(xen_cpuhp_setup());
	WARN_ON(xen_cpuhp_setup(xen_cpu_up_prepare_hvm, xen_cpu_dead_hvm));
	xen_unplug_emulated_devices();
	x86_init.irqs.intr_init = xen_init_IRQ;
	xen_hvm_init_time_ops();
@@ -1940,9 +1965,17 @@ static __init int xen_parse_nopv(char *arg)
}
early_param("xen_nopv", xen_parse_nopv);

static uint32_t __init xen_platform(void)
static uint32_t __init xen_platform_pv(void)
{
	if (xen_nopv)
	if (xen_pv_domain())
		return xen_cpuid_base();

	return 0;
}

static uint32_t __init xen_platform_hvm(void)
{
	if (xen_pv_domain() || xen_nopv)
		return 0;

	return xen_cpuid_base();
@@ -1964,11 +1997,9 @@ EXPORT_SYMBOL_GPL(xen_hvm_need_lapic);

static void xen_set_cpu_features(struct cpuinfo_x86 *c)
{
	if (xen_pv_domain()) {
	clear_cpu_bug(c, X86_BUG_SYSRET_SS_ATTRS);
	set_cpu_cap(c, X86_FEATURE_XENPV);
}
}

static void xen_pin_vcpu(int cpu)
{
@@ -2009,17 +2040,22 @@ static void xen_pin_vcpu(int cpu)
	}
}

const struct hypervisor_x86 x86_hyper_xen = {
	.name			= "Xen",
	.detect			= xen_platform,
#ifdef CONFIG_XEN_PVHVM
	.init_platform		= xen_hvm_guest_init,
#endif
	.x2apic_available	= xen_x2apic_para_available,
const struct hypervisor_x86 x86_hyper_xen_pv = {
	.name                   = "Xen PV",
	.detect                 = xen_platform_pv,
	.set_cpu_features       = xen_set_cpu_features,
	.pin_vcpu               = xen_pin_vcpu,
};
EXPORT_SYMBOL(x86_hyper_xen);
EXPORT_SYMBOL(x86_hyper_xen_pv);

const struct hypervisor_x86 x86_hyper_xen_hvm = {
	.name                   = "Xen HVM",
	.detect                 = xen_platform_hvm,
	.init_platform          = xen_hvm_guest_init,
	.pin_vcpu               = xen_pin_vcpu,
	.x2apic_available       = xen_x2apic_para_available,
};
EXPORT_SYMBOL(x86_hyper_xen_hvm);

#ifdef CONFIG_HOTPLUG_CPU
void xen_arch_register_cpu(int num)