Message ID | 20200121015713.69691-2-boqun.feng@gmail.com (mailing list archive) |
---|---|
State | Changes Requested, archived |
Headers | show |
Series | [1/2] pci: hyperv: x86: Move hypercall related definitions into tlfs header | expand |
Boqun Feng <boqun.feng@gmail.com> writes: > For future support of virtual PCI on non-x86 architecture. > > Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com> > --- > arch/x86/include/asm/hyperv-tlfs.h | 38 +++++++++++++++++++++++++++++ > arch/x86/include/asm/mshyperv.h | 8 ++++++ > drivers/pci/controller/pci-hyperv.c | 38 +++-------------------------- > 3 files changed, 50 insertions(+), 34 deletions(-) > > diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h > index b9ebc20b2385..debe017ae748 100644 > --- a/arch/x86/include/asm/hyperv-tlfs.h > +++ b/arch/x86/include/asm/hyperv-tlfs.h > @@ -912,4 +912,42 @@ struct hv_tlb_flush_ex { > struct hv_partition_assist_pg { > u32 tlb_lock_count; > }; > + > +union hv_msi_entry { > + u64 as_uint64; > + struct { > + u32 address; > + u32 data; > + } __packed; > +}; While Hyper-V code is full of this, I was once told that 'Union aliasing is UB. Avoid it for good.' Maybe we should start getting rid of it instead of adding more? > + > +struct hv_interrupt_entry { > + u32 source; /* 1 for MSI(-X) */ > + u32 reserved1; > + union hv_msi_entry msi_entry; > +} __packed; > + > +/* > + * flags for hv_device_interrupt_target.flags > + */ > +#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1 > +#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2 > + > +struct hv_device_interrupt_target { > + u32 vector; > + u32 flags; > + union { > + u64 vp_mask; > + struct hv_vpset vp_set; > + }; > +} __packed; > + > +/* HvRetargetDeviceInterrupt hypercall */ > +struct hv_retarget_device_interrupt { > + u64 partition_id; > + u64 device_id; > + struct hv_interrupt_entry int_entry; > + u64 reserved2; > + struct hv_device_interrupt_target int_target; > +} __packed __aligned(8); > #endif > diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h > index 6b79515abb82..d13319d82f6b 100644 > --- a/arch/x86/include/asm/mshyperv.h > +++ b/arch/x86/include/asm/mshyperv.h > @@ -240,6 +240,14 @@ bool hv_vcpu_is_preempted(int vcpu); > static inline void hv_apic_init(void) {} > #endif > > +#if IS_ENABLED(CONFIG_PCI_HYPERV) > +#define hv_set_msi_address_from_desc(msi_entry, msi_desc) \ > +do { \ > + (msi_entry)->address = (msi_desc)->msg.address_lo; \ > +} while (0) > + > +#endif /* CONFIG_PCI_HYPERV */ It seems to be pointless to put defines under #if IS_ENABLED(): in case it is not enabled and used you'll get a compilation error, in case it is enabled and not used no code is going to be generated anyways. > + > #else /* CONFIG_HYPERV */ > static inline void hyperv_init(void) {} > static inline void hyperv_setup_mmu_ops(void) {} > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c > index aacfcc90d929..2240f2b3643e 100644 > --- a/drivers/pci/controller/pci-hyperv.c > +++ b/drivers/pci/controller/pci-hyperv.c > @@ -406,36 +406,6 @@ struct pci_eject_response { > > static int pci_ring_size = (4 * PAGE_SIZE); > > -struct hv_interrupt_entry { > - u32 source; /* 1 for MSI(-X) */ > - u32 reserved1; > - u32 address; > - u32 data; > -}; > - > -/* > - * flags for hv_device_interrupt_target.flags > - */ > -#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1 > -#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2 > - > -struct hv_device_interrupt_target { > - u32 vector; > - u32 flags; > - union { > - u64 vp_mask; > - struct hv_vpset vp_set; > - }; > -}; > - > -struct retarget_msi_interrupt { > - u64 partition_id; /* use "self" */ > - u64 device_id; > - struct hv_interrupt_entry int_entry; > - u64 reserved2; > - struct hv_device_interrupt_target int_target; > -} __packed __aligned(8); > - > /* > * Driver specific state. > */ > @@ -482,7 +452,7 @@ struct hv_pcibus_device { > struct workqueue_struct *wq; > > /* hypercall arg, must not cross page boundary */ > - struct retarget_msi_interrupt retarget_msi_interrupt_params; > + struct hv_retarget_device_interrupt retarget_msi_interrupt_params; > > /* > * Don't put anything here: retarget_msi_interrupt_params must be last > @@ -1178,7 +1148,7 @@ static void hv_irq_unmask(struct irq_data *data) > { > struct msi_desc *msi_desc = irq_data_get_msi_desc(data); > struct irq_cfg *cfg = irqd_cfg(data); > - struct retarget_msi_interrupt *params; > + struct hv_retarget_device_interrupt *params; > struct hv_pcibus_device *hbus; > struct cpumask *dest; > cpumask_var_t tmp; > @@ -1200,8 +1170,8 @@ static void hv_irq_unmask(struct irq_data *data) > memset(params, 0, sizeof(*params)); > params->partition_id = HV_PARTITION_ID_SELF; > params->int_entry.source = 1; /* MSI(-X) */ > - params->int_entry.address = msi_desc->msg.address_lo; > - params->int_entry.data = msi_desc->msg.data; > + hv_set_msi_address_from_desc(¶ms->int_entry.msi_entry, msi_desc); I don't quite see why this hv_set_msi_address_from_desc() is needed at all. > + params->int_entry.msi_entry.data = msi_desc->msg.data; > params->device_id = (hbus->hdev->dev_instance.b[5] << 24) | > (hbus->hdev->dev_instance.b[4] << 16) | > (hbus->hdev->dev_instance.b[7] << 8) |
On Tue, Jan 21, 2020 at 09:57:13AM +0800, Boqun Feng wrote: > For future support of virtual PCI on non-x86 architecture. 1) Don't make up random subject line prefixes; look at previous practice and follow it, e.g., $ git log --oneline drivers/pci/controller/pci-hyperv.c | head 877b911a5ba0 PCI: hv: Avoid a kmemleak false positive caused by the hbus buffer 14ef39fddd23 PCI: hv: Change pci_protocol_version to per-hbus ac82fc832708 PCI: hv: Add hibernation support a8e37506e79a PCI: hv: Reorganize the code in preparation of hibernation f73f8a504e27 PCI: hv: Use bytes 4 and 5 from instance ID as the PCI domain numbers 348dd93e40c1 PCI: hv: Add a Hyper-V PCI interface driver for software backchannel interface 2) Make the commit log complete in itself. This one (and the previous on) is not complete without reading the subject. 3) This patch claims to be a "move", but in fact it also *adds* union hv_msi_entry, which didn't exist before. It's better if you do a pure move that doesn't add or change things, plus a separate patch that makes changes that need to be reviewed more closely. > Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com> > --- > arch/x86/include/asm/hyperv-tlfs.h | 38 +++++++++++++++++++++++++++++ > arch/x86/include/asm/mshyperv.h | 8 ++++++ > drivers/pci/controller/pci-hyperv.c | 38 +++-------------------------- > 3 files changed, 50 insertions(+), 34 deletions(-) > > diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h > index b9ebc20b2385..debe017ae748 100644 > --- a/arch/x86/include/asm/hyperv-tlfs.h > +++ b/arch/x86/include/asm/hyperv-tlfs.h > @@ -912,4 +912,42 @@ struct hv_tlb_flush_ex { > struct hv_partition_assist_pg { > u32 tlb_lock_count; > }; > + > +union hv_msi_entry { > + u64 as_uint64; > + struct { > + u32 address; > + u32 data; > + } __packed; > +}; > + > +struct hv_interrupt_entry { > + u32 source; /* 1 for MSI(-X) */ > + u32 reserved1; > + union hv_msi_entry msi_entry; > +} __packed; > + > +/* > + * flags for hv_device_interrupt_target.flags > + */ > +#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1 > +#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2 > + > +struct hv_device_interrupt_target { > + u32 vector; > + u32 flags; > + union { > + u64 vp_mask; > + struct hv_vpset vp_set; > + }; > +} __packed; > + > +/* HvRetargetDeviceInterrupt hypercall */ > +struct hv_retarget_device_interrupt { > + u64 partition_id; > + u64 device_id; > + struct hv_interrupt_entry int_entry; > + u64 reserved2; > + struct hv_device_interrupt_target int_target; > +} __packed __aligned(8); > #endif > diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h > index 6b79515abb82..d13319d82f6b 100644 > --- a/arch/x86/include/asm/mshyperv.h > +++ b/arch/x86/include/asm/mshyperv.h > @@ -240,6 +240,14 @@ bool hv_vcpu_is_preempted(int vcpu); > static inline void hv_apic_init(void) {} > #endif > > +#if IS_ENABLED(CONFIG_PCI_HYPERV) > +#define hv_set_msi_address_from_desc(msi_entry, msi_desc) \ > +do { \ > + (msi_entry)->address = (msi_desc)->msg.address_lo; \ > +} while (0) > + > +#endif /* CONFIG_PCI_HYPERV */ > + > #else /* CONFIG_HYPERV */ > static inline void hyperv_init(void) {} > static inline void hyperv_setup_mmu_ops(void) {} > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c > index aacfcc90d929..2240f2b3643e 100644 > --- a/drivers/pci/controller/pci-hyperv.c > +++ b/drivers/pci/controller/pci-hyperv.c > @@ -406,36 +406,6 @@ struct pci_eject_response { > > static int pci_ring_size = (4 * PAGE_SIZE); > > -struct hv_interrupt_entry { > - u32 source; /* 1 for MSI(-X) */ > - u32 reserved1; > - u32 address; > - u32 data; > -}; > - > -/* > - * flags for hv_device_interrupt_target.flags > - */ > -#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1 > -#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2 > - > -struct hv_device_interrupt_target { > - u32 vector; > - u32 flags; > - union { > - u64 vp_mask; > - struct hv_vpset vp_set; > - }; > -}; > - > -struct retarget_msi_interrupt { > - u64 partition_id; /* use "self" */ > - u64 device_id; > - struct hv_interrupt_entry int_entry; > - u64 reserved2; > - struct hv_device_interrupt_target int_target; > -} __packed __aligned(8); > - > /* > * Driver specific state. > */ > @@ -482,7 +452,7 @@ struct hv_pcibus_device { > struct workqueue_struct *wq; > > /* hypercall arg, must not cross page boundary */ > - struct retarget_msi_interrupt retarget_msi_interrupt_params; > + struct hv_retarget_device_interrupt retarget_msi_interrupt_params; > > /* > * Don't put anything here: retarget_msi_interrupt_params must be last > @@ -1178,7 +1148,7 @@ static void hv_irq_unmask(struct irq_data *data) > { > struct msi_desc *msi_desc = irq_data_get_msi_desc(data); > struct irq_cfg *cfg = irqd_cfg(data); > - struct retarget_msi_interrupt *params; > + struct hv_retarget_device_interrupt *params; > struct hv_pcibus_device *hbus; > struct cpumask *dest; > cpumask_var_t tmp; > @@ -1200,8 +1170,8 @@ static void hv_irq_unmask(struct irq_data *data) > memset(params, 0, sizeof(*params)); > params->partition_id = HV_PARTITION_ID_SELF; > params->int_entry.source = 1; /* MSI(-X) */ > - params->int_entry.address = msi_desc->msg.address_lo; > - params->int_entry.data = msi_desc->msg.data; > + hv_set_msi_address_from_desc(¶ms->int_entry.msi_entry, msi_desc); > + params->int_entry.msi_entry.data = msi_desc->msg.data; > params->device_id = (hbus->hdev->dev_instance.b[5] << 24) | > (hbus->hdev->dev_instance.b[4] << 16) | > (hbus->hdev->dev_instance.b[7] << 8) | > -- > 2.24.1 >
On Tue, Jan 21, 2020 at 10:25:47AM +0100, Vitaly Kuznetsov wrote: [...] > > > > +#if IS_ENABLED(CONFIG_PCI_HYPERV) > > +#define hv_set_msi_address_from_desc(msi_entry, msi_desc) \ > > +do { \ > > + (msi_entry)->address = (msi_desc)->msg.address_lo; \ > > +} while (0) > > + > > +#endif /* CONFIG_PCI_HYPERV */ > > It seems to be pointless to put defines under #if IS_ENABLED(): in case > it is not enabled and used you'll get a compilation error, in case it is > enabled and not used no code is going to be generated anyways. > OK I will remove the #if IS_ENABLED() in the next version. > > + > > #else /* CONFIG_HYPERV */ > > static inline void hyperv_init(void) {} > > static inline void hyperv_setup_mmu_ops(void) {} > > diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c > > index aacfcc90d929..2240f2b3643e 100644 > > --- a/drivers/pci/controller/pci-hyperv.c > > +++ b/drivers/pci/controller/pci-hyperv.c > > @@ -406,36 +406,6 @@ struct pci_eject_response { > > > > static int pci_ring_size = (4 * PAGE_SIZE); > > > > -struct hv_interrupt_entry { > > - u32 source; /* 1 for MSI(-X) */ > > - u32 reserved1; > > - u32 address; > > - u32 data; > > -}; > > - > > -/* > > - * flags for hv_device_interrupt_target.flags > > - */ > > -#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1 > > -#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2 > > - > > -struct hv_device_interrupt_target { > > - u32 vector; > > - u32 flags; > > - union { > > - u64 vp_mask; > > - struct hv_vpset vp_set; > > - }; > > -}; > > - > > -struct retarget_msi_interrupt { > > - u64 partition_id; /* use "self" */ > > - u64 device_id; > > - struct hv_interrupt_entry int_entry; > > - u64 reserved2; > > - struct hv_device_interrupt_target int_target; > > -} __packed __aligned(8); > > - > > /* > > * Driver specific state. > > */ > > @@ -482,7 +452,7 @@ struct hv_pcibus_device { > > struct workqueue_struct *wq; > > > > /* hypercall arg, must not cross page boundary */ > > - struct retarget_msi_interrupt retarget_msi_interrupt_params; > > + struct hv_retarget_device_interrupt retarget_msi_interrupt_params; > > > > /* > > * Don't put anything here: retarget_msi_interrupt_params must be last > > @@ -1178,7 +1148,7 @@ static void hv_irq_unmask(struct irq_data *data) > > { > > struct msi_desc *msi_desc = irq_data_get_msi_desc(data); > > struct irq_cfg *cfg = irqd_cfg(data); > > - struct retarget_msi_interrupt *params; > > + struct hv_retarget_device_interrupt *params; > > struct hv_pcibus_device *hbus; > > struct cpumask *dest; > > cpumask_var_t tmp; > > @@ -1200,8 +1170,8 @@ static void hv_irq_unmask(struct irq_data *data) > > memset(params, 0, sizeof(*params)); > > params->partition_id = HV_PARTITION_ID_SELF; > > params->int_entry.source = 1; /* MSI(-X) */ > > - params->int_entry.address = msi_desc->msg.address_lo; > > - params->int_entry.data = msi_desc->msg.data; > > + hv_set_msi_address_from_desc(¶ms->int_entry.msi_entry, msi_desc); > > I don't quite see why this hv_set_msi_address_from_desc() is needed at > all. > I will add some description in the next version, the reason that hv_set_msi_address_from_desc() is arm64 and x86 have different hv_interrupt_entry formats. So a generic interface is needed so that archs can have different ways to set ->address field from msi_desc. Regards, Boqun > > + params->int_entry.msi_entry.data = msi_desc->msg.data; > > params->device_id = (hbus->hdev->dev_instance.b[5] << 24) | > > (hbus->hdev->dev_instance.b[4] << 16) | > > (hbus->hdev->dev_instance.b[7] << 8) | > > -- > Vitaly >
diff --git a/arch/x86/include/asm/hyperv-tlfs.h b/arch/x86/include/asm/hyperv-tlfs.h index b9ebc20b2385..debe017ae748 100644 --- a/arch/x86/include/asm/hyperv-tlfs.h +++ b/arch/x86/include/asm/hyperv-tlfs.h @@ -912,4 +912,42 @@ struct hv_tlb_flush_ex { struct hv_partition_assist_pg { u32 tlb_lock_count; }; + +union hv_msi_entry { + u64 as_uint64; + struct { + u32 address; + u32 data; + } __packed; +}; + +struct hv_interrupt_entry { + u32 source; /* 1 for MSI(-X) */ + u32 reserved1; + union hv_msi_entry msi_entry; +} __packed; + +/* + * flags for hv_device_interrupt_target.flags + */ +#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1 +#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2 + +struct hv_device_interrupt_target { + u32 vector; + u32 flags; + union { + u64 vp_mask; + struct hv_vpset vp_set; + }; +} __packed; + +/* HvRetargetDeviceInterrupt hypercall */ +struct hv_retarget_device_interrupt { + u64 partition_id; + u64 device_id; + struct hv_interrupt_entry int_entry; + u64 reserved2; + struct hv_device_interrupt_target int_target; +} __packed __aligned(8); #endif diff --git a/arch/x86/include/asm/mshyperv.h b/arch/x86/include/asm/mshyperv.h index 6b79515abb82..d13319d82f6b 100644 --- a/arch/x86/include/asm/mshyperv.h +++ b/arch/x86/include/asm/mshyperv.h @@ -240,6 +240,14 @@ bool hv_vcpu_is_preempted(int vcpu); static inline void hv_apic_init(void) {} #endif +#if IS_ENABLED(CONFIG_PCI_HYPERV) +#define hv_set_msi_address_from_desc(msi_entry, msi_desc) \ +do { \ + (msi_entry)->address = (msi_desc)->msg.address_lo; \ +} while (0) + +#endif /* CONFIG_PCI_HYPERV */ + #else /* CONFIG_HYPERV */ static inline void hyperv_init(void) {} static inline void hyperv_setup_mmu_ops(void) {} diff --git a/drivers/pci/controller/pci-hyperv.c b/drivers/pci/controller/pci-hyperv.c index aacfcc90d929..2240f2b3643e 100644 --- a/drivers/pci/controller/pci-hyperv.c +++ b/drivers/pci/controller/pci-hyperv.c @@ -406,36 +406,6 @@ struct pci_eject_response { static int pci_ring_size = (4 * PAGE_SIZE); -struct hv_interrupt_entry { - u32 source; /* 1 for MSI(-X) */ - u32 reserved1; - u32 address; - u32 data; -}; - -/* - * flags for hv_device_interrupt_target.flags - */ -#define HV_DEVICE_INTERRUPT_TARGET_MULTICAST 1 -#define HV_DEVICE_INTERRUPT_TARGET_PROCESSOR_SET 2 - -struct hv_device_interrupt_target { - u32 vector; - u32 flags; - union { - u64 vp_mask; - struct hv_vpset vp_set; - }; -}; - -struct retarget_msi_interrupt { - u64 partition_id; /* use "self" */ - u64 device_id; - struct hv_interrupt_entry int_entry; - u64 reserved2; - struct hv_device_interrupt_target int_target; -} __packed __aligned(8); - /* * Driver specific state. */ @@ -482,7 +452,7 @@ struct hv_pcibus_device { struct workqueue_struct *wq; /* hypercall arg, must not cross page boundary */ - struct retarget_msi_interrupt retarget_msi_interrupt_params; + struct hv_retarget_device_interrupt retarget_msi_interrupt_params; /* * Don't put anything here: retarget_msi_interrupt_params must be last @@ -1178,7 +1148,7 @@ static void hv_irq_unmask(struct irq_data *data) { struct msi_desc *msi_desc = irq_data_get_msi_desc(data); struct irq_cfg *cfg = irqd_cfg(data); - struct retarget_msi_interrupt *params; + struct hv_retarget_device_interrupt *params; struct hv_pcibus_device *hbus; struct cpumask *dest; cpumask_var_t tmp; @@ -1200,8 +1170,8 @@ static void hv_irq_unmask(struct irq_data *data) memset(params, 0, sizeof(*params)); params->partition_id = HV_PARTITION_ID_SELF; params->int_entry.source = 1; /* MSI(-X) */ - params->int_entry.address = msi_desc->msg.address_lo; - params->int_entry.data = msi_desc->msg.data; + hv_set_msi_address_from_desc(¶ms->int_entry.msi_entry, msi_desc); + params->int_entry.msi_entry.data = msi_desc->msg.data; params->device_id = (hbus->hdev->dev_instance.b[5] << 24) | (hbus->hdev->dev_instance.b[4] << 16) | (hbus->hdev->dev_instance.b[7] << 8) |
For future support of virtual PCI on non-x86 architecture. Signed-off-by: Boqun Feng (Microsoft) <boqun.feng@gmail.com> --- arch/x86/include/asm/hyperv-tlfs.h | 38 +++++++++++++++++++++++++++++ arch/x86/include/asm/mshyperv.h | 8 ++++++ drivers/pci/controller/pci-hyperv.c | 38 +++-------------------------- 3 files changed, 50 insertions(+), 34 deletions(-)