diff --git a/PCI-Lock-down-BAR-access-when-module-security-is-ena.patch b/PCI-Lock-down-BAR-access-when-module-security-is-ena.patch index 23a514f3b..9500b96d2 100644 --- a/PCI-Lock-down-BAR-access-when-module-security-is-ena.patch +++ b/PCI-Lock-down-BAR-access-when-module-security-is-ena.patch @@ -1,8 +1,7 @@ -From 655fbf360e1481db4f06001f893d388c15ac307f Mon Sep 17 00:00:00 2001 +From 6f756b32a45b022428e33ce20181e874c73ca82e Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Thu, 8 Mar 2012 10:10:38 -0500 -Subject: [PATCH 02/20] PCI: Lock down BAR access when module security is - enabled +Subject: [PATCH] PCI: Lock down BAR access when module security is enabled Any hardware that can potentially generate DMA has to be locked down from userspace in order to avoid it being possible for an attacker to modify @@ -18,7 +17,7 @@ Signed-off-by: Matthew Garrett 3 files changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c -index 312f23a8429c..93e6ac103dd0 100644 +index bcd10c7..a950301 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -30,6 +30,7 @@ @@ -29,7 +28,7 @@ index 312f23a8429c..93e6ac103dd0 100644 #include "pci.h" static int sysfs_initialized; /* = 0 */ -@@ -710,6 +711,9 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj, +@@ -716,6 +717,9 @@ static ssize_t pci_write_config(struct file *filp, struct kobject *kobj, loff_t init_off = off; u8 *data = (u8 *) buf; @@ -39,7 +38,7 @@ index 312f23a8429c..93e6ac103dd0 100644 if (off > dev->cfg_size) return 0; if (off + count > dev->cfg_size) { -@@ -1004,6 +1008,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, +@@ -1007,6 +1011,9 @@ static int pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, resource_size_t start, end; int i; @@ -49,7 +48,7 @@ index 312f23a8429c..93e6ac103dd0 100644 for (i = 0; i < PCI_ROM_RESOURCE; i++) if (res == &pdev->resource[i]) break; -@@ -1105,6 +1112,9 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj, +@@ -1106,6 +1113,9 @@ static ssize_t pci_write_resource_io(struct file *filp, struct kobject *kobj, struct bin_attribute *attr, char *buf, loff_t off, size_t count) { @@ -60,7 +59,7 @@ index 312f23a8429c..93e6ac103dd0 100644 } diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c -index 3f155e78513f..4265ea07e3b0 100644 +index 2408abe..59f321c 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c @@ -116,6 +116,9 @@ static ssize_t proc_bus_pci_write(struct file *file, const char __user *buf, @@ -85,7 +84,7 @@ index 3f155e78513f..4265ea07e3b0 100644 ret = pci_domain_nr(dev->bus); @@ -233,7 +239,7 @@ static int proc_bus_pci_mmap(struct file *file, struct vm_area_struct *vma) struct pci_filp_private *fpriv = file->private_data; - int i, ret; + int i, ret, write_combine; - if (!capable(CAP_SYS_RAWIO)) + if (!capable(CAP_SYS_RAWIO) || secure_modules()) @@ -93,7 +92,7 @@ index 3f155e78513f..4265ea07e3b0 100644 /* Make sure the caller is mapping a real resource for this device */ diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c -index b91c4da68365..98f5637304d1 100644 +index b91c4da..98f5637 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c @@ -10,6 +10,7 @@ @@ -114,5 +113,5 @@ index b91c4da68365..98f5637304d1 100644 dev = pci_get_bus_and_slot(bus, dfn); -- -2.4.3 +2.9.2 diff --git a/arm64-pcie-acpi.patch b/arm64-pcie-acpi.patch deleted file mode 100644 index 50c646870..000000000 --- a/arm64-pcie-acpi.patch +++ /dev/null @@ -1,1247 +0,0 @@ -From 1fc02559de87cd88339a83ad05baa9c2b5bd1ac0 Mon Sep 17 00:00:00 2001 -From: Jayachandran C -Date: Fri, 10 Jun 2016 21:55:09 +0200 -Subject: [PATCH 01/11] PCI/ECAM: Move ecam.h to linux/include/pci-ecam.h - -This header will be used from arch/arm64 for ACPI PCI implementation -so it needs to be moved out of drivers/pci. - -Update users of the header file to use the new name. No functional -changes. - -Signed-off-by: Jayachandran C -Acked-by: Lorenzo Pieralisi ---- - drivers/pci/ecam.c | 3 +- - drivers/pci/ecam.h | 67 ------------------------------------- - drivers/pci/host/pci-host-common.c | 3 +- - drivers/pci/host/pci-host-generic.c | 3 +- - drivers/pci/host/pci-thunder-ecam.c | 3 +- - drivers/pci/host/pci-thunder-pem.c | 3 +- - include/linux/pci-ecam.h | 67 +++++++++++++++++++++++++++++++++++++ - 7 files changed, 72 insertions(+), 77 deletions(-) - delete mode 100644 drivers/pci/ecam.h - create mode 100644 include/linux/pci-ecam.h - -diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c -index f9832ad..820e26b 100644 ---- a/drivers/pci/ecam.c -+++ b/drivers/pci/ecam.c -@@ -19,10 +19,9 @@ - #include - #include - #include -+#include - #include - --#include "ecam.h" -- - /* - * On 64-bit systems, we do a single ioremap for the whole config space - * since we have enough virtual address range available. On 32-bit, we -diff --git a/drivers/pci/ecam.h b/drivers/pci/ecam.h -deleted file mode 100644 -index 9878beb..0000000 ---- a/drivers/pci/ecam.h -+++ /dev/null -@@ -1,67 +0,0 @@ --/* -- * Copyright 2016 Broadcom -- * -- * This program is free software; you can redistribute it and/or modify -- * it under the terms of the GNU General Public License, version 2, as -- * published by the Free Software Foundation (the "GPL"). -- * -- * This program is distributed in the hope that it will be useful, but -- * WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * General Public License version 2 (GPLv2) for more details. -- * -- * You should have received a copy of the GNU General Public License -- * version 2 (GPLv2) along with this source code. -- */ --#ifndef DRIVERS_PCI_ECAM_H --#define DRIVERS_PCI_ECAM_H -- --#include --#include -- --/* -- * struct to hold pci ops and bus shift of the config window -- * for a PCI controller. -- */ --struct pci_config_window; --struct pci_ecam_ops { -- unsigned int bus_shift; -- struct pci_ops pci_ops; -- int (*init)(struct device *, -- struct pci_config_window *); --}; -- --/* -- * struct to hold the mappings of a config space window. This -- * is expected to be used as sysdata for PCI controllers that -- * use ECAM. -- */ --struct pci_config_window { -- struct resource res; -- struct resource busr; -- void *priv; -- struct pci_ecam_ops *ops; -- union { -- void __iomem *win; /* 64-bit single mapping */ -- void __iomem **winp; /* 32-bit per-bus mapping */ -- }; --}; -- --/* create and free pci_config_window */ --struct pci_config_window *pci_ecam_create(struct device *dev, -- struct resource *cfgres, struct resource *busr, -- struct pci_ecam_ops *ops); --void pci_ecam_free(struct pci_config_window *cfg); -- --/* map_bus when ->sysdata is an instance of pci_config_window */ --void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn, -- int where); --/* default ECAM ops */ --extern struct pci_ecam_ops pci_generic_ecam_ops; -- --#ifdef CONFIG_PCI_HOST_GENERIC --/* for DT-based PCI controllers that support ECAM */ --int pci_host_common_probe(struct platform_device *pdev, -- struct pci_ecam_ops *ops); --#endif --#endif -diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c -index 8cba7ab..c18b9e3 100644 ---- a/drivers/pci/host/pci-host-common.c -+++ b/drivers/pci/host/pci-host-common.c -@@ -20,10 +20,9 @@ - #include - #include - #include -+#include - #include - --#include "../ecam.h" -- - static int gen_pci_parse_request_of_pci_ranges(struct device *dev, - struct list_head *resources, struct resource **bus_range) - { -diff --git a/drivers/pci/host/pci-host-generic.c b/drivers/pci/host/pci-host-generic.c -index 6eaceab..f0ca6de 100644 ---- a/drivers/pci/host/pci-host-generic.c -+++ b/drivers/pci/host/pci-host-generic.c -@@ -23,10 +23,9 @@ - #include - #include - #include -+#include - #include - --#include "../ecam.h" -- - static struct pci_ecam_ops gen_pci_cfg_cam_bus_ops = { - .bus_shift = 16, - .pci_ops = { -diff --git a/drivers/pci/host/pci-thunder-ecam.c b/drivers/pci/host/pci-thunder-ecam.c -index 540d030..a9fc1c9 100644 ---- a/drivers/pci/host/pci-thunder-ecam.c -+++ b/drivers/pci/host/pci-thunder-ecam.c -@@ -11,10 +11,9 @@ - #include - #include - #include -+#include - #include - --#include "../ecam.h" -- - static void set_val(u32 v, int where, int size, u32 *val) - { - int shift = (where & 3) * 8; -diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c -index 9b8ab94..5020d3d 100644 ---- a/drivers/pci/host/pci-thunder-pem.c -+++ b/drivers/pci/host/pci-thunder-pem.c -@@ -18,10 +18,9 @@ - #include - #include - #include -+#include - #include - --#include "../ecam.h" -- - #define PEM_CFG_WR 0x28 - #define PEM_CFG_RD 0x30 - -diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h -new file mode 100644 -index 0000000..9878beb ---- /dev/null -+++ b/include/linux/pci-ecam.h -@@ -0,0 +1,67 @@ -+/* -+ * Copyright 2016 Broadcom -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, version 2, as -+ * published by the Free Software Foundation (the "GPL"). -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License version 2 (GPLv2) for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * version 2 (GPLv2) along with this source code. -+ */ -+#ifndef DRIVERS_PCI_ECAM_H -+#define DRIVERS_PCI_ECAM_H -+ -+#include -+#include -+ -+/* -+ * struct to hold pci ops and bus shift of the config window -+ * for a PCI controller. -+ */ -+struct pci_config_window; -+struct pci_ecam_ops { -+ unsigned int bus_shift; -+ struct pci_ops pci_ops; -+ int (*init)(struct device *, -+ struct pci_config_window *); -+}; -+ -+/* -+ * struct to hold the mappings of a config space window. This -+ * is expected to be used as sysdata for PCI controllers that -+ * use ECAM. -+ */ -+struct pci_config_window { -+ struct resource res; -+ struct resource busr; -+ void *priv; -+ struct pci_ecam_ops *ops; -+ union { -+ void __iomem *win; /* 64-bit single mapping */ -+ void __iomem **winp; /* 32-bit per-bus mapping */ -+ }; -+}; -+ -+/* create and free pci_config_window */ -+struct pci_config_window *pci_ecam_create(struct device *dev, -+ struct resource *cfgres, struct resource *busr, -+ struct pci_ecam_ops *ops); -+void pci_ecam_free(struct pci_config_window *cfg); -+ -+/* map_bus when ->sysdata is an instance of pci_config_window */ -+void __iomem *pci_ecam_map_bus(struct pci_bus *bus, unsigned int devfn, -+ int where); -+/* default ECAM ops */ -+extern struct pci_ecam_ops pci_generic_ecam_ops; -+ -+#ifdef CONFIG_PCI_HOST_GENERIC -+/* for DT-based PCI controllers that support ECAM */ -+int pci_host_common_probe(struct platform_device *pdev, -+ struct pci_ecam_ops *ops); -+#endif -+#endif --- -2.7.4 - -From 5eb9996fc097629854f359f9ad3d959fdacb7f8f Mon Sep 17 00:00:00 2001 -From: Jayachandran C -Date: Fri, 10 Jun 2016 21:55:10 +0200 -Subject: [PATCH 02/11] PCI/ECAM: Add parent device field to pci_config_window - -Add a parent device field to struct pci_config_window. The parent -is not saved now, but will be useful to save it in some cases. -Specifically in case of ACPI for ARM64, it can be used to setup -ACPI companion and domain. - -Since the parent dev is in struct pci_config_window now, we need -not pass it to the init function as a separate argument. - -Signed-off-by: Jayachandran C -Acked-by: Lorenzo Pieralisi ---- - drivers/pci/ecam.c | 3 ++- - drivers/pci/host/pci-thunder-pem.c | 3 ++- - include/linux/pci-ecam.h | 4 ++-- - 3 files changed, 6 insertions(+), 4 deletions(-) - -diff --git a/drivers/pci/ecam.c b/drivers/pci/ecam.c -index 820e26b..66e0d71 100644 ---- a/drivers/pci/ecam.c -+++ b/drivers/pci/ecam.c -@@ -51,6 +51,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev, - if (!cfg) - return ERR_PTR(-ENOMEM); - -+ cfg->parent = dev; - cfg->ops = ops; - cfg->busr.start = busr->start; - cfg->busr.end = busr->end; -@@ -94,7 +95,7 @@ struct pci_config_window *pci_ecam_create(struct device *dev, - } - - if (ops->init) { -- err = ops->init(dev, cfg); -+ err = ops->init(cfg); - if (err) - goto err_exit; - } -diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c -index 5020d3d..91f6fc6 100644 ---- a/drivers/pci/host/pci-thunder-pem.c -+++ b/drivers/pci/host/pci-thunder-pem.c -@@ -284,8 +284,9 @@ static int thunder_pem_config_write(struct pci_bus *bus, unsigned int devfn, - return pci_generic_config_write(bus, devfn, where, size, val); - } - --static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg) -+static int thunder_pem_init(struct pci_config_window *cfg) - { -+ struct device *dev = cfg->parent; - resource_size_t bar4_start; - struct resource *res_pem; - struct thunder_pem_pci *pem_pci; -diff --git a/include/linux/pci-ecam.h b/include/linux/pci-ecam.h -index 9878beb..7adad20 100644 ---- a/include/linux/pci-ecam.h -+++ b/include/linux/pci-ecam.h -@@ -27,8 +27,7 @@ struct pci_config_window; - struct pci_ecam_ops { - unsigned int bus_shift; - struct pci_ops pci_ops; -- int (*init)(struct device *, -- struct pci_config_window *); -+ int (*init)(struct pci_config_window *); - }; - - /* -@@ -45,6 +44,7 @@ struct pci_config_window { - void __iomem *win; /* 64-bit single mapping */ - void __iomem **winp; /* 32-bit per-bus mapping */ - }; -+ struct device *parent;/* ECAM res was from this dev */ - }; - - /* create and free pci_config_window */ --- -2.7.4 - -From 6ed6c1365df5c9201e9b275e8ed4eaa64ef2ec0d Mon Sep 17 00:00:00 2001 -From: Sinan Kaya -Date: Fri, 10 Jun 2016 21:55:11 +0200 -Subject: [PATCH 03/11] PCI: Add new function to unmap IO resources - -We need to release I/O resources so that the same I/O resources -can be allocated again in pci_remap_iospace(), like in PCI hotplug removal -scenario. Therefore implement new pci_unmap_iospace() call which -unmaps I/O space as the symmetry to pci_remap_iospace(). - -Signed-off-by: Sinan Kaya -Signed-off-by: Tomasz Nowicki -Acked-by: Lorenzo Pieralisi ---- - drivers/pci/pci.c | 18 ++++++++++++++++++ - include/linux/pci.h | 1 + - 2 files changed, 19 insertions(+) - -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index c8b4dbd..eb431b5 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - #include - #include - #include "pci.h" -@@ -3165,6 +3166,23 @@ int __weak pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr) - #endif - } - -+/** -+ * pci_unmap_iospace - Unmap the memory mapped I/O space -+ * @res: resource to be unmapped -+ * -+ * Unmap the CPU virtual address @res from virtual address space. -+ * Only architectures that have memory mapped IO functions defined -+ * (and the PCI_IOBASE value defined) should call this function. -+ */ -+void pci_unmap_iospace(struct resource *res) -+{ -+#if defined(PCI_IOBASE) && defined(CONFIG_MMU) -+ unsigned long vaddr = (unsigned long)PCI_IOBASE + res->start; -+ -+ unmap_kernel_range(vaddr, resource_size(res)); -+#endif -+} -+ - static void __pci_set_master(struct pci_dev *dev, bool enable) - { - u16 old_cmd, cmd; -diff --git a/include/linux/pci.h b/include/linux/pci.h -index b67e4df..12349de 100644 ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -1167,6 +1167,7 @@ int pci_register_io_range(phys_addr_t addr, resource_size_t size); - unsigned long pci_address_to_pio(phys_addr_t addr); - phys_addr_t pci_pio_to_address(unsigned long pio); - int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr); -+void pci_unmap_iospace(struct resource *res); - - static inline pci_bus_addr_t pci_bus_address(struct pci_dev *pdev, int bar) - { --- -2.7.4 - -From 62f4d54fc2d2882b9ebaa920189574f422e12207 Mon Sep 17 00:00:00 2001 -From: Jayachandran C -Date: Fri, 10 Jun 2016 21:55:12 +0200 -Subject: [PATCH 04/11] ACPI/PCI: Support IO resources when parsing PCI host - bridge resources - -Platforms that have memory mapped IO port (such as ARM64) need special -handling for PCI I/O resources. For host bridge's resource probing case -these resources need to be fixed up with -pci_register_io_range()/pci_remap_iospace() etc. - -The same I/O resources need to be released after hotplug -removal so that it can be re-added back by the pci_remap_iospace() -function during insertion. As a consequence unmap I/O resources -with pci_unmap_iospace() when we release host bridge resources. - -Signed-off-by: Jayachandran C -Signed-off-by: Sinan Kaya -[ Tomasz: merged in Sinan's patch to unmap IO resources properly, updated changelog] -Signed-off-by: Tomasz Nowicki -Reviewed-by: Lorenzo Pieralisi ---- - drivers/acpi/pci_root.c | 39 +++++++++++++++++++++++++++++++++++++++ - 1 file changed, 39 insertions(+) - -diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c -index ae3fe4e..9a26dd1 100644 ---- a/drivers/acpi/pci_root.c -+++ b/drivers/acpi/pci_root.c -@@ -720,6 +720,40 @@ next: - } - } - -+#ifdef PCI_IOBASE -+static void acpi_pci_root_remap_iospace(struct resource_entry *entry) -+{ -+ struct resource *res = entry->res; -+ resource_size_t cpu_addr = res->start; -+ resource_size_t pci_addr = cpu_addr - entry->offset; -+ resource_size_t length = resource_size(res); -+ unsigned long port; -+ -+ if (pci_register_io_range(cpu_addr, length)) -+ goto err; -+ -+ port = pci_address_to_pio(cpu_addr); -+ if (port == (unsigned long)-1) -+ goto err; -+ -+ res->start = port; -+ res->end = port + length - 1; -+ entry->offset = port - pci_addr; -+ -+ if (pci_remap_iospace(res, cpu_addr) < 0) -+ goto err; -+ -+ pr_info("Remapped I/O %pa to %pR\n", &cpu_addr, res); -+ return; -+err: -+ res->flags |= IORESOURCE_DISABLED; -+} -+#else -+static inline void acpi_pci_root_remap_iospace(struct resource_entry *entry) -+{ -+} -+#endif -+ - int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) - { - int ret; -@@ -740,6 +774,9 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info) - "no IO and memory resources present in _CRS\n"); - else { - resource_list_for_each_entry_safe(entry, tmp, list) { -+ if (entry->res->flags & IORESOURCE_IO) -+ acpi_pci_root_remap_iospace(entry); -+ - if (entry->res->flags & IORESOURCE_DISABLED) - resource_list_destroy_entry(entry); - else -@@ -811,6 +848,8 @@ static void acpi_pci_root_release_info(struct pci_host_bridge *bridge) - - resource_list_for_each_entry(entry, &bridge->windows) { - res = entry->res; -+ if (res->flags & IORESOURCE_IO) -+ pci_unmap_iospace(res); - if (res->parent && - (res->flags & (IORESOURCE_MEM | IORESOURCE_IO))) - release_resource(res); --- -2.7.4 - -From dd4f7822d702cca83baa1de7a5f69344ffb82af9 Mon Sep 17 00:00:00 2001 -From: Tomasz Nowicki -Date: Fri, 10 Jun 2016 21:55:13 +0200 -Subject: [PATCH 05/11] ACPI/PCI: Add generic MCFG table handling - -According to PCI firmware specifications, on systems booting with ACPI, -PCI configuration for a host bridge must be set-up through the MCFG table -regions for non-hotpluggable bridges and _CBA method for hotpluggable ones. - -Current MCFG table handling code, as implemented for x86, cannot be -easily generalized owing to x86 specific quirks handling and related -code, which makes it hard to reuse on other architectures. - -In order to implement MCFG PCI configuration handling for new platforms -booting with ACPI (eg ARM64) this patch re-implements MCFG handling from -scratch in a streamlined fashion and provides (through a generic -interface available to all arches): - -- Simplified MCFG table parsing (executed through the pci_mmcfg_late_init() - hook as in current x86) -- MCFG regions look-up interface through domain:bus_start:bus_end tuple - -The new MCFG regions handling interface is added to generic ACPI code -so that existing architectures (eg x86) can be moved over to it and -architectures relying on MCFG for ACPI PCI config space can rely on it -without having to resort to arch specific implementations. - -Signed-off-by: Tomasz Nowicki -Signed-off-by: Jayachandran C -Reviewed-by: Lorenzo Pieralisi ---- - drivers/acpi/Kconfig | 3 ++ - drivers/acpi/Makefile | 1 + - drivers/acpi/pci_mcfg.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ - include/linux/pci-acpi.h | 2 ++ - include/linux/pci.h | 2 +- - 5 files changed, 99 insertions(+), 1 deletion(-) - create mode 100644 drivers/acpi/pci_mcfg.c - -diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig -index b7e2e77..f98c328 100644 ---- a/drivers/acpi/Kconfig -+++ b/drivers/acpi/Kconfig -@@ -217,6 +217,9 @@ config ACPI_PROCESSOR_IDLE - bool - select CPU_IDLE - -+config ACPI_MCFG -+ bool -+ - config ACPI_CPPC_LIB - bool - depends on ACPI_PROCESSOR -diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile -index 251ce85..632e81f 100644 ---- a/drivers/acpi/Makefile -+++ b/drivers/acpi/Makefile -@@ -40,6 +40,7 @@ acpi-$(CONFIG_ARCH_MIGHT_HAVE_ACPI_PDC) += processor_pdc.o - acpi-y += ec.o - acpi-$(CONFIG_ACPI_DOCK) += dock.o - acpi-y += pci_root.o pci_link.o pci_irq.o -+obj-$(CONFIG_ACPI_MCFG) += pci_mcfg.o - acpi-y += acpi_lpss.o acpi_apd.o - acpi-y += acpi_platform.o - acpi-y += acpi_pnp.o -diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c -new file mode 100644 -index 0000000..d3c3e85 ---- /dev/null -+++ b/drivers/acpi/pci_mcfg.c -@@ -0,0 +1,92 @@ -+/* -+ * Copyright (C) 2016 Broadcom -+ * Author: Jayachandran C -+ * Copyright (C) 2016 Semihalf -+ * Author: Tomasz Nowicki -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License, version 2, as -+ * published by the Free Software Foundation (the "GPL"). -+ * -+ * This program is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * General Public License version 2 (GPLv2) for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * version 2 (GPLv2) along with this source code. -+ */ -+ -+#define pr_fmt(fmt) "ACPI: " fmt -+ -+#include -+#include -+#include -+ -+/* Structure to hold entries from the MCFG table */ -+struct mcfg_entry { -+ struct list_head list; -+ phys_addr_t addr; -+ u16 segment; -+ u8 bus_start; -+ u8 bus_end; -+}; -+ -+/* List to save mcfg entries */ -+static LIST_HEAD(pci_mcfg_list); -+ -+phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res) -+{ -+ struct mcfg_entry *e; -+ -+ /* -+ * We expect exact match, unless MCFG entry end bus covers more than -+ * specified by caller. -+ */ -+ list_for_each_entry(e, &pci_mcfg_list, list) { -+ if (e->segment == seg && e->bus_start == bus_res->start && -+ e->bus_end >= bus_res->end) -+ return e->addr; -+ } -+ -+ return 0; -+} -+ -+static __init int pci_mcfg_parse(struct acpi_table_header *header) -+{ -+ struct acpi_table_mcfg *mcfg; -+ struct acpi_mcfg_allocation *mptr; -+ struct mcfg_entry *e, *arr; -+ int i, n; -+ -+ if (header->length < sizeof(struct acpi_table_mcfg)) -+ return -EINVAL; -+ -+ n = (header->length - sizeof(struct acpi_table_mcfg)) / -+ sizeof(struct acpi_mcfg_allocation); -+ mcfg = (struct acpi_table_mcfg *)header; -+ mptr = (struct acpi_mcfg_allocation *) &mcfg[1]; -+ -+ arr = kcalloc(n, sizeof(*arr), GFP_KERNEL); -+ if (!arr) -+ return -ENOMEM; -+ -+ for (i = 0, e = arr; i < n; i++, mptr++, e++) { -+ e->segment = mptr->pci_segment; -+ e->addr = mptr->address; -+ e->bus_start = mptr->start_bus_number; -+ e->bus_end = mptr->end_bus_number; -+ list_add(&e->list, &pci_mcfg_list); -+ } -+ -+ pr_info("MCFG table detected, %d entries\n", n); -+ return 0; -+} -+ -+/* Interface called by ACPI - parse and save MCFG table */ -+void __init pci_mmcfg_late_init(void) -+{ -+ int err = acpi_table_parse(ACPI_SIG_MCFG, pci_mcfg_parse); -+ if (err) -+ pr_err("Failed to parse MCFG (%d)\n", err); -+} -diff --git a/include/linux/pci-acpi.h b/include/linux/pci-acpi.h -index 89ab057..7d63a66 100644 ---- a/include/linux/pci-acpi.h -+++ b/include/linux/pci-acpi.h -@@ -24,6 +24,8 @@ static inline acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev) - } - extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle); - -+extern phys_addr_t pci_mcfg_lookup(u16 domain, struct resource *bus_res); -+ - static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev) - { - struct pci_bus *pbus = pdev->bus; -diff --git a/include/linux/pci.h b/include/linux/pci.h -index 12349de..ce03d65 100644 ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -1723,7 +1723,7 @@ void pcibios_free_irq(struct pci_dev *dev); - extern struct dev_pm_ops pcibios_pm_ops; - #endif - --#ifdef CONFIG_PCI_MMCONFIG -+#if defined(CONFIG_PCI_MMCONFIG) || defined(CONFIG_ACPI_MCFG) - void __init pci_mmcfg_early_init(void); - void __init pci_mmcfg_late_init(void); - #else --- -2.7.4 - -From fc1907f9c79f9a0a0c2f4d579896e678915fec48 Mon Sep 17 00:00:00 2001 -From: Tomasz Nowicki -Date: Fri, 10 Jun 2016 21:55:14 +0200 -Subject: [PATCH 06/11] PCI: Refactor generic bus domain assignment - -Change the way PCI bus domain number is assigned and improve function -name to reflect what function does. No functional changes. - -Instead of assigning bus domain number inside of pci_bus_assign_domain_nr() -simply return domain number and let pci_create_root_bus() do assignment. -This way pci_create_root_bus() setups bus structure data in the consistent -way. Since pci_bus_assign_domain_nr() now does not assign but retrieves -domain number instead, rename it to pci_bus_find_domain_nr(). - -Signed-off-by: Tomasz Nowicki -Reviewed-by: Lorenzo Pieralisi ---- - drivers/pci/pci.c | 4 ++-- - drivers/pci/probe.c | 4 +++- - include/linux/pci.h | 7 +------ - 3 files changed, 6 insertions(+), 9 deletions(-) - -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index eb431b5..b9a7833 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -4941,7 +4941,7 @@ int pci_get_new_domain_nr(void) - } - - #ifdef CONFIG_PCI_DOMAINS_GENERIC --void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) -+int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent) - { - static int use_dt_domains = -1; - int domain = -1; -@@ -4985,7 +4985,7 @@ void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent) - domain = -1; - } - -- bus->domain_nr = domain; -+ return domain; - } - #endif - #endif -diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c -index 8e3ef72..380d46d 100644 ---- a/drivers/pci/probe.c -+++ b/drivers/pci/probe.c -@@ -2127,7 +2127,9 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, - b->sysdata = sysdata; - b->ops = ops; - b->number = b->busn_res.start = bus; -- pci_bus_assign_domain_nr(b, parent); -+#ifdef CONFIG_PCI_DOMAINS_GENERIC -+ b->domain_nr = pci_bus_find_domain_nr(b, parent); -+#endif - b2 = pci_find_bus(pci_domain_nr(b), bus); - if (b2) { - /* If we already got to this bus through a different bridge, ignore it */ -diff --git a/include/linux/pci.h b/include/linux/pci.h -index ce03d65..48839e8 100644 ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -1390,12 +1390,7 @@ static inline int pci_domain_nr(struct pci_bus *bus) - { - return bus->domain_nr; - } --void pci_bus_assign_domain_nr(struct pci_bus *bus, struct device *parent); --#else --static inline void pci_bus_assign_domain_nr(struct pci_bus *bus, -- struct device *parent) --{ --} -+int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent); - #endif - - /* some architectures require additional setup to direct VGA traffic */ --- -2.7.4 - -From d6d45ae1d58658111d5e838c41b9ed4729bbb81e Mon Sep 17 00:00:00 2001 -From: Tomasz Nowicki -Date: Fri, 10 Jun 2016 21:55:15 +0200 -Subject: [PATCH 07/11] PCI: Factor DT specific pci_bus_find_domain_nr() code - out - -pci_bus_find_domain_nr() retrieves the host bridge domain number in a DT -specific way. Factor our pci_bus_find_domain_nr() in a separate DT -function (ie of_pci_bus_find_domain_nr()) so that DT code is self -contained, paving the way for retrieving domain number in -pci_bus_find_domain_nr() with additional firmware methods (ie ACPI). - -Signed-off-by: Tomasz Nowicki -Reviewed-by: Lorenzo Pieralisi ---- - drivers/pci/pci.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index b9a7833..97f7cd4 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -4941,7 +4941,7 @@ int pci_get_new_domain_nr(void) - } - - #ifdef CONFIG_PCI_DOMAINS_GENERIC --int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent) -+static int of_pci_bus_find_domain_nr(struct device *parent) - { - static int use_dt_domains = -1; - int domain = -1; -@@ -4987,6 +4987,11 @@ int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent) - - return domain; - } -+ -+int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent) -+{ -+ return of_pci_bus_find_domain_nr(parent); -+} - #endif - #endif - --- -2.7.4 - -From 92d59511fd365d3c0c31d074b5e96cf48c58f68b Mon Sep 17 00:00:00 2001 -From: Peter Robinson -Date: Thu, 30 Jun 2016 16:56:24 +0100 -Subject: [PATCH 08/11] ARM64/PCI: Add ACPI hook to assign domain number - -PCI core code provides a config option (CONFIG_PCI_DOMAINS_GENERIC) -that allows assigning the PCI bus domain number generically by -relying on device tree bindings, and falling back to a simple counter -when the respective DT properties (ie "linux,pci-domain") are not -specified in the host bridge device tree node. - -In a similar way, when a system is booted through ACPI, architectures -that are selecting CONFIG_PCI_DOMAINS_GENERIC (ie ARM64) require kernel -hooks to retrieve the domain number so that the PCI bus domain number -set-up can be handled seamlessly with DT and ACPI in generic core code -when CONFIG_PCI_DOMAINS_GENERIC is selected. - -Since currently it is not possible to retrieve a pointer to the PCI -host bridge ACPI device backing the host bridge from core PCI code -(which would allow retrieving the domain number in an arch agnostic -way through the ACPI _SEG method), an arch specific ACPI hook has to -be declared and implemented by all arches that rely on -CONFIG_PCI_DOMAINS_GENERIC to retrieve the domain number and set it -up in core PCI code. - -For the aforementioned reasons, introduce acpi_pci_bus_find_domain_nr() -hook to retrieve the domain number on a per-arch basis when the system -boots through ACPI. ARM64 dummy implementation of the same is provided -in first place in preparation for ARM64 ACPI based PCI host controller -driver. - -acpi_pci_bus_find_domain_nr() is called from generic -pci_bus_find_domain_nr() as an ACPI option to DT domain assignment. - -Signed-off-by: Tomasz Nowicki -Signed-off-by: Lorenzo Pieralisi ---- - arch/arm64/kernel/pci.c | 7 +++++++ - drivers/pci/pci.c | 4 +++- - include/linux/pci.h | 7 +++++++ - 3 files changed, 17 insertions(+), 1 deletion(-) - -diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c -index 3c4e308..d5d3d26 100644 ---- a/arch/arm64/kernel/pci.c -+++ b/arch/arm64/kernel/pci.c -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - - /* -@@ -85,6 +86,12 @@ EXPORT_SYMBOL(pcibus_to_node); - #endif - - #ifdef CONFIG_ACPI -+ -+int acpi_pci_bus_find_domain_nr(struct pci_bus *bus) -+{ -+ return 0; -+} -+ - /* Root bridge scanning */ - struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) - { -diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c -index 97f7cd4..4834cee 100644 ---- a/drivers/pci/pci.c -+++ b/drivers/pci/pci.c -@@ -7,6 +7,7 @@ - * Copyright 1997 -- 2000 Martin Mares - */ - -+#include - #include - #include - #include -@@ -4990,7 +4991,8 @@ static int of_pci_bus_find_domain_nr(struct device *parent) - - int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent) - { -- return of_pci_bus_find_domain_nr(parent); -+ return acpi_disabled ? of_pci_bus_find_domain_nr(parent) : -+ acpi_pci_bus_find_domain_nr(bus); - } - #endif - #endif -diff --git a/include/linux/pci.h b/include/linux/pci.h -index 48839e8..49ba8af 100644 ---- a/include/linux/pci.h -+++ b/include/linux/pci.h -@@ -1390,6 +1390,13 @@ static inline int pci_domain_nr(struct pci_bus *bus) - { - return bus->domain_nr; - } -+/* Arch specific ACPI hook to set-up domain number */ -+#ifdef CONFIG_ACPI -+int acpi_pci_bus_find_domain_nr(struct pci_bus *bus); -+#else -+static inline int acpi_pci_bus_find_domain_nr(struct pci_bus *bus) -+{ return 0; } -+#endif - int pci_bus_find_domain_nr(struct pci_bus *bus, struct device *parent); - #endif - --- -2.7.4 - -From bb06753d2e163d8100a017f06a6d9dd195d68a76 Mon Sep 17 00:00:00 2001 -From: Tomasz Nowicki -Date: Fri, 10 Jun 2016 21:55:17 +0200 -Subject: [PATCH 09/11] ARM64/PCI: ACPI support for legacy IRQs parsing and - consolidation with DT code - -To enable PCI legacy IRQs on platforms booting with ACPI, arch code -should include ACPI specific callbacks that parse and set-up the -device IRQ number, equivalent to the DT boot path. Owing to the current -ACPI core scan handlers implementation, ACPI PCI legacy IRQs bindings -cannot be parsed at device add time, since that would trigger ACPI scan -handlers ordering issues depending on how the ACPI tables are defined. - -To solve this problem and consolidate FW PCI legacy IRQs parsing in -one single pcibios callback (pending final removal), this patch moves -DT PCI IRQ parsing to the pcibios_alloc_irq() callback (called by -PCI core code at device probe time) and adds ACPI PCI legacy IRQs -parsing to the same callback too, so that FW PCI legacy IRQs parsing -is confined in one single arch callback that can be easily removed -when code parsing PCI legacy IRQs is consolidated and moved to core -PCI code. - -Signed-off-by: Tomasz Nowicki -Suggested-by: Lorenzo Pieralisi ---- - arch/arm64/kernel/pci.c | 11 ++++++++--- - 1 file changed, 8 insertions(+), 3 deletions(-) - -diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c -index d5d3d26..b3b8a2c 100644 ---- a/arch/arm64/kernel/pci.c -+++ b/arch/arm64/kernel/pci.c -@@ -51,11 +51,16 @@ int pcibios_enable_device(struct pci_dev *dev, int mask) - } - - /* -- * Try to assign the IRQ number from DT when adding a new device -+ * Try to assign the IRQ number when probing a new device - */ --int pcibios_add_device(struct pci_dev *dev) -+int pcibios_alloc_irq(struct pci_dev *dev) - { -- dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); -+ if (acpi_disabled) -+ dev->irq = of_irq_parse_and_map_pci(dev, 0, 0); -+#ifdef CONFIG_ACPI -+ else -+ return acpi_pci_irq_enable(dev); -+#endif - - return 0; - } --- -2.7.4 - -From b6e298840f532192a589f8ade128dec3fef3a4c6 Mon Sep 17 00:00:00 2001 -From: Tomasz Nowicki -Date: Fri, 10 Jun 2016 21:55:18 +0200 -Subject: [PATCH 10/11] ARM64/PCI: Implement ACPI low-level calls to access - PCI_Config region from AML - -ACPI spec6.1 - chapter: 5.5.2.4 defines OperationRegion (Declare Operation -Region). Following the spec: " [...] An Operation Region is a specific -region of operation within an address space that is declared as a subset -of the entire address space using a starting address (offset) and a length. -Control methods must have exclusive access to any address accessed via -fields declared in Operation Regions. [...]". - -OperationRegion allows to declare various of operation region address space -identifiers including PCI_Config. PCI_Config is meant to access PCI -configuration space from the ASL. So every time ASL opcode operates -on PCI_Config space region, ASL interpreter dispatches accesses to OS -low-level calls - raw_pci_write() and raw_pci_read() for Linux - so-called -ACPI RAW accessors. - -In order to support PCI_Config operation region, implement mentioned -raw_pci_write() and raw_pci_read() calls so they find associated bus -and call read/write ops. - -Waiting for clarification in the ACPI specifications in relation -to PCI_Config space handling before PCI bus enumeration is completed, -current code does not support PCI_Config region accesses before PCI bus -enumeration whilst providing full AML PCI_Config access availability -when the PCI bus enumeration is completed by the kernel so that -RAW accessors can look-up PCI operations through the struct pci_bus -associated with a PCI bus. - -Signed-off-by: Tomasz Nowicki -Signed-off-by: Jayachandran C -Reviewed-by: Lorenzo Pieralisi ---- - arch/arm64/kernel/pci.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c -index b3b8a2c..328f857 100644 ---- a/arch/arm64/kernel/pci.c -+++ b/arch/arm64/kernel/pci.c -@@ -71,13 +71,21 @@ int pcibios_alloc_irq(struct pci_dev *dev) - int raw_pci_read(unsigned int domain, unsigned int bus, - unsigned int devfn, int reg, int len, u32 *val) - { -- return -ENXIO; -+ struct pci_bus *b = pci_find_bus(domain, bus); -+ -+ if (!b) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ return b->ops->read(b, devfn, reg, len, val); - } - - int raw_pci_write(unsigned int domain, unsigned int bus, - unsigned int devfn, int reg, int len, u32 val) - { -- return -ENXIO; -+ struct pci_bus *b = pci_find_bus(domain, bus); -+ -+ if (!b) -+ return PCIBIOS_DEVICE_NOT_FOUND; -+ return b->ops->write(b, devfn, reg, len, val); - } - - #ifdef CONFIG_NUMA --- -2.7.4 - -From 3b8cff3fa89ba3ef6f1cf09a0667aa470b7fad0b Mon Sep 17 00:00:00 2001 -From: Tomasz Nowicki -Date: Fri, 10 Jun 2016 21:55:19 +0200 -Subject: [PATCH 11/11] ARM64/PCI: Support for ACPI based PCI host controller - -Implement pci_acpi_scan_root and other arch-specific call so that ARM64 -can start using ACPI to setup and enumerate PCI buses. - -Prior to buses enumeration the pci_acpi_scan_root() implementation looks -for configuration space start address (obtained through ACPI _CBA method or -MCFG interface). If succeed, it uses ECAM library to create new mapping. -Then it attaches generic ECAM ops (pci_generic_ecam_ops) which are used -for accessing configuration space later on. - -On ARM64, we need to use generic domains (CONFIG_PCI_DOMAINS_GENERIC). -In order to achieve that for ACPI case implement -acpi_pci_bus_find_domain_nr() body so that it retrieves pci_config_window -structure from bus sysdata and eventually gets domain number from -acpi_pci_root structure. - -ACPI requires to run acpi_pci_{add|remove}_bus while new PCI bus is created. -This allows to do some ACPI-specific additional configuration, like -PCI hotplug slot enumeration. In order to fulfill these requirements, -we implement arch-specific pcibios_{add|remove}_bus calls -and call acpi_pci_{add|remove}_bus from there. - -Signed-off-by: Tomasz Nowicki -Signed-off-by: Jayachandran C -Reviewed-by: Lorenzo Pieralisi ---- - arch/arm64/Kconfig | 2 + - arch/arm64/kernel/pci.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++-- - 2 files changed, 115 insertions(+), 3 deletions(-) - -diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig -index 5a0a691..4806cde 100644 ---- a/arch/arm64/Kconfig -+++ b/arch/arm64/Kconfig -@@ -3,6 +3,7 @@ config ARM64 - select ACPI_CCA_REQUIRED if ACPI - select ACPI_GENERIC_GSI if ACPI - select ACPI_REDUCED_HARDWARE_ONLY if ACPI -+ select ACPI_MCFG if ACPI - select ARCH_HAS_DEVMEM_IS_ALLOWED - select ARCH_HAS_ACPI_TABLE_UPGRADE if ACPI - select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE -@@ -96,6 +97,7 @@ config ARM64 - select OF_EARLY_FLATTREE - select OF_NUMA if NUMA && OF - select OF_RESERVED_MEM -+ select PCI_ECAM if ACPI - select PERF_USE_VMALLOC - select POWER_RESET - select POWER_SUPPLY -diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c -index 328f857..94cd43c 100644 ---- a/arch/arm64/kernel/pci.c -+++ b/arch/arm64/kernel/pci.c -@@ -18,6 +18,8 @@ - #include - #include - #include -+#include -+#include - #include - - /* -@@ -100,15 +102,123 @@ EXPORT_SYMBOL(pcibus_to_node); - - #ifdef CONFIG_ACPI - -+struct acpi_pci_generic_root_info { -+ struct acpi_pci_root_info common; -+ struct pci_config_window *cfg; /* config space mapping */ -+}; -+ - int acpi_pci_bus_find_domain_nr(struct pci_bus *bus) - { -+ struct pci_config_window *cfg = bus->sysdata; -+ struct acpi_device *adev = to_acpi_device(cfg->parent); -+ struct acpi_pci_root *root = acpi_driver_data(adev); -+ -+ return root->segment; -+} -+ -+int pcibios_root_bridge_prepare(struct pci_host_bridge *bridge) -+{ -+ if (!acpi_disabled) { -+ struct pci_config_window *cfg = bridge->bus->sysdata; -+ struct acpi_device *adev = to_acpi_device(cfg->parent); -+ ACPI_COMPANION_SET(&bridge->dev, adev); -+ } -+ - return 0; - } - --/* Root bridge scanning */ -+/* -+ * Lookup the bus range for the domain in MCFG, and set up config space -+ * mapping. -+ */ -+static struct pci_config_window * -+pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) -+{ -+ struct resource *bus_res = &root->secondary; -+ u16 seg = root->segment; -+ struct pci_config_window *cfg; -+ struct resource cfgres; -+ unsigned int bsz; -+ -+ /* Use address from _CBA if present, otherwise lookup MCFG */ -+ if (!root->mcfg_addr) -+ root->mcfg_addr = pci_mcfg_lookup(seg, bus_res); -+ -+ if (!root->mcfg_addr) { -+ dev_err(&root->device->dev, "%04x:%pR ECAM region not found\n", -+ seg, bus_res); -+ return NULL; -+ } -+ -+ bsz = 1 << pci_generic_ecam_ops.bus_shift; -+ cfgres.start = root->mcfg_addr + bus_res->start * bsz; -+ cfgres.end = cfgres.start + resource_size(bus_res) * bsz - 1; -+ cfgres.flags = IORESOURCE_MEM; -+ cfg = pci_ecam_create(&root->device->dev, &cfgres, bus_res, -+ &pci_generic_ecam_ops); -+ if (IS_ERR(cfg)) { -+ dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n", -+ seg, bus_res, PTR_ERR(cfg)); -+ return NULL; -+ } -+ -+ return cfg; -+} -+ -+/* release_info: free resources allocated by init_info */ -+static void pci_acpi_generic_release_info(struct acpi_pci_root_info *ci) -+{ -+ struct acpi_pci_generic_root_info *ri; -+ -+ ri = container_of(ci, struct acpi_pci_generic_root_info, common); -+ pci_ecam_free(ri->cfg); -+ kfree(ri); -+} -+ -+static struct acpi_pci_root_ops acpi_pci_root_ops = { -+ .release_info = pci_acpi_generic_release_info, -+}; -+ -+/* Interface called from ACPI code to setup PCI host controller */ - struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root) - { -- /* TODO: Should be revisited when implementing PCI on ACPI */ -- return NULL; -+ int node = acpi_get_node(root->device->handle); -+ struct acpi_pci_generic_root_info *ri; -+ struct pci_bus *bus, *child; -+ -+ ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node); -+ if (!ri) -+ return NULL; -+ -+ ri->cfg = pci_acpi_setup_ecam_mapping(root); -+ if (!ri->cfg) { -+ kfree(ri); -+ return NULL; -+ } -+ -+ acpi_pci_root_ops.pci_ops = &ri->cfg->ops->pci_ops; -+ bus = acpi_pci_root_create(root, &acpi_pci_root_ops, &ri->common, -+ ri->cfg); -+ if (!bus) -+ return NULL; -+ -+ pci_bus_size_bridges(bus); -+ pci_bus_assign_resources(bus); -+ -+ list_for_each_entry(child, &bus->children, node) -+ pcie_bus_configure_settings(child); -+ -+ return bus; -+} -+ -+void pcibios_add_bus(struct pci_bus *bus) -+{ -+ acpi_pci_add_bus(bus); - } -+ -+void pcibios_remove_bus(struct pci_bus *bus) -+{ -+ acpi_pci_remove_bus(bus); -+} -+ - #endif --- -2.7.4 - diff --git a/arm64-pcie-quirks-xgene.patch b/arm64-pcie-quirks-xgene.patch index 8e6805df6..9defc1763 100644 --- a/arm64-pcie-quirks-xgene.patch +++ b/arm64-pcie-quirks-xgene.patch @@ -1,13 +1,13 @@ -From 767b70aa55d013f0c7589955f410d488fed5776a Mon Sep 17 00:00:00 2001 +From 965e95a91066290f6555546f066a6e2aaba1199e Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 5 Jul 2016 23:49:39 +0100 -Subject: [PATCH 1/4] Some platforms may not be fully compliant with generic - set of PCI config accessors. For these cases we implement the way to - overwrite accessors set. Algorithm traverses available quirk list, matches - against tuple and returns - corresponding PCI config ops. oem_id and oem_table_id come from MCFG table - standard header. All quirks can be defined using DECLARE_ACPI_MCFG_FIXUP() - macro and kept self contained. Example: +Subject: [PATCH] Some platforms may not be fully compliant with generic set of + PCI config accessors. For these cases we implement the way to overwrite + accessors set. Algorithm traverses available quirk list, matches against + tuple and returns corresponding + PCI config ops. oem_id and oem_table_id come from MCFG table standard header. + All quirks can be defined using DECLARE_ACPI_MCFG_FIXUP() macro and kept self + contained. Example: /* Custom PCI config ops */ static struct pci_generic_ecam_ops foo_pci_ops = { @@ -30,7 +30,7 @@ Signed-off-by: Dongdong Liu 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c -index d3c3e85..deb0077 100644 +index b5b376e..a5c9067 100644 --- a/drivers/acpi/pci_mcfg.c +++ b/drivers/acpi/pci_mcfg.c @@ -22,6 +22,10 @@ @@ -45,7 +45,7 @@ index d3c3e85..deb0077 100644 /* Structure to hold entries from the MCFG table */ struct mcfg_entry { @@ -35,6 +39,38 @@ struct mcfg_entry { - /* List to save mcfg entries */ + /* List to save MCFG entries */ static LIST_HEAD(pci_mcfg_list); +extern struct pci_cfg_fixup __start_acpi_mcfg_fixups[]; @@ -103,10 +103,10 @@ index d3c3e85..deb0077 100644 arr = kcalloc(n, sizeof(*arr), GFP_KERNEL); if (!arr) diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h -index 6a67ab9..43604fc 100644 +index 2456397..c49bd36 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h -@@ -300,6 +300,13 @@ +@@ -308,6 +308,13 @@ VMLINUX_SYMBOL(__end_pci_fixups_suspend_late) = .; \ } \ \ @@ -159,12 +159,12 @@ index 7d63a66..c8a6559 100644 extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root, struct acpi_pci_root_ops *ops, -- -2.7.4 +2.9.2 -From 4f86a9b006b25dd7336043dab26058ed6fb2802d Mon Sep 17 00:00:00 2001 +From 817d09d7650319a827f00bd3b4c9b407d3977ba0 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 5 Jul 2016 23:52:46 +0100 -Subject: [PATCH 2/4] pci_generic_ecam_ops is used by default. Since there are +Subject: [PATCH] pci_generic_ecam_ops is used by default. Since there are platforms which have non-compliant ECAM space we need to overwrite these accessors prior to PCI buses enumeration. In order to do that we call pci_mcfg_get_ops to retrieve pci_ecam_ops structure so that we can use proper @@ -178,10 +178,10 @@ Signed-off-by: Tomasz Nowicki 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/arch/arm64/kernel/pci.c b/arch/arm64/kernel/pci.c -index 94cd43c..a891bda 100644 +index acf3872..ec513f1 100644 --- a/arch/arm64/kernel/pci.c +++ b/arch/arm64/kernel/pci.c -@@ -139,6 +139,7 @@ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) +@@ -126,6 +126,7 @@ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) struct pci_config_window *cfg; struct resource cfgres; unsigned int bsz; @@ -189,7 +189,7 @@ index 94cd43c..a891bda 100644 /* Use address from _CBA if present, otherwise lookup MCFG */ if (!root->mcfg_addr) -@@ -150,12 +151,12 @@ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) +@@ -137,12 +138,12 @@ pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root) return NULL; } @@ -206,12 +206,12 @@ index 94cd43c..a891bda 100644 dev_err(&root->device->dev, "%04x:%pR error %ld mapping ECAM\n", seg, bus_res, PTR_ERR(cfg)); -- -2.7.4 +2.9.2 -From cbdbd697bd6d716eb9d1705ee55445432e73eabb Mon Sep 17 00:00:00 2001 +From ac5cff2e2304a1969e39e967567aa41cade1839f Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 5 Jul 2016 23:53:59 +0100 -Subject: [PATCH 3/4] The ECAM quirk matching criteria per the discussion on +Subject: [PATCH] The ECAM quirk matching criteria per the discussion on https://lkml.org/lkml/2016/6/13/944 includes: OEM ID, OEM Table ID and OEM Revision. So this patch adds OEM Table ID into the check to match platform specific ECAM quirks as well. @@ -227,7 +227,7 @@ Signed-off-by: Duc Dang 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/pci_mcfg.c b/drivers/acpi/pci_mcfg.c -index deb0077..307ca9a 100644 +index a5c9067..5137d16 100644 --- a/drivers/acpi/pci_mcfg.c +++ b/drivers/acpi/pci_mcfg.c @@ -62,9 +62,12 @@ struct pci_ecam_ops *pci_mcfg_get_ops(struct acpi_pci_root *root) @@ -274,12 +274,12 @@ index c8a6559..5148c8d 100644 extern int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info); extern struct pci_bus *acpi_pci_root_create(struct acpi_pci_root *root, -- -2.7.4 +2.9.2 -From 78766cf255bc6aafac2f57372a0446f78322da19 Mon Sep 17 00:00:00 2001 +From b9c1592c6b615da0c26168c5c3e0f8fc256a23ca Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Tue, 5 Jul 2016 23:55:11 +0100 -Subject: [PATCH 4/4] X-Gene PCIe controller does not fully support ECAM. This +Subject: [PATCH] X-Gene PCIe controller does not fully support ECAM. This patch adds required ECAM fixup to allow X-Gene PCIe controller to be functional in ACPI boot mode. @@ -291,10 +291,10 @@ Signed-off-by: Duc Dang create mode 100644 drivers/pci/host/pci-xgene-ecam.c diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile -index 9c8698e..3480696 100644 +index 8843410..af4f505 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile -@@ -14,7 +14,7 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o +@@ -15,7 +15,7 @@ obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o obj-$(CONFIG_PCI_KEYSTONE) += pci-keystone-dw.o pci-keystone.o obj-$(CONFIG_PCIE_XILINX) += pcie-xilinx.o obj-$(CONFIG_PCIE_XILINX_NWL) += pcie-xilinx-nwl.o @@ -504,5 +504,5 @@ index 0000000..1bea63f + PCI_MCFG_DOMAIN_ANY, PCI_MCFG_BUS_ANY); +#endif -- -2.7.4 +2.9.2 diff --git a/config-arm-generic b/config-arm-generic index 20032cb49..cc5314aa9 100644 --- a/config-arm-generic +++ b/config-arm-generic @@ -145,6 +145,7 @@ CONFIG_PHY_MVEBU_SATA=y CONFIG_AHCI_MVEBU=m # CONFIG_CACHE_FEROCEON_L2 is not set # CONFIG_CACHE_FEROCEON_L2_WRITETHROUGH is not set +# CONFIG_PCI_AARDVARK is not set # Rockchips CONFIG_ARCH_ROCKCHIP=y diff --git a/config-armv7-generic b/config-armv7-generic index cc284c566..27e416e41 100644 --- a/config-armv7-generic +++ b/config-armv7-generic @@ -540,6 +540,7 @@ CONFIG_MTD_NAND_PXA3xx=m CONFIG_MTD_NAND_RICOH=m CONFIG_MTD_NAND_TMIO=m # CONFIG_MTD_NAND_BRCMNAND is not set +# CONFIG_MTD_NAND_MTK is not set # CONFIG_MTD_MT81xx_NOR is not set CONFIG_MTD_SPI_NOR=m # CONFIG_MTD_SPI_NOR_USE_4K_SECTORS is not set @@ -759,6 +760,7 @@ CONFIG_R8188EU=m # CONFIG_DM9000 is not set # CONFIG_MTD_AFS_PARTS is not set # CONFIG_SPI_PXA2XX is not set +# CONFIG_SPI_CADENCE_QUADSPI is not set # CONFIG_DEPRECATED_PARAM_STRUCT is not set # CONFIG_LATTICE_ECP3_CONFIG is not set # CONFIG_SERIAL_8250_EM is not set diff --git a/config-generic b/config-generic index 33497be0f..005adb193 100644 --- a/config-generic +++ b/config-generic @@ -9,6 +9,7 @@ CONFIG_HOTPLUG_CPU=y CONFIG_LOCALVERSION="" CONFIG_CROSS_COMPILE="" CONFIG_DEFAULT_HOSTNAME="(none)" +# CONFIG_GCC_PLUGINS is not set # # Code maturity level options @@ -113,7 +114,7 @@ CONFIG_HOTPLUG_PCI=y # CONFIG_HOTPLUG_PCI_SHPC is not set CONFIG_HOTPLUG_PCI_PCIE=y # CONFIG_PCIE_DW_PLAT is not set -CONFIG_PCIE_DPC=m +CONFIG_PCIE_DPC=y # CONFIG_SGI_IOC4 is not set diff --git a/gitrev b/gitrev index 5f0ea8f7a..04f182a74 100644 --- a/gitrev +++ b/gitrev @@ -1 +1 @@ -731c7d3a205ba89b475b2aa71b5f13dd6ae3de56 +d52bd54db8be8999df6df5a776f38c4f8b5e9cea diff --git a/kernel.spec b/kernel.spec index 95fbc58c7..01f745b08 100644 --- a/kernel.spec +++ b/kernel.spec @@ -69,7 +69,7 @@ Summary: The Linux kernel # The rc snapshot level %define rcrev 0 # The git snapshot level -%define gitrev 4 +%define gitrev 5 # Set rpm version accordingly %define rpmversion 4.%{upstream_sublevel}.0 %endif @@ -506,7 +506,6 @@ Patch422: geekbox-v4-device-tree-support.patch # This has major conflicts and needs to be rebased # Patch423: Initial-AllWinner-A64-and-PINE64-support.patch -Patch424: arm64-pcie-acpi.patch Patch425: arm64-pcie-quirks-xgene.patch # http://www.spinics.net/lists/linux-tegra/msg26029.html @@ -605,10 +604,6 @@ Patch835: 0001-Work-around-for-addition-of-metag-def-but-not-reloca.patch # https://lists.fedoraproject.org/archives/list/kernel@lists.fedoraproject.org/message/A4YCP7OGMX6JLFT5V44H57GOMAQLC3M4/ Patch839: drm-i915-Acquire-audio-powerwell-for-HD-Audio-regist.patch -#CVE-2016-5412 rhbz 1349916 1361040 -Patch842: kvm-ppc-Book3S-HV-Pull-out-TM-state-save.patch -Patch843: kvm-ppc-Book3S-HV-Save-restore-TM-state.patch - # END OF PATCH DEFINITIONS %endif @@ -2143,6 +2138,9 @@ fi # # %changelog +* Wed Aug 03 2016 Laura Abbott - 4.8.0-0.rc0.git5.1 +- Linux v4.7-11470-gd52bd54 + * Tue Aug 2 2016 Hans de Goede - Sync skylake hdaudio __unclaimed_reg WARN_ON fix with latest upstream version - Drop drm-i915-skl-Add-support-for-the-SAGV-fix-underrun-hangs.patch for now diff --git a/kvm-ppc-Book3S-HV-Pull-out-TM-state-save.patch b/kvm-ppc-Book3S-HV-Pull-out-TM-state-save.patch deleted file mode 100644 index b4259375f..000000000 --- a/kvm-ppc-Book3S-HV-Pull-out-TM-state-save.patch +++ /dev/null @@ -1,506 +0,0 @@ -Subject: [PATCH 1/2] KVM: PPC: Book3S HV: Pull out TM state save/restore into separate procedures -From: Paul Mackerras -Date: 2016-07-28 6:11:18 - -This moves the transactional memory state save and restore sequences -out of the guest entry/exit paths into separate procedures. This is -so that these sequences can be used in going into and out of nap -in a subsequent patch. - -The only code changes here are (a) saving and restore LR on the -stack, since these new procedures get called with a bl instruction, -(b) explicitly saving r1 into the PACA instead of assuming that -HSTATE_HOST_R1(r13) is already set, and (c) removing an unnecessary -and redundant setting of MSR[TM] that should have been removed by -commit 9d4d0bdd9e0a ("KVM: PPC: Book3S HV: Add transactional memory -support", 2013-09-24) but wasn't. - -Cc: stable@vger.kernel.org # v3.15+ -Signed-off-by: Paul Mackerras ---- - arch/powerpc/kvm/book3s_hv_rmhandlers.S | 449 +++++++++++++++++--------------- - 1 file changed, 237 insertions(+), 212 deletions(-) - -diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S -index 0d246fc..cfa4031 100644 ---- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S -+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S -@@ -689,112 +689,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) - - #ifdef CONFIG_PPC_TRANSACTIONAL_MEM - BEGIN_FTR_SECTION -- b skip_tm --END_FTR_SECTION_IFCLR(CPU_FTR_TM) -- -- /* Turn on TM/FP/VSX/VMX so we can restore them. */ -- mfmsr r5 -- li r6, MSR_TM >> 32 -- sldi r6, r6, 32 -- or r5, r5, r6 -- ori r5, r5, MSR_FP -- oris r5, r5, (MSR_VEC | MSR_VSX)@h -- mtmsrd r5 -- -- /* -- * The user may change these outside of a transaction, so they must -- * always be context switched. -- */ -- ld r5, VCPU_TFHAR(r4) -- ld r6, VCPU_TFIAR(r4) -- ld r7, VCPU_TEXASR(r4) -- mtspr SPRN_TFHAR, r5 -- mtspr SPRN_TFIAR, r6 -- mtspr SPRN_TEXASR, r7 -- -- ld r5, VCPU_MSR(r4) -- rldicl. r5, r5, 64 - MSR_TS_S_LG, 62 -- beq skip_tm /* TM not active in guest */ -- -- /* Make sure the failure summary is set, otherwise we'll program check -- * when we trechkpt. It's possible that this might have been not set -- * on a kvmppc_set_one_reg() call but we shouldn't let this crash the -- * host. -- */ -- oris r7, r7, (TEXASR_FS)@h -- mtspr SPRN_TEXASR, r7 -- -- /* -- * We need to load up the checkpointed state for the guest. -- * We need to do this early as it will blow away any GPRs, VSRs and -- * some SPRs. -- */ -- -- mr r31, r4 -- addi r3, r31, VCPU_FPRS_TM -- bl load_fp_state -- addi r3, r31, VCPU_VRS_TM -- bl load_vr_state -- mr r4, r31 -- lwz r7, VCPU_VRSAVE_TM(r4) -- mtspr SPRN_VRSAVE, r7 -- -- ld r5, VCPU_LR_TM(r4) -- lwz r6, VCPU_CR_TM(r4) -- ld r7, VCPU_CTR_TM(r4) -- ld r8, VCPU_AMR_TM(r4) -- ld r9, VCPU_TAR_TM(r4) -- mtlr r5 -- mtcr r6 -- mtctr r7 -- mtspr SPRN_AMR, r8 -- mtspr SPRN_TAR, r9 -- -- /* -- * Load up PPR and DSCR values but don't put them in the actual SPRs -- * till the last moment to avoid running with userspace PPR and DSCR for -- * too long. -- */ -- ld r29, VCPU_DSCR_TM(r4) -- ld r30, VCPU_PPR_TM(r4) -- -- std r2, PACATMSCRATCH(r13) /* Save TOC */ -- -- /* Clear the MSR RI since r1, r13 are all going to be foobar. */ -- li r5, 0 -- mtmsrd r5, 1 -- -- /* Load GPRs r0-r28 */ -- reg = 0 -- .rept 29 -- ld reg, VCPU_GPRS_TM(reg)(r31) -- reg = reg + 1 -- .endr -- -- mtspr SPRN_DSCR, r29 -- mtspr SPRN_PPR, r30 -- -- /* Load final GPRs */ -- ld 29, VCPU_GPRS_TM(29)(r31) -- ld 30, VCPU_GPRS_TM(30)(r31) -- ld 31, VCPU_GPRS_TM(31)(r31) -- -- /* TM checkpointed state is now setup. All GPRs are now volatile. */ -- TRECHKPT -- -- /* Now let's get back the state we need. */ -- HMT_MEDIUM -- GET_PACA(r13) -- ld r29, HSTATE_DSCR(r13) -- mtspr SPRN_DSCR, r29 -- ld r4, HSTATE_KVM_VCPU(r13) -- ld r1, HSTATE_HOST_R1(r13) -- ld r2, PACATMSCRATCH(r13) -- -- /* Set the MSR RI since we have our registers back. */ -- li r5, MSR_RI -- mtmsrd r5, 1 --skip_tm: -+ bl kvmppc_restore_tm -+END_FTR_SECTION_IFSET(CPU_FTR_TM) - #endif - - /* Load guest PMU registers */ -@@ -875,12 +771,6 @@ BEGIN_FTR_SECTION - /* Skip next section on POWER7 */ - b 8f - END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) -- /* Turn on TM so we can access TFHAR/TFIAR/TEXASR */ -- mfmsr r8 -- li r0, 1 -- rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG -- mtmsrd r8 -- - /* Load up POWER8-specific registers */ - ld r5, VCPU_IAMR(r4) - lwz r6, VCPU_PSPB(r4) -@@ -1470,106 +1360,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) - - #ifdef CONFIG_PPC_TRANSACTIONAL_MEM - BEGIN_FTR_SECTION -- b 2f --END_FTR_SECTION_IFCLR(CPU_FTR_TM) -- /* Turn on TM. */ -- mfmsr r8 -- li r0, 1 -- rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG -- mtmsrd r8 -- -- ld r5, VCPU_MSR(r9) -- rldicl. r5, r5, 64 - MSR_TS_S_LG, 62 -- beq 1f /* TM not active in guest. */ -- -- li r3, TM_CAUSE_KVM_RESCHED -- -- /* Clear the MSR RI since r1, r13 are all going to be foobar. */ -- li r5, 0 -- mtmsrd r5, 1 -- -- /* All GPRs are volatile at this point. */ -- TRECLAIM(R3) -- -- /* Temporarily store r13 and r9 so we have some regs to play with */ -- SET_SCRATCH0(r13) -- GET_PACA(r13) -- std r9, PACATMSCRATCH(r13) -- ld r9, HSTATE_KVM_VCPU(r13) -- -- /* Get a few more GPRs free. */ -- std r29, VCPU_GPRS_TM(29)(r9) -- std r30, VCPU_GPRS_TM(30)(r9) -- std r31, VCPU_GPRS_TM(31)(r9) -- -- /* Save away PPR and DSCR soon so don't run with user values. */ -- mfspr r31, SPRN_PPR -- HMT_MEDIUM -- mfspr r30, SPRN_DSCR -- ld r29, HSTATE_DSCR(r13) -- mtspr SPRN_DSCR, r29 -- -- /* Save all but r9, r13 & r29-r31 */ -- reg = 0 -- .rept 29 -- .if (reg != 9) && (reg != 13) -- std reg, VCPU_GPRS_TM(reg)(r9) -- .endif -- reg = reg + 1 -- .endr -- /* ... now save r13 */ -- GET_SCRATCH0(r4) -- std r4, VCPU_GPRS_TM(13)(r9) -- /* ... and save r9 */ -- ld r4, PACATMSCRATCH(r13) -- std r4, VCPU_GPRS_TM(9)(r9) -- -- /* Reload stack pointer and TOC. */ -- ld r1, HSTATE_HOST_R1(r13) -- ld r2, PACATOC(r13) -- -- /* Set MSR RI now we have r1 and r13 back. */ -- li r5, MSR_RI -- mtmsrd r5, 1 -- -- /* Save away checkpinted SPRs. */ -- std r31, VCPU_PPR_TM(r9) -- std r30, VCPU_DSCR_TM(r9) -- mflr r5 -- mfcr r6 -- mfctr r7 -- mfspr r8, SPRN_AMR -- mfspr r10, SPRN_TAR -- std r5, VCPU_LR_TM(r9) -- stw r6, VCPU_CR_TM(r9) -- std r7, VCPU_CTR_TM(r9) -- std r8, VCPU_AMR_TM(r9) -- std r10, VCPU_TAR_TM(r9) -- -- /* Restore r12 as trap number. */ -- lwz r12, VCPU_TRAP(r9) -- -- /* Save FP/VSX. */ -- addi r3, r9, VCPU_FPRS_TM -- bl store_fp_state -- addi r3, r9, VCPU_VRS_TM -- bl store_vr_state -- mfspr r6, SPRN_VRSAVE -- stw r6, VCPU_VRSAVE_TM(r9) --1: -- /* -- * We need to save these SPRs after the treclaim so that the software -- * error code is recorded correctly in the TEXASR. Also the user may -- * change these outside of a transaction, so they must always be -- * context switched. -- */ -- mfspr r5, SPRN_TFHAR -- mfspr r6, SPRN_TFIAR -- mfspr r7, SPRN_TEXASR -- std r5, VCPU_TFHAR(r9) -- std r6, VCPU_TFIAR(r9) -- std r7, VCPU_TEXASR(r9) --2: -+ bl kvmppc_save_tm -+END_FTR_SECTION_IFSET(CPU_FTR_TM) - #endif - - /* Increment yield count if they have a VPA */ -@@ -2694,6 +2486,239 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) - mr r4,r31 - blr - -+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -+/* -+ * Save transactional state and TM-related registers. -+ * Called with r9 pointing to the vcpu struct. -+ * This can modify all checkpointed registers, but -+ * restores r1, r2 and r9 (vcpu pointer) before exit. -+ */ -+kvmppc_save_tm: -+ mflr r0 -+ std r0, PPC_LR_STKOFF(r1) -+ -+ /* Turn on TM. */ -+ mfmsr r8 -+ li r0, 1 -+ rldimi r8, r0, MSR_TM_LG, 63-MSR_TM_LG -+ mtmsrd r8 -+ -+ ld r5, VCPU_MSR(r9) -+ rldicl. r5, r5, 64 - MSR_TS_S_LG, 62 -+ beq 1f /* TM not active in guest. */ -+ -+ std r1, HSTATE_HOST_R1(r13) -+ li r3, TM_CAUSE_KVM_RESCHED -+ -+ /* Clear the MSR RI since r1, r13 are all going to be foobar. */ -+ li r5, 0 -+ mtmsrd r5, 1 -+ -+ /* All GPRs are volatile at this point. */ -+ TRECLAIM(R3) -+ -+ /* Temporarily store r13 and r9 so we have some regs to play with */ -+ SET_SCRATCH0(r13) -+ GET_PACA(r13) -+ std r9, PACATMSCRATCH(r13) -+ ld r9, HSTATE_KVM_VCPU(r13) -+ -+ /* Get a few more GPRs free. */ -+ std r29, VCPU_GPRS_TM(29)(r9) -+ std r30, VCPU_GPRS_TM(30)(r9) -+ std r31, VCPU_GPRS_TM(31)(r9) -+ -+ /* Save away PPR and DSCR soon so don't run with user values. */ -+ mfspr r31, SPRN_PPR -+ HMT_MEDIUM -+ mfspr r30, SPRN_DSCR -+ ld r29, HSTATE_DSCR(r13) -+ mtspr SPRN_DSCR, r29 -+ -+ /* Save all but r9, r13 & r29-r31 */ -+ reg = 0 -+ .rept 29 -+ .if (reg != 9) && (reg != 13) -+ std reg, VCPU_GPRS_TM(reg)(r9) -+ .endif -+ reg = reg + 1 -+ .endr -+ /* ... now save r13 */ -+ GET_SCRATCH0(r4) -+ std r4, VCPU_GPRS_TM(13)(r9) -+ /* ... and save r9 */ -+ ld r4, PACATMSCRATCH(r13) -+ std r4, VCPU_GPRS_TM(9)(r9) -+ -+ /* Reload stack pointer and TOC. */ -+ ld r1, HSTATE_HOST_R1(r13) -+ ld r2, PACATOC(r13) -+ -+ /* Set MSR RI now we have r1 and r13 back. */ -+ li r5, MSR_RI -+ mtmsrd r5, 1 -+ -+ /* Save away checkpinted SPRs. */ -+ std r31, VCPU_PPR_TM(r9) -+ std r30, VCPU_DSCR_TM(r9) -+ mflr r5 -+ mfcr r6 -+ mfctr r7 -+ mfspr r8, SPRN_AMR -+ mfspr r10, SPRN_TAR -+ std r5, VCPU_LR_TM(r9) -+ stw r6, VCPU_CR_TM(r9) -+ std r7, VCPU_CTR_TM(r9) -+ std r8, VCPU_AMR_TM(r9) -+ std r10, VCPU_TAR_TM(r9) -+ -+ /* Restore r12 as trap number. */ -+ lwz r12, VCPU_TRAP(r9) -+ -+ /* Save FP/VSX. */ -+ addi r3, r9, VCPU_FPRS_TM -+ bl store_fp_state -+ addi r3, r9, VCPU_VRS_TM -+ bl store_vr_state -+ mfspr r6, SPRN_VRSAVE -+ stw r6, VCPU_VRSAVE_TM(r9) -+1: -+ /* -+ * We need to save these SPRs after the treclaim so that the software -+ * error code is recorded correctly in the TEXASR. Also the user may -+ * change these outside of a transaction, so they must always be -+ * context switched. -+ */ -+ mfspr r5, SPRN_TFHAR -+ mfspr r6, SPRN_TFIAR -+ mfspr r7, SPRN_TEXASR -+ std r5, VCPU_TFHAR(r9) -+ std r6, VCPU_TFIAR(r9) -+ std r7, VCPU_TEXASR(r9) -+ -+ ld r0, PPC_LR_STKOFF(r1) -+ mtlr r0 -+ blr -+ -+/* -+ * Restore transactional state and TM-related registers. -+ * Called with r4 pointing to the vcpu struct. -+ * This potentially modifies all checkpointed registers. -+ * It restores r1, r2, r4 from the PACA. -+ */ -+kvmppc_restore_tm: -+ mflr r0 -+ std r0, PPC_LR_STKOFF(r1) -+ -+ /* Turn on TM/FP/VSX/VMX so we can restore them. */ -+ mfmsr r5 -+ li r6, MSR_TM >> 32 -+ sldi r6, r6, 32 -+ or r5, r5, r6 -+ ori r5, r5, MSR_FP -+ oris r5, r5, (MSR_VEC | MSR_VSX)@h -+ mtmsrd r5 -+ -+ /* -+ * The user may change these outside of a transaction, so they must -+ * always be context switched. -+ */ -+ ld r5, VCPU_TFHAR(r4) -+ ld r6, VCPU_TFIAR(r4) -+ ld r7, VCPU_TEXASR(r4) -+ mtspr SPRN_TFHAR, r5 -+ mtspr SPRN_TFIAR, r6 -+ mtspr SPRN_TEXASR, r7 -+ -+ ld r5, VCPU_MSR(r4) -+ rldicl. r5, r5, 64 - MSR_TS_S_LG, 62 -+ beqlr /* TM not active in guest */ -+ std r1, HSTATE_HOST_R1(r13) -+ -+ /* Make sure the failure summary is set, otherwise we'll program check -+ * when we trechkpt. It's possible that this might have been not set -+ * on a kvmppc_set_one_reg() call but we shouldn't let this crash the -+ * host. -+ */ -+ oris r7, r7, (TEXASR_FS)@h -+ mtspr SPRN_TEXASR, r7 -+ -+ /* -+ * We need to load up the checkpointed state for the guest. -+ * We need to do this early as it will blow away any GPRs, VSRs and -+ * some SPRs. -+ */ -+ -+ mr r31, r4 -+ addi r3, r31, VCPU_FPRS_TM -+ bl load_fp_state -+ addi r3, r31, VCPU_VRS_TM -+ bl load_vr_state -+ mr r4, r31 -+ lwz r7, VCPU_VRSAVE_TM(r4) -+ mtspr SPRN_VRSAVE, r7 -+ -+ ld r5, VCPU_LR_TM(r4) -+ lwz r6, VCPU_CR_TM(r4) -+ ld r7, VCPU_CTR_TM(r4) -+ ld r8, VCPU_AMR_TM(r4) -+ ld r9, VCPU_TAR_TM(r4) -+ mtlr r5 -+ mtcr r6 -+ mtctr r7 -+ mtspr SPRN_AMR, r8 -+ mtspr SPRN_TAR, r9 -+ -+ /* -+ * Load up PPR and DSCR values but don't put them in the actual SPRs -+ * till the last moment to avoid running with userspace PPR and DSCR for -+ * too long. -+ */ -+ ld r29, VCPU_DSCR_TM(r4) -+ ld r30, VCPU_PPR_TM(r4) -+ -+ std r2, PACATMSCRATCH(r13) /* Save TOC */ -+ -+ /* Clear the MSR RI since r1, r13 are all going to be foobar. */ -+ li r5, 0 -+ mtmsrd r5, 1 -+ -+ /* Load GPRs r0-r28 */ -+ reg = 0 -+ .rept 29 -+ ld reg, VCPU_GPRS_TM(reg)(r31) -+ reg = reg + 1 -+ .endr -+ -+ mtspr SPRN_DSCR, r29 -+ mtspr SPRN_PPR, r30 -+ -+ /* Load final GPRs */ -+ ld 29, VCPU_GPRS_TM(29)(r31) -+ ld 30, VCPU_GPRS_TM(30)(r31) -+ ld 31, VCPU_GPRS_TM(31)(r31) -+ -+ /* TM checkpointed state is now setup. All GPRs are now volatile. */ -+ TRECHKPT -+ -+ /* Now let's get back the state we need. */ -+ HMT_MEDIUM -+ GET_PACA(r13) -+ ld r29, HSTATE_DSCR(r13) -+ mtspr SPRN_DSCR, r29 -+ ld r4, HSTATE_KVM_VCPU(r13) -+ ld r1, HSTATE_HOST_R1(r13) -+ ld r2, PACATMSCRATCH(r13) -+ -+ /* Set the MSR RI since we have our registers back. */ -+ li r5, MSR_RI -+ mtmsrd r5, 1 -+ -+ ld r0, PPC_LR_STKOFF(r1) -+ mtlr r0 -+ blr -+#endif -+ - /* - * We come here if we get any exception or interrupt while we are - * executing host real mode code while in guest MMU context. --- -2.8.0.rc3 diff --git a/kvm-ppc-Book3S-HV-Save-restore-TM-state.patch b/kvm-ppc-Book3S-HV-Save-restore-TM-state.patch deleted file mode 100644 index f63aa795d..000000000 --- a/kvm-ppc-Book3S-HV-Save-restore-TM-state.patch +++ /dev/null @@ -1,67 +0,0 @@ -Subject: [PATCH 2/2] KVM: PPC: Book3S HV: Save/restore TM state in H_CEDE -From: Paul Mackerras -Date: 2016-07-28 6:11:19 - -It turns out that if the guest does a H_CEDE while the CPU is in -a transactional state, and the H_CEDE does a nap, and the nap -loses the architected state of the CPU (which is is allowed to do), -then we lose the checkpointed state of the virtual CPU. In addition, -the transactional-memory state recorded in the MSR gets reset back -to non-transactional, and when we try to return to the guest, we take -a TM bad thing type of program interrupt because we are trying to -transition from non-transactional to transactional with a hrfid -instruction, which is not permitted. - -The result of the program interrupt occurring at that point is that -the host CPU will hang in an infinite loop with interrupts disabled. -Thus this is a denial of service vulnerability in the host which can -be triggered by any guest (and depending on the guest kernel, it can -potentially triggered by unprivileged userspace in the guest). - -This vulnerability has been assigned the ID CVE-2016-5412. - -To fix this, we save the TM state before napping and restore it -on exit from the nap, when handling a H_CEDE in real mode. The -case where H_CEDE exits to host virtual mode is already OK (as are -other hcalls which exit to host virtual mode) because the exit -path saves the TM state. - -Cc: stable@vger.kernel.org # v3.15+ -Signed-off-by: Paul Mackerras ---- - arch/powerpc/kvm/book3s_hv_rmhandlers.S | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/arch/powerpc/kvm/book3s_hv_rmhandlers.S b/arch/powerpc/kvm/book3s_hv_rmhandlers.S -index cfa4031..543124f 100644 ---- a/arch/powerpc/kvm/book3s_hv_rmhandlers.S -+++ b/arch/powerpc/kvm/book3s_hv_rmhandlers.S -@@ -2093,6 +2093,13 @@ _GLOBAL(kvmppc_h_cede) /* r3 = vcpu pointer, r11 = msr, r13 = paca */ - /* save FP state */ - bl kvmppc_save_fp - -+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -+BEGIN_FTR_SECTION -+ ld r9, HSTATE_KVM_VCPU(r13) -+ bl kvmppc_save_tm -+END_FTR_SECTION_IFSET(CPU_FTR_TM) -+#endif -+ - /* - * Set DEC to the smaller of DEC and HDEC, so that we wake - * no later than the end of our timeslice (HDEC interrupts -@@ -2169,6 +2176,12 @@ kvm_end_cede: - bl kvmhv_accumulate_time - #endif - -+#ifdef CONFIG_PPC_TRANSACTIONAL_MEM -+BEGIN_FTR_SECTION -+ bl kvmppc_restore_tm -+END_FTR_SECTION_IFSET(CPU_FTR_TM) -+#endif -+ - /* load up FP state */ - bl kvmppc_load_fp - --- -2.8.0.rc3 diff --git a/sources b/sources index 3a0f73ab9..0035fb427 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ 5276563eb1f39a048e4a8a887408c031 linux-4.7.tar.xz fe259c02c75eec61d1aa4b1211f3c853 perf-man-4.7.tar.gz -6661b4dfc07bb1f534b89ad8a862543d patch-4.7-git3.xz +0578e1a487d8580174a3c5542687f8ca patch-4.7-git5.xz