aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-04-02 19:15:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-04-02 19:15:32 -0400
commitcea061e455c88312b86142e68c8fc5b8e1294ca2 (patch)
tree6e8afe1c4fb696582626db294b46daa59dcfb6c0
parentd22fff81418edc92be534cad8d59da914049bf69 (diff)
parent47a9973d3ed8994589c845c8b1a293a475a549a9 (diff)
Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 platform updates from Ingo Molnar: "The main changes in this cycle were: - Add "Jailhouse" hypervisor support (Jan Kiszka) - Update DeviceTree support (Ivan Gorinov) - Improve DMI date handling (Andy Shevchenko)" * 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/PCI: Fix a potential regression when using dmi_get_bios_year() firmware/dmi_scan: Uninline dmi_get_bios_year() helper x86/devicetree: Use CPU description from Device Tree of/Documentation: Specify local APIC ID in "reg" MAINTAINERS: Add entry for Jailhouse x86/jailhouse: Allow to use PCI_MMCONFIG without ACPI x86: Consolidate PCI_MMCONFIG configs x86: Align x86_64 PCI_MMCONFIG with 32-bit variant x86/jailhouse: Enable PCI mmconfig access in inmates PCI: Scan all functions when running over Jailhouse jailhouse: Provide detection for non-x86 systems x86/devicetree: Fix device IRQ settings in DT x86/devicetree: Initialize device tree before using it pci: Simplify code by using the new dmi_get_bios_year() helper ACPI/sleep: Simplify code by using the new dmi_get_bios_year() helper x86/pci: Simplify code by using the new dmi_get_bios_year() helper dmi: Introduce the dmi_get_bios_year() helper function x86/platform/quark: Re-use DEFINE_SHOW_ATTRIBUTE() macro x86/platform/atom: Re-use DEFINE_SHOW_ATTRIBUTE() macro
-rw-r--r--Documentation/devicetree/bindings/jailhouse.txt8
-rw-r--r--Documentation/devicetree/bindings/x86/ce4100.txt37
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/x86/Kconfig12
-rw-r--r--arch/x86/include/asm/jailhouse_para.h2
-rw-r--r--arch/x86/include/asm/pci_x86.h2
-rw-r--r--arch/x86/kernel/Makefile2
-rw-r--r--arch/x86/kernel/cpu/amd.c2
-rw-r--r--arch/x86/kernel/devicetree.c66
-rw-r--r--arch/x86/kernel/jailhouse.c8
-rw-r--r--arch/x86/pci/acpi.c8
-rw-r--r--arch/x86/pci/direct.c5
-rw-r--r--arch/x86/pci/legacy.c4
-rw-r--r--arch/x86/pci/mmconfig-shared.c13
-rw-r--r--arch/x86/platform/atom/punit_atom_debug.c17
-rw-r--r--arch/x86/platform/intel-quark/imr.c24
-rw-r--r--drivers/acpi/sleep.c4
-rw-r--r--drivers/firmware/dmi_scan.c20
-rw-r--r--drivers/pci/pci.c6
-rw-r--r--drivers/pci/probe.c22
-rw-r--r--include/linux/dmi.h2
-rw-r--r--include/linux/hypervisor.h17
22 files changed, 185 insertions, 103 deletions
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 @@
1Jailhouse non-root cell device tree bindings
2--------------------------------------------
3
4When running in a non-root Jailhouse cell (partition), the device tree of this
5platform shall have a top-level "hypervisor" node with the following
6properties:
7
8- compatible = "jailhouse,cell"
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
7name in their compatible property because they first appeared in this 7name in their compatible property because they first appeared in this
8SoC. 8SoC.
9 9
10The CPU node 10The CPU nodes
11------------ 11-------------
12 cpu@0 { 12
13 device_type = "cpu"; 13 cpus {
14 compatible = "intel,ce4100"; 14 #address-cells = <1>;
15 reg = <0>; 15 #size-cells = <0>;
16 lapic = <&lapic0>; 16
17 cpu@0 {
18 device_type = "cpu";
19 compatible = "intel,ce4100";
20 reg = <0x00>;
21 };
22
23 cpu@2 {
24 device_type = "cpu";
25 compatible = "intel,ce4100";
26 reg = <0x02>;
27 };
17 }; 28 };
18 29
19The reg property describes the CPU number. The lapic property points to 30A "cpu" node describes one logical processor (hardware thread).
20the local APIC timer. 31
32Required properties:
33
34- device_type
35 Device type, must be "cpu".
36
37- reg
38 Local APIC ID, the unique number assigned to each processor by
39 system hardware.
21 40
22The SoC node 41The SoC node
23------------ 42------------
diff --git a/MAINTAINERS b/MAINTAINERS
index e7f482fd73bd..689f875b47fa 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -7534,6 +7534,13 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
7534S: Maintained 7534S: Maintained
7535F: drivers/media/dvb-frontends/ix2505v* 7535F: drivers/media/dvb-frontends/ix2505v*
7536 7536
7537JAILHOUSE HYPERVISOR INTERFACE
7538M: Jan Kiszka <jan.kiszka@siemens.com>
7539L: jailhouse-dev@googlegroups.com
7540S: Maintained
7541F: arch/x86/kernel/jailhouse.c
7542F: arch/x86/include/asm/jailhouse_para.h
7543
7537JC42.4 TEMPERATURE SENSOR DRIVER 7544JC42.4 TEMPERATURE SENSOR DRIVER
7538M: Guenter Roeck <linux@roeck-us.net> 7545M: Guenter Roeck <linux@roeck-us.net>
7539L: linux-hwmon@vger.kernel.org 7546L: linux-hwmon@vger.kernel.org
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 518b41b097dc..a0fb8bc346d5 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2626,8 +2626,10 @@ config PCI_DIRECT
2626 depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC || PCI_GOMMCONFIG)) 2626 depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC || PCI_GOMMCONFIG))
2627 2627
2628config PCI_MMCONFIG 2628config PCI_MMCONFIG
2629 def_bool y 2629 bool "Support mmconfig PCI config space access" if X86_64
2630 depends on X86_32 && PCI && (ACPI || SFI) && (PCI_GOMMCONFIG || PCI_GOANY) 2630 default y
2631 depends on PCI && (ACPI || SFI || JAILHOUSE_GUEST)
2632 depends on X86_64 || (PCI_GOANY || PCI_GOMMCONFIG)
2631 2633
2632config PCI_OLPC 2634config PCI_OLPC
2633 def_bool y 2635 def_bool y
@@ -2642,9 +2644,9 @@ config PCI_DOMAINS
2642 def_bool y 2644 def_bool y
2643 depends on PCI 2645 depends on PCI
2644 2646
2645config PCI_MMCONFIG 2647config MMCONF_FAM10H
2646 bool "Support mmconfig PCI config space access" 2648 def_bool y
2647 depends on X86_64 && PCI && ACPI 2649 depends on X86_64 && PCI_MMCONFIG && ACPI
2648 2650
2649config PCI_CNB20LE_QUIRK 2651config PCI_CNB20LE_QUIRK
2650 bool "Read CNB20LE Host Bridge Windows" if EXPERT 2652 bool "Read CNB20LE Host Bridge Windows" if EXPERT
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 @@
1/* SPDX-License-Identifier: GPL2.0 */ 1/* SPDX-License-Identifier: GPL2.0 */
2 2
3/* 3/*
4 * Jailhouse paravirt_ops implementation 4 * Jailhouse paravirt detection
5 * 5 *
6 * Copyright (c) Siemens AG, 2015-2017 6 * Copyright (c) Siemens AG, 2015-2017
7 * 7 *
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,
151 phys_addr_t addr); 151 phys_addr_t addr);
152extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end); 152extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end);
153extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus); 153extern struct pci_mmcfg_region *pci_mmconfig_lookup(int segment, int bus);
154extern struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start,
155 int end, u64 addr);
154 156
155extern struct list_head pci_mmcfg_list; 157extern struct list_head pci_mmcfg_list;
156 158
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)
146 obj-$(CONFIG_GART_IOMMU) += amd_gart_64.o aperture_64.o 146 obj-$(CONFIG_GART_IOMMU) += amd_gart_64.o aperture_64.o
147 obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o 147 obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_64.o
148 148
149 obj-$(CONFIG_PCI_MMCONFIG) += mmconf-fam10h_64.o 149 obj-$(CONFIG_MMCONF_FAM10H) += mmconf-fam10h_64.o
150 obj-y += vsmp_64.o 150 obj-y += vsmp_64.o
151endif 151endif
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)
716 716
717static void init_amd_gh(struct cpuinfo_x86 *c) 717static void init_amd_gh(struct cpuinfo_x86 *c)
718{ 718{
719#ifdef CONFIG_X86_64 719#ifdef CONFIG_MMCONF_FAM10H
720 /* do this for boot cpu */ 720 /* do this for boot cpu */
721 if (c == &boot_cpu_data) 721 if (c == &boot_cpu_data)
722 check_enable_amd_mmconf_dmi(); 722 check_enable_amd_mmconf_dmi();
diff --git a/arch/x86/kernel/devicetree.c b/arch/x86/kernel/devicetree.c
index 45416826f6ee..f39f3a06c26f 100644
--- a/arch/x86/kernel/devicetree.c
+++ b/arch/x86/kernel/devicetree.c
@@ -11,6 +11,7 @@
11#include <linux/of_address.h> 11#include <linux/of_address.h>
12#include <linux/of_platform.h> 12#include <linux/of_platform.h>
13#include <linux/of_irq.h> 13#include <linux/of_irq.h>
14#include <linux/libfdt.h>
14#include <linux/slab.h> 15#include <linux/slab.h>
15#include <linux/pci.h> 16#include <linux/pci.h>
16#include <linux/of_pci.h> 17#include <linux/of_pci.h>
@@ -130,34 +131,52 @@ static void __init dtb_setup_hpet(void)
130#endif 131#endif
131} 132}
132 133
134#ifdef CONFIG_X86_LOCAL_APIC
135
136static void __init dtb_cpu_setup(void)
137{
138 struct device_node *dn;
139 u32 apic_id, version;
140 int ret;
141
142 version = GET_APIC_VERSION(apic_read(APIC_LVR));
143 for_each_node_by_type(dn, "cpu") {
144 ret = of_property_read_u32(dn, "reg", &apic_id);
145 if (ret < 0) {
146 pr_warn("%pOF: missing local APIC ID\n", dn);
147 continue;
148 }
149 generic_processor_info(apic_id, version);
150 }
151}
152
133static void __init dtb_lapic_setup(void) 153static void __init dtb_lapic_setup(void)
134{ 154{
135#ifdef CONFIG_X86_LOCAL_APIC
136 struct device_node *dn; 155 struct device_node *dn;
137 struct resource r; 156 struct resource r;
157 unsigned long lapic_addr = APIC_DEFAULT_PHYS_BASE;
138 int ret; 158 int ret;
139 159
140 dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic"); 160 dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic");
141 if (!dn) 161 if (dn) {
142 return; 162 ret = of_address_to_resource(dn, 0, &r);
143 163 if (WARN_ON(ret))
144 ret = of_address_to_resource(dn, 0, &r); 164 return;
145 if (WARN_ON(ret)) 165 lapic_addr = r.start;
146 return; 166 }
147 167
148 /* Did the boot loader setup the local APIC ? */ 168 /* Did the boot loader setup the local APIC ? */
149 if (!boot_cpu_has(X86_FEATURE_APIC)) { 169 if (!boot_cpu_has(X86_FEATURE_APIC)) {
150 if (apic_force_enable(r.start)) 170 if (apic_force_enable(lapic_addr))
151 return; 171 return;
152 } 172 }
153 smp_found_config = 1; 173 smp_found_config = 1;
154 pic_mode = 1; 174 pic_mode = 1;
155 register_lapic_address(r.start); 175 register_lapic_address(lapic_addr);
156 generic_processor_info(boot_cpu_physical_apicid,
157 GET_APIC_VERSION(apic_read(APIC_LVR)));
158#endif
159} 176}
160 177
178#endif /* CONFIG_X86_LOCAL_APIC */
179
161#ifdef CONFIG_X86_IO_APIC 180#ifdef CONFIG_X86_IO_APIC
162static unsigned int ioapic_id; 181static unsigned int ioapic_id;
163 182
@@ -194,19 +213,22 @@ static struct of_ioapic_type of_ioapic_type[] =
194static int dt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, 213static int dt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
195 unsigned int nr_irqs, void *arg) 214 unsigned int nr_irqs, void *arg)
196{ 215{
197 struct of_phandle_args *irq_data = (void *)arg; 216 struct irq_fwspec *fwspec = (struct irq_fwspec *)arg;
198 struct of_ioapic_type *it; 217 struct of_ioapic_type *it;
199 struct irq_alloc_info tmp; 218 struct irq_alloc_info tmp;
219 int type_index;
200 220
201 if (WARN_ON(irq_data->args_count < 2)) 221 if (WARN_ON(fwspec->param_count < 2))
202 return -EINVAL; 222 return -EINVAL;
203 if (irq_data->args[1] >= ARRAY_SIZE(of_ioapic_type)) 223
224 type_index = fwspec->param[1];
225 if (type_index >= ARRAY_SIZE(of_ioapic_type))
204 return -EINVAL; 226 return -EINVAL;
205 227
206 it = &of_ioapic_type[irq_data->args[1]]; 228 it = &of_ioapic_type[type_index];
207 ioapic_set_alloc_attr(&tmp, NUMA_NO_NODE, it->trigger, it->polarity); 229 ioapic_set_alloc_attr(&tmp, NUMA_NO_NODE, it->trigger, it->polarity);
208 tmp.ioapic_id = mpc_ioapic_id(mp_irqdomain_ioapic_idx(domain)); 230 tmp.ioapic_id = mpc_ioapic_id(mp_irqdomain_ioapic_idx(domain));
209 tmp.ioapic_pin = irq_data->args[0]; 231 tmp.ioapic_pin = fwspec->param[0];
210 232
211 return mp_irqdomain_alloc(domain, virq, nr_irqs, &tmp); 233 return mp_irqdomain_alloc(domain, virq, nr_irqs, &tmp);
212} 234}
@@ -255,7 +277,10 @@ static void __init dtb_ioapic_setup(void) {}
255 277
256static void __init dtb_apic_setup(void) 278static void __init dtb_apic_setup(void)
257{ 279{
280#ifdef CONFIG_X86_LOCAL_APIC
258 dtb_lapic_setup(); 281 dtb_lapic_setup();
282 dtb_cpu_setup();
283#endif
259 dtb_ioapic_setup(); 284 dtb_ioapic_setup();
260} 285}
261 286
@@ -270,14 +295,15 @@ static void __init x86_flattree_get_config(void)
270 295
271 map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128); 296 map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
272 297
273 initial_boot_params = dt = early_memremap(initial_dtb, map_len); 298 dt = early_memremap(initial_dtb, map_len);
274 size = of_get_flat_dt_size(); 299 size = fdt_totalsize(dt);
275 if (map_len < size) { 300 if (map_len < size) {
276 early_memunmap(dt, map_len); 301 early_memunmap(dt, map_len);
277 initial_boot_params = dt = early_memremap(initial_dtb, size); 302 dt = early_memremap(initial_dtb, size);
278 map_len = size; 303 map_len = size;
279 } 304 }
280 305
306 early_init_dt_verify(dt);
281 unflatten_and_copy_device_tree(); 307 unflatten_and_copy_device_tree();
282 early_memunmap(dt, map_len); 308 early_memunmap(dt, map_len);
283} 309}
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)
124 if (pcibios_last_bus < 0) 124 if (pcibios_last_bus < 0)
125 pcibios_last_bus = 0xff; 125 pcibios_last_bus = 0xff;
126 126
127#ifdef CONFIG_PCI_MMCONFIG
128 if (setup_data.pci_mmconfig_base) {
129 pci_mmconfig_add(0, 0, pcibios_last_bus,
130 setup_data.pci_mmconfig_base);
131 pci_mmcfg_arch_init();
132 }
133#endif
134
127 return 0; 135 return 0;
128} 136}
129 137
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index 7df49c40665e..5559dcaddd5e 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -140,12 +140,10 @@ static const struct dmi_system_id pci_crs_quirks[] __initconst = {
140 140
141void __init pci_acpi_crs_quirks(void) 141void __init pci_acpi_crs_quirks(void)
142{ 142{
143 int year; 143 int year = dmi_get_bios_year();
144 144
145 if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008) { 145 if (year >= 0 && year < 2008 && iomem_resource.end <= 0xffffffff)
146 if (iomem_resource.end <= 0xffffffff) 146 pci_use_crs = false;
147 pci_use_crs = false;
148 }
149 147
150 dmi_check_system(pci_crs_quirks); 148 dmi_check_system(pci_crs_quirks);
151 149
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 = {
195static int __init pci_sanity_check(const struct pci_raw_ops *o) 195static int __init pci_sanity_check(const struct pci_raw_ops *o)
196{ 196{
197 u32 x = 0; 197 u32 x = 0;
198 int year, devfn; 198 int devfn;
199 199
200 if (pci_probe & PCI_NO_CHECKS) 200 if (pci_probe & PCI_NO_CHECKS)
201 return 1; 201 return 1;
202 /* Assume Type 1 works for newer systems. 202 /* Assume Type 1 works for newer systems.
203 This handles machines that don't have anything on PCI Bus 0. */ 203 This handles machines that don't have anything on PCI Bus 0. */
204 dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); 204 if (dmi_get_bios_year() >= 2001)
205 if (year >= 2001)
206 return 1; 205 return 1;
207 206
208 for (devfn = 0; devfn < 0x100; devfn++) { 207 for (devfn = 0; devfn < 0x100; devfn++) {
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 @@
4#include <linux/init.h> 4#include <linux/init.h>
5#include <linux/export.h> 5#include <linux/export.h>
6#include <linux/pci.h> 6#include <linux/pci.h>
7#include <asm/jailhouse_para.h>
7#include <asm/pci_x86.h> 8#include <asm/pci_x86.h>
8 9
9/* 10/*
@@ -34,13 +35,14 @@ int __init pci_legacy_init(void)
34 35
35void pcibios_scan_specific_bus(int busn) 36void pcibios_scan_specific_bus(int busn)
36{ 37{
38 int stride = jailhouse_paravirt() ? 1 : 8;
37 int devfn; 39 int devfn;
38 u32 l; 40 u32 l;
39 41
40 if (pci_find_bus(0, busn)) 42 if (pci_find_bus(0, busn))
41 return; 43 return;
42 44
43 for (devfn = 0; devfn < 256; devfn += 8) { 45 for (devfn = 0; devfn < 256; devfn += stride) {
44 if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) && 46 if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) &&
45 l != 0x0000 && l != 0xffff) { 47 l != 0x0000 && l != 0xffff) {
46 DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l); 48 DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l);
diff --git a/arch/x86/pci/mmconfig-shared.c b/arch/x86/pci/mmconfig-shared.c
index 96684d0adcf9..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,
94 return new; 94 return new;
95} 95}
96 96
97static struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start, 97struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start,
98 int end, u64 addr) 98 int end, u64 addr)
99{ 99{
100 struct pci_mmcfg_region *new; 100 struct pci_mmcfg_region *new;
101 101
@@ -547,19 +547,14 @@ static void __init pci_mmcfg_reject_broken(int early)
547static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg, 547static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
548 struct acpi_mcfg_allocation *cfg) 548 struct acpi_mcfg_allocation *cfg)
549{ 549{
550 int year;
551
552 if (cfg->address < 0xFFFFFFFF) 550 if (cfg->address < 0xFFFFFFFF)
553 return 0; 551 return 0;
554 552
555 if (!strncmp(mcfg->header.oem_id, "SGI", 3)) 553 if (!strncmp(mcfg->header.oem_id, "SGI", 3))
556 return 0; 554 return 0;
557 555
558 if (mcfg->header.revision >= 1) { 556 if ((mcfg->header.revision >= 1) && (dmi_get_bios_year() >= 2010))
559 if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && 557 return 0;
560 year >= 2010)
561 return 0;
562 }
563 558
564 pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx " 559 pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
565 "is above 4GB, ignored\n", cfg->pci_segment, 560 "is above 4GB, ignored\n", cfg->pci_segment,
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)
109 109
110 return 0; 110 return 0;
111} 111}
112 112DEFINE_SHOW_ATTRIBUTE(punit_dev_state);
113static int punit_dev_state_open(struct inode *inode, struct file *file)
114{
115 return single_open(file, punit_dev_state_show, inode->i_private);
116}
117
118static const struct file_operations punit_dev_state_ops = {
119 .open = punit_dev_state_open,
120 .read = seq_read,
121 .llseek = seq_lseek,
122 .release = single_release,
123};
124 113
125static struct dentry *punit_dbg_file; 114static struct dentry *punit_dbg_file;
126 115
@@ -132,9 +121,9 @@ static int punit_dbgfs_register(struct punit_device *punit_device)
132 if (!punit_dbg_file) 121 if (!punit_dbg_file)
133 return -ENXIO; 122 return -ENXIO;
134 123
135 dev_state = debugfs_create_file("dev_power_state", S_IFREG | S_IRUGO, 124 dev_state = debugfs_create_file("dev_power_state", 0444,
136 punit_dbg_file, punit_device, 125 punit_dbg_file, punit_device,
137 &punit_dev_state_ops); 126 &punit_dev_state_fops);
138 if (!dev_state) { 127 if (!dev_state) {
139 pr_err("punit_dev_state register failed\n"); 128 pr_err("punit_dev_state register failed\n");
140 debugfs_remove(punit_dbg_file); 129 debugfs_remove(punit_dbg_file);
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)
224 mutex_unlock(&idev->lock); 224 mutex_unlock(&idev->lock);
225 return ret; 225 return ret;
226} 226}
227 227DEFINE_SHOW_ATTRIBUTE(imr_dbgfs_state);
228/**
229 * imr_state_open - debugfs open callback.
230 *
231 * @inode: pointer to struct inode.
232 * @file: pointer to struct file.
233 * @return: result of single open.
234 */
235static int imr_state_open(struct inode *inode, struct file *file)
236{
237 return single_open(file, imr_dbgfs_state_show, inode->i_private);
238}
239
240static const struct file_operations imr_state_ops = {
241 .open = imr_state_open,
242 .read = seq_read,
243 .llseek = seq_lseek,
244 .release = single_release,
245};
246 228
247/** 229/**
248 * imr_debugfs_register - register debugfs hooks. 230 * imr_debugfs_register - register debugfs hooks.
@@ -252,8 +234,8 @@ static const struct file_operations imr_state_ops = {
252 */ 234 */
253static int imr_debugfs_register(struct imr_device *idev) 235static int imr_debugfs_register(struct imr_device *idev)
254{ 236{
255 idev->file = debugfs_create_file("imr_state", S_IFREG | S_IRUGO, NULL, 237 idev->file = debugfs_create_file("imr_state", 0444, NULL, idev,
256 idev, &imr_state_ops); 238 &imr_dbgfs_state_fops);
257 return PTR_ERR_OR_ZERO(idev->file); 239 return PTR_ERR_OR_ZERO(idev->file);
258} 240}
259 241
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)
376 376
377static void __init acpi_sleep_dmi_check(void) 377static void __init acpi_sleep_dmi_check(void)
378{ 378{
379 int year;
380
381 if (ignore_blacklist) 379 if (ignore_blacklist)
382 return; 380 return;
383 381
384 if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012) 382 if (dmi_get_bios_year() >= 2012)
385 acpi_nvs_nosave_s3(); 383 acpi_nvs_nosave_s3();
386 384
387 dmi_check_system(acpisleep_dmi_table); 385 dmi_check_system(acpisleep_dmi_table);
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
@@ -1005,6 +1005,26 @@ out:
1005EXPORT_SYMBOL(dmi_get_date); 1005EXPORT_SYMBOL(dmi_get_date);
1006 1006
1007/** 1007/**
1008 * dmi_get_bios_year - get a year out of DMI_BIOS_DATE field
1009 *
1010 * Returns year on success, -ENXIO if DMI is not selected,
1011 * or a different negative error code if DMI field is not present
1012 * or not parseable.
1013 */
1014int dmi_get_bios_year(void)
1015{
1016 bool exists;
1017 int year;
1018
1019 exists = dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL);
1020 if (!exists)
1021 return -ENODATA;
1022
1023 return year ? year : -ERANGE;
1024}
1025EXPORT_SYMBOL(dmi_get_bios_year);
1026
1027/**
1008 * dmi_walk - Walk the DMI table and get called back for every record 1028 * dmi_walk - Walk the DMI table and get called back for every record
1009 * @decode: Callback function 1029 * @decode: Callback function
1010 * @private_data: Private data to be passed to the callback function 1030 * @private_data: Private data to be passed to the callback function
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index bd6f156dc3cf..99ec0ef5ba82 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)
2258 */ 2258 */
2259bool pci_bridge_d3_possible(struct pci_dev *bridge) 2259bool pci_bridge_d3_possible(struct pci_dev *bridge)
2260{ 2260{
2261 unsigned int year;
2262
2263 if (!pci_is_pcie(bridge)) 2261 if (!pci_is_pcie(bridge))
2264 return false; 2262 return false;
2265 2263
@@ -2287,10 +2285,8 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge)
2287 * It should be safe to put PCIe ports from 2015 or newer 2285 * It should be safe to put PCIe ports from 2015 or newer
2288 * to D3. 2286 * to D3.
2289 */ 2287 */
2290 if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && 2288 if (dmi_get_bios_year() >= 2015)
2291 year >= 2015) {
2292 return true; 2289 return true;
2293 }
2294 break; 2290 break;
2295 } 2291 }
2296 2292
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 @@
16#include <linux/pci-aspm.h> 16#include <linux/pci-aspm.h>
17#include <linux/aer.h> 17#include <linux/aer.h>
18#include <linux/acpi.h> 18#include <linux/acpi.h>
19#include <linux/hypervisor.h>
19#include <linux/irqdomain.h> 20#include <linux/irqdomain.h>
20#include <linux/pm_runtime.h> 21#include <linux/pm_runtime.h>
21#include "pci.h" 22#include "pci.h"
@@ -2518,14 +2519,29 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus,
2518{ 2519{
2519 unsigned int used_buses, normal_bridges = 0, hotplug_bridges = 0; 2520 unsigned int used_buses, normal_bridges = 0, hotplug_bridges = 0;
2520 unsigned int start = bus->busn_res.start; 2521 unsigned int start = bus->busn_res.start;
2521 unsigned int devfn, cmax, max = start; 2522 unsigned int devfn, fn, cmax, max = start;
2522 struct pci_dev *dev; 2523 struct pci_dev *dev;
2524 int nr_devs;
2523 2525
2524 dev_dbg(&bus->dev, "scanning bus\n"); 2526 dev_dbg(&bus->dev, "scanning bus\n");
2525 2527
2526 /* Go find them, Rover! */ 2528 /* Go find them, Rover! */
2527 for (devfn = 0; devfn < 0x100; devfn += 8) 2529 for (devfn = 0; devfn < 256; devfn += 8) {
2528 pci_scan_slot(bus, devfn); 2530 nr_devs = pci_scan_slot(bus, devfn);
2531
2532 /*
2533 * The Jailhouse hypervisor may pass individual functions of a
2534 * multi-function device to a guest without passing function 0.
2535 * Look for them as well.
2536 */
2537 if (jailhouse_paravirt() && nr_devs == 0) {
2538 for (fn = 1; fn < 8; fn++) {
2539 dev = pci_scan_single_device(bus, devfn + fn);
2540 if (dev)
2541 dev->multifunction = 1;
2542 }
2543 }
2544 }
2529 2545
2530 /* Reserve buses for SR-IOV capability */ 2546 /* Reserve buses for SR-IOV capability */
2531 used_buses = pci_iov_bus_range(bus); 2547 used_buses = pci_iov_bus_range(bus);
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index 46e151172d95..6a86d8db16d9 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -106,6 +106,7 @@ extern void dmi_scan_machine(void);
106extern void dmi_memdev_walk(void); 106extern void dmi_memdev_walk(void);
107extern void dmi_set_dump_stack_arch_desc(void); 107extern void dmi_set_dump_stack_arch_desc(void);
108extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp); 108extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp);
109extern int dmi_get_bios_year(void);
109extern int dmi_name_in_vendors(const char *str); 110extern int dmi_name_in_vendors(const char *str);
110extern int dmi_name_in_serial(const char *str); 111extern int dmi_name_in_serial(const char *str);
111extern int dmi_available; 112extern int dmi_available;
@@ -133,6 +134,7 @@ static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp)
133 *dayp = 0; 134 *dayp = 0;
134 return false; 135 return false;
135} 136}
137static inline int dmi_get_bios_year(void) { return -ENXIO; }
136static inline int dmi_name_in_vendors(const char *s) { return 0; } 138static inline int dmi_name_in_vendors(const char *s) { return 0; }
137static inline int dmi_name_in_serial(const char *s) { return 0; } 139static inline int dmi_name_in_serial(const char *s) { return 0; }
138#define dmi_available 0 140#define dmi_available 0
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 @@
8 */ 8 */
9 9
10#ifdef CONFIG_X86 10#ifdef CONFIG_X86
11
12#include <asm/jailhouse_para.h>
11#include <asm/x86_init.h> 13#include <asm/x86_init.h>
14
12static inline void hypervisor_pin_vcpu(int cpu) 15static inline void hypervisor_pin_vcpu(int cpu)
13{ 16{
14 x86_platform.hyper.pin_vcpu(cpu); 17 x86_platform.hyper.pin_vcpu(cpu);
15} 18}
16#else 19
20#else /* !CONFIG_X86 */
21
22#include <linux/of.h>
23
17static inline void hypervisor_pin_vcpu(int cpu) 24static inline void hypervisor_pin_vcpu(int cpu)
18{ 25{
19} 26}
20#endif 27
28static inline bool jailhouse_paravirt(void)
29{
30 return of_find_compatible_node(NULL, NULL, "jailhouse,cell");
31}
32
33#endif /* !CONFIG_X86 */
21 34
22#endif /* __LINUX_HYPEVISOR_H */ 35#endif /* __LINUX_HYPEVISOR_H */