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

Commit 76d36ab7 authored by Vitaly Kuznetsov's avatar Vitaly Kuznetsov Committed by Greg Kroah-Hartman
Browse files

hv: switch to cpuhp state machine for synic init/cleanup



To make it possible to online/offline CPUs switch to cpuhp infrastructure
for doing hv_synic_init()/hv_synic_cleanup().

Signed-off-by: default avatarVitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: default avatarK. Y. Srinivasan <kys@microsoft.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent e7e97dd8
Loading
Loading
Loading
Loading
+7 −8
Original line number Diff line number Diff line
@@ -496,7 +496,7 @@ void hv_synic_free(void)
 * retrieve the initialized message and event pages.  Otherwise, we create and
 * initialize the message and event pages.
 */
void hv_synic_init(void *arg)
int hv_synic_init(unsigned int cpu)
{
	u64 version;
	union hv_synic_simp simp;
@@ -505,10 +505,8 @@ void hv_synic_init(void *arg)
	union hv_synic_scontrol sctrl;
	u64 vp_index;

	int cpu = smp_processor_id();

	if (!hv_context.hypercall_page)
		return;
		return -EFAULT;

	/* Check the version */
	rdmsrl(HV_X64_MSR_SVERSION, version);
@@ -563,7 +561,7 @@ void hv_synic_init(void *arg)
						HV_TIMER_FREQUENCY,
						HV_MIN_DELTA_TICKS,
						HV_MAX_MAX_DELTA_TICKS);
	return;
	return 0;
}

/*
@@ -583,16 +581,15 @@ void hv_synic_clockevents_cleanup(void)
/*
 * hv_synic_cleanup - Cleanup routine for hv_synic_init().
 */
void hv_synic_cleanup(void *arg)
int hv_synic_cleanup(unsigned int cpu)
{
	union hv_synic_sint shared_sint;
	union hv_synic_simp simp;
	union hv_synic_siefp siefp;
	union hv_synic_scontrol sctrl;
	int cpu = smp_processor_id();

	if (!hv_context.synic_initialized)
		return;
		return -EFAULT;

	/* Turn off clockevent device */
	if (ms_hyperv.features & HV_X64_MSR_SYNTIMER_AVAILABLE) {
@@ -624,4 +621,6 @@ void hv_synic_cleanup(void *arg)
	rdmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);
	sctrl.enable = 0;
	wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64);

	return 0;
}
+2 −2
Original line number Diff line number Diff line
@@ -505,9 +505,9 @@ extern int hv_synic_alloc(void);

extern void hv_synic_free(void);

extern void hv_synic_init(void *irqarg);
extern int hv_synic_init(unsigned int cpu);

extern void hv_synic_cleanup(void *arg);
extern int hv_synic_cleanup(unsigned int cpu);

extern void hv_synic_clockevents_cleanup(void);

+11 −8
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ static struct acpi_device *hv_acpi_dev;

static struct completion probe_event;

static int hyperv_cpuhp_online;

static void hyperv_report_panic(struct pt_regs *regs)
{
@@ -997,7 +998,12 @@ static int vmbus_bus_init(void)
	 * Initialize the per-cpu interrupt state and
	 * connect to the host.
	 */
	on_each_cpu(hv_synic_init, NULL, 1);
	ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "x86/hyperv:online",
				hv_synic_init, hv_synic_cleanup);
	if (ret < 0)
		goto err_alloc;
	hyperv_cpuhp_online = ret;

	ret = vmbus_connect();
	if (ret)
		goto err_connect;
@@ -1019,7 +1025,7 @@ static int vmbus_bus_init(void)
	return 0;

err_connect:
	on_each_cpu(hv_synic_cleanup, NULL, 1);
	cpuhp_remove_state(hyperv_cpuhp_online);
err_alloc:
	hv_synic_free();
	hv_remove_vmbus_irq();
@@ -1478,12 +1484,9 @@ static struct acpi_driver vmbus_acpi_driver = {

static void hv_kexec_handler(void)
{
	int cpu;

	hv_synic_clockevents_cleanup();
	vmbus_initiate_unload(false);
	for_each_online_cpu(cpu)
		smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1);
	cpuhp_remove_state(hyperv_cpuhp_online);
	hv_cleanup(false);
};

@@ -1495,7 +1498,7 @@ static void hv_crash_handler(struct pt_regs *regs)
	 * doing the cleanup for current CPU only. This should be sufficient
	 * for kdump.
	 */
	hv_synic_cleanup(NULL);
	hv_synic_cleanup(smp_processor_id());
	hv_cleanup(true);
};

@@ -1559,8 +1562,8 @@ static void __exit vmbus_exit(void)
	hv_cleanup(false);
	for_each_online_cpu(cpu) {
		tasklet_kill(hv_context.event_dpc[cpu]);
		smp_call_function_single(cpu, hv_synic_cleanup, NULL, 1);
	}
	cpuhp_remove_state(hyperv_cpuhp_online);
	hv_synic_free();
	acpi_bus_unregister_driver(&vmbus_acpi_driver);
	if (vmbus_proto_version > VERSION_WIN7)