Commit cea061e4 authored by Linus Torvalds's avatar Linus Torvalds

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
parents d22fff81 47a9973d
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"
...@@ -7,17 +7,36 @@ Many of the "generic" devices like HPET or IO APIC have the ce4100 ...@@ -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 name in their compatible property because they first appeared in this
SoC. SoC.
The CPU node The CPU nodes
------------ -------------
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 { cpu@0 {
device_type = "cpu"; device_type = "cpu";
compatible = "intel,ce4100"; compatible = "intel,ce4100";
reg = <0>; reg = <0x00>;
lapic = <&lapic0>;
}; };
The reg property describes the CPU number. The lapic property points to cpu@2 {
the local APIC timer. device_type = "cpu";
compatible = "intel,ce4100";
reg = <0x02>;
};
};
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 The SoC node
------------ ------------
......
...@@ -7534,6 +7534,13 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/ ...@@ -7534,6 +7534,13 @@ Q: http://patchwork.linuxtv.org/project/linux-media/list/
S: Maintained S: Maintained
F: drivers/media/dvb-frontends/ix2505v* F: drivers/media/dvb-frontends/ix2505v*
JAILHOUSE HYPERVISOR INTERFACE
M: Jan Kiszka <jan.kiszka@siemens.com>
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 JC42.4 TEMPERATURE SENSOR DRIVER
M: Guenter Roeck <linux@roeck-us.net> M: Guenter Roeck <linux@roeck-us.net>
L: linux-hwmon@vger.kernel.org L: linux-hwmon@vger.kernel.org
......
...@@ -2626,8 +2626,10 @@ config PCI_DIRECT ...@@ -2626,8 +2626,10 @@ config PCI_DIRECT
depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC || PCI_GOMMCONFIG)) depends on PCI && (X86_64 || (PCI_GODIRECT || PCI_GOANY || PCI_GOOLPC || PCI_GOMMCONFIG))
config PCI_MMCONFIG config PCI_MMCONFIG
def_bool y bool "Support mmconfig PCI config space access" if X86_64
depends on X86_32 && PCI && (ACPI || SFI) && (PCI_GOMMCONFIG || PCI_GOANY) default y
depends on PCI && (ACPI || SFI || JAILHOUSE_GUEST)
depends on X86_64 || (PCI_GOANY || PCI_GOMMCONFIG)
config PCI_OLPC config PCI_OLPC
def_bool y def_bool y
...@@ -2642,9 +2644,9 @@ config PCI_DOMAINS ...@@ -2642,9 +2644,9 @@ config PCI_DOMAINS
def_bool y def_bool y
depends on PCI depends on PCI
config PCI_MMCONFIG config MMCONF_FAM10H
bool "Support mmconfig PCI config space access" def_bool y
depends on X86_64 && PCI && ACPI depends on X86_64 && PCI_MMCONFIG && ACPI
config PCI_CNB20LE_QUIRK config PCI_CNB20LE_QUIRK
bool "Read CNB20LE Host Bridge Windows" if EXPERT bool "Read CNB20LE Host Bridge Windows" if EXPERT
......
/* SPDX-License-Identifier: GPL2.0 */ /* SPDX-License-Identifier: GPL2.0 */
/* /*
* Jailhouse paravirt_ops implementation * Jailhouse paravirt detection
* *
* Copyright (c) Siemens AG, 2015-2017 * Copyright (c) Siemens AG, 2015-2017
* *
......
...@@ -151,6 +151,8 @@ extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end, ...@@ -151,6 +151,8 @@ extern int pci_mmconfig_insert(struct device *dev, u16 seg, u8 start, u8 end,
phys_addr_t addr); phys_addr_t addr);
extern int pci_mmconfig_delete(u16 seg, u8 start, u8 end); 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 *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; extern struct list_head pci_mmcfg_list;
......
...@@ -146,6 +146,6 @@ ifeq ($(CONFIG_X86_64),y) ...@@ -146,6 +146,6 @@ ifeq ($(CONFIG_X86_64),y)
obj-$(CONFIG_GART_IOMMU) += amd_gart_64.o aperture_64.o obj-$(CONFIG_GART_IOMMU) += amd_gart_64.o aperture_64.o
obj-$(CONFIG_CALGARY_IOMMU) += pci-calgary_64.o tce_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 obj-y += vsmp_64.o
endif endif
...@@ -716,7 +716,7 @@ static void init_amd_k8(struct cpuinfo_x86 *c) ...@@ -716,7 +716,7 @@ static void init_amd_k8(struct cpuinfo_x86 *c)
static void init_amd_gh(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 */ /* do this for boot cpu */
if (c == &boot_cpu_data) if (c == &boot_cpu_data)
check_enable_amd_mmconf_dmi(); check_enable_amd_mmconf_dmi();
......
...@@ -11,6 +11,7 @@ ...@@ -11,6 +11,7 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/of_platform.h> #include <linux/of_platform.h>
#include <linux/of_irq.h> #include <linux/of_irq.h>
#include <linux/libfdt.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/of_pci.h> #include <linux/of_pci.h>
...@@ -130,34 +131,52 @@ static void __init dtb_setup_hpet(void) ...@@ -130,34 +131,52 @@ static void __init dtb_setup_hpet(void)
#endif #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) static void __init dtb_lapic_setup(void)
{ {
#ifdef CONFIG_X86_LOCAL_APIC
struct device_node *dn; struct device_node *dn;
struct resource r; struct resource r;
unsigned long lapic_addr = APIC_DEFAULT_PHYS_BASE;
int ret; int ret;
dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic"); dn = of_find_compatible_node(NULL, NULL, "intel,ce4100-lapic");
if (!dn) if (dn) {
return;
ret = of_address_to_resource(dn, 0, &r); ret = of_address_to_resource(dn, 0, &r);
if (WARN_ON(ret)) if (WARN_ON(ret))
return; return;
lapic_addr = r.start;
}
/* Did the boot loader setup the local APIC ? */ /* Did the boot loader setup the local APIC ? */
if (!boot_cpu_has(X86_FEATURE_APIC)) { if (!boot_cpu_has(X86_FEATURE_APIC)) {
if (apic_force_enable(r.start)) if (apic_force_enable(lapic_addr))
return; return;
} }
smp_found_config = 1; smp_found_config = 1;
pic_mode = 1; pic_mode = 1;
register_lapic_address(r.start); register_lapic_address(lapic_addr);
generic_processor_info(boot_cpu_physical_apicid,
GET_APIC_VERSION(apic_read(APIC_LVR)));
#endif
} }
#endif /* CONFIG_X86_LOCAL_APIC */
#ifdef CONFIG_X86_IO_APIC #ifdef CONFIG_X86_IO_APIC
static unsigned int ioapic_id; static unsigned int ioapic_id;
...@@ -194,19 +213,22 @@ static struct of_ioapic_type of_ioapic_type[] = ...@@ -194,19 +213,22 @@ static struct of_ioapic_type of_ioapic_type[] =
static int dt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq, static int dt_irqdomain_alloc(struct irq_domain *domain, unsigned int virq,
unsigned int nr_irqs, void *arg) 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 of_ioapic_type *it;
struct irq_alloc_info tmp; struct irq_alloc_info tmp;
int type_index;
if (WARN_ON(irq_data->args_count < 2)) if (WARN_ON(fwspec->param_count < 2))
return -EINVAL; return -EINVAL;
if (irq_data->args[1] >= ARRAY_SIZE(of_ioapic_type))
type_index = fwspec->param[1];
if (type_index >= ARRAY_SIZE(of_ioapic_type))
return -EINVAL; return -EINVAL;
it = &of_ioapic_type[irq_data->args[1]]; it = &of_ioapic_type[type_index];
ioapic_set_alloc_attr(&tmp, NUMA_NO_NODE, it->trigger, it->polarity); 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_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); return mp_irqdomain_alloc(domain, virq, nr_irqs, &tmp);
} }
...@@ -255,7 +277,10 @@ static void __init dtb_ioapic_setup(void) {} ...@@ -255,7 +277,10 @@ static void __init dtb_ioapic_setup(void) {}
static void __init dtb_apic_setup(void) static void __init dtb_apic_setup(void)
{ {
#ifdef CONFIG_X86_LOCAL_APIC
dtb_lapic_setup(); dtb_lapic_setup();
dtb_cpu_setup();
#endif
dtb_ioapic_setup(); dtb_ioapic_setup();
} }
...@@ -270,14 +295,15 @@ static void __init x86_flattree_get_config(void) ...@@ -270,14 +295,15 @@ static void __init x86_flattree_get_config(void)
map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128); map_len = max(PAGE_SIZE - (initial_dtb & ~PAGE_MASK), (u64)128);
initial_boot_params = dt = early_memremap(initial_dtb, map_len); dt = early_memremap(initial_dtb, map_len);
size = of_get_flat_dt_size(); size = fdt_totalsize(dt);
if (map_len < size) { if (map_len < size) {
early_memunmap(dt, map_len); early_memunmap(dt, map_len);
initial_boot_params = dt = early_memremap(initial_dtb, size); dt = early_memremap(initial_dtb, size);
map_len = size; map_len = size;
} }
early_init_dt_verify(dt);
unflatten_and_copy_device_tree(); unflatten_and_copy_device_tree();
early_memunmap(dt, map_len); early_memunmap(dt, map_len);
} }
......
...@@ -124,6 +124,14 @@ static int __init jailhouse_pci_arch_init(void) ...@@ -124,6 +124,14 @@ static int __init jailhouse_pci_arch_init(void)
if (pcibios_last_bus < 0) if (pcibios_last_bus < 0)
pcibios_last_bus = 0xff; 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; return 0;
} }
......
...@@ -140,12 +140,10 @@ static const struct dmi_system_id pci_crs_quirks[] __initconst = { ...@@ -140,12 +140,10 @@ static const struct dmi_system_id pci_crs_quirks[] __initconst = {
void __init pci_acpi_crs_quirks(void) void __init pci_acpi_crs_quirks(void)
{ {
int year; int year = dmi_get_bios_year();
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year < 2008) { if (year >= 0 && year < 2008 && iomem_resource.end <= 0xffffffff)
if (iomem_resource.end <= 0xffffffff)
pci_use_crs = false; pci_use_crs = false;
}
dmi_check_system(pci_crs_quirks); dmi_check_system(pci_crs_quirks);
......
...@@ -195,14 +195,13 @@ static const struct pci_raw_ops pci_direct_conf2 = { ...@@ -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) static int __init pci_sanity_check(const struct pci_raw_ops *o)
{ {
u32 x = 0; u32 x = 0;
int year, devfn; int devfn;
if (pci_probe & PCI_NO_CHECKS) if (pci_probe & PCI_NO_CHECKS)
return 1; return 1;
/* Assume Type 1 works for newer systems. /* Assume Type 1 works for newer systems.
This handles machines that don't have anything on PCI Bus 0. */ This handles machines that don't have anything on PCI Bus 0. */
dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL); if (dmi_get_bios_year() >= 2001)
if (year >= 2001)
return 1; return 1;
for (devfn = 0; devfn < 0x100; devfn++) { for (devfn = 0; devfn < 0x100; devfn++) {
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/export.h> #include <linux/export.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <asm/jailhouse_para.h>
#include <asm/pci_x86.h> #include <asm/pci_x86.h>
/* /*
...@@ -34,13 +35,14 @@ int __init pci_legacy_init(void) ...@@ -34,13 +35,14 @@ int __init pci_legacy_init(void)
void pcibios_scan_specific_bus(int busn) void pcibios_scan_specific_bus(int busn)
{ {
int stride = jailhouse_paravirt() ? 1 : 8;
int devfn; int devfn;
u32 l; u32 l;
if (pci_find_bus(0, busn)) if (pci_find_bus(0, busn))
return; 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) && if (!raw_pci_read(0, busn, devfn, PCI_VENDOR_ID, 2, &l) &&
l != 0x0000 && l != 0xffff) { l != 0x0000 && l != 0xffff) {
DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l); DBG("Found device at %02x:%02x [%04x]\n", busn, devfn, l);
......
...@@ -94,7 +94,7 @@ static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start, ...@@ -94,7 +94,7 @@ static struct pci_mmcfg_region *pci_mmconfig_alloc(int segment, int start,
return new; return new;
} }
static struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start, struct pci_mmcfg_region *__init pci_mmconfig_add(int segment, int start,
int end, u64 addr) int end, u64 addr)
{ {
struct pci_mmcfg_region *new; struct pci_mmcfg_region *new;
...@@ -547,19 +547,14 @@ static void __init pci_mmcfg_reject_broken(int early) ...@@ -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, static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
struct acpi_mcfg_allocation *cfg) struct acpi_mcfg_allocation *cfg)
{ {
int year;
if (cfg->address < 0xFFFFFFFF) if (cfg->address < 0xFFFFFFFF)
return 0; return 0;
if (!strncmp(mcfg->header.oem_id, "SGI", 3)) if (!strncmp(mcfg->header.oem_id, "SGI", 3))
return 0; return 0;
if (mcfg->header.revision >= 1) { if ((mcfg->header.revision >= 1) && (dmi_get_bios_year() >= 2010))
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
year >= 2010)
return 0; return 0;
}
pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx " pr_err(PREFIX "MCFG region for %04x [bus %02x-%02x] at %#llx "
"is above 4GB, ignored\n", cfg->pci_segment, "is above 4GB, ignored\n", cfg->pci_segment,
......
...@@ -109,18 +109,7 @@ static int punit_dev_state_show(struct seq_file *seq_file, void *unused) ...@@ -109,18 +109,7 @@ static int punit_dev_state_show(struct seq_file *seq_file, void *unused)
return 0; return 0;
} }
DEFINE_SHOW_ATTRIBUTE(punit_dev_state);
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,
};
static struct dentry *punit_dbg_file; static struct dentry *punit_dbg_file;
...@@ -132,9 +121,9 @@ static int punit_dbgfs_register(struct punit_device *punit_device) ...@@ -132,9 +121,9 @@ static int punit_dbgfs_register(struct punit_device *punit_device)
if (!punit_dbg_file) if (!punit_dbg_file)
return -ENXIO; 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_dbg_file, punit_device,
&punit_dev_state_ops); &punit_dev_state_fops);
if (!dev_state) { if (!dev_state) {
pr_err("punit_dev_state register failed\n"); pr_err("punit_dev_state register failed\n");
debugfs_remove(punit_dbg_file); debugfs_remove(punit_dbg_file);
......
...@@ -224,25 +224,7 @@ static int imr_dbgfs_state_show(struct seq_file *s, void *unused) ...@@ -224,25 +224,7 @@ static int imr_dbgfs_state_show(struct seq_file *s, void *unused)
mutex_unlock(&idev->lock); mutex_unlock(&idev->lock);
return ret; return ret;
} }
DEFINE_SHOW_ATTRIBUTE(imr_dbgfs_state);
/**
* 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,
};
/** /**
* imr_debugfs_register - register debugfs hooks. * imr_debugfs_register - register debugfs hooks.
...@@ -252,8 +234,8 @@ static const struct file_operations imr_state_ops = { ...@@ -252,8 +234,8 @@ static const struct file_operations imr_state_ops = {
*/ */
static int imr_debugfs_register(struct imr_device *idev) static int imr_debugfs_register(struct imr_device *idev)
{ {
idev->file = debugfs_create_file("imr_state", S_IFREG | S_IRUGO, NULL, idev->file = debugfs_create_file("imr_state", 0444, NULL, idev,
idev, &imr_state_ops); &imr_dbgfs_state_fops);
return PTR_ERR_OR_ZERO(idev->file); return PTR_ERR_OR_ZERO(idev->file);
} }
......
...@@ -376,12 +376,10 @@ void __init acpi_sleep_no_blacklist(void) ...@@ -376,12 +376,10 @@ void __init acpi_sleep_no_blacklist(void)
static void __init acpi_sleep_dmi_check(void) static void __init acpi_sleep_dmi_check(void)
{ {
int year;
if (ignore_blacklist) if (ignore_blacklist)
return; return;
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && year >= 2012) if (dmi_get_bios_year() >= 2012)
acpi_nvs_nosave_s3(); acpi_nvs_nosave_s3();
dmi_check_system(acpisleep_dmi_table); dmi_check_system(acpisleep_dmi_table);
......
...@@ -1004,6 +1004,26 @@ bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp) ...@@ -1004,6 +1004,26 @@ bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp)
} }
EXPORT_SYMBOL(dmi_get_date); 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 * dmi_walk - Walk the DMI table and get called back for every record
* @decode: Callback function * @decode: Callback function
......
...@@ -2258,8 +2258,6 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev) ...@@ -2258,8 +2258,6 @@ void pci_config_pm_runtime_put(struct pci_dev *pdev)
*/ */
bool pci_bridge_d3_possible(struct pci_dev *bridge) bool pci_bridge_d3_possible(struct pci_dev *bridge)
{ {
unsigned int year;
if (!pci_is_pcie(bridge)) if (!pci_is_pcie(bridge))
return false; return false;
...@@ -2287,10 +2285,8 @@ bool pci_bridge_d3_possible(struct pci_dev *bridge) ...@@ -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 * It should be safe to put PCIe ports from 2015 or newer
* to D3. * to D3.
*/ */
if (dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) && if (dmi_get_bios_year() >= 2015)
year >= 2015) {
return true; return true;
}
break; break;
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/pci-aspm.h> #include <linux/pci-aspm.h>
#include <linux/aer.h> #include <linux/aer.h>
#include <linux/acpi.h> #include <linux/acpi.h>
#include <linux/hypervisor.h>
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
#include "pci.h" #include "pci.h"
...@@ -2518,14 +2519,29 @@ static unsigned int pci_scan_child_bus_extend(struct pci_bus *bus, ...@@ -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 used_buses, normal_bridges = 0, hotplug_bridges = 0;
unsigned int start = bus->busn_res.start; unsigned int start = bus->busn_res.start;
unsigned int devfn, cmax, max = start; unsigned int devfn, fn, cmax, max = start;
struct pci_dev *dev; struct pci_dev *dev;
int nr_devs;
dev_dbg(&bus->dev, "scanning bus\n"); dev_dbg(&bus->dev, "scanning bus\n");
/* Go find them, Rover! */ /* Go find them, Rover! */
for (devfn = 0; devfn < 0x100; devfn += 8) for (devfn = 0; devfn < 256; devfn += 8) {
pci_scan_slot(bus, devfn); 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 */ /* Reserve buses for SR-IOV capability */
used_buses = pci_iov_bus_range(bus); used_buses = pci_iov_bus_range(bus);
......
...@@ -106,6 +106,7 @@ extern void dmi_scan_machine(void); ...@@ -106,6 +106,7 @@ extern void dmi_scan_machine(void);
extern void dmi_memdev_walk(void); extern void dmi_memdev_walk(void);
extern void dmi_set_dump_stack_arch_desc(void); extern void dmi_set_dump_stack_arch_desc(void);
extern bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp); 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_vendors(const char *str);
extern int dmi_name_in_serial(const char *str); extern int dmi_name_in_serial(const char *str);
extern int dmi_available; extern int dmi_available;
...@@ -133,6 +134,7 @@ static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp) ...@@ -133,6 +134,7 @@ static inline bool dmi_get_date(int field, int *yearp, int *monthp, int *dayp)
*dayp = 0; *dayp = 0;
return false; 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_vendors(const char *s) { return 0; }
static inline int dmi_name_in_serial(const char *s) { return 0; } static inline int dmi_name_in_serial(const char *s) { return 0; }
#define dmi_available 0 #define dmi_available 0
......
...@@ -8,15 +8,28 @@ ...@@ -8,15 +8,28 @@
*/ */
#ifdef CONFIG_X86 #ifdef CONFIG_X86
#include <asm/jailhouse_para.h>
#include <asm/x86_init.h> #include <asm/x86_init.h>
static inline void hypervisor_pin_vcpu(int cpu) static inline void hypervisor_pin_vcpu(int cpu)
{ {
x86_platform.hyper.pin_vcpu(cpu); x86_platform.hyper.pin_vcpu(cpu);
} }
#else
#else /* !CONFIG_X86 */
#include <linux/of.h>
static inline void hypervisor_pin_vcpu(int cpu) 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 */ #endif /* __LINUX_HYPEVISOR_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment