Commit 8fd12b03 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'hyperv-next-signed-20260421' of...

Merge tag 'hyperv-next-signed-20260421' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux

Pull Hyper-V updates from Wei Liu:

 - Fix cross-compilation for hv tools (Aditya Garg)

 - Fix vmemmap_shift exceeding MAX_FOLIO_ORDER in mshv_vtl (Naman Jain)

 - Limit channel interrupt scan to relid high water mark (Michael
   Kelley)

 - Export hv_vmbus_exists() and use it in pci-hyperv (Dexuan Cui)

 - Fix cleanup and shutdown issues for MSHV (Jork Loeser)

 - Introduce more tracing support for MSHV (Stanislav Kinsburskii)

* tag 'hyperv-next-signed-20260421' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  x86/hyperv: Skip LP/VP creation on kexec
  x86/hyperv: move stimer cleanup to hv_machine_shutdown()
  Drivers: hv: vmbus: fix hyperv_cpuhp_online variable shadowing
  mshv: Add tracepoint for GPA intercept handling
  mshv_vtl: Fix vmemmap_shift exceeding MAX_FOLIO_ORDER
  tools: hv: Fix cross-compilation
  Drivers: hv: vmbus: Export hv_vmbus_exists() and use it in pci-hyperv
  mshv: Introduce tracing support
  Drivers: hv: vmbus: Limit channel interrupt scan to relid high water mark
parents beaba8bf 5170a82e
Loading
Loading
Loading
Loading
+13 −2
Original line number Diff line number Diff line
@@ -237,8 +237,12 @@ void hv_remove_crash_handler(void)
#ifdef CONFIG_KEXEC_CORE
static void hv_machine_shutdown(void)
{
	if (kexec_in_progress && hv_kexec_handler)
	if (kexec_in_progress) {
		hv_stimer_global_cleanup();

		if (hv_kexec_handler)
			hv_kexec_handler();
	}

	/*
	 * Call hv_cpu_die() on all the CPUs, otherwise later the hypervisor
@@ -427,6 +431,10 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus)
	}

#ifdef CONFIG_X86_64
	/* If AP LPs exist, we are in a kexec'd kernel and VPs already exist */
	if (num_present_cpus() == 1 || hv_lp_exists(1))
		return;

	for_each_present_cpu(i) {
		if (i == 0)
			continue;
@@ -434,6 +442,9 @@ static void __init hv_smp_prepare_cpus(unsigned int max_cpus)
		BUG_ON(ret);
	}

	ret = hv_call_notify_all_processors_started();
	WARN_ON(ret);

	for_each_present_cpu(i) {
		if (i == 0)
			continue;
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ hv_utils-y := hv_util.o hv_kvp.o hv_snapshot.o hv_utils_transport.o
mshv_root-y := mshv_root_main.o mshv_synic.o mshv_eventfd.o mshv_irq.o \
	       mshv_root_hv_call.o mshv_portid_table.o mshv_regions.o
mshv_root-$(CONFIG_DEBUG_FS) += mshv_debugfs.o
mshv_root-$(CONFIG_TRACEPOINTS) += mshv_trace.o
mshv_vtl-y := mshv_vtl_main.o

# Code that must be built-in
+12 −4
Original line number Diff line number Diff line
@@ -384,8 +384,18 @@ static void free_channel(struct vmbus_channel *channel)

void vmbus_channel_map_relid(struct vmbus_channel *channel)
{
	if (WARN_ON(channel->offermsg.child_relid >= MAX_CHANNEL_RELIDS))
	u32 new_relid = channel->offermsg.child_relid;

	if (WARN_ON(new_relid >= MAX_CHANNEL_RELIDS))
		return;

	/*
	 * This function is always called in the tasklet for the connect CPU.
	 * So updating the relid hiwater mark does not need to be atomic.
	 */
	if (new_relid > READ_ONCE(vmbus_connection.relid_hiwater))
		WRITE_ONCE(vmbus_connection.relid_hiwater, new_relid);

	/*
	 * The mapping of the channel's relid is visible from the CPUs that
	 * execute vmbus_chan_sched() by the time that vmbus_chan_sched() will
@@ -411,9 +421,7 @@ void vmbus_channel_map_relid(struct vmbus_channel *channel)
	 *      of the VMBus driver and vmbus_chan_sched() can not run before
	 *      vmbus_bus_resume() has completed execution (cf. resume_noirq).
	 */
	virt_store_mb(
		vmbus_connection.channels[channel->offermsg.child_relid],
		channel);
	virt_store_mb(vmbus_connection.channels[new_relid], channel);
}

void vmbus_channel_unmap_relid(struct vmbus_channel *channel)
+47 −0
Original line number Diff line number Diff line
@@ -239,3 +239,50 @@ int hv_call_create_vp(int node, u64 partition_id, u32 vp_index, u32 flags)
	return ret;
}
EXPORT_SYMBOL_GPL(hv_call_create_vp);

int hv_call_notify_all_processors_started(void)
{
	struct hv_input_notify_partition_event *input;
	u64 status;
	unsigned long irq_flags;
	int ret = 0;

	local_irq_save(irq_flags);
	input = *this_cpu_ptr(hyperv_pcpu_input_arg);
	memset(input, 0, sizeof(*input));
	input->event = HV_PARTITION_ALL_LOGICAL_PROCESSORS_STARTED;
	status = hv_do_hypercall(HVCALL_NOTIFY_PARTITION_EVENT,
				 input, NULL);
	local_irq_restore(irq_flags);

	if (!hv_result_success(status)) {
		hv_status_err(status, "\n");
		ret = hv_result_to_errno(status);
	}
	return ret;
}

bool hv_lp_exists(u32 lp_index)
{
	struct hv_input_get_logical_processor_run_time *input;
	struct hv_output_get_logical_processor_run_time *output;
	unsigned long flags;
	u64 status;

	local_irq_save(flags);
	input = *this_cpu_ptr(hyperv_pcpu_input_arg);
	output = *this_cpu_ptr(hyperv_pcpu_output_arg);

	input->lp_index = lp_index;
	status = hv_do_hypercall(HVCALL_GET_LOGICAL_PROCESSOR_RUN_TIME,
				 input, output);
	local_irq_restore(flags);

	if (!hv_result_success(status) &&
	    hv_result(status) != HV_STATUS_INVALID_LP_INDEX) {
		hv_status_err(status, "\n");
		BUG();
	}

	return hv_result_success(status);
}
+2 −1
Original line number Diff line number Diff line
@@ -276,8 +276,9 @@ struct vmbus_connection {
	struct list_head chn_list;
	struct mutex channel_mutex;

	/* Array of channels */
	/* Array of channel pointers, indexed by relid */
	struct vmbus_channel **channels;
	u32 relid_hiwater;

	/*
	 * An offer message is handled first on the work_queue, and then
Loading