summaryrefslogtreecommitdiff
path: root/drivers/pci/host/pci-hyperv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/pci/host/pci-hyperv.c')
-rw-r--r--drivers/pci/host/pci-hyperv.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/pci/host/pci-hyperv.c b/drivers/pci/host/pci-hyperv.c
index 763ff8745828..dafb4cdb2b7f 100644
--- a/drivers/pci/host/pci-hyperv.c
+++ b/drivers/pci/host/pci-hyperv.c
@@ -72,6 +72,7 @@ enum {
PCI_PROTOCOL_VERSION_CURRENT = PCI_PROTOCOL_VERSION_1_1
};
+#define CPU_AFFINITY_ALL -1ULL
#define PCI_CONFIG_MMIO_LENGTH 0x2000
#define CFG_PAGE_OFFSET 0x1000
#define CFG_PAGE_SIZE (PCI_CONFIG_MMIO_LENGTH - CFG_PAGE_OFFSET)
@@ -130,7 +131,8 @@ union pci_version {
*/
union win_slot_encoding {
struct {
- u32 func:8;
+ u32 dev:5;
+ u32 func:3;
u32 reserved:24;
} bits;
u32 slot;
@@ -483,7 +485,8 @@ static u32 devfn_to_wslot(int devfn)
union win_slot_encoding wslot;
wslot.slot = 0;
- wslot.bits.func = PCI_SLOT(devfn) | (PCI_FUNC(devfn) << 5);
+ wslot.bits.dev = PCI_SLOT(devfn);
+ wslot.bits.func = PCI_FUNC(devfn);
return wslot.slot;
}
@@ -501,7 +504,7 @@ static int wslot_to_devfn(u32 wslot)
union win_slot_encoding slot_no;
slot_no.slot = wslot;
- return PCI_DEVFN(0, slot_no.bits.func);
+ return PCI_DEVFN(slot_no.bits.dev, slot_no.bits.func);
}
/*
@@ -866,7 +869,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
hv_int_desc_free(hpdev, int_desc);
}
- int_desc = kzalloc(sizeof(*int_desc), GFP_KERNEL);
+ int_desc = kzalloc(sizeof(*int_desc), GFP_ATOMIC);
if (!int_desc)
goto drop_reference;
@@ -887,9 +890,13 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
* processors because Hyper-V only supports 64 in a guest.
*/
affinity = irq_data_get_affinity_mask(data);
- for_each_cpu_and(cpu, affinity, cpu_online_mask) {
- int_pkt->int_desc.cpu_mask |=
- (1ULL << vmbus_cpu_number_to_vp_number(cpu));
+ if (cpumask_weight(affinity) >= 32) {
+ int_pkt->int_desc.cpu_mask = CPU_AFFINITY_ALL;
+ } else {
+ for_each_cpu_and(cpu, affinity, cpu_online_mask) {
+ int_pkt->int_desc.cpu_mask |=
+ (1ULL << vmbus_cpu_number_to_vp_number(cpu));
+ }
}
ret = vmbus_sendpacket(hpdev->hbus->hdev->channel, int_pkt,