Commit 86782c16 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'hyperv-fixes-signed-20260406' of...

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

Pull Hyper-V fixes from Wei Liu:

 - Two fixes for Hyper-V PCI driver (Long Li, Sahil Chandna)

 - Fix an infinite loop issue in MSHV driver (Stanislav Kinsburskii)

* tag 'hyperv-fixes-signed-20260406' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux:
  mshv: Fix infinite fault loop on permission-denied GPA intercepts
  PCI: hv: Fix double ida_free in hv_pci_probe error path
  PCI: hv: Set default NUMA node to 0 for devices without affinity info
parents 66d64899 16cbec24
Loading
Loading
Loading
Loading
+12 −3
Original line number Diff line number Diff line
@@ -630,7 +630,7 @@ static bool mshv_handle_gpa_intercept(struct mshv_vp *vp)
{
	struct mshv_partition *p = vp->vp_partition;
	struct mshv_mem_region *region;
	bool ret;
	bool ret = false;
	u64 gfn;
#if defined(CONFIG_X86_64)
	struct hv_x64_memory_intercept_message *msg =
@@ -641,6 +641,8 @@ static bool mshv_handle_gpa_intercept(struct mshv_vp *vp)
		(struct hv_arm64_memory_intercept_message *)
		vp->vp_intercept_msg_page->u.payload;
#endif
	enum hv_intercept_access_type access_type =
		msg->header.intercept_access_type;

	gfn = HVPFN_DOWN(msg->guest_physical_address);

@@ -648,12 +650,19 @@ static bool mshv_handle_gpa_intercept(struct mshv_vp *vp)
	if (!region)
		return false;

	if (access_type == HV_INTERCEPT_ACCESS_WRITE &&
	    !(region->hv_map_flags & HV_MAP_GPA_WRITABLE))
		goto put_region;

	if (access_type == HV_INTERCEPT_ACCESS_EXECUTE &&
	    !(region->hv_map_flags & HV_MAP_GPA_EXECUTABLE))
		goto put_region;

	/* Only movable memory ranges are supported for GPA intercepts */
	if (region->mreg_type == MSHV_REGION_TYPE_MEM_MOVABLE)
		ret = mshv_region_handle_gfn_fault(region, gfn);
	else
		ret = false;

put_region:
	mshv_region_put(region);

	return ret;
+9 −3
Original line number Diff line number Diff line
@@ -2485,6 +2485,14 @@ static void hv_pci_assign_numa_node(struct hv_pcibus_device *hbus)
		if (!hv_dev)
			continue;

		/*
		 * If the Hyper-V host doesn't provide a NUMA node for the
		 * device, default to node 0. With NUMA_NO_NODE the kernel
		 * may spread work across NUMA nodes, which degrades
		 * performance on Hyper-V.
		 */
		set_dev_node(&dev->dev, 0);

		if (hv_dev->desc.flags & HV_PCI_DEVICE_FLAG_NUMA_AFFINITY &&
		    hv_dev->desc.virtual_numa_node < num_possible_nodes())
			/*
@@ -3778,7 +3786,7 @@ static int hv_pci_probe(struct hv_device *hdev,
					   hbus->bridge->domain_nr);
	if (!hbus->wq) {
		ret = -ENOMEM;
		goto free_dom;
		goto free_bus;
	}

	hdev->channel->next_request_id_callback = vmbus_next_request_id;
@@ -3874,8 +3882,6 @@ static int hv_pci_probe(struct hv_device *hdev,
	vmbus_close(hdev->channel);
destroy_wq:
	destroy_workqueue(hbus->wq);
free_dom:
	pci_bus_release_emul_domain_nr(hbus->bridge->domain_nr);
free_bus:
	kfree(hbus);
	return ret;
+6 −0
Original line number Diff line number Diff line
@@ -1533,4 +1533,10 @@ struct hv_mmio_write_input {
	u8 data[HV_HYPERCALL_MMIO_MAX_DATA_LENGTH];
} __packed;

enum hv_intercept_access_type {
	HV_INTERCEPT_ACCESS_READ	= 0,
	HV_INTERCEPT_ACCESS_WRITE	= 1,
	HV_INTERCEPT_ACCESS_EXECUTE	= 2
};

#endif /* _HV_HVGDK_MINI_H */
+2 −2
Original line number Diff line number Diff line
@@ -779,7 +779,7 @@ struct hv_x64_intercept_message_header {
	u32 vp_index;
	u8 instruction_length:4;
	u8 cr8:4; /* Only set for exo partitions */
	u8 intercept_access_type;
	u8 intercept_access_type; /* enum hv_intercept_access_type */
	union hv_x64_vp_execution_state execution_state;
	struct hv_x64_segment_register cs_segment;
	u64 rip;
@@ -825,7 +825,7 @@ union hv_arm64_vp_execution_state {
struct hv_arm64_intercept_message_header {
	u32 vp_index;
	u8 instruction_length;
	u8 intercept_access_type;
	u8 intercept_access_type; /* enum hv_intercept_access_type */
	union hv_arm64_vp_execution_state execution_state;
	u64 pc;
	u64 cpsr;