From 3130451e270960065e8de684c60b898e970c940c Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 14 Feb 2018 17:43:16 +0200 Subject: [PATCH 01/19] x86/platform/atom: Re-use DEFINE_SHOW_ATTRIBUTE() macro ...instead of open coding file operations followed by custom ->open() callbacks per each attribute. While here, replace permissions by explicit octal value. Signed-off-by: Andy Shevchenko Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/20180214154317.52290-1-andriy.shevchenko@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/platform/atom/punit_atom_debug.c | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/arch/x86/platform/atom/punit_atom_debug.c b/arch/x86/platform/atom/punit_atom_debug.c index d49d3be81953..034813d4ab1e 100644 --- a/arch/x86/platform/atom/punit_atom_debug.c +++ b/arch/x86/platform/atom/punit_atom_debug.c @@ -109,18 +109,7 @@ static int punit_dev_state_show(struct seq_file *seq_file, void *unused) return 0; } - -static int punit_dev_state_open(struct inode *inode, struct file *file) -{ - return single_open(file, punit_dev_state_show, inode->i_private); -} - -static const struct file_operations punit_dev_state_ops = { - .open = punit_dev_state_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(punit_dev_state); static struct dentry *punit_dbg_file; @@ -132,9 +121,9 @@ static int punit_dbgfs_register(struct punit_device *punit_device) if (!punit_dbg_file) return -ENXIO; - dev_state = debugfs_create_file("dev_power_state", S_IFREG | S_IRUGO, + dev_state = debugfs_create_file("dev_power_state", 0444, punit_dbg_file, punit_device, - &punit_dev_state_ops); + &punit_dev_state_fops); if (!dev_state) { pr_err("punit_dev_state register failed\n"); debugfs_remove(punit_dbg_file); From a66b86f0026b07b0ea7340e3690ac9fd5ac1499a Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Wed, 14 Feb 2018 17:43:17 +0200 Subject: [PATCH 02/19] x86/platform/quark: Re-use DEFINE_SHOW_ATTRIBUTE() macro ...instead of open coding file operations followed by custom ->open() callbacks per each attribute. While here, replace permissions by explicit octal value. Signed-off-by: Andy Shevchenko Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Thomas Gleixner Link: http://lkml.kernel.org/r/20180214154317.52290-2-andriy.shevchenko@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/platform/intel-quark/imr.c | 24 +++--------------------- 1 file changed, 3 insertions(+), 21 deletions(-) diff --git a/arch/x86/platform/intel-quark/imr.c b/arch/x86/platform/intel-quark/imr.c index 17d6d2296e4d..49828c2707ac 100644 --- a/arch/x86/platform/intel-quark/imr.c +++ b/arch/x86/platform/intel-quark/imr.c @@ -224,25 +224,7 @@ static int imr_dbgfs_state_show(struct seq_file *s, void *unused) mutex_unlock(&idev->lock); return ret; } - -/** - * imr_state_open - debugfs open callback. - * - * @inode: pointer to struct inode. - * @file: pointer to struct file. - * @return: result of single open. - */ -static int imr_state_open(struct inode *inode, struct file *file) -{ - return single_open(file, imr_dbgfs_state_show, inode->i_private); -} - -static const struct file_operations imr_state_ops = { - .open = imr_state_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; +DEFINE_SHOW_ATTRIBUTE(imr_dbgfs_state); /** * imr_debugfs_register - register debugfs hooks. @@ -252,8 +234,8 @@ static const struct file_operations imr_state_ops = { */ static int imr_debugfs_register(struct imr_device *idev) { - idev->file = debugfs_create_file("imr_state", S_IFREG | S_IRUGO, NULL, - idev, &imr_state_ops); + idev->file = debugfs_create_file("imr_state", 0444, NULL, idev, + &imr_dbgfs_state_fops); return PTR_ERR_OR_ZERO(idev->file); } From 492a1abd61e4b4f78c1c5804840a304a9e32da04 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 22 Feb 2018 14:59:20 +0200 Subject: [PATCH 03/19] dmi: Introduce the dmi_get_bios_year() helper function The pattern to only extract the year portion of date is used in several places and more users may come. By using this helper they may create slightly cleaner code. Signed-off-by: Andy Shevchenko [ Minor stylistic cleanup. ] Cc: Bjorn Helgaas Cc: Jean Delvare Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Rafael J. Wysocki Cc: Thomas Gleixner Cc: linux-acpi@vger.kernel.org Cc: linux-pci@vger.kernel.org Link: http://lkml.kernel.org/r/20180222125923.57385-1-andriy.shevchenko@linux.intel.com Signed-off-by: Ingo Molnar --- include/linux/dmi.h | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 46e151172d95..0bade156e908 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -147,4 +147,13 @@ static inline const struct dmi_system_id * #endif +static inline int dmi_get_bios_year(void) +{ + int year; + + dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); + + return year; +} + #endif /* __DMI_H__ */ From 69c42d493db452ea87c1ac56e83c978512f4e6ec Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 22 Feb 2018 14:59:21 +0200 Subject: [PATCH 04/19] x86/pci: Simplify code by using the new dmi_get_bios_year() helper ...instead of open coding its functionality. No changes in functionality. Signed-off-by: Andy Shevchenko Cc: Bjorn Helgaas Cc: Jean Delvare Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Rafael J. Wysocki Cc: Thomas Gleixner Cc: linux-acpi@vger.kernel.org Cc: linux-pci@vger.kernel.org Link: http://lkml.kernel.org/r/20180222125923.57385-2-andriy.shevchenko@linux.intel.com Signed-off-by: Ingo Molnar --- arch/x86/pci/acpi.c | 8 ++------ arch/x86/pci/direct.c | 5 ++--- arch/x86/pci/mmconfig-shared.c | 9 ++------- 3 files changed, 6 insertions(+), 16 deletions(-) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 7df49c40665e..00e60de30328 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -140,12 +140,8 @@ static const struct dmi_system_id pci_crs_quirks[] __initconst = { void __init pci_acpi_crs_quirks(void) { - int year; - - if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008) { - if (iomem_resource.end <= 0xffffffff) - pci_use_crs = false; - } + if ((dmi_get_bios_year() < 2008) && (iomem_resource.end <= 0xffffffff)) + pci_use_crs = false; dmi_check_system(pci_crs_quirks); diff --git a/arch/x86/pci/direct.c b/arch/x86/pci/direct.c index 2d9503323d10..a51074c55982 100644 --- a/arch/x86/pci/direct.c +++ b/arch/x86/pci/direct.c @@ -195,14 +195,13 @@ static const struct pci_raw_ops pci_direct_conf2 = { static int __init pci_sanity_check(const struct pci_raw_ops *o) { u32 x = 0; - int year, devfn; + int devfn; if (pci_probe & PCI_NO_CHECKS) return 1; /* Assume Type 1 works for newer systems. This handles machines that don't have anything on PCI Bus 0. */ - dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); - if (year >= 2001) + if (dmi_get_bios_year() >= 2001) return 1; for (devfn = 0; devfn < 0x100; devfn++) { diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 96684d0adcf9..0b40482578b8 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -547,19 +547,14 @@ static void __init pci_mmcfg_reject_broken(int early) static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, struct acpi_mcfg_allocation *cfg) { - int year; - if (cfg->address < 0xFFFFFFFF) return 0; if (!strncmp(mcfg->header.oem_id, "SGI", 3)) return 0; - if (mcfg->header.revision >= 1) { - if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && - year >= 2010) - return 0; - } + if ((mcfg->header.revision >= 1) && (dmi_get_bios_year() >= 2010)) + return 0; pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx " "is above 4GB, ignored\n", cfg->pci_segment, From 9c0a30b67bd916a7da1a7101dbf3115e5f10d852 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 22 Feb 2018 14:59:22 +0200 Subject: [PATCH 05/19] ACPI/sleep: Simplify code by using the new dmi_get_bios_year() helper ...instead of open coding its functionality. No changes in functionality. Signed-off-by: Andy Shevchenko Cc: Bjorn Helgaas Cc: Jean Delvare Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Rafael J. Wysocki Cc: Thomas Gleixner Cc: linux-acpi@vger.kernel.org Cc: linux-pci@vger.kernel.org Link: http://lkml.kernel.org/r/20180222125923.57385-3-andriy.shevchenko@linux.intel.com Signed-off-by: Ingo Molnar --- drivers/acpi/sleep.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 46cde0912762..b35923e3a926 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -376,12 +376,10 @@ void __init acpi_sleep_no_blacklist(void) static void __init acpi_sleep_dmi_check(void) { - int year; - if (ignore_blacklist) return; - if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012) + if (dmi_get_bios_year() >= 2012) acpi_nvs_nosave_s3(); dmi_check_system(acpisleep_dmi_table); From ac95090a0440be1b17aa1b5d9462d9c67146ce0b Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Thu, 22 Feb 2018 14:59:23 +0200 Subject: [PATCH 06/19] pci: Simplify code by using the new dmi_get_bios_year() helper ...instead of open coding its functionality. No changes in functionality. Signed-off-by: Andy Shevchenko Cc: Bjorn Helgaas Cc: Jean Delvare Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Rafael J. Wysocki Cc: Thomas Gleixner Cc: linux-acpi@vger.kernel.org Cc: linux-pci@vger.kernel.org Link: http://lkml.kernel.org/r/20180222125923.57385-4-andriy.shevchenko@linux.intel.com Signed-off-by: Ingo Molnar --- drivers/pci/pci.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index f6a4dd10d9b0..ae654e21439d 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -2258,8 +2258,6 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev) */ bool pci_bridge_d3_possible(struct pci_dev *bridge) { - unsigned int year; - if (!pci_is_pcie(bridge)) return false; @@ -2287,10 +2285,8 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge) * It should be safe to put PCIe ports from 2015 or newer * to D3. */ - if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && - year >= 2015) { + if (dmi_get_bios_year() >= 2015) return true; - } break; } From 628df9dc5ad886b0a9b33c75a7b09710eb859ca1 Mon Sep 17 00:00:00 2001 From: Ivan Gorinov Date: Wed, 7 Mar 2018 11:46:29 -0800 Subject: [PATCH 07/19] x86/devicetree: Initialize device tree before using it Commit 08d53aa58cb1 added CRC32 calculation in early_init_dt_verify() and checking in late initcall of_fdt_raw_init(), making early_init_dt_verify() mandatory. The required call to early_init_dt_verify() was not added to the x86-specific implementation, causing failure to create the sysfs entry in of_fdt_raw_init(). Fixes: 08d53aa58cb1 ("of/fdt: export fdt blob as /sys/firmware/fdt") Signed-off-by: Ivan Gorinov Signed-off-by: Thomas Gleixner Cc: Mark Rutland Cc: Rob Herring Link: https://lkml.kernel.org/r/c8c7e941efc63b5d25ebf9b6350b0f3df38f6098.1520450752.git.ivan.gorinov@intel.com --- arch/x86/kernel/devicetree.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 25de5f6ca997..63d2ebc21825 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -270,14 +271,15 @@ static void __init x86_flattree_get_config(void) map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128); - initial_boot_params = dt = early_memremap(initial_dtb, map_len); - size = of_get_flat_dt_size(); + dt = early_memremap(initial_dtb, map_len); + size = fdt_totalsize(dt); if (map_len < size) { early_memunmap(dt, map_len); - initial_boot_params = dt = early_memremap(initial_dtb, size); + dt = early_memremap(initial_dtb, size); map_len = size; } + early_init_dt_verify(dt); unflatten_and_copy_device_tree(); early_memunmap(dt, map_len); } From 0a5169add90e43ab45ab1ba34223b8583fcaf675 Mon Sep 17 00:00:00 2001 From: Ivan Gorinov Date: Wed, 7 Mar 2018 11:46:53 -0800 Subject: [PATCH 08/19] x86/devicetree: Fix device IRQ settings in DT IRQ parameters for the SoC devices connected directly to I/O APIC lines (without PCI IRQ routing) may be specified in the Device Tree. Called from DT IRQ parser, irq_create_fwspec_mapping() calls irq_domain_alloc_irqs() with a pointer to irq_fwspec structure as @arg. But x86-specific DT IRQ allocation code casts @arg to of_phandle_args structure pointer and crashes trying to read the IRQ parameters. The function was not converted when the mapping descriptor was changed to irq_fwspec in the generic irqdomain code. Fixes: 11e4438ee330 ("irqdomain: Introduce a firmware-specific IRQ specifier structure") Signed-off-by: Ivan Gorinov Signed-off-by: Thomas Gleixner Cc: Mark Rutland Cc: Rob Herring Link: https://lkml.kernel.org/r/a234dee27ea60ce76141872da0d6bdb378b2a9ee.1520450752.git.ivan.gorinov@intel.com --- arch/x86/kernel/devicetree.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 63d2ebc21825..5cd387fcc777 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -195,19 +195,22 @@ static struct of_ioapic_type of_ioapic_type[] = static int dt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, unsigned int nr_irqs, void *arg) { - struct of_phandle_args *irq_data = (void *)arg; + struct irq_fwspec *fwspec = (struct irq_fwspec *)arg; struct of_ioapic_type *it; struct irq_alloc_info tmp; + int type_index; - if (WARN_ON(irq_data->args_count < 2)) - return -EINVAL; - if (irq_data->args[1] >= ARRAY_SIZE(of_ioapic_type)) + if (WARN_ON(fwspec->param_count < 2)) return -EINVAL; - it = &of_ioapic_type[irq_data->args[1]]; + type_index = fwspec->param[1]; + if (type_index >= ARRAY_SIZE(of_ioapic_type)) + return -EINVAL; + + it = &of_ioapic_type[type_index]; ioapic_set_alloc_attr(&tmp, NUMA_NO_NODE, it->trigger, it->polarity); tmp.ioapic_id = mpc_ioapic_id(mp_irqdomain_ioapic_idx(domain)); - tmp.ioapic_pin = irq_data->args[0]; + tmp.ioapic_pin = fwspec->param[0]; return mp_irqdomain_alloc(domain, virq, nr_irqs, &tmp); } From 63338a38db955cb4e0352c11b78732157c78d30b Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 7 Mar 2018 08:39:12 +0100 Subject: [PATCH 09/19] jailhouse: Provide detection for non-x86 systems Implement jailhouse_paravirt() via device tree probing on architectures != x86. Will be used by the PCI core. Signed-off-by: Jan Kiszka Signed-off-by: Thomas Gleixner Reviewed-by: Juergen Gross Cc: jailhouse-dev@googlegroups.com Cc: Mark Rutland Cc: linux-pci@vger.kernel.org Cc: virtualization@lists.linux-foundation.org Cc: Andy Shevchenko Cc: Rob Herring Cc: Bjorn Helgaas Link: https://lkml.kernel.org/r/dae9fe0c6e63141c28ca90492fa5712b4c33ffb5.1520408357.git.jan.kiszka@siemens.com --- Documentation/devicetree/bindings/jailhouse.txt | 8 ++++++++ arch/x86/include/asm/jailhouse_para.h | 2 +- include/linux/hypervisor.h | 17 +++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 Documentation/devicetree/bindings/jailhouse.txt diff --git a/Documentation/devicetree/bindings/jailhouse.txt b/Documentation/devicetree/bindings/jailhouse.txt new file mode 100644 index 000000000000..2901c25ff340 --- /dev/null +++ b/Documentation/devicetree/bindings/jailhouse.txt @@ -0,0 +1,8 @@ +Jailhouse non-root cell device tree bindings +-------------------------------------------- + +When running in a non-root Jailhouse cell (partition), the device tree of this +platform shall have a top-level "hypervisor" node with the following +properties: + +- compatible = "jailhouse,cell" diff --git a/arch/x86/include/asm/jailhouse_para.h b/arch/x86/include/asm/jailhouse_para.h index 875b54376689..b885a961a150 100644 --- a/arch/x86/include/asm/jailhouse_para.h +++ b/arch/x86/include/asm/jailhouse_para.h @@ -1,7 +1,7 @@ /* SPDX-License-Identifier: GPL2.0 */ /* - * Jailhouse paravirt_ops implementation + * Jailhouse paravirt detection * * Copyright (c) Siemens AG, 2015-2017 * diff --git a/include/linux/hypervisor.h b/include/linux/hypervisor.h index b19563f9a8eb..fc08b433c856 100644 --- a/include/linux/hypervisor.h +++ b/include/linux/hypervisor.h @@ -8,15 +8,28 @@ */ #ifdef CONFIG_X86 + +#include #include + static inline void hypervisor_pin_vcpu(int cpu) { x86_platform.hyper.pin_vcpu(cpu); } -#else + +#else /* !CONFIG_X86 */ + +#include + static inline void hypervisor_pin_vcpu(int cpu) { } -#endif + +static inline bool jailhouse_paravirt(void) +{ + return of_find_compatible_node(NULL, NULL, "jailhouse,cell"); +} + +#endif /* !CONFIG_X86 */ #endif /* __LINUX_HYPEVISOR_H */ From 690f4304104f37e473bd5e43fc5247f5cd35b225 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 7 Mar 2018 08:39:13 +0100 Subject: [PATCH 10/19] PCI: Scan all functions when running over Jailhouse Per PCIe r4.0, sec 7.5.1.1.9, multi-function devices are required to have a function 0. Therefore, Linux scans for devices at function 0 (devfn 0/8/16/...) and only scans for other functions if function 0 has its Multi-Function Device bit set or ARI or SR-IOV indicate there are more functions. The Jailhouse hypervisor may pass individual functions of a multi-function device to a guest without passing function 0, which means a Linux guest won't find them. Change Linux PCI probing so it scans all function numbers when running as a guest over Jailhouse. This is technically prohibited by the spec, so it is possible that PCI devices without the Multi-Function Device bit set may have unexpected behavior in response to this probe. Originally-by: Benedikt Spranger Signed-off-by: Jan Kiszka Signed-off-by: Thomas Gleixner Reviewed-by: Andy Shevchenko Acked-by: Bjorn Helgaas Cc: jailhouse-dev@googlegroups.com Cc: Benedikt Spranger Cc: linux-pci@vger.kernel.org Cc: virtualization@lists.linux-foundation.org Link: https://lkml.kernel.org/r/06e279b2a3e06cf6689ab3975f8ab592bba02362.1520408357.git.jan.kiszka@siemens.com --- arch/x86/pci/legacy.c | 4 +++- drivers/pci/probe.c | 22 +++++++++++++++++++--- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/arch/x86/pci/legacy.c b/arch/x86/pci/legacy.c index 1cb01abcb1be..dfbe6ac38830 100644 --- a/arch/x86/pci/legacy.c +++ b/arch/x86/pci/legacy.c @@ -4,6 +4,7 @@ #include #include #include +#include #include /* @@ -34,13 +35,14 @@ int __init pci_legacy_init(void) void pcibios_scan_specific_bus(int busn) { + int stride = jailhouse_paravirt() ? 1 : 8; int devfn; u32 l; if (pci_find_bus(0, busn)) return; - for (devfn = 0; devfn < 256; devfn += 8) { + for (devfn = 0; devfn < 256; devfn += stride) { if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) && l != 0x0000 && l != 0xffff) { DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l); diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index ef5377438a1e..3c365dc996e7 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include "pci.h" @@ -2518,14 +2519,29 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, { unsigned int used_buses, normal_bridges = 0, hotplug_bridges = 0; unsigned int start = bus->busn_res.start; - unsigned int devfn, cmax, max = start; + unsigned int devfn, fn, cmax, max = start; struct pci_dev *dev; + int nr_devs; dev_dbg(&bus->dev, "scanning bus\n"); /* Go find them, Rover! */ - for (devfn = 0; devfn < 0x100; devfn += 8) - pci_scan_slot(bus, devfn); + for (devfn = 0; devfn < 256; devfn += 8) { + nr_devs = pci_scan_slot(bus, devfn); + + /* + * The Jailhouse hypervisor may pass individual functions of a + * multi-function device to a guest without passing function 0. + * Look for them as well. + */ + if (jailhouse_paravirt() && nr_devs == 0) { + for (fn = 1; fn < 8; fn++) { + dev = pci_scan_single_device(bus, devfn + fn); + if (dev) + dev->multifunction = 1; + } + } + } /* Reserve buses for SR-IOV capability */ used_buses = pci_iov_bus_range(bus); From 6fa4a94e150be25d02547d51f03b4bc34aaec32f Mon Sep 17 00:00:00 2001 From: Otavio Pontes Date: Wed, 7 Mar 2018 08:39:14 +0100 Subject: [PATCH 11/19] x86/jailhouse: Enable PCI mmconfig access in inmates Use the PCI mmconfig base address exported by jailhouse in boot parameters in order to access the memory mapped PCI configuration space. [Jan: rebased, fixed !CONFIG_PCI_MMCONFIG, used pcibios_last_bus] Signed-off-by: Otavio Pontes Signed-off-by: Jan Kiszka Signed-off-by: Thomas Gleixner Reviewed-by: Andy Shevchenko Cc: jailhouse-dev@googlegroups.com Cc: linux-pci@vger.kernel.org Cc: virtualization@lists.linux-foundation.org Cc: Bjorn Helgaas Link: https://lkml.kernel.org/r/2ee9e4401fa22377b3965893a558120f169be82b.1520408357.git.jan.kiszka@siemens.com --- arch/x86/include/asm/pci_x86.h | 2 ++ arch/x86/kernel/jailhouse.c | 8 ++++++++ arch/x86/pci/mmconfig-shared.c | 4 ++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/pci_x86.h b/arch/x86/include/asm/pci_x86.h index eb66fa9cd0fc..959d618dbb17 100644 --- a/arch/x86/include/asm/pci_x86.h +++ b/arch/x86/include/asm/pci_x86.h @@ -151,6 +151,8 @@ extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, phys_addr_t addr); extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end); extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); +extern struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start, + int end, u64 addr); extern struct list_head pci_mmcfg_list; diff --git a/arch/x86/kernel/jailhouse.c b/arch/x86/kernel/jailhouse.c index b68fd895235a..fa183a131edc 100644 --- a/arch/x86/kernel/jailhouse.c +++ b/arch/x86/kernel/jailhouse.c @@ -124,6 +124,14 @@ static int __init jailhouse_pci_arch_init(void) if (pcibios_last_bus < 0) pcibios_last_bus = 0xff; +#ifdef CONFIG_PCI_MMCONFIG + if (setup_data.pci_mmconfig_base) { + pci_mmconfig_add(0, 0, pcibios_last_bus, + setup_data.pci_mmconfig_base); + pci_mmcfg_arch_init(); + } +#endif + return 0; } diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c index 0b40482578b8..7389db538c30 100644 --- a/arch/x86/pci/mmconfig-shared.c +++ b/arch/x86/pci/mmconfig-shared.c @@ -94,8 +94,8 @@ static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start, return new; } -static struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start, - int end, u64 addr) +struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start, + int end, u64 addr) { struct pci_mmcfg_region *new; From 55027a7772b1a9c36fb9731fc6c847b6a59c5bef Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 7 Mar 2018 08:39:15 +0100 Subject: [PATCH 12/19] x86: Align x86_64 PCI_MMCONFIG with 32-bit variant Allow to enable PCI_MMCONFIG when only SFI is present and make this option default on. This will help consolidating both into one Kconfig statement. Signed-off-by: Jan Kiszka Signed-off-by: Thomas Gleixner Cc: jailhouse-dev@googlegroups.com Cc: linux-pci@vger.kernel.org Cc: virtualization@lists.linux-foundation.org Cc: Andy Shevchenko Cc: Bjorn Helgaas Link: https://lkml.kernel.org/r/a2faf78c54f340f5549149e8b679c95950dae83d.1520408357.git.jan.kiszka@siemens.com --- arch/x86/Kconfig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index c1236b187824..6bd763640925 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2658,7 +2658,8 @@ config PCI_DOMAINS config PCI_MMCONFIG bool "Support mmconfig PCI config space access" - depends on X86_64 && PCI && ACPI + default y + depends on X86_64 && PCI && (ACPI || SFI) config PCI_CNB20LE_QUIRK bool "Read CNB20LE Host Bridge Windows" if EXPERT From b45c9f3656b691ab7324c7eaefb3416bea0326d8 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 7 Mar 2018 08:39:16 +0100 Subject: [PATCH 13/19] x86: Consolidate PCI_MMCONFIG configs Since e279b6c1d329 ("x86: start unification of arch/x86/Kconfig.*"), there exist two PCI_MMCONFIG entries, one from the original i386 and another from x86_64. Consolidate both entries into a single one. Signed-off-by: Jan Kiszka Signed-off-by: Thomas Gleixner Cc: jailhouse-dev@googlegroups.com Cc: linux-pci@vger.kernel.org Cc: virtualization@lists.linux-foundation.org Cc: Andy Shevchenko Cc: Bjorn Helgaas Link: https://lkml.kernel.org/r/2a0ccd51ea6f7996e07162918228e23bdc1fbb03.1520408357.git.jan.kiszka@siemens.com --- arch/x86/Kconfig | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 6bd763640925..573b7c49d9f8 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2640,8 +2640,10 @@ config PCI_DIRECT depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC || PCI_GOMMCONFIG)) config PCI_MMCONFIG - def_bool y - depends on X86_32 && PCI && (ACPI || SFI) && (PCI_GOMMCONFIG || PCI_GOANY) + bool "Support mmconfig PCI config space access" if X86_64 + default y + depends on PCI && (ACPI || SFI) + depends on X86_64 || (PCI_GOANY || PCI_GOMMCONFIG) config PCI_OLPC def_bool y @@ -2656,11 +2658,6 @@ config PCI_DOMAINS def_bool y depends on PCI -config PCI_MMCONFIG - bool "Support mmconfig PCI config space access" - default y - depends on X86_64 && PCI && (ACPI || SFI) - config PCI_CNB20LE_QUIRK bool "Read CNB20LE Host Bridge Windows" if EXPERT depends on PCI From 8364e1f8379c7f9d3e63f127a585f889906b3e10 Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 7 Mar 2018 08:39:17 +0100 Subject: [PATCH 14/19] x86/jailhouse: Allow to use PCI_MMCONFIG without ACPI Jailhouse does not use ACPI, but it does support MMCONFIG. Make sure the latter can be built without having to enable ACPI as well. Primarily, its required to make the AMD mmconf-fam10h_64 depend upon MMCONFIG and ACPI, instead of just the former. Saves some bytes in the Jailhouse non-root kernel. Signed-off-by: Jan Kiszka Signed-off-by: Thomas Gleixner Cc: jailhouse-dev@googlegroups.com Cc: linux-pci@vger.kernel.org Cc: virtualization@lists.linux-foundation.org Cc: Andy Shevchenko Cc: Bjorn Helgaas Link: https://lkml.kernel.org/r/788bbd5325d1922235e9562c213057425fbc548c.1520408357.git.jan.kiszka@siemens.com --- arch/x86/Kconfig | 6 +++++- arch/x86/kernel/Makefile | 2 +- arch/x86/kernel/cpu/amd.c | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 573b7c49d9f8..7f00f60a2028 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2642,7 +2642,7 @@ config PCI_DIRECT config PCI_MMCONFIG bool "Support mmconfig PCI config space access" if X86_64 default y - depends on PCI && (ACPI || SFI) + depends on PCI && (ACPI || SFI || JAILHOUSE_GUEST) depends on X86_64 || (PCI_GOANY || PCI_GOMMCONFIG) config PCI_OLPC @@ -2658,6 +2658,10 @@ config PCI_DOMAINS def_bool y depends on PCI +config MMCONF_FAM10H + def_bool y + depends on X86_64 && PCI_MMCONFIG && ACPI + config PCI_CNB20LE_QUIRK bool "Read CNB20LE Host Bridge Windows" if EXPERT depends on PCI diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 29786c87e864..73ccf80c09a2 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile @@ -146,6 +146,6 @@ ifeq ($(CONFIG_X86_64),y) obj-$(CONFIG_GART_IOMMU) += amd_gart_64.o aperture_64.o obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o - obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o + obj-$(CONFIG_MMCONF_FAM10H) += mmconf-fam10h_64.o obj-y += vsmp_64.o endif diff --git a/arch/x86/kernel/cpu/amd.c b/arch/x86/kernel/cpu/amd.c index f0e6456ca7d3..12bc0a1139da 100644 --- a/arch/x86/kernel/cpu/amd.c +++ b/arch/x86/kernel/cpu/amd.c @@ -716,7 +716,7 @@ static void init_amd_k8(struct cpuinfo_x86 *c) static void init_amd_gh(struct cpuinfo_x86 *c) { -#ifdef CONFIG_X86_64 +#ifdef CONFIG_MMCONF_FAM10H /* do this for boot cpu */ if (c == &boot_cpu_data) check_enable_amd_mmconf_dmi(); From e21c963c0fe3dc6d8a5c23474eb8f560b184132a Mon Sep 17 00:00:00 2001 From: Jan Kiszka Date: Wed, 7 Mar 2018 08:39:18 +0100 Subject: [PATCH 15/19] MAINTAINERS: Add entry for Jailhouse Signed-off-by: Jan Kiszka Signed-off-by: Thomas Gleixner Cc: jailhouse-dev@googlegroups.com Cc: linux-pci@vger.kernel.org Cc: virtualization@lists.linux-foundation.org Cc: Andy Shevchenko Cc: Bjorn Helgaas Link: https://lkml.kernel.org/r/8be8af4084d862faa43d55c7bae94af7e0da1609.1520408357.git.jan.kiszka@siemens.com --- MAINTAINERS | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 9a7f76eadae9..272d8c98c0e1 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -7521,6 +7521,13 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ S: Maintained F: drivers/media/dvb-frontends/ix2505v* +JAILHOUSE HYPERVISOR INTERFACE +M: Jan Kiszka +L: jailhouse-dev@googlegroups.com +S: Maintained +F: arch/x86/kernel/jailhouse.c +F: arch/x86/include/asm/jailhouse_para.h + JC42.4 TEMPERATURE SENSOR DRIVER M: Guenter Roeck L: linux-hwmon@vger.kernel.org From 7f2e85840871f199057e65232ebde846192ed989 Mon Sep 17 00:00:00 2001 From: Ivan Gorinov Date: Thu, 22 Mar 2018 14:35:33 -0700 Subject: [PATCH 16/19] of/Documentation: Specify local APIC ID in "reg" Use the "reg" property to specify the processor's local APIC ID instead of setting it to the CPU node index in Device Tree. Local APIC ID is assigned by hardware and visible in the APIC ID register. Some processor models allow APIC ID to be changed by software, but CPUID instruction executed with %eax = 0x0b always returns the initial ID in %edx. Local APIC ID does not match the node index in many systems. Signed-off-by: Ivan Gorinov Signed-off-by: Thomas Gleixner Reviewed-by: Andy Shevchenko Reviewed-by: Rob Herring Cc: Mark Rutland Cc: Rob Herring Cc: Frank Rowand Link: https://lkml.kernel.org/r/4b1a471a56ac0ebd7510f4759afce9104595d6da.1521753738.git.ivan.gorinov@intel.com --- .../devicetree/bindings/x86/ce4100.txt | 37 ++++++++++++++----- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/Documentation/devicetree/bindings/x86/ce4100.txt b/Documentation/devicetree/bindings/x86/ce4100.txt index b49ae593a60b..cd1221bfb539 100644 --- a/Documentation/devicetree/bindings/x86/ce4100.txt +++ b/Documentation/devicetree/bindings/x86/ce4100.txt @@ -7,17 +7,36 @@ Many of the "generic" devices like HPET or IO APIC have the ce4100 name in their compatible property because they first appeared in this SoC. -The CPU node ------------- - cpu@0 { - device_type = "cpu"; - compatible = "intel,ce4100"; - reg = <0>; - lapic = <&lapic0>; +The CPU nodes +------------- + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "intel,ce4100"; + reg = <0x00>; + }; + + cpu@2 { + device_type = "cpu"; + compatible = "intel,ce4100"; + reg = <0x02>; + }; }; -The reg property describes the CPU number. The lapic property points to -the local APIC timer. +A "cpu" node describes one logical processor (hardware thread). + +Required properties: + +- device_type + Device type, must be "cpu". + +- reg + Local APIC ID, the unique number assigned to each processor by + system hardware. The SoC node ------------ From 4e07db9c8db87e3b71be4c3cd626ddc9bacd5a1e Mon Sep 17 00:00:00 2001 From: Ivan Gorinov Date: Thu, 22 Mar 2018 14:35:47 -0700 Subject: [PATCH 17/19] x86/devicetree: Use CPU description from Device Tree Current x86 Device Tree implementation does not support multiprocessing. Use new DT bindings to describe the processors. Signed-off-by: Ivan Gorinov Signed-off-by: Thomas Gleixner Reviewed-by: Andy Shevchenko Cc: Mark Rutland Cc: Rob Herring Cc: Frank Rowand Link: https://lkml.kernel.org/r/c291fb2cef51b730b59916d7745be0eaa4378c6c.1521753738.git.ivan.gorinov@intel.com --- arch/x86/kernel/devicetree.c | 45 ++++++++++++++++++++++++++---------- 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c index 5cd387fcc777..c9d2b19749b8 100644 --- a/arch/x86/kernel/devicetree.c +++ b/arch/x86/kernel/devicetree.c @@ -131,34 +131,52 @@ static void __init dtb_setup_hpet(void) #endif } +#ifdef CONFIG_X86_LOCAL_APIC + +static void __init dtb_cpu_setup(void) +{ + struct device_node *dn; + u32 apic_id, version; + int ret; + + version = GET_APIC_VERSION(apic_read(APIC_LVR)); + for_each_node_by_type(dn, "cpu") { + ret = of_property_read_u32(dn, "reg", &apic_id); + if (ret < 0) { + pr_warn("%pOF: missing local APIC ID\n", dn); + continue; + } + generic_processor_info(apic_id, version); + } +} + static void __init dtb_lapic_setup(void) { -#ifdef CONFIG_X86_LOCAL_APIC struct device_node *dn; struct resource r; + unsigned long lapic_addr = APIC_DEFAULT_PHYS_BASE; int ret; dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic"); - if (!dn) - return; - - ret = of_address_to_resource(dn, 0, &r); - if (WARN_ON(ret)) - return; + if (dn) { + ret = of_address_to_resource(dn, 0, &r); + if (WARN_ON(ret)) + return; + lapic_addr = r.start; + } /* Did the boot loader setup the local APIC ? */ if (!boot_cpu_has(X86_FEATURE_APIC)) { - if (apic_force_enable(r.start)) + if (apic_force_enable(lapic_addr)) return; } smp_found_config = 1; pic_mode = 1; - register_lapic_address(r.start); - generic_processor_info(boot_cpu_physical_apicid, - GET_APIC_VERSION(apic_read(APIC_LVR))); -#endif + register_lapic_address(lapic_addr); } +#endif /* CONFIG_X86_LOCAL_APIC */ + #ifdef CONFIG_X86_IO_APIC static unsigned int ioapic_id; @@ -259,7 +277,10 @@ static void __init dtb_ioapic_setup(void) {} static void __init dtb_apic_setup(void) { +#ifdef CONFIG_X86_LOCAL_APIC dtb_lapic_setup(); + dtb_cpu_setup(); +#endif dtb_ioapic_setup(); } From 3af345258617e0412059c1ab6462495947f73e89 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 20 Mar 2018 20:07:59 +0200 Subject: [PATCH 18/19] firmware/dmi_scan: Uninline dmi_get_bios_year() helper Uninline dmi_get_bios_year() which, in particular, allows us to optimize it in the future. While doing this, convert the function to return an error code when BIOS date is not present or not parsable, or CONFIG_DMI=n. Additionally, during the move, add a bit of documentation. Suggested-by: Bjorn Helgaas Suggested-by: Rafael J. Wysocki Signed-off-by: Andy Shevchenko Reviewed-by: Jean Delvare Reviewed-by: Rafael J. Wysocki Acked-by: Thomas Gleixner Cc: Bjorn Helgaas Cc: Linus Torvalds Cc: Lukas Wunner Cc: Peter Zijlstra Cc: Rafael J . Wysocki Cc: linux-acpi@vger.kernel.org Cc: linux-pci@vger.kernel.org Fixes: 492a1abd61e4 ("dmi: Introduce the dmi_get_bios_year() helper function") Signed-off-by: Ingo Molnar --- drivers/firmware/dmi_scan.c | 20 ++++++++++++++++++++ include/linux/dmi.h | 11 ++--------- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c index e763e1484331..e35c5e04c46a 100644 --- a/drivers/firmware/dmi_scan.c +++ b/drivers/firmware/dmi_scan.c @@ -1004,6 +1004,26 @@ out: } EXPORT_SYMBOL(dmi_get_date); +/** + * dmi_get_bios_year - get a year out of DMI_BIOS_DATE field + * + * Returns year on success, -ENXIO if DMI is not selected, + * or a different negative error code if DMI field is not present + * or not parseable. + */ +int dmi_get_bios_year(void) +{ + bool exists; + int year; + + exists = dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); + if (!exists) + return -ENODATA; + + return year ? year : -ERANGE; +} +EXPORT_SYMBOL(dmi_get_bios_year); + /** * dmi_walk - Walk the DMI table and get called back for every record * @decode: Callback function diff --git a/include/linux/dmi.h b/include/linux/dmi.h index 0bade156e908..6a86d8db16d9 100644 --- a/include/linux/dmi.h +++ b/include/linux/dmi.h @@ -106,6 +106,7 @@ extern void dmi_scan_machine(void); extern void dmi_memdev_walk(void); extern void dmi_set_dump_stack_arch_desc(void); extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp); +extern int dmi_get_bios_year(void); extern int dmi_name_in_vendors(const char *str); extern int dmi_name_in_serial(const char *str); extern int dmi_available; @@ -133,6 +134,7 @@ static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp) *dayp = 0; return false; } +static inline int dmi_get_bios_year(void) { return -ENXIO; } static inline int dmi_name_in_vendors(const char *s) { return 0; } static inline int dmi_name_in_serial(const char *s) { return 0; } #define dmi_available 0 @@ -147,13 +149,4 @@ static inline const struct dmi_system_id * #endif -static inline int dmi_get_bios_year(void) -{ - int year; - - dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); - - return year; -} - #endif /* __DMI_H__ */ From 47a9973d3ed8994589c845c8b1a293a475a549a9 Mon Sep 17 00:00:00 2001 From: Andy Shevchenko Date: Tue, 20 Mar 2018 20:08:00 +0200 Subject: [PATCH 19/19] x86/PCI: Fix a potential regression when using dmi_get_bios_year() dmi_get_bios_year() may return 0 when it cannot parse the BIOS date string. Previously this has been checked in pci_acpi_crs_quirks(). Update the code to restore old behaviour. Reported-by: Jean Delvare Signed-off-by: Andy Shevchenko Reviewed-by: Jean Delvare Reviewed-by: Rafael J. Wysocki Acked-by: Thomas Gleixner Cc: Bjorn Helgaas Cc: Linus Torvalds Cc: Lukas Wunner Cc: Peter Zijlstra Cc: Rafael J . Wysocki Cc: linux-acpi@vger.kernel.org Cc: linux-pci@vger.kernel.org Fixes: 69c42d493db4 ("x86/pci: Simplify code by using the new dmi_get_bios_year() helper") Signed-off-by: Ingo Molnar --- arch/x86/pci/acpi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c index 00e60de30328..5559dcaddd5e 100644 --- a/arch/x86/pci/acpi.c +++ b/arch/x86/pci/acpi.c @@ -140,7 +140,9 @@ static const struct dmi_system_id pci_crs_quirks[] __initconst = { void __init pci_acpi_crs_quirks(void) { - if ((dmi_get_bios_year() < 2008) && (iomem_resource.end <= 0xffffffff)) + int year = dmi_get_bios_year(); + + if (year >= 0 && year < 2008 && iomem_resource.end <= 0xffffffff) pci_use_crs = false; dmi_check_system(pci_crs_quirks);