linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 33/42] x86, boot: Add add_pci handler for SETUP_PCI
       [not found] <1436300428-21163-1-git-send-email-yinghai@kernel.org>
@ 2015-07-07 20:20 ` Yinghai Lu
  2015-07-14 22:30   ` Bjorn Helgaas
  2015-07-07 20:20 ` [PATCH 35/42] x86, boot, PCI: Convert SETUP_PCI data to list Yinghai Lu
  2015-07-07 20:20 ` [PATCH 37/42] x86, boot, PCI: Export SETUP_PCI data via sysfs Yinghai Lu
  2 siblings, 1 reply; 6+ messages in thread
From: Yinghai Lu @ 2015-07-07 20:20 UTC (permalink / raw)
  To: Kees Cook, H. Peter Anvin, Baoquan He
  Cc: linux-kernel, Yinghai Lu, Bjorn Helgaas, Matt Fleming, linux-pci

Let it reserve setup_data, and keep it's own list.

Also clear the hdr.setup_data, as all handler now handle or
reserve setup_data locally already.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: Matt Fleming <matt.fleming@intel.com>
Cc: linux-pci@vger.kernel.org
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/pci.h |  2 ++
 arch/x86/kernel/setup.c    |  8 ++++++++
 arch/x86/pci/common.c      | 42 ++++++++++++++++++++++++++++--------------
 3 files changed, 38 insertions(+), 14 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 4625943..7d2468c 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -80,8 +80,10 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 
 #ifdef CONFIG_PCI
 extern void early_quirks(void);
+void add_pci(u64 pa_data);
 #else
 static inline void early_quirks(void) { }
+static inline void add_pci(u64 pa_data) { }
 #endif
 
 extern void pci_iommu_alloc(void);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index a3b65f1..de0f830 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -440,6 +440,8 @@ static void __init parse_setup_data(void)
 		pa_next = data->next;
 		early_memunmap(data, sizeof(*data));
 
+		printk(KERN_DEBUG "setup_data type: %d @ %#010llx\n",
+				data_type, pa_data);
 		switch (data_type) {
 		case SETUP_E820_EXT:
 			parse_e820_ext(pa_data, data_len);
@@ -447,14 +449,20 @@ static void __init parse_setup_data(void)
 		case SETUP_DTB:
 			add_dtb(pa_data);
 			break;
+		case SETUP_PCI:
+			add_pci(pa_data);
+			break;
 		case SETUP_EFI:
 			parse_efi_setup(pa_data, data_len);
 			break;
 		default:
+			pr_warn("Unknown setup_data type: %d @ %#010llx ignored!\n",
+				data_type, pa_data);
 			break;
 		}
 		pa_data = pa_next;
 	}
+	boot_params.hdr.setup_data = 0; /* all done */
 }
 
 static void __init memblock_x86_reserve_range_setup_data(void)
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 8fd6f44..16ace12 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -9,6 +9,7 @@
 #include <linux/pci-acpi.h>
 #include <linux/ioport.h>
 #include <linux/init.h>
+#include <linux/memblock.h>
 #include <linux/dmi.h>
 #include <linux/slab.h>
 
@@ -641,31 +642,44 @@ unsigned int pcibios_assign_all_busses(void)
 	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
+static u64 pci_setup_data;
+void __init add_pci(u64 pa_data)
+{
+	struct setup_data *data;
+
+	data = early_memremap(pa_data, sizeof(*data));
+	memblock_reserve(pa_data, sizeof(*data) + data->len);
+	data->next = pci_setup_data;
+	pci_setup_data = pa_data;
+	early_memunmap(data, sizeof(*data));
+}
+
 int pcibios_add_device(struct pci_dev *dev)
 {
 	struct setup_data *data;
 	struct pci_setup_rom *rom;
 	u64 pa_data;
 
-	pa_data = boot_params.hdr.setup_data;
+	pa_data = pci_setup_data;
 	while (pa_data) {
 		data = ioremap(pa_data, sizeof(*rom));
 		if (!data)
 			return -ENOMEM;
 
-		if (data->type == SETUP_PCI) {
-			rom = (struct pci_setup_rom *)data;
-
-			if ((pci_domain_nr(dev->bus) == rom->segment) &&
-			    (dev->bus->number == rom->bus) &&
-			    (PCI_SLOT(dev->devfn) == rom->device) &&
-			    (PCI_FUNC(dev->devfn) == rom->function) &&
-			    (dev->vendor == rom->vendor) &&
-			    (dev->device == rom->devid)) {
-				dev->rom = pa_data +
-				      offsetof(struct pci_setup_rom, romdata);
-				dev->romlen = rom->pcilen;
-			}
+		rom = (struct pci_setup_rom *)data;
+
+		if ((pci_domain_nr(dev->bus) == rom->segment) &&
+		    (dev->bus->number == rom->bus) &&
+		    (PCI_SLOT(dev->devfn) == rom->device) &&
+		    (PCI_FUNC(dev->devfn) == rom->function) &&
+		    (dev->vendor == rom->vendor) &&
+		    (dev->device == rom->devid)) {
+			dev->rom = pa_data +
+			      offsetof(struct pci_setup_rom, romdata);
+			dev->romlen = rom->pcilen;
+			dev_printk(KERN_DEBUG, &dev->dev, "set rom to [%#010lx, %#010lx] via SETUP_PCI\n",
+				   (unsigned long)dev->rom,
+				   (unsigned long)(dev->rom + dev->romlen - 1));
 		}
 		pa_data = data->next;
 		iounmap(data);
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 35/42] x86, boot, PCI: Convert SETUP_PCI data to list
       [not found] <1436300428-21163-1-git-send-email-yinghai@kernel.org>
  2015-07-07 20:20 ` [PATCH 33/42] x86, boot: Add add_pci handler for SETUP_PCI Yinghai Lu
@ 2015-07-07 20:20 ` Yinghai Lu
  2015-07-14 22:35   ` Bjorn Helgaas
  2015-07-07 20:20 ` [PATCH 37/42] x86, boot, PCI: Export SETUP_PCI data via sysfs Yinghai Lu
  2 siblings, 1 reply; 6+ messages in thread
From: Yinghai Lu @ 2015-07-07 20:20 UTC (permalink / raw)
  To: Kees Cook, H. Peter Anvin, Baoquan He
  Cc: linux-kernel, Yinghai Lu, Bjorn Helgaas, linux-pci

So we could avoid ioremap every time later.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/include/asm/pci.h |  2 ++
 arch/x86/kernel/setup.c    |  1 +
 arch/x86/pci/common.c      | 77 +++++++++++++++++++++++++++++++++++++---------
 3 files changed, 65 insertions(+), 15 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 7d2468c..1c905a8 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -81,9 +81,11 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
 #ifdef CONFIG_PCI
 extern void early_quirks(void);
 void add_pci(u64 pa_data);
+int fill_setup_pci_entries(void);
 #else
 static inline void early_quirks(void) { }
 static inline void add_pci(u64 pa_data) { }
+static inline int fill_setup_pci_entries(void) { }
 #endif
 
 extern void pci_iommu_alloc(void);
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index 35d9ff5..6badf66 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -1180,6 +1180,7 @@ void __init setup_arch(char **cmdline_p)
 	acpi_boot_init();
 	sfi_init();
 	x86_dtb_init();
+	fill_setup_pci_entries();
 
 	/*
 	 * get boot-time SMP configuration:
diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 16ace12..32d4f21 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -642,7 +642,7 @@ unsigned int pcibios_assign_all_busses(void)
 	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
 }
 
-static u64 pci_setup_data;
+static u64 pci_setup_data __initdata;
 void __init add_pci(u64 pa_data)
 {
 	struct setup_data *data;
@@ -654,36 +654,83 @@ void __init add_pci(u64 pa_data)
 	early_memunmap(data, sizeof(*data));
 }
 
-int pcibios_add_device(struct pci_dev *dev)
+struct firmware_setup_pci_entry {
+	struct list_head list;
+	uint16_t vendor;
+	uint16_t devid;
+	uint64_t pcilen;
+	unsigned long segment;
+	unsigned long bus;
+	unsigned long device;
+	unsigned long function;
+	phys_addr_t romdata;
+};
+
+static LIST_HEAD(setup_pci_entries);
+
+int __init fill_setup_pci_entries(void)
 {
 	struct setup_data *data;
 	struct pci_setup_rom *rom;
+	struct firmware_setup_pci_entry *entry;
+	phys_addr_t pa_entry;
 	u64 pa_data;
 
 	pa_data = pci_setup_data;
 	while (pa_data) {
-		data = ioremap(pa_data, sizeof(*rom));
+		data  = early_memremap(pa_data, sizeof(*rom));
 		if (!data)
 			return -ENOMEM;
-
 		rom = (struct pci_setup_rom *)data;
 
-		if ((pci_domain_nr(dev->bus) == rom->segment) &&
-		    (dev->bus->number == rom->bus) &&
-		    (PCI_SLOT(dev->devfn) == rom->device) &&
-		    (PCI_FUNC(dev->devfn) == rom->function) &&
-		    (dev->vendor == rom->vendor) &&
-		    (dev->device == rom->devid)) {
-			dev->rom = pa_data +
-			      offsetof(struct pci_setup_rom, romdata);
-			dev->romlen = rom->pcilen;
+		pa_entry = memblock_alloc(sizeof(*entry), sizeof(long));
+		if (!pa_entry) {
+			early_memunmap(data, sizeof(*rom));
+			return -ENOMEM;
+		}
+
+		entry = phys_to_virt(pa_entry);
+		entry->segment = rom->segment;
+		entry->bus = rom->bus;
+		entry->device = rom->device;
+		entry->function = rom->function;
+		entry->vendor = rom->vendor;
+		entry->devid = rom->devid;
+		entry->pcilen = rom->pcilen;
+		entry->romdata = pa_data +
+				 offsetof(struct pci_setup_rom, romdata);
+
+		list_add(&entry->list, &setup_pci_entries);
+
+		memblock_free(pa_data, sizeof(*rom));
+		pa_data = data->next;
+		early_memunmap(data, sizeof(*rom));
+	}
+
+	pci_setup_data = 0;
+
+	return 0;
+}
+
+int pcibios_add_device(struct pci_dev *dev)
+{
+	struct firmware_setup_pci_entry *entry;
+
+	list_for_each_entry(entry, &setup_pci_entries, list) {
+		if ((pci_domain_nr(dev->bus) == entry->segment) &&
+		    (dev->bus->number == entry->bus) &&
+		    (PCI_SLOT(dev->devfn) == entry->device) &&
+		    (PCI_FUNC(dev->devfn) == entry->function) &&
+		    (dev->vendor == entry->vendor) &&
+		    (dev->device == entry->devid)) {
+			dev->rom = entry->romdata;
+			dev->romlen = entry->pcilen;
 			dev_printk(KERN_DEBUG, &dev->dev, "set rom to [%#010lx, %#010lx] via SETUP_PCI\n",
 				   (unsigned long)dev->rom,
 				   (unsigned long)(dev->rom + dev->romlen - 1));
 		}
-		pa_data = data->next;
-		iounmap(data);
 	}
+
 	return 0;
 }
 
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 37/42] x86, boot, PCI: Export SETUP_PCI data via sysfs
       [not found] <1436300428-21163-1-git-send-email-yinghai@kernel.org>
  2015-07-07 20:20 ` [PATCH 33/42] x86, boot: Add add_pci handler for SETUP_PCI Yinghai Lu
  2015-07-07 20:20 ` [PATCH 35/42] x86, boot, PCI: Convert SETUP_PCI data to list Yinghai Lu
@ 2015-07-07 20:20 ` Yinghai Lu
  2 siblings, 0 replies; 6+ messages in thread
From: Yinghai Lu @ 2015-07-07 20:20 UTC (permalink / raw)
  To: Kees Cook, H. Peter Anvin, Baoquan He
  Cc: linux-kernel, Yinghai Lu, Bjorn Helgaas, linux-pci

So we could let kexec-tools to rebuild SETUP_PCI and pass it to
second kernel if needed.

Now kexec-tools already build SETUP_EFI and SETUP_E820EXT.

Cc: Bjorn Helgaas <bhelgaas@google.com>
Cc: linux-pci@vger.kernel.org
Signed-off-by: Yinghai Lu <yinghai@kernel.org>
---
 arch/x86/pci/common.c | 175 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 175 insertions(+)

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 4d6b128..9112d92 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -656,6 +656,8 @@ void __init add_pci(u64 pa_data)
 
 struct firmware_setup_pci_entry {
 	struct list_head list;
+	struct kobject kobj;
+	struct bin_attribute *rom_attr;
 	uint16_t vendor;
 	uint16_t devid;
 	uint64_t pcilen;
@@ -777,6 +779,179 @@ int pcibios_add_device(struct pci_dev *dev)
 	return 0;
 }
 
+#ifdef CONFIG_SYSFS
+static inline struct firmware_setup_pci_entry *
+to_setup_pci_entry(struct kobject *kobj)
+{
+	return container_of(kobj, struct firmware_setup_pci_entry, kobj);
+}
+
+static ssize_t vendor_show(struct firmware_setup_pci_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%04llx\n",
+			(unsigned long long)entry->vendor);
+}
+
+static ssize_t devid_show(struct firmware_setup_pci_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%04llx\n",
+			(unsigned long long)entry->devid);
+}
+
+static ssize_t pcilen_show(struct firmware_setup_pci_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%llx\n",
+			(unsigned long long)entry->pcilen);
+}
+
+static ssize_t segment_show(struct firmware_setup_pci_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%04llx\n",
+			(unsigned long long)entry->segment);
+}
+
+static ssize_t bus_show(struct firmware_setup_pci_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%02llx\n",
+			(unsigned long long)entry->bus);
+}
+
+static ssize_t device_show(struct firmware_setup_pci_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%02llx\n",
+			(unsigned long long)entry->device);
+}
+
+static ssize_t function_show(struct firmware_setup_pci_entry *entry, char *buf)
+{
+	return snprintf(buf, PAGE_SIZE, "0x%1llx\n",
+			(unsigned long long)entry->function);
+}
+
+struct setup_pci_attribute {
+	struct attribute attr;
+	ssize_t (*show)(struct firmware_setup_pci_entry *entry, char *buf);
+};
+
+static inline struct setup_pci_attribute *to_setup_pci_attr(
+							struct attribute *attr)
+{
+	return container_of(attr, struct setup_pci_attribute, attr);
+}
+
+static ssize_t setup_pci_attr_show(struct kobject *kobj,
+				   struct attribute *attr, char *buf)
+{
+	struct firmware_setup_pci_entry *entry = to_setup_pci_entry(kobj);
+	struct setup_pci_attribute *setup_pci_attr = to_setup_pci_attr(attr);
+
+	return setup_pci_attr->show(entry, buf);
+}
+
+static struct setup_pci_attribute setup_pci_vendor_attr = __ATTR_RO(vendor);
+static struct setup_pci_attribute setup_pci_devid_attr = __ATTR_RO(devid);
+static struct setup_pci_attribute setup_pci_pcilen_attr = __ATTR_RO(pcilen);
+static struct setup_pci_attribute setup_pci_segment_attr = __ATTR_RO(segment);
+static struct setup_pci_attribute setup_pci_bus_attr = __ATTR_RO(bus);
+static struct setup_pci_attribute setup_pci_device_attr = __ATTR_RO(device);
+static struct setup_pci_attribute setup_pci_function_attr = __ATTR_RO(function);
+
+/*
+ * These are default attributes that are added for every memmap entry.
+ */
+static struct attribute *def_attrs[] = {
+	&setup_pci_vendor_attr.attr,
+	&setup_pci_devid_attr.attr,
+	&setup_pci_pcilen_attr.attr,
+	&setup_pci_segment_attr.attr,
+	&setup_pci_bus_attr.attr,
+	&setup_pci_device_attr.attr,
+	&setup_pci_function_attr.attr,
+	NULL
+};
+
+static const struct sysfs_ops setup_pci_attr_ops = {
+	.show = setup_pci_attr_show,
+};
+
+static struct kobj_type __refdata setup_pci_ktype = {
+	.sysfs_ops      = &setup_pci_attr_ops,
+	.default_attrs  = def_attrs,
+};
+
+static ssize_t setup_pci_rom_read(struct file *filp, struct kobject *kobj,
+				  struct bin_attribute *bin_attr, char *buf,
+				  loff_t off, size_t count)
+{
+	struct firmware_setup_pci_entry *entry = to_setup_pci_entry(kobj);
+
+	if (off >= entry->pcilen)
+		count = 0;
+	else {
+		unsigned char *rom = phys_to_virt(entry->romdata);
+
+		if (off + count > entry->pcilen)
+			count = entry->pcilen - off;
+
+		memcpy(buf, rom + off, count);
+	}
+
+	return count;
+}
+
+static int __init add_sysfs_fw_setup_pci_entry(
+					struct firmware_setup_pci_entry *entry)
+{
+	int retval = 0;
+	static int setup_pci_entries_nr;
+	static struct kset *setup_pci_kset;
+	struct bin_attribute *attr;
+
+	kobject_init(&entry->kobj, &setup_pci_ktype);
+
+	if (!setup_pci_kset) {
+		setup_pci_kset = kset_create_and_add("setup_pci", NULL,
+						     firmware_kobj);
+		if (!setup_pci_kset)
+			return -ENOMEM;
+	}
+
+	entry->kobj.kset = setup_pci_kset;
+	retval = kobject_add(&entry->kobj, NULL, "%d", setup_pci_entries_nr++);
+	if (retval) {
+		kobject_put(&entry->kobj);
+		return retval;
+	}
+
+	attr = kzalloc(sizeof(*attr), GFP_ATOMIC);
+	if (!attr)
+		return -ENOMEM;
+
+	sysfs_bin_attr_init(attr);
+	attr->size = entry->pcilen;
+	attr->attr.name = "rom";
+	attr->attr.mode = S_IRUSR;
+	attr->read = setup_pci_rom_read;
+	retval = sysfs_create_bin_file(&entry->kobj, attr);
+	if (retval)
+		kfree(attr);
+	entry->rom_attr = attr;
+
+	return retval;
+}
+
+static int __init firmware_setup_pci_init(void)
+{
+	struct firmware_setup_pci_entry *entry;
+
+	list_for_each_entry(entry, &setup_pci_entries, list)
+		add_sysfs_fw_setup_pci_entry(entry);
+
+	return 0;
+}
+late_initcall(firmware_setup_pci_init);
+#endif
+
 int pcibios_enable_device(struct pci_dev *dev, int mask)
 {
 	int err;
-- 
1.8.4.5


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 33/42] x86, boot: Add add_pci handler for SETUP_PCI
  2015-07-07 20:20 ` [PATCH 33/42] x86, boot: Add add_pci handler for SETUP_PCI Yinghai Lu
@ 2015-07-14 22:30   ` Bjorn Helgaas
  0 siblings, 0 replies; 6+ messages in thread
From: Bjorn Helgaas @ 2015-07-14 22:30 UTC (permalink / raw)
  To: Yinghai Lu
  Cc: Kees Cook, H. Peter Anvin, Baoquan He, linux-kernel, Matt Fleming,
	linux-pci

On Tue, Jul 07, 2015 at 01:20:19PM -0700, Yinghai Lu wrote:
> Let it reserve setup_data, and keep it's own list.

s/it's/its/

> Also clear the hdr.setup_data, as all handler now handle or
> reserve setup_data locally already.
> 
> Cc: Bjorn Helgaas <bhelgaas@google.com>
> Cc: Matt Fleming <matt.fleming@intel.com>
> Cc: linux-pci@vger.kernel.org
> Signed-off-by: Yinghai Lu <yinghai@kernel.org>
> ---
>  arch/x86/include/asm/pci.h |  2 ++
>  arch/x86/kernel/setup.c    |  8 ++++++++
>  arch/x86/pci/common.c      | 42 ++++++++++++++++++++++++++++--------------
>  3 files changed, 38 insertions(+), 14 deletions(-)
> 
> diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
> index 4625943..7d2468c 100644
> --- a/arch/x86/include/asm/pci.h
> +++ b/arch/x86/include/asm/pci.h
> @@ -80,8 +80,10 @@ extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
>  
>  #ifdef CONFIG_PCI
>  extern void early_quirks(void);
> +void add_pci(u64 pa_data);
>  #else
>  static inline void early_quirks(void) { }
> +static inline void add_pci(u64 pa_data) { }
>  #endif
>  
>  extern void pci_iommu_alloc(void);
> diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
> index a3b65f1..de0f830 100644
> --- a/arch/x86/kernel/setup.c
> +++ b/arch/x86/kernel/setup.c
> @@ -440,6 +440,8 @@ static void __init parse_setup_data(void)
>  		pa_next = data->next;
>  		early_memunmap(data, sizeof(*data));
>  
> +		printk(KERN_DEBUG "setup_data type: %d @ %#010llx\n",
> +				data_type, pa_data);
>  		switch (data_type) {
>  		case SETUP_E820_EXT:
>  			parse_e820_ext(pa_data, data_len);
> @@ -447,14 +449,20 @@ static void __init parse_setup_data(void)
>  		case SETUP_DTB:
>  			add_dtb(pa_data);
>  			break;
> +		case SETUP_PCI:
> +			add_pci(pa_data);
> +			break;
>  		case SETUP_EFI:
>  			parse_efi_setup(pa_data, data_len);
>  			break;
>  		default:
> +			pr_warn("Unknown setup_data type: %d @ %#010llx ignored!\n",
> +				data_type, pa_data);
>  			break;
>  		}
>  		pa_data = pa_next;
>  	}
> +	boot_params.hdr.setup_data = 0; /* all done */
>  }
>  
>  static void __init memblock_x86_reserve_range_setup_data(void)
> diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
> index 8fd6f44..16ace12 100644
> --- a/arch/x86/pci/common.c
> +++ b/arch/x86/pci/common.c
> @@ -9,6 +9,7 @@
>  #include <linux/pci-acpi.h>
>  #include <linux/ioport.h>
>  #include <linux/init.h>
> +#include <linux/memblock.h>
>  #include <linux/dmi.h>
>  #include <linux/slab.h>
>  
> @@ -641,31 +642,44 @@ unsigned int pcibios_assign_all_busses(void)
>  	return (pci_probe & PCI_ASSIGN_ALL_BUSSES) ? 1 : 0;
>  }
>  
> +static u64 pci_setup_data;
> +void __init add_pci(u64 pa_data)
> +{
> +	struct setup_data *data;
> +
> +	data = early_memremap(pa_data, sizeof(*data));
> +	memblock_reserve(pa_data, sizeof(*data) + data->len);
> +	data->next = pci_setup_data;
> +	pci_setup_data = pa_data;
> +	early_memunmap(data, sizeof(*data));
> +}
> +
>  int pcibios_add_device(struct pci_dev *dev)
>  {
>  	struct setup_data *data;
>  	struct pci_setup_rom *rom;
>  	u64 pa_data;
>  
> -	pa_data = boot_params.hdr.setup_data;
> +	pa_data = pci_setup_data;
>  	while (pa_data) {
>  		data = ioremap(pa_data, sizeof(*rom));
>  		if (!data)
>  			return -ENOMEM;
>  
> -		if (data->type == SETUP_PCI) {
> -			rom = (struct pci_setup_rom *)data;
> -
> -			if ((pci_domain_nr(dev->bus) == rom->segment) &&
> -			    (dev->bus->number == rom->bus) &&
> -			    (PCI_SLOT(dev->devfn) == rom->device) &&
> -			    (PCI_FUNC(dev->devfn) == rom->function) &&
> -			    (dev->vendor == rom->vendor) &&
> -			    (dev->device == rom->devid)) {
> -				dev->rom = pa_data +
> -				      offsetof(struct pci_setup_rom, romdata);
> -				dev->romlen = rom->pcilen;
> -			}
> +		rom = (struct pci_setup_rom *)data;
> +
> +		if ((pci_domain_nr(dev->bus) == rom->segment) &&
> +		    (dev->bus->number == rom->bus) &&
> +		    (PCI_SLOT(dev->devfn) == rom->device) &&
> +		    (PCI_FUNC(dev->devfn) == rom->function) &&
> +		    (dev->vendor == rom->vendor) &&
> +		    (dev->device == rom->devid)) {
> +			dev->rom = pa_data +
> +			      offsetof(struct pci_setup_rom, romdata);
> +			dev->romlen = rom->pcilen;
> +			dev_printk(KERN_DEBUG, &dev->dev, "set rom to [%#010lx, %#010lx] via SETUP_PCI\n",
> +				   (unsigned long)dev->rom,
> +				   (unsigned long)(dev->rom + dev->romlen - 1));

"set ROM to [mem %#010lx-%#010lx] via SETUP_PCI" so it matches the way we
print other MMIO ranges.

>  		}
>  		pa_data = data->next;
>  		iounmap(data);
> -- 
> 1.8.4.5
> 

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 35/42] x86, boot, PCI: Convert SETUP_PCI data to list
  2015-07-07 20:20 ` [PATCH 35/42] x86, boot, PCI: Convert SETUP_PCI data to list Yinghai Lu
@ 2015-07-14 22:35   ` Bjorn Helgaas
  2015-07-15  1:57     ` Yinghai Lu
  0 siblings, 1 reply; 6+ messages in thread
From: Bjorn Helgaas @ 2015-07-14 22:35 UTC (permalink / raw)
  To: Yinghai Lu; +Cc: Kees Cook, H. Peter Anvin, Baoquan He, linux-kernel, linux-pci

On Tue, Jul 07, 2015 at 01:20:21PM -0700, Yinghai Lu wrote:
> So we could avoid ioremap every time later.

The changelog (not just the subject) should say what you're doing.

> diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
> index 16ace12..32d4f21 100644
> --- a/arch/x86/pci/common.c
> +++ b/arch/x86/pci/common.c

> +struct firmware_setup_pci_entry {
> +	struct list_head list;
> +	uint16_t vendor;
> +	uint16_t devid;
> +	uint64_t pcilen;

Is there a reason to use uint16_t and uint64_t instead of u16 and u64?

> +	unsigned long segment;
> +	unsigned long bus;
> +	unsigned long device;
> +	unsigned long function;
> +	phys_addr_t romdata;
> +};

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 35/42] x86, boot, PCI: Convert SETUP_PCI data to list
  2015-07-14 22:35   ` Bjorn Helgaas
@ 2015-07-15  1:57     ` Yinghai Lu
  0 siblings, 0 replies; 6+ messages in thread
From: Yinghai Lu @ 2015-07-15  1:57 UTC (permalink / raw)
  To: Bjorn Helgaas
  Cc: Kees Cook, H. Peter Anvin, Baoquan He, Linux Kernel Mailing List,
	linux-pci@vger.kernel.org

On Tue, Jul 14, 2015 at 3:35 PM, Bjorn Helgaas <bhelgaas@google.com> wrote:
>> diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
>> index 16ace12..32d4f21 100644
>> --- a/arch/x86/pci/common.c
>> +++ b/arch/x86/pci/common.c
>
>> +struct firmware_setup_pci_entry {
>> +     struct list_head list;
>> +     uint16_t vendor;
>> +     uint16_t devid;
>> +     uint64_t pcilen;
>
> Is there a reason to use uint16_t and uint64_t instead of u16 and u64?

keep them same as arch/x86/include/asm/pci.h::pci_setup_rom.

and we have that from:

commit dd5fc854de5fd37adfcef8a366cd21a55aa01d3d
Author: Matthew Garrett <mjg@redhat.com>
Date:   Wed Dec 5 14:33:26 2012 -0700

    EFI: Stash ROMs if they're not in the PCI BAR

    EFI provides support for providing PCI ROMs via means other than the ROM
    BAR. This support vanishes after we've exited boot services, so add support
    for stashing copies of the ROMs in setup_data if they're not otherwise
    available.

    Signed-off-by: Matthew Garrett <mjg@redhat.com>
    Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
    Tested-by: Seth Forshee <seth.forshee@canonical.com>

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 6e41b93..dba7805 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -171,4 +171,16 @@ cpumask_of_pcibus(const struct pci_bus *bus)
 }
 #endif

+struct pci_setup_rom {
+       struct setup_data data;
+       uint16_t vendor;
+       uint16_t devid;
+       uint64_t pcilen;
+       unsigned long segment;
+       unsigned long bus;
+       unsigned long device;
+       unsigned long function;
+       uint8_t romdata[0];
+};
+
 #endif /* _ASM_X86_PCI_H */

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-07-15  1:57 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <1436300428-21163-1-git-send-email-yinghai@kernel.org>
2015-07-07 20:20 ` [PATCH 33/42] x86, boot: Add add_pci handler for SETUP_PCI Yinghai Lu
2015-07-14 22:30   ` Bjorn Helgaas
2015-07-07 20:20 ` [PATCH 35/42] x86, boot, PCI: Convert SETUP_PCI data to list Yinghai Lu
2015-07-14 22:35   ` Bjorn Helgaas
2015-07-15  1:57     ` Yinghai Lu
2015-07-07 20:20 ` [PATCH 37/42] x86, boot, PCI: Export SETUP_PCI data via sysfs Yinghai Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).