Skip to content

Commit e4ef737

Browse files
sunilmutallenpais
authored andcommitted
PCI: hv: Make the code arch neutral by adding arch specific interfaces
Encapsulate arch dependencies in Hyper-V vPCI through a set of arch-dependent interfaces. Adding these arch specific interfaces will allow for an implementation for other architectures, such as arm64. There are no functional changes expected from this patch. Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Sunil Muthuswamy <[email protected]> Signed-off-by: Lorenzo Pieralisi <[email protected]> Signed-off-by: Bjorn Helgaas <[email protected]> Reviewed-by: Boqun Feng <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Reviewed-by: Michael Kelley <[email protected]> Signed-off-by: Tyler Hicks <[email protected]> Signed-off-by: Allen Pais <[email protected]>
1 parent 7d8048d commit e4ef737

File tree

3 files changed

+83
-53
lines changed

3 files changed

+83
-53
lines changed

arch/x86/include/asm/hyperv-tlfs.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,39 @@ enum hv_interrupt_type {
585585
HV_X64_INTERRUPT_TYPE_MAXIMUM = 0x000A,
586586
};
587587

588+
union hv_msi_address_register {
589+
u32 as_uint32;
590+
struct {
591+
u32 reserved1:2;
592+
u32 destination_mode:1;
593+
u32 redirection_hint:1;
594+
u32 reserved2:8;
595+
u32 destination_id:8;
596+
u32 msi_base:12;
597+
};
598+
} __packed;
599+
600+
union hv_msi_data_register {
601+
u32 as_uint32;
602+
struct {
603+
u32 vector:8;
604+
u32 delivery_mode:3;
605+
u32 reserved1:3;
606+
u32 level_assert:1;
607+
u32 trigger_mode:1;
608+
u32 reserved2:16;
609+
};
610+
} __packed;
611+
612+
/* HvRetargetDeviceInterrupt hypercall */
613+
union hv_msi_entry {
614+
u64 as_uint64;
615+
struct {
616+
union hv_msi_address_register address;
617+
union hv_msi_data_register data;
618+
} __packed;
619+
};
620+
588621
#include <asm-generic/hyperv-tlfs.h>
589622

590623
#endif

drivers/pci/controller/pci-hyperv.c

Lines changed: 50 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,6 @@
4343
#include <linux/pci-ecam.h>
4444
#include <linux/delay.h>
4545
#include <linux/semaphore.h>
46-
#include <linux/irqdomain.h>
47-
#include <asm/irqdomain.h>
48-
#include <asm/apic.h>
4946
#include <linux/irq.h>
5047
#include <linux/msi.h>
5148
#include <linux/hyperv.h>
@@ -583,6 +580,42 @@ struct hv_pci_compl {
583580

584581
static void hv_pci_onchannelcallback(void *context);
585582

583+
#ifdef CONFIG_X86
584+
#define DELIVERY_MODE APIC_DELIVERY_MODE_FIXED
585+
#define FLOW_HANDLER handle_edge_irq
586+
#define FLOW_NAME "edge"
587+
588+
static int hv_pci_irqchip_init(void)
589+
{
590+
return 0;
591+
}
592+
593+
static struct irq_domain *hv_pci_get_root_domain(void)
594+
{
595+
return x86_vector_domain;
596+
}
597+
598+
static unsigned int hv_msi_get_int_vector(struct irq_data *data)
599+
{
600+
struct irq_cfg *cfg = irqd_cfg(data);
601+
602+
return cfg->vector;
603+
}
604+
605+
static void hv_set_msi_entry_from_desc(union hv_msi_entry *msi_entry,
606+
struct msi_desc *msi_desc)
607+
{
608+
msi_entry->address.as_uint32 = msi_desc->msg.address_lo;
609+
msi_entry->data.as_uint32 = msi_desc->msg.data;
610+
}
611+
612+
static int hv_msi_prepare(struct irq_domain *domain, struct device *dev,
613+
int nvec, msi_alloc_info_t *info)
614+
{
615+
return pci_msi_prepare(domain, dev, nvec, info);
616+
}
617+
#endif /* CONFIG_X86 */
618+
586619
/**
587620
* hv_pci_generic_compl() - Invoked for a completion packet
588621
* @context: Set up by the sender of the packet.
@@ -1195,14 +1228,6 @@ static void hv_msi_free(struct irq_domain *domain, struct msi_domain_info *info,
11951228
put_pcichild(hpdev);
11961229
}
11971230

1198-
static int hv_set_affinity(struct irq_data *data, const struct cpumask *dest,
1199-
bool force)
1200-
{
1201-
struct irq_data *parent = data->parent_data;
1202-
1203-
return parent->chip->irq_set_affinity(parent, dest, force);
1204-
}
1205-
12061231
static void hv_irq_mask(struct irq_data *data)
12071232
{
12081233
pci_msi_mask_irq(data);
@@ -1243,7 +1268,6 @@ static int hv_msi_prepare(struct irq_domain *domain, struct device *dev,
12431268
static void hv_irq_unmask(struct irq_data *data)
12441269
{
12451270
struct msi_desc *msi_desc = irq_data_get_msi_desc(data);
1246-
struct irq_cfg *cfg = irqd_cfg(data);
12471271
struct hv_retarget_device_interrupt *params;
12481272
struct tran_int_desc *int_desc;
12491273
struct hv_pcibus_device *hbus;
@@ -1275,7 +1299,7 @@ static void hv_irq_unmask(struct irq_data *data)
12751299
(hbus->hdev->dev_instance.b[7] << 8) |
12761300
(hbus->hdev->dev_instance.b[6] & 0xf8) |
12771301
PCI_FUNC(pdev->devfn);
1278-
params->int_target.vector = cfg->vector;
1302+
params->int_target.vector = hv_msi_get_int_vector(data);
12791303

12801304
/*
12811305
* Honoring apic->delivery_mode set to APIC_DELIVERY_MODE_FIXED by
@@ -1376,7 +1400,7 @@ static u32 hv_compose_msi_req_v1(
13761400
int_pkt->wslot.slot = slot;
13771401
int_pkt->int_desc.vector = vector;
13781402
int_pkt->int_desc.vector_count = vector_count;
1379-
int_pkt->int_desc.delivery_mode = APIC_DELIVERY_MODE_FIXED;
1403+
int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
13801404

13811405
/*
13821406
* Create MSI w/ dummy vCPU set, overwritten by subsequent retarget in
@@ -1406,7 +1430,7 @@ static u32 hv_compose_msi_req_v2(
14061430
int_pkt->wslot.slot = slot;
14071431
int_pkt->int_desc.vector = vector;
14081432
int_pkt->int_desc.vector_count = vector_count;
1409-
int_pkt->int_desc.delivery_mode = APIC_DELIVERY_MODE_FIXED;
1433+
int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
14101434
cpu = hv_compose_msi_req_get_cpu(affinity);
14111435
int_pkt->int_desc.processor_array[0] =
14121436
hv_cpu_number_to_vp_number(cpu);
@@ -1426,7 +1450,7 @@ static u32 hv_compose_msi_req_v3(
14261450
int_pkt->int_desc.vector = vector;
14271451
int_pkt->int_desc.reserved = 0;
14281452
int_pkt->int_desc.vector_count = vector_count;
1429-
int_pkt->int_desc.delivery_mode = APIC_DELIVERY_MODE_FIXED;
1453+
int_pkt->int_desc.delivery_mode = DELIVERY_MODE;
14301454
cpu = hv_compose_msi_req_get_cpu(affinity);
14311455
int_pkt->int_desc.processor_array[0] =
14321456
hv_cpu_number_to_vp_number(cpu);
@@ -1660,7 +1684,7 @@ static void hv_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
16601684
static struct irq_chip hv_msi_irq_chip = {
16611685
.name = "Hyper-V PCIe MSI",
16621686
.irq_compose_msi_msg = hv_compose_msi_msg,
1663-
.irq_set_affinity = hv_set_affinity,
1687+
.irq_set_affinity = irq_chip_set_affinity_parent,
16641688
.irq_ack = irq_chip_ack_parent,
16651689
.irq_mask = hv_irq_mask,
16661690
.irq_unmask = hv_irq_unmask,
@@ -1691,12 +1715,12 @@ static int hv_pcie_init_irq_domain(struct hv_pcibus_device *hbus)
16911715
hbus->msi_info.flags = (MSI_FLAG_USE_DEF_DOM_OPS |
16921716
MSI_FLAG_USE_DEF_CHIP_OPS | MSI_FLAG_MULTI_PCI_MSI |
16931717
MSI_FLAG_PCI_MSIX);
1694-
hbus->msi_info.handler = handle_edge_irq;
1695-
hbus->msi_info.handler_name = "edge";
1718+
hbus->msi_info.handler = FLOW_HANDLER;
1719+
hbus->msi_info.handler_name = FLOW_NAME;
16961720
hbus->msi_info.data = hbus;
16971721
hbus->irq_domain = pci_msi_create_irq_domain(hbus->fwnode,
16981722
&hbus->msi_info,
1699-
x86_vector_domain);
1723+
hv_pci_get_root_domain());
17001724
if (!hbus->irq_domain) {
17011725
dev_err(&hbus->hdev->device,
17021726
"Failed to build an MSI IRQ domain\n");
@@ -3626,9 +3650,15 @@ static void __exit exit_hv_pci_drv(void)
36263650

36273651
static int __init init_hv_pci_drv(void)
36283652
{
3653+
int ret;
3654+
36293655
if (!hv_is_hyperv_initialized())
36303656
return -ENODEV;
36313657

3658+
ret = hv_pci_irqchip_init();
3659+
if (ret)
3660+
return ret;
3661+
36323662
/* Set the invalid domain number's bit, so it will not be used */
36333663
set_bit(HVPCI_DOM_INVALID, hvpci_dom_map);
36343664

include/asm-generic/hyperv-tlfs.h

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -539,39 +539,6 @@ enum hv_interrupt_source {
539539
HV_INTERRUPT_SOURCE_IOAPIC,
540540
};
541541

542-
union hv_msi_address_register {
543-
u32 as_uint32;
544-
struct {
545-
u32 reserved1:2;
546-
u32 destination_mode:1;
547-
u32 redirection_hint:1;
548-
u32 reserved2:8;
549-
u32 destination_id:8;
550-
u32 msi_base:12;
551-
};
552-
} __packed;
553-
554-
union hv_msi_data_register {
555-
u32 as_uint32;
556-
struct {
557-
u32 vector:8;
558-
u32 delivery_mode:3;
559-
u32 reserved1:3;
560-
u32 level_assert:1;
561-
u32 trigger_mode:1;
562-
u32 reserved2:16;
563-
};
564-
} __packed;
565-
566-
/* HvRetargetDeviceInterrupt hypercall */
567-
union hv_msi_entry {
568-
u64 as_uint64;
569-
struct {
570-
union hv_msi_address_register address;
571-
union hv_msi_data_register data;
572-
} __packed;
573-
};
574-
575542
union hv_ioapic_rte {
576543
u64 as_uint64;
577544

0 commit comments

Comments
 (0)