Message ID | 20180102200549.22984-6-ard.biesheuvel@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | add support for relative references in special sections | expand |
On Tue, Jan 02, 2018 at 08:05:44PM +0000, Ard Biesheuvel wrote: > diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c > index 10684b17d0bd..b6d51b4d5ce1 100644 > --- a/drivers/pci/quirks.c > +++ b/drivers/pci/quirks.c > @@ -3556,9 +3556,16 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, > f->vendor == (u16) PCI_ANY_ID) && > (f->device == dev->device || > f->device == (u16) PCI_ANY_ID)) { > - calltime = fixup_debug_start(dev, f->hook); > - f->hook(dev); > - fixup_debug_report(dev, calltime, f->hook); > + void (*hook)(struct pci_dev *dev); > +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS > + hook = (void *)((unsigned long)&f->hook_offset + > + f->hook_offset); > +#else > + hook = f->hook; > +#endif More of a nitpick but I've seen this pattern in several places in your code, maybe worth defining a macro (couldn't come up with a better name): #define offset_to_ptr(off) \ ((void *)((unsigned long)&(off) + (off))) -- Catalin
On 5 January 2018 at 17:41, Catalin Marinas <catalin.marinas@arm.com> wrote: > On Tue, Jan 02, 2018 at 08:05:44PM +0000, Ard Biesheuvel wrote: >> diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c >> index 10684b17d0bd..b6d51b4d5ce1 100644 >> --- a/drivers/pci/quirks.c >> +++ b/drivers/pci/quirks.c >> @@ -3556,9 +3556,16 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, >> f->vendor == (u16) PCI_ANY_ID) && >> (f->device == dev->device || >> f->device == (u16) PCI_ANY_ID)) { >> - calltime = fixup_debug_start(dev, f->hook); >> - f->hook(dev); >> - fixup_debug_report(dev, calltime, f->hook); >> + void (*hook)(struct pci_dev *dev); >> +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS >> + hook = (void *)((unsigned long)&f->hook_offset + >> + f->hook_offset); >> +#else >> + hook = f->hook; >> +#endif > > More of a nitpick but I've seen this pattern in several places in your > code, maybe worth defining a macro (couldn't come up with a better > name): > > #define offset_to_ptr(off) \ > ((void *)((unsigned long)&(off) + (off))) > Yeah, good point. Or even static inline void *offset_to_ptr(const s32 *off) { return (void *)((unsigned long)off + *off); }
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 10684b17d0bd..b6d51b4d5ce1 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3556,9 +3556,16 @@ static void pci_do_fixups(struct pci_dev *dev, struct pci_fixup *f, f->vendor == (u16) PCI_ANY_ID) && (f->device == dev->device || f->device == (u16) PCI_ANY_ID)) { - calltime = fixup_debug_start(dev, f->hook); - f->hook(dev); - fixup_debug_report(dev, calltime, f->hook); + void (*hook)(struct pci_dev *dev); +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + hook = (void *)((unsigned long)&f->hook_offset + + f->hook_offset); +#else + hook = f->hook; +#endif + calltime = fixup_debug_start(dev, hook); + hook(dev); + fixup_debug_report(dev, calltime, hook); } } diff --git a/include/linux/pci.h b/include/linux/pci.h index c170c9250c8b..086c3965710b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -1792,7 +1792,11 @@ struct pci_fixup { u16 device; /* You can use PCI_ANY_ID here of course */ u32 class; /* You can use PCI_ANY_ID here too */ unsigned int class_shift; /* should be 0, 8, 16 */ +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS + int hook_offset; +#else void (*hook)(struct pci_dev *dev); +#endif }; enum pci_fixup_pass { @@ -1806,12 +1810,28 @@ enum pci_fixup_pass { pci_fixup_suspend_late, /* pci_device_suspend_late() */ }; +#ifdef CONFIG_HAVE_ARCH_PREL32_RELOCATIONS +#define __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ + class_shift, hook) \ + __ADDRESSABLE(hook) \ + asm(".section " #sec ", \"a\" \n" \ + ".balign 16 \n" \ + ".short " #vendor ", " #device " \n" \ + ".long " #class ", " #class_shift " \n" \ + ".long " VMLINUX_SYMBOL_STR(hook) " - . \n" \ + ".previous \n"); +#define DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ + class_shift, hook) \ + __DECLARE_PCI_FIXUP_SECTION(sec, name, vendor, device, class, \ + class_shift, hook) +#else /* Anonymous variables would be nice... */ #define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, class, \ class_shift, hook) \ static const struct pci_fixup __PASTE(__pci_fixup_##name,__LINE__) __used \ __attribute__((__section__(#section), aligned((sizeof(void *))))) \ = { vendor, device, class, class_shift, hook }; +#endif #define DECLARE_PCI_FIXUP_CLASS_EARLY(vendor, device, class, \ class_shift, hook) \