Skip to content

Commit 52bf803

Browse files
committed
Merge tag 'hyperv-fixes-signed-20211007' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux
Pull hyperv fixes from Wei Liu: - Replace uuid.h with types.h in a header (Andy Shevchenko) - Avoid sleeping in atomic context in PCI driver (Long Li) - Avoid sending IPI to self when it shouldn't (Vitaly Kuznetsov) * tag 'hyperv-fixes-signed-20211007' of git://git.kernel.org/pub/scm/linux/kernel/git/hyperv/linux: x86/hyperv: Avoid erroneously sending IPI to 'self' hyper-v: Replace uuid.h with types.h PCI: hv: Fix sleep while in non-sleep context when removing child devices from the bus
2 parents 5af4055 + f5c20e4 commit 52bf803

File tree

3 files changed

+26
-9
lines changed

3 files changed

+26
-9
lines changed

arch/x86/hyperv/hv_apic.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,17 +122,27 @@ static bool __send_ipi_mask_ex(const struct cpumask *mask, int vector,
122122
ipi_arg->reserved = 0;
123123
ipi_arg->vp_set.valid_bank_mask = 0;
124124

125-
if (!cpumask_equal(mask, cpu_present_mask)) {
125+
/*
126+
* Use HV_GENERIC_SET_ALL and avoid converting cpumask to VP_SET
127+
* when the IPI is sent to all currently present CPUs.
128+
*/
129+
if (!cpumask_equal(mask, cpu_present_mask) || exclude_self) {
126130
ipi_arg->vp_set.format = HV_GENERIC_SET_SPARSE_4K;
127131
if (exclude_self)
128132
nr_bank = cpumask_to_vpset_noself(&(ipi_arg->vp_set), mask);
129133
else
130134
nr_bank = cpumask_to_vpset(&(ipi_arg->vp_set), mask);
131-
}
132-
if (nr_bank < 0)
133-
goto ipi_mask_ex_done;
134-
if (!nr_bank)
135+
136+
/*
137+
* 'nr_bank <= 0' means some CPUs in cpumask can't be
138+
* represented in VP_SET. Return an error and fall back to
139+
* native (architectural) method of sending IPIs.
140+
*/
141+
if (nr_bank <= 0)
142+
goto ipi_mask_ex_done;
143+
} else {
135144
ipi_arg->vp_set.format = HV_GENERIC_SET_ALL;
145+
}
136146

137147
status = hv_do_rep_hypercall(HVCALL_SEND_IPI_EX, 0, nr_bank,
138148
ipi_arg, NULL);

drivers/pci/controller/pci-hyperv.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3301,17 +3301,24 @@ static int hv_pci_bus_exit(struct hv_device *hdev, bool keep_devs)
33013301
return 0;
33023302

33033303
if (!keep_devs) {
3304-
/* Delete any children which might still exist. */
3304+
struct list_head removed;
3305+
3306+
/* Move all present children to the list on stack */
3307+
INIT_LIST_HEAD(&removed);
33053308
spin_lock_irqsave(&hbus->device_list_lock, flags);
3306-
list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry) {
3309+
list_for_each_entry_safe(hpdev, tmp, &hbus->children, list_entry)
3310+
list_move_tail(&hpdev->list_entry, &removed);
3311+
spin_unlock_irqrestore(&hbus->device_list_lock, flags);
3312+
3313+
/* Remove all children in the list */
3314+
list_for_each_entry_safe(hpdev, tmp, &removed, list_entry) {
33073315
list_del(&hpdev->list_entry);
33083316
if (hpdev->pci_slot)
33093317
pci_destroy_slot(hpdev->pci_slot);
33103318
/* For the two refs got in new_pcichild_device() */
33113319
put_pcichild(hpdev);
33123320
put_pcichild(hpdev);
33133321
}
3314-
spin_unlock_irqrestore(&hbus->device_list_lock, flags);
33153322
}
33163323

33173324
ret = hv_send_resources_released(hdev);

include/uapi/linux/hyperv.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
#ifndef _UAPI_HYPERV_H
2727
#define _UAPI_HYPERV_H
2828

29-
#include <linux/uuid.h>
29+
#include <linux/types.h>
3030

3131
/*
3232
* Framework version for util services.

0 commit comments

Comments
 (0)