diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:02:38 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-06 01:02:38 +0000 |
commit | 08b74a000942a380fe028845f92cd3a0dee827d5 (patch) | |
tree | aa78b4e12607c3e1fcce8d5cc42df4330792f118 /debian/patches | |
parent | Adding upstream version 4.19.249. (diff) | |
download | linux-debian.tar.xz linux-debian.zip |
Adding debian version 4.19.249-2.debian/4.19.249-2debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/patches')
261 files changed, 28237 insertions, 0 deletions
diff --git a/debian/patches/bugfix/all/PCI-ACPI-Evaluate-PCI-Boot-Configuration-_DSM.patch b/debian/patches/bugfix/all/PCI-ACPI-Evaluate-PCI-Boot-Configuration-_DSM.patch new file mode 100644 index 000000000..2172fa43d --- /dev/null +++ b/debian/patches/bugfix/all/PCI-ACPI-Evaluate-PCI-Boot-Configuration-_DSM.patch @@ -0,0 +1,80 @@ +From: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Date: Sat, 15 Jun 2019 10:23:57 +1000 +Subject: [PATCH 1/4] PCI/ACPI: Evaluate PCI Boot Configuration _DSM +Origin: https://git.kernel.org/linus/a78cf9657ba5426f54aa93a067c10d097944c082 + +Evaluate _DSM Function #5, the "PCI Boot Configuration" function. If the +result is 0, the OS should preserve any resource assignments made by the +firmware. + +Link: https://lore.kernel.org/r/20190615002359.29577-2-benh@kernel.crashing.org +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +[bhelgaas: commit log] +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +--- + drivers/acpi/pci_root.c | 12 ++++++++++++ + include/linux/pci-acpi.h | 7 ++++--- + include/linux/pci.h | 2 ++ + 3 files changed, 18 insertions(+), 3 deletions(-) + +Index: linux/drivers/acpi/pci_root.c +=================================================================== +--- linux.orig/drivers/acpi/pci_root.c ++++ linux/drivers/acpi/pci_root.c +@@ -884,6 +884,7 @@ struct pci_bus *acpi_pci_root_create(str + int node = acpi_get_node(device->handle); + struct pci_bus *bus; + struct pci_host_bridge *host_bridge; ++ union acpi_object *obj; + + info->root = root; + info->bridge = device; +@@ -920,6 +921,17 @@ struct pci_bus *acpi_pci_root_create(str + if (!(root->osc_control_set & OSC_PCI_EXPRESS_LTR_CONTROL)) + host_bridge->native_ltr = 0; + ++ /* ++ * Evaluate the "PCI Boot Configuration" _DSM Function. If it ++ * exists and returns 0, we must preserve any PCI resource ++ * assignments made by firmware for this host bridge. ++ */ ++ obj = acpi_evaluate_dsm(ACPI_HANDLE(bus->bridge), &pci_acpi_dsm_guid, 1, ++ IGNORE_PCI_BOOT_CONFIG_DSM, NULL); ++ if (obj && obj->type == ACPI_TYPE_INTEGER && obj->integer.value == 0) ++ host_bridge->preserve_config = 1; ++ ACPI_FREE(obj); ++ + pci_scan_child_bus(bus); + pci_set_host_bridge_release(host_bridge, acpi_pci_root_release_info, + info); +Index: linux/include/linux/pci-acpi.h +=================================================================== +--- linux.orig/include/linux/pci-acpi.h ++++ linux/include/linux/pci-acpi.h +@@ -107,9 +107,10 @@ static inline void acpiphp_check_host_br + #endif + + extern const guid_t pci_acpi_dsm_guid; +-#define DEVICE_LABEL_DSM 0x07 +-#define RESET_DELAY_DSM 0x08 +-#define FUNCTION_DELAY_DSM 0x09 ++#define IGNORE_PCI_BOOT_CONFIG_DSM 0x05 ++#define DEVICE_LABEL_DSM 0x07 ++#define RESET_DELAY_DSM 0x08 ++#define FUNCTION_DELAY_DSM 0x09 + + #else /* CONFIG_ACPI */ + static inline void acpi_pci_add_bus(struct pci_bus *bus) { } +Index: linux/include/linux/pci.h +=================================================================== +--- linux.orig/include/linux/pci.h ++++ linux/include/linux/pci.h +@@ -486,6 +486,8 @@ struct pci_host_bridge { + unsigned int native_shpc_hotplug:1; /* OS may use SHPC hotplug */ + unsigned int native_pme:1; /* OS may use PCIe PME */ + unsigned int native_ltr:1; /* OS may use PCIe LTR */ ++ unsigned int preserve_config:1; /* Preserve FW resource setup */ ++ + /* Resource alignment requirements */ + resource_size_t (*align_resource)(struct pci_dev *dev, + const struct resource *res, diff --git a/debian/patches/bugfix/all/PCI-Don-t-auto-realloc-if-we-re-preserving-firmware-.patch b/debian/patches/bugfix/all/PCI-Don-t-auto-realloc-if-we-re-preserving-firmware-.patch new file mode 100644 index 000000000..04fa61629 --- /dev/null +++ b/debian/patches/bugfix/all/PCI-Don-t-auto-realloc-if-we-re-preserving-firmware-.patch @@ -0,0 +1,35 @@ +From: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Date: Sat, 15 Jun 2019 10:23:58 +1000 +Subject: [PATCH 2/4] PCI: Don't auto-realloc if we're preserving firmware config +Origin: https://git.kernel.org/linus/7ac0d094fbe95bf7cc96b3066a97e1090ddc734a + +Prevent auto-enabling of bridges reallocation when the FW tells us that the +initial configuration must be preserved for a given host bridge. + +Link: https://lore.kernel.org/r/20190615002359.29577-3-benh@kernel.crashing.org +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +--- + drivers/pci/setup-bus.c | 5 +++++ + 1 file changed, 5 insertions(+) + +Index: linux/drivers/pci/setup-bus.c +=================================================================== +--- linux.orig/drivers/pci/setup-bus.c ++++ linux/drivers/pci/setup-bus.c +@@ -1724,10 +1724,15 @@ static enum enable_type pci_realloc_dete + enum enable_type enable_local) + { + bool unassigned = false; ++ struct pci_host_bridge *host; + + if (enable_local != undefined) + return enable_local; + ++ host = pci_find_host_bridge(bus); ++ if (host->preserve_config) ++ return auto_disabled; ++ + pci_walk_bus(bus, iov_resources_unassigned, &unassigned); + if (unassigned) + return auto_enabled; diff --git a/debian/patches/bugfix/all/USB-drop-HDC_LOCAL_MEM-flag.patch b/debian/patches/bugfix/all/USB-drop-HDC_LOCAL_MEM-flag.patch new file mode 100644 index 000000000..727419539 --- /dev/null +++ b/debian/patches/bugfix/all/USB-drop-HDC_LOCAL_MEM-flag.patch @@ -0,0 +1,191 @@ +From: Laurentiu Tudor <laurentiu.tudor@nxp.com> +Date: Wed, 29 May 2019 13:28:43 +0300 +Subject: USB: drop HCD_LOCAL_MEM flag +Origin: https://git.kernel.org/linus/2d7a3dc3e24f43504b1f25eae8195e600f4cce8b + +With the addition of the local memory allocator, the HCD_LOCAL_MEM +flag can be dropped and the checks against it replaced with a check +for the localmem_pool ptr being initialized. + +Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> +Tested-by: Fredrik Noring <noring@nocrew.org> +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Christoph Hellwig <hch@lst.de> +--- + drivers/usb/core/buffer.c | 8 +++----- + drivers/usb/core/hcd.c | 15 ++++++--------- + drivers/usb/host/ehci-hcd.c | 2 +- + drivers/usb/host/fotg210-hcd.c | 2 +- + drivers/usb/host/ohci-hcd.c | 2 +- + drivers/usb/host/ohci-sm501.c | 5 +++-- + drivers/usb/host/ohci-tmio.c | 2 +- + drivers/usb/host/uhci-hcd.c | 2 +- + include/linux/usb/hcd.h | 1 - + 9 files changed, 17 insertions(+), 22 deletions(-) + +--- a/drivers/usb/core/buffer.c ++++ b/drivers/usb/core/buffer.c +@@ -68,7 +68,7 @@ + + if (!IS_ENABLED(CONFIG_HAS_DMA) || + (!is_device_dma_capable(hcd->self.sysdev) && +- !(hcd->driver->flags & HCD_LOCAL_MEM))) ++ !hcd->localmem_pool)) + return 0; + + for (i = 0; i < HCD_BUFFER_POOLS; i++) { +@@ -134,8 +134,7 @@ + + /* some USB hosts just use PIO */ + if (!IS_ENABLED(CONFIG_HAS_DMA) || +- (!is_device_dma_capable(bus->sysdev) && +- !(hcd->driver->flags & HCD_LOCAL_MEM))) { ++ !is_device_dma_capable(bus->sysdev)) { + *dma = ~(dma_addr_t) 0; + return kmalloc(size, mem_flags); + } +@@ -166,8 +165,7 @@ + } + + if (!IS_ENABLED(CONFIG_HAS_DMA) || +- (!is_device_dma_capable(bus->sysdev) && +- !(hcd->driver->flags & HCD_LOCAL_MEM))) { ++ !is_device_dma_capable(bus->sysdev)) { + kfree(addr); + return; + } +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -1346,14 +1346,14 @@ + * using regular system memory - like pci devices doing bus mastering. + * + * To support host controllers with limited dma capabilities we provide dma +- * bounce buffers. This feature can be enabled using the HCD_LOCAL_MEM flag. ++ * bounce buffers. This feature can be enabled by initializing ++ * hcd->localmem_pool using usb_hcd_setup_local_mem(). + * For this to work properly the host controller code must first use the + * function dma_declare_coherent_memory() to point out which memory area + * that should be used for dma allocations. + * +- * The HCD_LOCAL_MEM flag then tells the usb code to allocate all data for +- * dma using dma_alloc_coherent() which in turn allocates from the memory +- * area pointed out with dma_declare_coherent_memory(). ++ * The initialized hcd->localmem_pool then tells the usb code to allocate all ++ * data for dma using the genalloc API. + * + * So, to summarize... + * +@@ -1363,9 +1363,6 @@ + * (a) "normal" kernel memory is no good, and + * (b) there's not enough to share + * +- * - The only *portable* hook for such stuff in the +- * DMA framework is dma_declare_coherent_memory() +- * + * - So we use that, even though the primary requirement + * is that the memory be "local" (hence addressable + * by that device), not "coherent". +@@ -1532,7 +1529,7 @@ + urb->setup_dma)) + return -EAGAIN; + urb->transfer_flags |= URB_SETUP_MAP_SINGLE; +- } else if (hcd->driver->flags & HCD_LOCAL_MEM) { ++ } else if (hcd->localmem_pool) { + ret = hcd_alloc_coherent( + urb->dev->bus, mem_flags, + &urb->setup_dma, +@@ -1602,7 +1599,7 @@ + else + urb->transfer_flags |= URB_DMA_MAP_SINGLE; + } +- } else if (hcd->driver->flags & HCD_LOCAL_MEM) { ++ } else if (hcd->localmem_pool) { + ret = hcd_alloc_coherent( + urb->dev->bus, mem_flags, + &urb->transfer_dma, +--- a/drivers/usb/host/ehci-hcd.c ++++ b/drivers/usb/host/ehci-hcd.c +@@ -560,7 +560,7 @@ + ehci->command = temp; + + /* Accept arbitrarily long scatter-gather lists */ +- if (!(hcd->driver->flags & HCD_LOCAL_MEM)) ++ if (!hcd->localmem_pool) + hcd->self.sg_tablesize = ~0; + + /* Prepare for unlinking active QHs */ +--- a/drivers/usb/host/fotg210-hcd.c ++++ b/drivers/usb/host/fotg210-hcd.c +@@ -4998,7 +4998,7 @@ + fotg210->command = temp; + + /* Accept arbitrarily long scatter-gather lists */ +- if (!(hcd->driver->flags & HCD_LOCAL_MEM)) ++ if (!hcd->localmem_pool) + hcd->self.sg_tablesize = ~0; + return 0; + } +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -457,7 +457,7 @@ + struct usb_hcd *hcd = ohci_to_hcd(ohci); + + /* Accept arbitrarily long scatter-gather lists */ +- if (!(hcd->driver->flags & HCD_LOCAL_MEM)) ++ if (!hcd->localmem_pool) + hcd->self.sg_tablesize = ~0; + + if (distrust_firmware) +--- a/drivers/usb/host/ohci-sm501.c ++++ b/drivers/usb/host/ohci-sm501.c +@@ -49,7 +49,7 @@ + * generic hardware linkage + */ + .irq = ohci_irq, +- .flags = HCD_USB11 | HCD_MEMORY | HCD_LOCAL_MEM, ++ .flags = HCD_USB11 | HCD_MEMORY, + + /* + * basic lifecycle operations +@@ -153,7 +153,8 @@ + * fine. This is however not always the case - buffers may be allocated + * using kmalloc() - so the usb core needs to be told that it must copy + * data into our local memory if the buffers happen to be placed in +- * regular memory. The HCD_LOCAL_MEM flag does just that. ++ * regular memory. A non-null hcd->localmem_pool initialized by the ++ * the call to usb_hcd_setup_local_mem() below does just that. + */ + + retval = usb_hcd_setup_local_mem(hcd, mem->start, +--- a/drivers/usb/host/ohci-tmio.c ++++ b/drivers/usb/host/ohci-tmio.c +@@ -153,7 +153,7 @@ + + /* generic hardware linkage */ + .irq = ohci_irq, +- .flags = HCD_USB11 | HCD_MEMORY | HCD_LOCAL_MEM, ++ .flags = HCD_USB11 | HCD_MEMORY, + + /* basic lifecycle operations */ + .start = ohci_tmio_start, +--- a/drivers/usb/host/uhci-hcd.c ++++ b/drivers/usb/host/uhci-hcd.c +@@ -581,7 +581,7 @@ + + hcd->uses_new_polling = 1; + /* Accept arbitrarily long scatter-gather lists */ +- if (!(hcd->driver->flags & HCD_LOCAL_MEM)) ++ if (!hcd->localmem_pool) + hcd->self.sg_tablesize = ~0; + + spin_lock_init(&uhci->lock); +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -256,7 +256,6 @@ + + int flags; + #define HCD_MEMORY 0x0001 /* HC regs use memory (else I/O) */ +-#define HCD_LOCAL_MEM 0x0002 /* HC needs local memory */ + #define HCD_SHARED 0x0004 /* Two (or more) usb_hcds share HW */ + #define HCD_USB11 0x0010 /* USB 1.1 */ + #define HCD_USB2 0x0020 /* USB 2.0 */ diff --git a/debian/patches/bugfix/all/USB-ohci-sm501-fix-error-return-code-in-ohci_hcd_sm5.patch b/debian/patches/bugfix/all/USB-ohci-sm501-fix-error-return-code-in-ohci_hcd_sm5.patch new file mode 100644 index 000000000..08a838c66 --- /dev/null +++ b/debian/patches/bugfix/all/USB-ohci-sm501-fix-error-return-code-in-ohci_hcd_sm5.patch @@ -0,0 +1,33 @@ +From: Wei Yongjun <weiyongjun1@huawei.com> +Date: Wed, 6 May 2020 13:56:25 +0000 +Subject: USB: ohci-sm501: fix error return code in ohci_hcd_sm501_drv_probe() +Origin: https://git.kernel.org/linus/b919e077cccfbb77beb98809568b2fb0b4d113ec + +Fix to return a negative error code from the error handling +case instead of 0, as done elsewhere in this function. + +Fixes: 7d9e6f5aebe8 ("usb: host: ohci-sm501: init genalloc for local memory") +Signed-off-by: Wei Yongjun <weiyongjun1@huawei.com> +Acked-by: Alan Stern <stern@rowland.harvard.edu> +Link: https://lore.kernel.org/r/20200506135625.106910-1-weiyongjun1@huawei.com +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/usb/host/ohci-sm501.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/drivers/usb/host/ohci-sm501.c ++++ b/drivers/usb/host/ohci-sm501.c +@@ -156,9 +156,10 @@ + * regular memory. The HCD_LOCAL_MEM flag does just that. + */ + +- if (usb_hcd_setup_local_mem(hcd, mem->start, +- mem->start - mem->parent->start, +- resource_size(mem)) < 0) ++ retval = usb_hcd_setup_local_mem(hcd, mem->start, ++ mem->start - mem->parent->start, ++ resource_size(mem)); ++ if (retval < 0) + goto err5; + retval = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (retval) diff --git a/debian/patches/bugfix/all/USB-use-genalloc-for-USB-HCs-with-local-memory.patch b/debian/patches/bugfix/all/USB-use-genalloc-for-USB-HCs-with-local-memory.patch new file mode 100644 index 000000000..88caafd5a --- /dev/null +++ b/debian/patches/bugfix/all/USB-use-genalloc-for-USB-HCs-with-local-memory.patch @@ -0,0 +1,280 @@ +From: Laurentiu Tudor <laurentiu.tudor@nxp.com> +Date: Wed, 29 May 2019 13:28:40 +0300 +Subject: USB: use genalloc for USB HCs with local memory +Origin: https://git.kernel.org/linus/b0310c2f09bbe8aebefb97ed67949a3a7092aca6 + +For HCs that have local memory, replace the current DMA API usage with +a genalloc generic allocator to manage the mappings for these devices. +To help users, introduce a new HCD API, usb_hcd_setup_local_mem() that +will setup up the genalloc backing up the device local memory. It will +be used in subsequent patches. This is in preparation for dropping +the existing "coherent" dma mem declaration APIs. The current +implementation was relying on a short circuit in the DMA API that in +the end, was acting as an allocator for these type of devices. + +Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> +Tested-by: Fredrik Noring <noring@nocrew.org> +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Christoph Hellwig <hch@lst.de> +--- + drivers/usb/Kconfig | 1 + + drivers/usb/core/buffer.c | 9 +++++++++ + drivers/usb/core/hcd.c | 36 ++++++++++++++++++++++++++++++++++++ + drivers/usb/host/ohci-hcd.c | 23 ++++++++++++++++++----- + drivers/usb/host/ohci-mem.c | 35 +++++++++++++++++++++++++++++++---- + drivers/usb/host/ohci.h | 2 ++ + include/linux/usb/hcd.h | 5 +++++ + 7 files changed, 102 insertions(+), 9 deletions(-) + +--- a/drivers/usb/Kconfig ++++ b/drivers/usb/Kconfig +@@ -44,6 +44,7 @@ + config USB + tristate "Support for Host-side USB" + depends on USB_ARCH_HAS_HCD ++ select GENERIC_ALLOCATOR + select USB_COMMON + select NLS # for UTF-8 strings + ---help--- +--- a/drivers/usb/core/buffer.c ++++ b/drivers/usb/core/buffer.c +@@ -16,6 +16,7 @@ + #include <linux/io.h> + #include <linux/dma-mapping.h> + #include <linux/dmapool.h> ++#include <linux/genalloc.h> + #include <linux/usb.h> + #include <linux/usb/hcd.h> + +@@ -128,6 +129,9 @@ + if (size == 0) + return NULL; + ++ if (hcd->localmem_pool) ++ return gen_pool_dma_alloc(hcd->localmem_pool, size, dma); ++ + /* some USB hosts just use PIO */ + if (!IS_ENABLED(CONFIG_HAS_DMA) || + (!is_device_dma_capable(bus->sysdev) && +@@ -156,6 +160,11 @@ + if (!addr) + return; + ++ if (hcd->localmem_pool) { ++ gen_pool_free(hcd->localmem_pool, (unsigned long)addr, size); ++ return; ++ } ++ + if (!IS_ENABLED(CONFIG_HAS_DMA) || + (!is_device_dma_capable(bus->sysdev) && + !(hcd->driver->flags & HCD_LOCAL_MEM))) { +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -29,6 +29,8 @@ + #include <linux/workqueue.h> + #include <linux/pm_runtime.h> + #include <linux/types.h> ++#include <linux/genalloc.h> ++#include <linux/io.h> + + #include <linux/phy/phy.h> + #include <linux/usb.h> +@@ -3025,6 +3027,40 @@ + } + EXPORT_SYMBOL_GPL(usb_hcd_platform_shutdown); + ++int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr, ++ dma_addr_t dma, size_t size) ++{ ++ int err; ++ void *local_mem; ++ ++ hcd->localmem_pool = devm_gen_pool_create(hcd->self.sysdev, PAGE_SHIFT, ++ dev_to_node(hcd->self.sysdev), ++ dev_name(hcd->self.sysdev)); ++ if (IS_ERR(hcd->localmem_pool)) ++ return PTR_ERR(hcd->localmem_pool); ++ ++ local_mem = devm_memremap(hcd->self.sysdev, phys_addr, ++ size, MEMREMAP_WC); ++ if (!local_mem) ++ return -ENOMEM; ++ ++ /* ++ * Here we pass a dma_addr_t but the arg type is a phys_addr_t. ++ * It's not backed by system memory and thus there's no kernel mapping ++ * for it. ++ */ ++ err = gen_pool_add_virt(hcd->localmem_pool, (unsigned long)local_mem, ++ dma, size, dev_to_node(hcd->self.sysdev)); ++ if (err < 0) { ++ dev_err(hcd->self.sysdev, "gen_pool_add_virt failed with %d\n", ++ err); ++ return err; ++ } ++ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(usb_hcd_setup_local_mem); ++ + /*-------------------------------------------------------------------------*/ + + #if IS_ENABLED(CONFIG_USB_MON) +--- a/drivers/usb/host/ohci-hcd.c ++++ b/drivers/usb/host/ohci-hcd.c +@@ -40,6 +40,7 @@ + #include <linux/dmapool.h> + #include <linux/workqueue.h> + #include <linux/debugfs.h> ++#include <linux/genalloc.h> + + #include <asm/io.h> + #include <asm/irq.h> +@@ -514,8 +515,15 @@ + timer_setup(&ohci->io_watchdog, io_watchdog_func, 0); + ohci->prev_frame_no = IO_WATCHDOG_OFF; + +- ohci->hcca = dma_alloc_coherent (hcd->self.controller, +- sizeof(*ohci->hcca), &ohci->hcca_dma, GFP_KERNEL); ++ if (hcd->localmem_pool) ++ ohci->hcca = gen_pool_dma_alloc(hcd->localmem_pool, ++ sizeof(*ohci->hcca), ++ &ohci->hcca_dma); ++ else ++ ohci->hcca = dma_alloc_coherent(hcd->self.controller, ++ sizeof(*ohci->hcca), ++ &ohci->hcca_dma, ++ GFP_KERNEL); + if (!ohci->hcca) + return -ENOMEM; + +@@ -999,9 +1007,14 @@ + remove_debug_files (ohci); + ohci_mem_cleanup (ohci); + if (ohci->hcca) { +- dma_free_coherent (hcd->self.controller, +- sizeof *ohci->hcca, +- ohci->hcca, ohci->hcca_dma); ++ if (hcd->localmem_pool) ++ gen_pool_free(hcd->localmem_pool, ++ (unsigned long)ohci->hcca, ++ sizeof(*ohci->hcca)); ++ else ++ dma_free_coherent(hcd->self.controller, ++ sizeof(*ohci->hcca), ++ ohci->hcca, ohci->hcca_dma); + ohci->hcca = NULL; + ohci->hcca_dma = 0; + } +--- a/drivers/usb/host/ohci-mem.c ++++ b/drivers/usb/host/ohci-mem.c +@@ -36,6 +36,13 @@ + + static int ohci_mem_init (struct ohci_hcd *ohci) + { ++ /* ++ * HCs with local memory allocate from localmem_pool so there's ++ * no need to create the below dma pools. ++ */ ++ if (ohci_to_hcd(ohci)->localmem_pool) ++ return 0; ++ + ohci->td_cache = dma_pool_create ("ohci_td", + ohci_to_hcd(ohci)->self.controller, + sizeof (struct td), +@@ -88,8 +95,12 @@ + { + dma_addr_t dma; + struct td *td; ++ struct usb_hcd *hcd = ohci_to_hcd(hc); + +- td = dma_pool_zalloc (hc->td_cache, mem_flags, &dma); ++ if (hcd->localmem_pool) ++ td = gen_pool_dma_zalloc(hcd->localmem_pool, sizeof(*td), &dma); ++ else ++ td = dma_pool_zalloc(hc->td_cache, mem_flags, &dma); + if (td) { + /* in case hc fetches it, make it look dead */ + td->hwNextTD = cpu_to_hc32 (hc, dma); +@@ -103,6 +114,7 @@ + td_free (struct ohci_hcd *hc, struct td *td) + { + struct td **prev = &hc->td_hash [TD_HASH_FUNC (td->td_dma)]; ++ struct usb_hcd *hcd = ohci_to_hcd(hc); + + while (*prev && *prev != td) + prev = &(*prev)->td_hash; +@@ -110,7 +122,12 @@ + *prev = td->td_hash; + else if ((td->hwINFO & cpu_to_hc32(hc, TD_DONE)) != 0) + ohci_dbg (hc, "no hash for td %p\n", td); +- dma_pool_free (hc->td_cache, td, td->td_dma); ++ ++ if (hcd->localmem_pool) ++ gen_pool_free(hcd->localmem_pool, (unsigned long)td, ++ sizeof(*td)); ++ else ++ dma_pool_free(hc->td_cache, td, td->td_dma); + } + + /*-------------------------------------------------------------------------*/ +@@ -121,8 +138,12 @@ + { + dma_addr_t dma; + struct ed *ed; ++ struct usb_hcd *hcd = ohci_to_hcd(hc); + +- ed = dma_pool_zalloc (hc->ed_cache, mem_flags, &dma); ++ if (hcd->localmem_pool) ++ ed = gen_pool_dma_zalloc(hcd->localmem_pool, sizeof(*ed), &dma); ++ else ++ ed = dma_pool_zalloc(hc->ed_cache, mem_flags, &dma); + if (ed) { + INIT_LIST_HEAD (&ed->td_list); + ed->dma = dma; +@@ -133,6 +154,12 @@ + static void + ed_free (struct ohci_hcd *hc, struct ed *ed) + { +- dma_pool_free (hc->ed_cache, ed, ed->dma); ++ struct usb_hcd *hcd = ohci_to_hcd(hc); ++ ++ if (hcd->localmem_pool) ++ gen_pool_free(hcd->localmem_pool, (unsigned long)ed, ++ sizeof(*ed)); ++ else ++ dma_pool_free(hc->ed_cache, ed, ed->dma); + } + +--- a/drivers/usb/host/ohci.h ++++ b/drivers/usb/host/ohci.h +@@ -385,6 +385,8 @@ + + /* + * memory management for queue data structures ++ * ++ * @td_cache and @ed_cache are %NULL if &usb_hcd.localmem_pool is used. + */ + struct dma_pool *td_cache; + struct dma_pool *ed_cache; +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -211,6 +211,9 @@ + #define HC_IS_RUNNING(state) ((state) & __ACTIVE) + #define HC_IS_SUSPENDED(state) ((state) & __SUSPEND) + ++ /* memory pool for HCs having local memory, or %NULL */ ++ struct gen_pool *localmem_pool; ++ + /* more shared queuing code would be good; it should support + * smarter scheduling, handle transaction translators, etc; + * input size of periodic table to an interrupt scheduler. +@@ -461,6 +464,8 @@ + unsigned int irqnum, unsigned long irqflags); + extern void usb_remove_hcd(struct usb_hcd *hcd); + extern int usb_hcd_find_raw_port_number(struct usb_hcd *hcd, int port1); ++int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr, ++ dma_addr_t dma, size_t size); + + struct platform_device; + extern void usb_hcd_platform_shutdown(struct platform_device *dev); diff --git a/debian/patches/bugfix/all/cpupower-bump-soname-version.patch b/debian/patches/bugfix/all/cpupower-bump-soname-version.patch new file mode 100644 index 000000000..5691bd454 --- /dev/null +++ b/debian/patches/bugfix/all/cpupower-bump-soname-version.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Thu, 9 Jun 2016 23:35:08 +0100 +Subject: cpupower: Bump soname version +Forwarded: http://mid.gmane.org/20160610005619.GQ7555@decadent.org.uk + +Several functions in the libcpupower API are renamed or removed in +Linux 4.7. This is an backward-incompatible ABI change, so the +library soname should change from libcpupower.so.0 to +libcpupower.so.1. + +Fixes: ac5a181d065d ("cpupower: Add cpuidle parts into library") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + tools/power/cpupower/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/tools/power/cpupower/Makefile +=================================================================== +--- linux.orig/tools/power/cpupower/Makefile ++++ linux/tools/power/cpupower/Makefile +@@ -66,7 +66,7 @@ DESTDIR ?= + + VERSION= $(shell ./utils/version-gen.sh) + LIB_MAJ= 0.0.1 +-LIB_MIN= 0 ++LIB_MIN= 1 + + PACKAGE = cpupower + PACKAGE_BUGREPORT = linux-pm@vger.kernel.org diff --git a/debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch b/debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch new file mode 100644 index 000000000..0ad8fc6cd --- /dev/null +++ b/debian/patches/bugfix/all/cpupower-fix-checks-for-cpu-existence.patch @@ -0,0 +1,51 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Thu, 03 Nov 2016 15:25:26 -0600 +Subject: cpupower: Fix checks for CPU existence +Forwarded: https://marc.info/?l=linux-pm&m=149248268214265 + +Calls to cpufreq_cpu_exists(cpu) were converted to +cpupower_is_cpu_online(cpu) when libcpupower was introduced and the +former function was deleted. However, cpupower_is_cpu_online() does +not distinguish physically absent and offline CPUs, and does not set +errno. + +cpufreq-set has already been fixed (commit c25badc9ceb6). + +In cpufreq-bench, which prints an error message for offline CPUs, +properly distinguish and report the zero and negative cases. + +Fixes: ac5a181d065d ("cpupower: Add cpuidle parts into library") +Fixes: 53d1cd6b125f ("cpupowerutils: bench - Fix cpu online check") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +[carnil: Update/Refresh patch for 4.14.17: The issue with the +incorrect check has been fixed with upstream commit 53d1cd6b125f. +Keep in the patch the distinction and report for the zero and +negative cases.] +--- +Index: linux/tools/power/cpupower/bench/system.c +=================================================================== +--- linux.orig/tools/power/cpupower/bench/system.c ++++ linux/tools/power/cpupower/bench/system.c +@@ -58,12 +58,19 @@ long long int get_time() + + int set_cpufreq_governor(char *governor, unsigned int cpu) + { ++ int rc; + + dprintf("set %s as cpufreq governor\n", governor); + +- if (cpupower_is_cpu_online(cpu) != 1) { +- perror("cpufreq_cpu_exists"); +- fprintf(stderr, "error: cpu %u does not exist\n", cpu); ++ rc = cpupower_is_cpu_online(cpu); ++ if (rc != 1) { ++ if (rc < 0) ++ fprintf(stderr, "cpupower_is_cpu_online: %s\n", ++ strerror(-rc)); ++ else ++ fprintf(stderr, ++ "error: cpu %u is offline or does not exist\n", ++ cpu); + return -1; + } + diff --git a/debian/patches/bugfix/all/disable-some-marvell-phys.patch b/debian/patches/bugfix/all/disable-some-marvell-phys.patch new file mode 100644 index 000000000..297b38c56 --- /dev/null +++ b/debian/patches/bugfix/all/disable-some-marvell-phys.patch @@ -0,0 +1,93 @@ +From: Ian Campbell <ijc@hellion.org.uk> +Subject: phy/marvell: disable 4-port phys +Date: Wed, 20 Nov 2013 08:30:14 +0000 +Bug-Debian: https://bugs.debian.org/723177 +Forwarded: http://thread.gmane.org/gmane.linux.debian.devel.bugs.general/1107774/ + +The Marvell PHY was originally disabled because it can cause networking +failures on some systems. According to Lennert Buytenhek this is because some +of the variants added did not share the same register layout. Since the known +cases are all 4-ports disable those variants (indicated by a 4 in the +penultimate position of the model name) until they can be audited for +correctness. + +[bwh: Also #if-out the init functions for these PHYs to avoid + compiler warnings] + +Index: linux/drivers/net/phy/marvell.c +=================================================================== +--- linux.orig/drivers/net/phy/marvell.c ++++ linux/drivers/net/phy/marvell.c +@@ -950,6 +950,7 @@ static int m88e1118_config_init(struct p + return genphy_soft_reset(phydev); + } + ++#if 0 + static int m88e1149_config_init(struct phy_device *phydev) + { + int err; +@@ -975,7 +976,9 @@ static int m88e1149_config_init(struct p + + return genphy_soft_reset(phydev); + } ++#endif + ++#if 0 + static int m88e1145_config_init_rgmii(struct phy_device *phydev) + { + int err; +@@ -1050,6 +1053,7 @@ static int m88e1145_config_init(struct p + + return 0; + } ++#endif + + /* The VOD can be out of specification on link up. Poke an + * undocumented register, in an undocumented page, with a magic value +@@ -2165,6 +2169,7 @@ static struct phy_driver marvell_drivers + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + }, ++#if 0 + { + .phy_id = MARVELL_PHY_ID_88E1145, + .phy_id_mask = MARVELL_PHY_ID_MASK, +@@ -2185,6 +2190,8 @@ static struct phy_driver marvell_drivers + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + }, ++#endif ++#if 0 + { + .phy_id = MARVELL_PHY_ID_88E1149R, + .phy_id_mask = MARVELL_PHY_ID_MASK, +@@ -2204,6 +2211,8 @@ static struct phy_driver marvell_drivers + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + }, ++#endif ++#if 0 + { + .phy_id = MARVELL_PHY_ID_88E1240, + .phy_id_mask = MARVELL_PHY_ID_MASK, +@@ -2223,6 +2232,7 @@ static struct phy_driver marvell_drivers + .get_strings = marvell_get_strings, + .get_stats = marvell_get_stats, + }, ++#endif + { + .phy_id = MARVELL_PHY_ID_88E1116R, + .phy_id_mask = MARVELL_PHY_ID_MASK, +@@ -2359,9 +2369,9 @@ static struct mdio_device_id __maybe_unu + { MARVELL_PHY_ID_88E1111, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E1118, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E1121R, MARVELL_PHY_ID_MASK }, +- { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK }, +- { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK }, +- { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK }, ++/* { MARVELL_PHY_ID_88E1145, MARVELL_PHY_ID_MASK }, */ ++/* { MARVELL_PHY_ID_88E1149R, MARVELL_PHY_ID_MASK }, */ ++/* { MARVELL_PHY_ID_88E1240, MARVELL_PHY_ID_MASK }, */ + { MARVELL_PHY_ID_88E1318S, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E1116R, MARVELL_PHY_ID_MASK }, + { MARVELL_PHY_ID_88E1510, MARVELL_PHY_ID_MASK }, diff --git a/debian/patches/bugfix/all/documentation-media-uapi-explicitly-say-there-are-no-invariant-sections.patch b/debian/patches/bugfix/all/documentation-media-uapi-explicitly-say-there-are-no-invariant-sections.patch new file mode 100644 index 000000000..97e5d0a64 --- /dev/null +++ b/debian/patches/bugfix/all/documentation-media-uapi-explicitly-say-there-are-no-invariant-sections.patch @@ -0,0 +1,52 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 23 Nov 2018 13:38:34 -0500 +Subject: media: Documentation/media: uapi: Explicitly say there are no + Invariant Sections +Origin: https://git.kernel.org/linus/861c56c13d817b76e802d664e6ce7edb09cb9417 +Bug-Debian: https://bugs.debian.org/698668 + +The GNU Free Documentation License allows for a work to specify +Invariant Sections that are not allowed to be modified. (Debian +considers that this makes such works non-free.) + +The Linux Media Infrastructure userspace API documentation does not +specify any such sections, but it also doesn't say there are none (as +is recommended by the license text). Make it explicit that there are +none. + +Signed-off-by: Aaro Koskinen <aaro.koskinen@nokia.com> +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +Signed-off-by: Gerd Hoffmann <kraxel@redhat.com> +Signed-off-by: Hans Verkuil <hans.verkuil@cisco.com> +Signed-off-by: Johannes Stezenbach <js@linuxtv.org> +Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> +Signed-off-by: Marcus Metzler <mocm@metzlerbros.de> +Signed-off-by: Michael Ira Krufky <mkrufky@gmail.com> +Signed-off-by: Ralph Metzler <rjkm@metzlerbros.de> +Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com> +Signed-off-by: Sean Young <sean@mess.org> +Signed-off-by: Sylwester Nawrocki <snawrocki@kernel.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: Kate Stewart <kstewart@linuxfoundation.org> +Signed-off-by: Mauro Carvalho Chehab <mchehab+samsung@kernel.org> +--- + Documentation/media/media_uapi.rst | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +Index: linux/Documentation/media/media_uapi.rst +=================================================================== +--- linux.orig/Documentation/media/media_uapi.rst ++++ linux/Documentation/media/media_uapi.rst +@@ -10,9 +10,9 @@ Linux Media Infrastructure userspace API + + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.1 or +-any later version published by the Free Software Foundation. A copy of +-the license is included in the chapter entitled "GNU Free Documentation +-License". ++any later version published by the Free Software Foundation, with no ++Invariant Sections. A copy of the license is included in the chapter ++entitled "GNU Free Documentation License". + + .. only:: html + diff --git a/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch b/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch new file mode 100644 index 000000000..633c5c34c --- /dev/null +++ b/debian/patches/bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch @@ -0,0 +1,2895 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: firmware: Remove redundant log messages from drivers +Date: Sun, 09 Dec 2012 16:40:31 +0000 +Forwarded: no + +Now that firmware_class logs every success and failure consistently, +many other log messages can be removed from drivers. + +This will probably need to be split up into multiple patches prior to +upstream submission. + +Index: linux/arch/arm/mach-netx/xc.c +=================================================================== +--- linux.orig/arch/arm/mach-netx/xc.c ++++ linux/arch/arm/mach-netx/xc.c +@@ -127,10 +127,8 @@ int xc_request_firmware(struct xc *x) + + ret = request_firmware(&fw, name, x->dev); + +- if (ret < 0) { +- dev_err(x->dev, "request_firmware failed\n"); ++ if (ret) + return ret; +- } + + head = (struct fw_header *)fw->data; + if (head->magic != 0x4e657458) { +Index: linux/arch/x86/kernel/cpu/microcode/amd.c +=================================================================== +--- linux.orig/arch/x86/kernel/cpu/microcode/amd.c ++++ linux/arch/x86/kernel/cpu/microcode/amd.c +@@ -755,10 +755,8 @@ static enum ucode_state request_microcod + if (c->x86 >= 0x15) + snprintf(fw_name, sizeof(fw_name), "amd-ucode/microcode_amd_fam%.2xh.bin", c->x86); + +- if (request_firmware_direct(&fw, (const char *)fw_name, device)) { +- pr_debug("failed to load file %s\n", fw_name); ++ if (request_firmware_direct(&fw, (const char *)fw_name, device)) + goto out; +- } + + ret = UCODE_ERROR; + if (*(u32 *)fw->data != UCODE_MAGIC) { +Index: linux/drivers/atm/ambassador.c +=================================================================== +--- linux.orig/drivers/atm/ambassador.c ++++ linux/drivers/atm/ambassador.c +@@ -1929,10 +1929,8 @@ static int ucode_init(loader_block *lb, + int res; + + res = request_ihex_firmware(&fw, "atmsar11.fw", &dev->pci_dev->dev); +- if (res) { +- PRINTK (KERN_ERR, "Cannot load microcode data"); ++ if (res) + return res; +- } + + /* First record contains just the start address */ + rec = (const struct ihex_binrec *)fw->data; +Index: linux/drivers/atm/fore200e.c +=================================================================== +--- linux.orig/drivers/atm/fore200e.c ++++ linux/drivers/atm/fore200e.c +@@ -2505,10 +2505,9 @@ static int fore200e_load_and_start_fw(st + return err; + + sprintf(buf, "%s%s", fore200e->bus->proc_name, FW_EXT); +- if ((err = request_firmware(&firmware, buf, device)) < 0) { +- printk(FORE200E "problem loading firmware image %s\n", fore200e->bus->model_name); ++ err = request_firmware(&firmware, buf, device); ++ if (err) + return err; +- } + + fw_data = (const __le32 *)firmware->data; + fw_size = firmware->size / sizeof(u32); +Index: linux/drivers/bluetooth/ath3k.c +=================================================================== +--- linux.orig/drivers/bluetooth/ath3k.c ++++ linux/drivers/bluetooth/ath3k.c +@@ -430,10 +430,8 @@ static int ath3k_load_patch(struct usb_d + le32_to_cpu(fw_version.rom_version)); + + ret = request_firmware(&firmware, filename, &udev->dev); +- if (ret < 0) { +- BT_ERR("Patch file not found %s", filename); ++ if (ret) + return ret; +- } + + pt_rom_version = get_unaligned_le32(firmware->data + + firmware->size - 8); +@@ -493,10 +491,8 @@ static int ath3k_load_syscfg(struct usb_ + le32_to_cpu(fw_version.rom_version), clk_value, ".dfu"); + + ret = request_firmware(&firmware, filename, &udev->dev); +- if (ret < 0) { +- BT_ERR("Configuration file not found %s", filename); ++ if (ret) + return ret; +- } + + ret = ath3k_load_fwfile(udev, firmware); + release_firmware(firmware); +Index: linux/drivers/bluetooth/bcm203x.c +=================================================================== +--- linux.orig/drivers/bluetooth/bcm203x.c ++++ linux/drivers/bluetooth/bcm203x.c +@@ -189,7 +189,6 @@ static int bcm203x_probe(struct usb_inte + return -ENOMEM; + + if (request_firmware(&firmware, "BCM2033-MD.hex", &udev->dev) < 0) { +- BT_ERR("Mini driver request failed"); + usb_free_urb(data->urb); + return -EIO; + } +@@ -214,7 +213,6 @@ static int bcm203x_probe(struct usb_inte + release_firmware(firmware); + + if (request_firmware(&firmware, "BCM2033-FW.bin", &udev->dev) < 0) { +- BT_ERR("Firmware request failed"); + usb_free_urb(data->urb); + kfree(data->buffer); + return -EIO; +Index: linux/drivers/bluetooth/bfusb.c +=================================================================== +--- linux.orig/drivers/bluetooth/bfusb.c ++++ linux/drivers/bluetooth/bfusb.c +@@ -652,10 +652,8 @@ static int bfusb_probe(struct usb_interf + skb_queue_head_init(&data->pending_q); + skb_queue_head_init(&data->completed_q); + +- if (request_firmware(&firmware, "bfubase.frm", &udev->dev) < 0) { +- BT_ERR("Firmware request failed"); ++ if (request_firmware(&firmware, "bfubase.frm", &udev->dev)) + goto done; +- } + + BT_DBG("firmware data %p size %zu", firmware->data, firmware->size); + +Index: linux/drivers/bluetooth/bt3c_cs.c +=================================================================== +--- linux.orig/drivers/bluetooth/bt3c_cs.c ++++ linux/drivers/bluetooth/bt3c_cs.c +@@ -566,10 +566,8 @@ static int bt3c_open(struct bt3c_info *i + + /* Load firmware */ + err = request_firmware(&firmware, "BT3CPCC.bin", &info->p_dev->dev); +- if (err < 0) { +- BT_ERR("Firmware request failed"); ++ if (err) + goto error; +- } + + err = bt3c_load_firmware(info, firmware->data, firmware->size); + +Index: linux/drivers/bluetooth/btmrvl_sdio.c +=================================================================== +--- linux.orig/drivers/bluetooth/btmrvl_sdio.c ++++ linux/drivers/bluetooth/btmrvl_sdio.c +@@ -455,8 +455,6 @@ static int btmrvl_sdio_download_helper(s + ret = request_firmware(&fw_helper, card->helper, + &card->func->dev); + if ((ret < 0) || !fw_helper) { +- BT_ERR("request_firmware(helper) failed, error code = %d", +- ret); + ret = -ENOENT; + goto done; + } +@@ -555,8 +553,6 @@ static int btmrvl_sdio_download_fw_w_hel + ret = request_firmware(&fw_firmware, card->firmware, + &card->func->dev); + if ((ret < 0) || !fw_firmware) { +- BT_ERR("request_firmware(firmware) failed, error code = %d", +- ret); + ret = -ENOENT; + goto done; + } +Index: linux/drivers/char/dsp56k.c +=================================================================== +--- linux.orig/drivers/char/dsp56k.c ++++ linux/drivers/char/dsp56k.c +@@ -140,11 +140,8 @@ static int dsp56k_upload(u_char __user * + } + err = request_firmware(&fw, fw_name, &pdev->dev); + platform_device_unregister(pdev); +- if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fw_name, err); ++ if (err) + return err; +- } + if (fw->size % 3) { + printk(KERN_ERR "Bogus length %d in image \"%s\"\n", + fw->size, fw_name); +Index: linux/drivers/dma/imx-sdma.c +=================================================================== +--- linux.orig/drivers/dma/imx-sdma.c ++++ linux/drivers/dma/imx-sdma.c +@@ -1674,11 +1674,8 @@ static void sdma_load_firmware(const str + const struct sdma_script_start_addrs *addr; + unsigned short *ram_code; + +- if (!fw) { +- dev_info(sdma->dev, "external firmware not found, using ROM firmware\n"); +- /* In this case we just use the ROM firmware. */ ++ if (!fw) + return; +- } + + if (fw->size < sizeof(*header)) + goto err_firmware; +Index: linux/drivers/gpu/drm/mga/mga_warp.c +=================================================================== +--- linux.orig/drivers/gpu/drm/mga/mga_warp.c ++++ linux/drivers/gpu/drm/mga/mga_warp.c +@@ -79,11 +79,8 @@ int mga_warp_install_microcode(drm_mga_p + } + rc = request_ihex_firmware(&fw, firmware_name, &pdev->dev); + platform_device_unregister(pdev); +- if (rc) { +- DRM_ERROR("mga: Failed to load microcode \"%s\"\n", +- firmware_name); ++ if (rc) + return rc; +- } + + size = 0; + where = 0; +Index: linux/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +=================================================================== +--- linux.orig/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c ++++ linux/drivers/gpu/drm/nouveau/nvkm/engine/gr/gf100.c +@@ -1920,10 +1920,8 @@ gf100_gr_ctor_fw_legacy(struct gf100_gr + if (ret) { + snprintf(f, sizeof(f), "nouveau/%s", fwname); + ret = request_firmware(&fw, f, device->dev); +- if (ret) { +- nvkm_error(subdev, "failed to load %s\n", fwname); ++ if (ret) + return ret; +- } + } + + fuc->size = fw->size; +Index: linux/drivers/gpu/drm/r128/r128_cce.c +=================================================================== +--- linux.orig/drivers/gpu/drm/r128/r128_cce.c ++++ linux/drivers/gpu/drm/r128/r128_cce.c +@@ -154,11 +154,8 @@ static int r128_cce_load_microcode(drm_r + } + rc = request_firmware(&fw, FIRMWARE_NAME, &pdev->dev); + platform_device_unregister(pdev); +- if (rc) { +- pr_err("r128_cce: Failed to load firmware \"%s\"\n", +- FIRMWARE_NAME); ++ if (rc) + return rc; +- } + + if (fw->size != 256 * 8) { + pr_err("r128_cce: Bogus length %zu in firmware \"%s\"\n", +Index: linux/drivers/gpu/drm/radeon/ni.c +=================================================================== +--- linux.orig/drivers/gpu/drm/radeon/ni.c ++++ linux/drivers/gpu/drm/radeon/ni.c +@@ -830,9 +830,6 @@ int ni_init_microcode(struct radeon_devi + + out: + if (err) { +- if (err != -EINVAL) +- pr_err("ni_cp: Failed to load firmware \"%s\"\n", +- fw_name); + release_firmware(rdev->pfp_fw); + rdev->pfp_fw = NULL; + release_firmware(rdev->me_fw); +Index: linux/drivers/gpu/drm/radeon/r100.c +=================================================================== +--- linux.orig/drivers/gpu/drm/radeon/r100.c ++++ linux/drivers/gpu/drm/radeon/r100.c +@@ -1041,9 +1041,7 @@ static int r100_cp_init_microcode(struct + } + + err = request_firmware(&rdev->me_fw, fw_name, rdev->dev); +- if (err) { +- pr_err("radeon_cp: Failed to load firmware \"%s\"\n", fw_name); +- } else if (rdev->me_fw->size % 8) { ++ if (err == 0 && rdev->me_fw->size % 8) { + pr_err("radeon_cp: Bogus length %zu in firmware \"%s\"\n", + rdev->me_fw->size, fw_name); + err = -EINVAL; +Index: linux/drivers/gpu/drm/radeon/r600.c +=================================================================== +--- linux.orig/drivers/gpu/drm/radeon/r600.c ++++ linux/drivers/gpu/drm/radeon/r600.c +@@ -2593,9 +2593,6 @@ int r600_init_microcode(struct radeon_de + + out: + if (err) { +- if (err != -EINVAL) +- pr_err("r600_cp: Failed to load firmware \"%s\"\n", +- fw_name); + release_firmware(rdev->pfp_fw); + rdev->pfp_fw = NULL; + release_firmware(rdev->me_fw); +Index: linux/drivers/infiniband/hw/qib/qib_sd7220.c +=================================================================== +--- linux.orig/drivers/infiniband/hw/qib/qib_sd7220.c ++++ linux/drivers/infiniband/hw/qib/qib_sd7220.c +@@ -406,10 +406,8 @@ int qib_sd7220_init(struct qib_devdata * + } + + ret = request_firmware(&fw, SD7220_FW_NAME, &dd->pcidev->dev); +- if (ret) { +- qib_dev_err(dd, "Failed to load IB SERDES image\n"); ++ if (ret) + goto done; +- } + + /* Substitute our deduced value for was_reset */ + ret = qib_ibsd_ucode_loaded(dd->pport, fw); +Index: linux/drivers/input/touchscreen/atmel_mxt_ts.c +=================================================================== +--- linux.orig/drivers/input/touchscreen/atmel_mxt_ts.c ++++ linux/drivers/input/touchscreen/atmel_mxt_ts.c +@@ -2783,10 +2783,8 @@ static int mxt_load_fw(struct device *de + int ret; + + ret = request_firmware(&fw, fn, dev); +- if (ret) { +- dev_err(dev, "Unable to open firmware %s\n", fn); ++ if (ret) + return ret; +- } + + /* Check for incorrect enc file */ + ret = mxt_check_firmware_format(dev, fw); +Index: linux/drivers/isdn/hardware/mISDN/speedfax.c +=================================================================== +--- linux.orig/drivers/isdn/hardware/mISDN/speedfax.c ++++ linux/drivers/isdn/hardware/mISDN/speedfax.c +@@ -392,11 +392,8 @@ setup_instance(struct sfax_hw *card) + card->isar.owner = THIS_MODULE; + + err = request_firmware(&firmware, "isdn/ISAR.BIN", &card->pdev->dev); +- if (err < 0) { +- pr_info("%s: firmware request failed %d\n", +- card->name, err); ++ if (err) + goto error_fw; +- } + if (debug & DEBUG_HW) + pr_notice("%s: got firmware %zu bytes\n", + card->name, firmware->size); +Index: linux/drivers/media/tuners/tuner-xc2028.c +=================================================================== +--- linux.orig/drivers/media/tuners/tuner-xc2028.c ++++ linux/drivers/media/tuners/tuner-xc2028.c +@@ -1367,7 +1367,6 @@ static void load_firmware_cb(const struc + + tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error"); + if (!fw) { +- tuner_err("Could not load firmware %s.\n", priv->fname); + priv->state = XC2028_NODEV; + return; + } +Index: linux/drivers/media/usb/dvb-usb/dib0700_devices.c +=================================================================== +--- linux.orig/drivers/media/usb/dvb-usb/dib0700_devices.c ++++ linux/drivers/media/usb/dvb-usb/dib0700_devices.c +@@ -2416,12 +2416,9 @@ static int stk9090m_frontend_attach(stru + + dib9000_i2c_enumeration(&adap->dev->i2c_adap, 1, 0x10, 0x80); + +- if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) { +- deb_info("%s: Upload failed. (file not found?)\n", __func__); ++ if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) + return -ENODEV; +- } else { +- deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); +- } ++ deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); + stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size; + stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data; + +@@ -2486,12 +2483,9 @@ static int nim9090md_frontend_attach(str + msleep(20); + dib0700_set_gpio(adap->dev, GPIO0, GPIO_OUT, 1); + +- if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) { +- deb_info("%s: Upload failed. (file not found?)\n", __func__); ++ if (request_firmware(&state->frontend_firmware, "dib9090.fw", &adap->dev->udev->dev)) + return -EIO; +- } else { +- deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); +- } ++ deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); + nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size; + nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data; + nim9090md_config[1].microcode_B_fe_size = state->frontend_firmware->size; +Index: linux/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +=================================================================== +--- linux.orig/drivers/media/usb/dvb-usb/dvb-usb-firmware.c ++++ linux/drivers/media/usb/dvb-usb/dvb-usb-firmware.c +@@ -89,13 +89,9 @@ int dvb_usb_download_firmware(struct usb + int ret; + const struct firmware *fw = NULL; + +- if ((ret = request_firmware(&fw, props->firmware, &udev->dev)) != 0) { +- err("did not find the firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware", +- props->firmware,ret); ++ ret = request_firmware(&fw, props->firmware, &udev->dev); ++ if (ret) + return ret; +- } +- +- info("downloading firmware from file '%s'",props->firmware); + + switch (props->usb_ctrl) { + case CYPRESS_AN2135: +Index: linux/drivers/media/usb/dvb-usb/gp8psk.c +=================================================================== +--- linux.orig/drivers/media/usb/dvb-usb/gp8psk.c ++++ linux/drivers/media/usb/dvb-usb/gp8psk.c +@@ -134,19 +134,14 @@ static int gp8psk_load_bcm4500fw(struct + const u8 *ptr; + u8 *buf; + if ((ret = request_firmware(&fw, bcm4500_firmware, +- &d->udev->dev)) != 0) { +- err("did not find the bcm4500 firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware", +- bcm4500_firmware,ret); ++ &d->udev->dev)) != 0) + return ret; +- } + + ret = -EINVAL; + + if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0)) + goto out_rel_fw; + +- info("downloading bcm4500 firmware from file '%s'",bcm4500_firmware); +- + ptr = fw->data; + buf = kmalloc(64, GFP_KERNEL); + if (!buf) { +Index: linux/drivers/media/usb/dvb-usb/opera1.c +=================================================================== +--- linux.orig/drivers/media/usb/dvb-usb/opera1.c ++++ linux/drivers/media/usb/dvb-usb/opera1.c +@@ -453,8 +453,6 @@ static int opera1_xilinx_load_firmware(s + info("start downloading fpga firmware %s",filename); + + if ((ret = request_firmware(&fw, filename, &dev->dev)) != 0) { +- err("did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware", +- filename); + return ret; + } else { + p = kmalloc(fw->size, GFP_KERNEL); +Index: linux/drivers/media/dvb-frontends/af9013.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/af9013.c ++++ linux/drivers/media/dvb-frontends/af9013.c +@@ -1059,14 +1059,8 @@ static int af9013_download_firmware(stru + + /* Request the firmware, will block and timeout */ + ret = request_firmware(&firmware, name, &client->dev); +- if (ret) { +- dev_info(&client->dev, "firmware file '%s' not found %d\n", +- name, ret); ++ if (ret) + goto err; +- } +- +- dev_info(&client->dev, "downloading firmware from file '%s'\n", +- name); + + /* Write firmware checksum & size */ + for (i = 0; i < firmware->size; i++) +Index: linux/drivers/media/dvb-frontends/bcm3510.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/bcm3510.c ++++ linux/drivers/media/dvb-frontends/bcm3510.c +@@ -636,10 +636,9 @@ static int bcm3510_download_firmware(str + int ret,i; + + deb_info("requesting firmware\n"); +- if ((ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE)) < 0) { +- err("could not load firmware (%s): %d",BCM3510_DEFAULT_FIRMWARE,ret); ++ ret = st->config->request_firmware(fe, &fw, BCM3510_DEFAULT_FIRMWARE); ++ if (ret) + return ret; +- } + deb_info("got firmware: %zu\n", fw->size); + + b = fw->data; +Index: linux/drivers/media/dvb-frontends/cx24116.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/cx24116.c ++++ linux/drivers/media/dvb-frontends/cx24116.c +@@ -491,13 +491,8 @@ static int cx24116_firmware_ondemand(str + __func__, CX24116_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, CX24116_DEFAULT_FIRMWARE, + state->i2c->dev.parent); +- printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", +- __func__); +- if (ret) { +- printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n", +- __func__); ++ if (ret) + return ret; +- } + + /* Make sure we don't recurse back through here + * during loading */ +Index: linux/drivers/media/dvb-frontends/drxd_hard.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/drxd_hard.c ++++ linux/drivers/media/dvb-frontends/drxd_hard.c +@@ -903,10 +903,8 @@ static int load_firmware(struct drxd_sta + { + const struct firmware *fw; + +- if (request_firmware(&fw, fw_name, state->dev) < 0) { +- printk(KERN_ERR "drxd: firmware load failure [%s]\n", fw_name); ++ if (request_firmware(&fw, fw_name, state->dev)) + return -EIO; +- } + + state->microcode = kmemdup(fw->data, fw->size, GFP_KERNEL); + if (!state->microcode) { +Index: linux/drivers/media/dvb-frontends/drxk_hard.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/drxk_hard.c ++++ linux/drivers/media/dvb-frontends/drxk_hard.c +@@ -6281,10 +6281,6 @@ static void load_firmware_cb(const struc + + dprintk(1, ": %s\n", fw ? "firmware loaded" : "firmware not loaded"); + if (!fw) { +- pr_err("Could not load firmware file %s.\n", +- state->microcode_name); +- pr_info("Copy %s to your hotplug directory!\n", +- state->microcode_name); + state->microcode_name = NULL; + + /* +Index: linux/drivers/media/dvb-frontends/ds3000.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/ds3000.c ++++ linux/drivers/media/dvb-frontends/ds3000.c +@@ -360,12 +360,8 @@ static int ds3000_firmware_ondemand(stru + DS3000_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, DS3000_DEFAULT_FIRMWARE, + state->i2c->dev.parent); +- printk(KERN_INFO "%s: Waiting for firmware upload(2)...\n", __func__); +- if (ret) { +- printk(KERN_ERR "%s: No firmware uploaded (timeout or file not found?)\n", +- __func__); ++ if (ret) + return ret; +- } + + ret = ds3000_load_firmware(fe, fw); + if (ret) +Index: linux/drivers/media/dvb-frontends/nxt200x.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/nxt200x.c ++++ linux/drivers/media/dvb-frontends/nxt200x.c +@@ -886,12 +886,8 @@ static int nxt2002_init(struct dvb_front + __func__, NXT2002_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, NXT2002_DEFAULT_FIRMWARE, + state->i2c->dev.parent); +- pr_debug("%s: Waiting for firmware upload(2)...\n", __func__); +- if (ret) { +- pr_err("%s: No firmware uploaded (timeout or file not found?)\n", +- __func__); ++ if (ret) + return ret; +- } + + ret = nxt2002_load_firmware(fe, fw); + release_firmware(fw); +@@ -953,12 +949,8 @@ static int nxt2004_init(struct dvb_front + __func__, NXT2004_DEFAULT_FIRMWARE); + ret = request_firmware(&fw, NXT2004_DEFAULT_FIRMWARE, + state->i2c->dev.parent); +- pr_debug("%s: Waiting for firmware upload(2)...\n", __func__); +- if (ret) { +- pr_err("%s: No firmware uploaded (timeout or file not found?)\n", +- __func__); ++ if (ret) + return ret; +- } + + ret = nxt2004_load_firmware(fe, fw); + release_firmware(fw); +Index: linux/drivers/media/dvb-frontends/or51132.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/or51132.c ++++ linux/drivers/media/dvb-frontends/or51132.c +@@ -337,10 +337,8 @@ static int or51132_set_parameters(struct + printk("or51132: Waiting for firmware upload(%s)...\n", + fwname); + ret = request_firmware(&fw, fwname, state->i2c->dev.parent); +- if (ret) { +- printk(KERN_WARNING "or51132: No firmware uploaded(timeout or file not found?)\n"); ++ if (ret) + return ret; +- } + ret = or51132_load_firmware(fe, fw); + release_firmware(fw); + if (ret) { +Index: linux/drivers/media/dvb-frontends/or51211.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/or51211.c ++++ linux/drivers/media/dvb-frontends/or51211.c +@@ -371,11 +371,8 @@ static int or51211_init(struct dvb_front + OR51211_DEFAULT_FIRMWARE); + ret = config->request_firmware(fe, &fw, + OR51211_DEFAULT_FIRMWARE); +- pr_info("Got Hotplug firmware\n"); +- if (ret) { +- pr_warn("No firmware uploaded (timeout or file not found?)\n"); ++ if (ret) + return ret; +- } + + ret = or51211_load_firmware(fe, fw); + release_firmware(fw); +Index: linux/drivers/media/dvb-frontends/sp8870.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/sp8870.c ++++ linux/drivers/media/dvb-frontends/sp8870.c +@@ -315,10 +315,8 @@ static int sp8870_init (struct dvb_front + + /* request the firmware, this will block until someone uploads it */ + printk("sp8870: waiting for firmware upload (%s)...\n", SP8870_DEFAULT_FIRMWARE); +- if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) { +- printk("sp8870: no firmware upload (timeout or file not found?)\n"); ++ if (state->config->request_firmware(fe, &fw, SP8870_DEFAULT_FIRMWARE)) + return -EIO; +- } + + if (sp8870_firmware_upload(state, fw)) { + printk("sp8870: writing firmware to device failed\n"); +Index: linux/drivers/media/dvb-frontends/sp887x.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/sp887x.c ++++ linux/drivers/media/dvb-frontends/sp887x.c +@@ -526,10 +526,8 @@ static int sp887x_init(struct dvb_fronte + /* request the firmware, this will block until someone uploads it */ + printk("sp887x: waiting for firmware upload (%s)...\n", SP887X_DEFAULT_FIRMWARE); + ret = state->config->request_firmware(fe, &fw, SP887X_DEFAULT_FIRMWARE); +- if (ret) { +- printk("sp887x: no firmware upload (timeout or file not found?)\n"); ++ if (ret) + return ret; +- } + + ret = sp887x_initial_setup(fe, fw); + release_firmware(fw); +Index: linux/drivers/media/dvb-frontends/tda10048.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/tda10048.c ++++ linux/drivers/media/dvb-frontends/tda10048.c +@@ -495,8 +495,6 @@ static int tda10048_firmware_upload(stru + ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE, + state->i2c->dev.parent); + if (ret) { +- printk(KERN_ERR "%s: Upload failed. (file not found?)\n", +- __func__); + return -EIO; + } else { + printk(KERN_INFO "%s: firmware read %zu bytes.\n", +Index: linux/drivers/media/dvb-frontends/tda1004x.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/tda1004x.c ++++ linux/drivers/media/dvb-frontends/tda1004x.c +@@ -401,10 +401,8 @@ static int tda10045_fwupload(struct dvb_ + /* request the firmware, this will block until someone uploads it */ + printk(KERN_INFO "tda1004x: waiting for firmware upload (%s)...\n", TDA10045_DEFAULT_FIRMWARE); + ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); +- if (ret) { +- printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); ++ if (ret) + return ret; +- } + + /* reset chip */ + tda1004x_write_mask(state, TDA1004X_CONFC4, 0x10, 0); +@@ -545,7 +543,6 @@ static int tda10046_fwupload(struct dvb_ + /* remain compatible to old bug: try to load with tda10045 image name */ + ret = state->config->request_firmware(fe, &fw, TDA10045_DEFAULT_FIRMWARE); + if (ret) { +- printk(KERN_ERR "tda1004x: no firmware upload (timeout or file not found?)\n"); + return ret; + } else { + printk(KERN_INFO "tda1004x: please rename the firmware file to %s\n", +Index: linux/drivers/media/dvb-frontends/tda10071.c +=================================================================== +--- linux.orig/drivers/media/dvb-frontends/tda10071.c ++++ linux/drivers/media/dvb-frontends/tda10071.c +@@ -850,12 +850,8 @@ static int tda10071_init(struct dvb_fron + + /* request the firmware, this will block and timeout */ + ret = request_firmware(&fw, fw_file, &client->dev); +- if (ret) { +- dev_err(&client->dev, +- "did not find the firmware file '%s' (status %d). You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware\n", +- fw_file, ret); ++ if (ret) + goto error; +- } + + /* init */ + for (i = 0; i < ARRAY_SIZE(tab2); i++) { +Index: linux/drivers/media/pci/ngene/ngene-core.c +=================================================================== +--- linux.orig/drivers/media/pci/ngene/ngene-core.c ++++ linux/drivers/media/pci/ngene/ngene-core.c +@@ -1253,19 +1253,14 @@ static int ngene_load_firm(struct ngene + break; + } + +- if (request_firmware(&fw, fw_name, &dev->pci_dev->dev) < 0) { +- dev_err(pdev, "Could not load firmware file %s.\n", fw_name); +- dev_info(pdev, "Copy %s to your hotplug directory!\n", +- fw_name); ++ if (request_firmware(&fw, fw_name, &dev->pci_dev->dev)) + return -1; +- } + if (size == 0) + size = fw->size; + if (size != fw->size) { + dev_err(pdev, "Firmware %s has invalid size!", fw_name); + err = -1; + } else { +- dev_info(pdev, "Loading firmware file %s.\n", fw_name); + ngene_fw = (u8 *) fw->data; + err = ngene_command_load_firmware(dev, ngene_fw, size); + } +Index: linux/drivers/media/common/siano/smscoreapi.c +=================================================================== +--- linux.orig/drivers/media/common/siano/smscoreapi.c ++++ linux/drivers/media/common/siano/smscoreapi.c +@@ -1164,10 +1164,8 @@ static int smscore_load_firmware_from_fi + return -EINVAL; + + rc = request_firmware(&fw, fw_filename, coredev->device); +- if (rc < 0) { +- pr_err("failed to open firmware file '%s'\n", fw_filename); ++ if (rc < 0) + return rc; +- } + pr_debug("read fw %s, buffer size=0x%zx\n", fw_filename, fw->size); + fw_buf = kmalloc(ALIGN(fw->size + sizeof(struct sms_firmware), + SMS_ALLOC_ALIGNMENT), GFP_KERNEL | coredev->gfp_buf_flags); +Index: linux/drivers/media/pci/ttpci/av7110.c +=================================================================== +--- linux.orig/drivers/media/pci/ttpci/av7110.c ++++ linux/drivers/media/pci/ttpci/av7110.c +@@ -1516,13 +1516,8 @@ static int get_firmware(struct av7110* a + /* request the av7110 firmware, this will block until someone uploads it */ + ret = request_firmware(&fw, "dvb-ttpci-01.fw", &av7110->dev->pci->dev); + if (ret) { +- if (ret == -ENOENT) { +- printk(KERN_ERR "dvb-ttpci: could not load firmware, file not found: dvb-ttpci-01.fw\n"); +- printk(KERN_ERR "dvb-ttpci: usually this should be in /usr/lib/hotplug/firmware or /lib/firmware\n"); +- printk(KERN_ERR "dvb-ttpci: and can be downloaded from https://linuxtv.org/download/dvb/firmware/\n"); +- } else +- printk(KERN_ERR "dvb-ttpci: cannot request firmware (error %i)\n", +- ret); ++ if (ret == -ENOENT) ++ printk(KERN_ERR "dvb-ttpci: firmware can be downloaded from https://linuxtv.org/download/dvb/firmware/\n"); + return -EINVAL; + } + +Index: linux/drivers/media/pci/ttpci/av7110_hw.c +=================================================================== +--- linux.orig/drivers/media/pci/ttpci/av7110_hw.c ++++ linux/drivers/media/pci/ttpci/av7110_hw.c +@@ -247,11 +247,8 @@ int av7110_bootarm(struct av7110 *av7110 + //saa7146_setgpio(dev, 3, SAA7146_GPIO_INPUT); + + ret = request_firmware(&fw, fw_name, &dev->pci->dev); +- if (ret) { +- printk(KERN_ERR "dvb-ttpci: Failed to load firmware \"%s\"\n", +- fw_name); ++ if (ret) + return ret; +- } + + mwdebi(av7110, DEBISWAB, DPRAM_BASE, fw->data, fw->size); + release_firmware(fw); +Index: linux/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +=================================================================== +--- linux.orig/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c ++++ linux/drivers/media/usb/ttusb-budget/dvb-ttusb-budget.c +@@ -295,10 +295,8 @@ static int ttusb_boot_dsp(struct ttusb * + + err = request_firmware(&fw, "ttusb-budget/dspbootcode.bin", + &ttusb->dev->dev); +- if (err) { +- printk(KERN_ERR "ttusb-budget: failed to request firmware\n"); ++ if (err) + return err; +- } + + /* BootBlock */ + b[0] = 0xaa; +Index: linux/drivers/media/usb/ttusb-dec/ttusb_dec.c +=================================================================== +--- linux.orig/drivers/media/usb/ttusb-dec/ttusb_dec.c ++++ linux/drivers/media/usb/ttusb-dec/ttusb_dec.c +@@ -1334,11 +1334,8 @@ static int ttusb_dec_boot_dsp(struct ttu + dprintk("%s\n", __func__); + + result = request_firmware(&fw_entry, dec->firmware_name, &dec->udev->dev); +- if (result) { +- printk(KERN_ERR "%s: Firmware (%s) unavailable.\n", +- __func__, dec->firmware_name); ++ if (result) + return result; +- } + + firmware = fw_entry->data; + firmware_size = fw_entry->size; +Index: linux/drivers/media/radio/radio-wl1273.c +=================================================================== +--- linux.orig/drivers/media/radio/radio-wl1273.c ++++ linux/drivers/media/radio/radio-wl1273.c +@@ -510,11 +510,8 @@ static int wl1273_fm_upload_firmware_pat + * Uploading the firmware patch is not always necessary, + * so we only print an info message. + */ +- if (request_firmware(&fw_p, fw_name, dev)) { +- dev_info(dev, "%s - %s not found\n", __func__, fw_name); +- ++ if (request_firmware(&fw_p, fw_name, dev)) + return 0; +- } + + ptr = (__u8 *) fw_p->data; + packet_num = ptr[0]; +Index: linux/drivers/media/radio/wl128x/fmdrv_common.c +=================================================================== +--- linux.orig/drivers/media/radio/wl128x/fmdrv_common.c ++++ linux/drivers/media/radio/wl128x/fmdrv_common.c +@@ -1245,10 +1245,8 @@ static int fm_download_firmware(struct f + + ret = request_firmware(&fw_entry, fw_name, + &fmdev->radio_dev->dev); +- if (ret < 0) { +- fmerr("Unable to read firmware(%s) content\n", fw_name); ++ if (ret) + return ret; +- } + fmdbg("Firmware(%s) length : %zu bytes\n", fw_name, fw_entry->size); + + fw_data = (void *)fw_entry->data; +Index: linux/drivers/media/pci/bt8xx/bttv-cards.c +=================================================================== +--- linux.orig/drivers/media/pci/bt8xx/bttv-cards.c ++++ linux/drivers/media/pci/bt8xx/bttv-cards.c +@@ -3916,10 +3916,8 @@ static int pvr_boot(struct bttv *btv) + int rc; + + rc = request_firmware(&fw_entry, "hcwamc.rbf", &btv->c.pci->dev); +- if (rc != 0) { +- pr_warn("%d: no altera firmware [via hotplug]\n", btv->c.nr); ++ if (rc != 0) + return rc; +- } + rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size); + pr_info("%d: altera firmware upload %s\n", + btv->c.nr, (rc < 0) ? "failed" : "ok"); +Index: linux/drivers/media/usb/cpia2/cpia2_core.c +=================================================================== +--- linux.orig/drivers/media/usb/cpia2/cpia2_core.c ++++ linux/drivers/media/usb/cpia2/cpia2_core.c +@@ -921,11 +921,8 @@ static int apply_vp_patch(struct camera_ + struct cpia2_command cmd; + + ret = request_firmware(&fw, fw_name, &cam->dev->dev); +- if (ret) { +- printk(KERN_ERR "cpia2: failed to load VP patch \"%s\"\n", +- fw_name); ++ if (ret) + return ret; +- } + + cmd.req_mode = CAMERAACCESS_TYPE_REPEAT | CAMERAACCESS_VP; + cmd.direction = TRANSFER_WRITE; +Index: linux/drivers/media/pci/cx18/cx18-av-firmware.c +=================================================================== +--- linux.orig/drivers/media/pci/cx18/cx18-av-firmware.c ++++ linux/drivers/media/pci/cx18/cx18-av-firmware.c +@@ -79,10 +79,8 @@ int cx18_av_loadfw(struct cx18 *cx) + int i; + int retries1 = 0; + +- if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) { +- CX18_ERR_DEV(sd, "unable to open firmware %s\n", FWFILE); ++ if (request_firmware(&fw, FWFILE, &cx->pci_dev->dev) != 0) + return -EINVAL; +- } + + /* The firmware load often has byte errors, so allow for several + retries, both at byte level and at the firmware load level. */ +Index: linux/drivers/media/pci/cx18/cx18-dvb.c +=================================================================== +--- linux.orig/drivers/media/pci/cx18/cx18-dvb.c ++++ linux/drivers/media/pci/cx18/cx18-dvb.c +@@ -137,9 +137,7 @@ static int yuan_mpc718_mt352_reqfw(struc + int ret; + + ret = request_firmware(fw, fn, &cx->pci_dev->dev); +- if (ret) +- CX18_ERR("Unable to open firmware file %s\n", fn); +- else { ++ if (!ret) { + size_t sz = (*fw)->size; + if (sz < 2 || sz > 64 || (sz % 2) != 0) { + CX18_ERR("Firmware %s has a bad size: %lu bytes\n", +Index: linux/drivers/media/pci/cx18/cx18-firmware.c +=================================================================== +--- linux.orig/drivers/media/pci/cx18/cx18-firmware.c ++++ linux/drivers/media/pci/cx18/cx18-firmware.c +@@ -101,11 +101,8 @@ static int load_cpu_fw_direct(const char + u32 __iomem *dst = (u32 __iomem *)mem; + const u32 *src; + +- if (request_firmware(&fw, fn, &cx->pci_dev->dev)) { +- CX18_ERR("Unable to open firmware %s\n", fn); +- CX18_ERR("Did you put the firmware in the hotplug firmware directory?\n"); ++ if (request_firmware(&fw, fn, &cx->pci_dev->dev)) + return -ENOMEM; +- } + + src = (const u32 *)fw->data; + +@@ -146,8 +143,6 @@ static int load_apu_fw_direct(const char + int sz; + + if (request_firmware(&fw, fn, &cx->pci_dev->dev)) { +- CX18_ERR("unable to open firmware %s\n", fn); +- CX18_ERR("did you put the firmware in the hotplug firmware directory?\n"); + cx18_setup_page(cx, 0); + return -ENOMEM; + } +Index: linux/drivers/media/usb/cx231xx/cx231xx-417.c +=================================================================== +--- linux.orig/drivers/media/usb/cx231xx/cx231xx-417.c ++++ linux/drivers/media/usb/cx231xx/cx231xx-417.c +@@ -996,11 +996,6 @@ static int cx231xx_load_firmware(struct + dev->dev); + + if (retval != 0) { +- dev_err(dev->dev, +- "ERROR: Hotplug firmware request failed (%s).\n", +- CX231xx_FIRM_IMAGE_NAME); +- dev_err(dev->dev, +- "Please fix your hotplug setup, the board will not work without firmware loaded!\n"); + vfree(p_current_fw); + vfree(p_buffer); + return retval; +Index: linux/drivers/media/pci/cx23885/cx23885-417.c +=================================================================== +--- linux.orig/drivers/media/pci/cx23885/cx23885-417.c ++++ linux/drivers/media/pci/cx23885/cx23885-417.c +@@ -929,12 +929,8 @@ static int cx23885_load_firmware(struct + retval = request_firmware(&firmware, CX23885_FIRM_IMAGE_NAME, + &dev->pci->dev); + +- if (retval != 0) { +- pr_err("ERROR: Hotplug firmware request failed (%s).\n", +- CX23885_FIRM_IMAGE_NAME); +- pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); ++ if (retval != 0) + return -1; +- } + + if (firmware->size != CX23885_FIRM_IMAGE_SIZE) { + pr_err("ERROR: Firmware size mismatch (have %zu, expected %d)\n", +Index: linux/drivers/media/pci/cx23885/cx23885-cards.c +=================================================================== +--- linux.orig/drivers/media/pci/cx23885/cx23885-cards.c ++++ linux/drivers/media/pci/cx23885/cx23885-cards.c +@@ -2425,10 +2425,7 @@ void cx23885_card_setup(struct cx23885_d + cinfo.rev, filename); + + ret = request_firmware(&fw, filename, &dev->pci->dev); +- if (ret != 0) +- pr_err("did not find the firmware file '%s'. You can use <kernel_dir>/scripts/get_dvb_firmware to get the firmware.", +- filename); +- else ++ if (ret == 0) + altera_init(&netup_config, fw); + + release_firmware(fw); +Index: linux/drivers/media/i2c/cx25840/cx25840-firmware.c +=================================================================== +--- linux.orig/drivers/media/i2c/cx25840/cx25840-firmware.c ++++ linux/drivers/media/i2c/cx25840/cx25840-firmware.c +@@ -122,10 +122,8 @@ int cx25840_loadfw(struct i2c_client *cl + if (is_cx231xx(state) && max_buf_size > 16) + max_buf_size = 16; + +- if (request_firmware(&fw, fwname, FWDEV(client)) != 0) { +- v4l_err(client, "unable to open firmware %s\n", fwname); ++ if (request_firmware(&fw, fwname, FWDEV(client)) != 0) + return -EINVAL; +- } + + start_fw_load(client); + +Index: linux/drivers/media/pci/cx88/cx88-blackbird.c +=================================================================== +--- linux.orig/drivers/media/pci/cx88/cx88-blackbird.c ++++ linux/drivers/media/pci/cx88/cx88-blackbird.c +@@ -471,12 +471,8 @@ static int blackbird_load_firmware(struc + retval = request_firmware(&firmware, CX2341X_FIRM_ENC_FILENAME, + &dev->pci->dev); + +- if (retval != 0) { +- pr_err("Hotplug firmware request failed (%s).\n", +- CX2341X_FIRM_ENC_FILENAME); +- pr_err("Please fix your hotplug setup, the board will not work without firmware loaded!\n"); ++ if (retval != 0) + return -EIO; +- } + + if (firmware->size != BLACKBIRD_FIRM_IMAGE_SIZE) { + pr_err("Firmware size mismatch (have %zd, expected %d)\n", +Index: linux/drivers/media/usb/gspca/vicam.c +=================================================================== +--- linux.orig/drivers/media/usb/gspca/vicam.c ++++ linux/drivers/media/usb/gspca/vicam.c +@@ -239,10 +239,8 @@ static int sd_init(struct gspca_dev *gsp + + ret = request_ihex_firmware(&fw, VICAM_FIRMWARE, + &gspca_dev->dev->dev); +- if (ret) { +- pr_err("Failed to load \"vicam/firmware.fw\": %d\n", ret); ++ if (ret) + return ret; +- } + + firmware_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!firmware_buf) { +Index: linux/drivers/media/pci/ivtv/ivtv-firmware.c +=================================================================== +--- linux.orig/drivers/media/pci/ivtv/ivtv-firmware.c ++++ linux/drivers/media/pci/ivtv/ivtv-firmware.c +@@ -80,8 +80,6 @@ retry: + release_firmware(fw); + return size; + } +- IVTV_ERR("Unable to open firmware %s (must be %ld bytes)\n", fn, size); +- IVTV_ERR("Did you put the firmware in the hotplug firmware directory?\n"); + return -ENOMEM; + } + +Index: linux/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +=================================================================== +--- linux.orig/drivers/media/usb/pvrusb2/pvrusb2-hdw.c ++++ linux/drivers/media/usb/pvrusb2/pvrusb2-hdw.c +@@ -1379,25 +1379,6 @@ static int pvr2_locate_firmware(struct p + "request_firmware fatal error with code=%d",ret); + return ret; + } +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "***WARNING*** Device %s firmware seems to be missing.", +- fwtypename); +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "Did you install the pvrusb2 firmware files in their proper location?"); +- if (fwcount == 1) { +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "request_firmware unable to locate %s file %s", +- fwtypename,fwnames[0]); +- } else { +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "request_firmware unable to locate one of the following %s files:", +- fwtypename); +- for (idx = 0; idx < fwcount; idx++) { +- pvr2_trace(PVR2_TRACE_ERROR_LEGS, +- "request_firmware: Failed to find %s", +- fwnames[idx]); +- } +- } + return ret; + } + +Index: linux/drivers/media/usb/s2255/s2255drv.c +=================================================================== +--- linux.orig/drivers/media/usb/s2255/s2255drv.c ++++ linux/drivers/media/usb/s2255/s2255drv.c +@@ -2298,10 +2298,8 @@ static int s2255_probe(struct usb_interf + } + /* load the first chunk */ + if (request_firmware(&dev->fw_data->fw, +- FIRMWARE_FILE_NAME, &dev->udev->dev)) { +- dev_err(&interface->dev, "sensoray 2255 failed to get firmware\n"); ++ FIRMWARE_FILE_NAME, &dev->udev->dev)) + goto errorREQFW; +- } + /* check the firmware is valid */ + fw_size = dev->fw_data->fw->size; + pdata = (__le32 *) &dev->fw_data->fw->data[fw_size - 8]; +Index: linux/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +=================================================================== +--- linux.orig/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c ++++ linux/drivers/media/platform/s5p-mfc/s5p_mfc_ctrl.c +@@ -69,10 +69,8 @@ int s5p_mfc_load_firmware(struct s5p_mfc + } + } + +- if (err != 0) { +- mfc_err("Firmware is not present in the /lib/firmware directory nor compiled in kernel\n"); ++ if (err != 0) + return -EINVAL; +- } + if (fw_blob->size > dev->fw_buf.size) { + mfc_err("MFC firmware is too big to be loaded\n"); + release_firmware(fw_blob); +Index: linux/drivers/media/pci/saa7164/saa7164-fw.c +=================================================================== +--- linux.orig/drivers/media/pci/saa7164/saa7164-fw.c ++++ linux/drivers/media/pci/saa7164/saa7164-fw.c +@@ -416,11 +416,8 @@ int saa7164_downloadfirmware(struct saa7 + __func__, fwname); + + ret = request_firmware(&fw, fwname, &dev->pci->dev); +- if (ret) { +- printk(KERN_ERR "%s() Upload failed. (file not found?)\n", +- __func__); ++ if (ret) + return -ENOMEM; +- } + + printk(KERN_INFO "%s() firmware read %zu bytes.\n", + __func__, fw->size); +Index: linux/drivers/misc/ti-st/st_kim.c +=================================================================== +--- linux.orig/drivers/misc/ti-st/st_kim.c ++++ linux/drivers/misc/ti-st/st_kim.c +@@ -301,11 +301,8 @@ static long download_firmware(struct kim + request_firmware(&kim_gdata->fw_entry, bts_scr_name, + &kim_gdata->kim_pdev->dev); + if (unlikely((err != 0) || (kim_gdata->fw_entry->data == NULL) || +- (kim_gdata->fw_entry->size == 0))) { +- pr_err(" request_firmware failed(errno %ld) for %s", err, +- bts_scr_name); ++ (kim_gdata->fw_entry->size == 0))) + return -EINVAL; +- } + ptr = (void *)kim_gdata->fw_entry->data; + len = kim_gdata->fw_entry->size; + /* bts_header to remove out magic number and +Index: linux/drivers/net/can/softing/softing_fw.c +=================================================================== +--- linux.orig/drivers/net/can/softing/softing_fw.c ++++ linux/drivers/net/can/softing/softing_fw.c +@@ -237,11 +237,8 @@ int softing_load_app_fw(const char *file + int8_t type_end = 0, type_entrypoint = 0; + + ret = request_firmware(&fw, file, &card->pdev->dev); +- if (ret) { +- dev_alert(&card->pdev->dev, "request_firmware(%s) got %i\n", +- file, ret); ++ if (ret) + return ret; +- } + dev_dbg(&card->pdev->dev, "firmware(%s) got %lu bytes\n", + file, (unsigned long)fw->size); + /* parse the firmware */ +Index: linux/drivers/net/ethernet/3com/typhoon.c +=================================================================== +--- linux.orig/drivers/net/ethernet/3com/typhoon.c ++++ linux/drivers/net/ethernet/3com/typhoon.c +@@ -1283,11 +1283,8 @@ typhoon_request_firmware(struct typhoon + return 0; + + err = request_firmware(&typhoon_fw, FIRMWARE_NAME, &tp->pdev->dev); +- if (err) { +- netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", +- FIRMWARE_NAME); ++ if (err) + return err; +- } + + image_data = typhoon_fw->data; + remaining = typhoon_fw->size; +Index: linux/drivers/net/ethernet/adaptec/starfire.c +=================================================================== +--- linux.orig/drivers/net/ethernet/adaptec/starfire.c ++++ linux/drivers/net/ethernet/adaptec/starfire.c +@@ -1015,11 +1015,8 @@ static int netdev_open(struct net_device + #endif /* VLAN_SUPPORT */ + + retval = request_firmware(&fw_rx, FIRMWARE_RX, &np->pci_dev->dev); +- if (retval) { +- printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n", +- FIRMWARE_RX); ++ if (retval) + goto out_init; +- } + if (fw_rx->size % 4) { + printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n", + fw_rx->size, FIRMWARE_RX); +@@ -1027,11 +1024,8 @@ static int netdev_open(struct net_device + goto out_rx; + } + retval = request_firmware(&fw_tx, FIRMWARE_TX, &np->pci_dev->dev); +- if (retval) { +- printk(KERN_ERR "starfire: Failed to load firmware \"%s\"\n", +- FIRMWARE_TX); ++ if (retval) + goto out_rx; +- } + if (fw_tx->size % 4) { + printk(KERN_ERR "starfire: bogus length %zu in \"%s\"\n", + fw_tx->size, FIRMWARE_TX); +Index: linux/drivers/net/ethernet/alteon/acenic.c +=================================================================== +--- linux.orig/drivers/net/ethernet/alteon/acenic.c ++++ linux/drivers/net/ethernet/alteon/acenic.c +@@ -2890,11 +2890,8 @@ static int ace_load_firmware(struct net_ + fw_name = "acenic/tg1.bin"; + + ret = request_firmware(&fw, fw_name, &ap->pdev->dev); +- if (ret) { +- printk(KERN_ERR "%s: Failed to load firmware \"%s\"\n", +- ap->name, fw_name); ++ if (ret) + return ret; +- } + + fw_data = (void *)fw->data; + +Index: linux/drivers/net/ethernet/broadcom/bnx2.c +=================================================================== +--- linux.orig/drivers/net/ethernet/broadcom/bnx2.c ++++ linux/drivers/net/ethernet/broadcom/bnx2.c +@@ -3720,16 +3720,13 @@ static int bnx2_request_uncached_firmwar + } + + rc = request_firmware(&bp->mips_firmware, mips_fw_file, &bp->pdev->dev); +- if (rc) { +- pr_err("Can't load firmware file \"%s\"\n", mips_fw_file); ++ if (rc) + goto out; +- } + + rc = request_firmware(&bp->rv2p_firmware, rv2p_fw_file, &bp->pdev->dev); +- if (rc) { +- pr_err("Can't load firmware file \"%s\"\n", rv2p_fw_file); ++ if (rc) + goto err_release_mips_firmware; +- } ++ + mips_fw = (const struct bnx2_mips_fw_file *) bp->mips_firmware->data; + rv2p_fw = (const struct bnx2_rv2p_fw_file *) bp->rv2p_firmware->data; + if (bp->mips_firmware->size < sizeof(*mips_fw) || +Index: linux/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +=================================================================== +--- linux.orig/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c ++++ linux/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +@@ -13557,11 +13557,8 @@ static int bnx2x_init_firmware(struct bn + BNX2X_DEV_INFO("Loading %s\n", fw_file_name); + + rc = request_firmware(&bp->firmware, fw_file_name, &bp->pdev->dev); +- if (rc) { +- BNX2X_ERR("Can't load firmware file %s\n", +- fw_file_name); ++ if (rc) + goto request_firmware_exit; +- } + + rc = bnx2x_check_firmware(bp); + if (rc) { +Index: linux/drivers/net/ethernet/broadcom/tg3.c +=================================================================== +--- linux.orig/drivers/net/ethernet/broadcom/tg3.c ++++ linux/drivers/net/ethernet/broadcom/tg3.c +@@ -11408,11 +11408,8 @@ static int tg3_request_firmware(struct t + { + const struct tg3_firmware_hdr *fw_hdr; + +- if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) { +- netdev_err(tp->dev, "Failed to load firmware \"%s\"\n", +- tp->fw_needed); ++ if (request_firmware(&tp->fw, tp->fw_needed, &tp->pdev->dev)) + return -ENOENT; +- } + + fw_hdr = (struct tg3_firmware_hdr *)tp->fw->data; + +Index: linux/drivers/net/ethernet/brocade/bna/cna_fwimg.c +=================================================================== +--- linux.orig/drivers/net/ethernet/brocade/bna/cna_fwimg.c ++++ linux/drivers/net/ethernet/brocade/bna/cna_fwimg.c +@@ -32,10 +32,8 @@ cna_read_firmware(struct pci_dev *pdev, + const struct firmware *fw; + u32 n; + +- if (request_firmware(&fw, fw_name, &pdev->dev)) { +- dev_alert(&pdev->dev, "can't load firmware %s\n", fw_name); ++ if (request_firmware(&fw, fw_name, &pdev->dev)) + goto error; +- } + + *bfi_image = (u32 *)fw->data; + *bfi_image_size = fw->size/sizeof(u32); +Index: linux/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +=================================================================== +--- linux.orig/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c ++++ linux/drivers/net/ethernet/chelsio/cxgb3/cxgb3_main.c +@@ -1038,12 +1038,8 @@ int t3_get_edc_fw(struct cphy *phy, int + fw_name = get_edc_fw_name(edc_idx); + if (fw_name) + ret = request_firmware(&fw, fw_name, &adapter->pdev->dev); +- if (ret < 0) { +- dev_err(&adapter->pdev->dev, +- "could not upgrade firmware: unable to load %s\n", +- fw_name); ++ if (ret) + return ret; +- } + + /* check size, take checksum in account */ + if (fw->size > size + 4) { +@@ -1080,11 +1076,8 @@ static int upgrade_fw(struct adapter *ad + struct device *dev = &adap->pdev->dev; + + ret = request_firmware(&fw, FW_FNAME, dev); +- if (ret < 0) { +- dev_err(dev, "could not upgrade firmware: unable to load %s\n", +- FW_FNAME); ++ if (ret) + return ret; +- } + ret = t3_load_fw(adap, fw->data, fw->size); + release_firmware(fw); + +@@ -1129,11 +1122,8 @@ static int update_tpsram(struct adapter + snprintf(buf, sizeof(buf), TPSRAM_NAME, rev); + + ret = request_firmware(&tpsram, buf, dev); +- if (ret < 0) { +- dev_err(dev, "could not load TP SRAM: unable to load %s\n", +- buf); ++ if (ret) + return ret; +- } + + ret = t3_check_tpsram(adap, tpsram->data, tpsram->size); + if (ret) +Index: linux/drivers/net/ethernet/intel/e100.c +=================================================================== +--- linux.orig/drivers/net/ethernet/intel/e100.c ++++ linux/drivers/net/ethernet/intel/e100.c +@@ -1265,9 +1265,6 @@ static const struct firmware *e100_reque + + if (err) { + if (required) { +- netif_err(nic, probe, nic->netdev, +- "Failed to load firmware \"%s\": %d\n", +- fw_name, err); + return ERR_PTR(err); + } else { + netif_info(nic, probe, nic->netdev, +Index: linux/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +=================================================================== +--- linux.orig/drivers/net/ethernet/myricom/myri10ge/myri10ge.c ++++ linux/drivers/net/ethernet/myricom/myri10ge/myri10ge.c +@@ -581,8 +581,6 @@ static int myri10ge_load_hotplug_firmwar + unsigned i; + + if ((status = request_firmware(&fw, mgp->fw_name, dev)) < 0) { +- dev_err(dev, "Unable to load %s firmware image via hotplug\n", +- mgp->fw_name); + status = -EINVAL; + goto abort_with_nothing; + } +Index: linux/drivers/net/ethernet/smsc/smc91c92_cs.c +=================================================================== +--- linux.orig/drivers/net/ethernet/smsc/smc91c92_cs.c ++++ linux/drivers/net/ethernet/smsc/smc91c92_cs.c +@@ -647,10 +647,8 @@ static int osi_load_firmware(struct pcmc + int i, err; + + err = request_firmware(&fw, FIRMWARE_NAME, &link->dev); +- if (err) { +- pr_err("Failed to load firmware \"%s\"\n", FIRMWARE_NAME); ++ if (err) + return err; +- } + + /* Download the Seven of Diamonds firmware */ + for (i = 0; i < fw->size; i++) { +Index: linux/drivers/net/ethernet/sun/cassini.c +=================================================================== +--- linux.orig/drivers/net/ethernet/sun/cassini.c ++++ linux/drivers/net/ethernet/sun/cassini.c +@@ -805,11 +805,8 @@ static void cas_saturn_firmware_init(str + return; + + err = request_firmware(&fw, fw_name, &cp->pdev->dev); +- if (err) { +- pr_err("Failed to load firmware \"%s\"\n", +- fw_name); ++ if (err) + return; +- } + if (fw->size < 2) { + pr_err("bogus length %zu in \"%s\"\n", + fw->size, fw_name); +Index: linux/drivers/net/hamradio/yam.c +=================================================================== +--- linux.orig/drivers/net/hamradio/yam.c ++++ linux/drivers/net/hamradio/yam.c +@@ -372,11 +372,8 @@ static unsigned char *add_mcs(unsigned c + } + err = request_firmware(&fw, fw_name[predef], &pdev->dev); + platform_device_unregister(pdev); +- if (err) { +- printk(KERN_ERR "Failed to load firmware \"%s\"\n", +- fw_name[predef]); ++ if (err) + return NULL; +- } + if (fw->size != YAM_FPGA_SIZE) { + printk(KERN_ERR "Bogus length %zu in firmware \"%s\"\n", + fw->size, fw_name[predef]); +Index: linux/drivers/net/usb/kaweth.c +=================================================================== +--- linux.orig/drivers/net/usb/kaweth.c ++++ linux/drivers/net/usb/kaweth.c +@@ -390,10 +390,8 @@ static int kaweth_download_firmware(stru + int ret; + + ret = request_firmware(&fw, fwname, &kaweth->dev->dev); +- if (ret) { +- dev_err(&kaweth->intf->dev, "Firmware request failed\n"); ++ if (ret) + return ret; +- } + + if (fw->size > KAWETH_FIRMWARE_BUF_SIZE) { + dev_err(&kaweth->intf->dev, "Firmware too big: %zu\n", +Index: linux/drivers/net/wimax/i2400m/fw.c +=================================================================== +--- linux.orig/drivers/net/wimax/i2400m/fw.c ++++ linux/drivers/net/wimax/i2400m/fw.c +@@ -1583,11 +1583,8 @@ int i2400m_dev_bootstrap(struct i2400m * + } + d_printf(1, dev, "trying firmware %s (%d)\n", fw_name, itr); + ret = request_firmware(&fw, fw_name, dev); +- if (ret < 0) { +- dev_err(dev, "fw %s: cannot load file: %d\n", +- fw_name, ret); ++ if (ret) + continue; +- } + i2400m->fw_name = fw_name; + ret = i2400m_fw_bootstrap(i2400m, fw, flags); + release_firmware(fw); +@@ -1630,8 +1627,6 @@ void i2400m_fw_cache(struct i2400m *i240 + kref_init(&i2400m_fw->kref); + result = request_firmware(&i2400m_fw->fw, i2400m->fw_name, dev); + if (result < 0) { +- dev_err(dev, "firmware %s: failed to cache: %d\n", +- i2400m->fw_name, result); + kfree(i2400m_fw); + i2400m_fw = (void *) ~0; + } else +Index: linux/drivers/net/wireless/atmel/at76c50x-usb.c +=================================================================== +--- linux.orig/drivers/net/wireless/atmel/at76c50x-usb.c ++++ linux/drivers/net/wireless/atmel/at76c50x-usb.c +@@ -1622,13 +1622,8 @@ static struct fwentry *at76_load_firmwar + + at76_dbg(DBG_FW, "downloading firmware %s", fwe->fwname); + ret = request_firmware(&fwe->fw, fwe->fwname, &udev->dev); +- if (ret < 0) { +- dev_err(&udev->dev, "firmware %s not found!\n", +- fwe->fwname); +- dev_err(&udev->dev, +- "you may need to download the firmware from http://developer.berlios.de/projects/at76c503a/\n"); ++ if (ret) + goto exit; +- } + + at76_dbg(DBG_FW, "got it."); + fwh = (struct at76_fw_header *)(fwe->fw->data); +Index: linux/drivers/net/wireless/ath/ath9k/hif_usb.c +=================================================================== +--- linux.orig/drivers/net/wireless/ath/ath9k/hif_usb.c ++++ linux/drivers/net/wireless/ath/ath9k/hif_usb.c +@@ -1164,9 +1164,6 @@ static void ath9k_hif_usb_firmware_cb(co + if (!ret) + return; + +- dev_err(&hif_dev->udev->dev, +- "ath9k_htc: Failed to get firmware %s\n", +- hif_dev->fw_name); + goto err_fw; + } + +Index: linux/drivers/net/wireless/ath/carl9170/usb.c +=================================================================== +--- linux.orig/drivers/net/wireless/ath/carl9170/usb.c ++++ linux/drivers/net/wireless/ath/carl9170/usb.c +@@ -1029,7 +1029,6 @@ static void carl9170_usb_firmware_step2( + return; + } + +- dev_err(&ar->udev->dev, "firmware not found.\n"); + carl9170_usb_firmware_failed(ar); + } + +Index: linux/drivers/net/wireless/atmel/atmel.c +=================================================================== +--- linux.orig/drivers/net/wireless/atmel/atmel.c ++++ linux/drivers/net/wireless/atmel/atmel.c +@@ -3893,12 +3893,8 @@ static int reset_atmel_card(struct net_d + strcpy(priv->firmware_id, "atmel_at76c502.bin"); + } + err = request_firmware(&fw_entry, priv->firmware_id, priv->sys_dev); +- if (err != 0) { +- printk(KERN_ALERT +- "%s: firmware %s is missing, cannot continue.\n", +- dev->name, priv->firmware_id); ++ if (err != 0) + return err; +- } + } else { + int fw_index = 0; + int success = 0; +Index: linux/drivers/net/wireless/broadcom/b43/main.c +=================================================================== +--- linux.orig/drivers/net/wireless/broadcom/b43/main.c ++++ linux/drivers/net/wireless/broadcom/b43/main.c +@@ -2263,19 +2263,8 @@ int b43_do_request_fw(struct b43_request + } + err = request_firmware(&ctx->blob, ctx->fwname, + ctx->dev->dev->dev); +- if (err == -ENOENT) { +- snprintf(ctx->errors[ctx->req_type], +- sizeof(ctx->errors[ctx->req_type]), +- "Firmware file \"%s\" not found\n", +- ctx->fwname); ++ if (err) + return err; +- } else if (err) { +- snprintf(ctx->errors[ctx->req_type], +- sizeof(ctx->errors[ctx->req_type]), +- "Firmware file \"%s\" request failed (err=%d)\n", +- ctx->fwname, err); +- return err; +- } + fw_ready: + if (ctx->blob->size < sizeof(struct b43_fw_header)) + goto err_format; +Index: linux/drivers/net/wireless/broadcom/b43legacy/main.c +=================================================================== +--- linux.orig/drivers/net/wireless/broadcom/b43legacy/main.c ++++ linux/drivers/net/wireless/broadcom/b43legacy/main.c +@@ -1554,11 +1554,8 @@ static int do_request_fw(struct b43legac + } else { + err = request_firmware(fw, path, dev->dev->dev); + } +- if (err) { +- b43legacyerr(dev->wl, "Firmware file \"%s\" not found " +- "or load failed.\n", path); ++ if (err) + return err; +- } + if ((*fw)->size < sizeof(struct b43legacy_fw_header)) + goto err_format; + hdr = (struct b43legacy_fw_header *)((*fw)->data); +Index: linux/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +=================================================================== +--- linux.orig/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c ++++ linux/drivers/net/wireless/broadcom/brcm80211/brcmsmac/mac80211_if.c +@@ -378,19 +378,13 @@ static int brcms_request_fw(struct brcms + sprintf(fw_name, "%s-%d.fw", brcms_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); +- if (status) { +- wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", +- KBUILD_MODNAME, fw_name); ++ if (status) + return status; +- } + sprintf(fw_name, "%s_hdr-%d.fw", brcms_firmwares[i], + UCODE_LOADER_API_VER); + status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); +- if (status) { +- wiphy_err(wl->wiphy, "%s: fail to load firmware %s\n", +- KBUILD_MODNAME, fw_name); ++ if (status) + return status; +- } + wl->fw.hdr_num_entries[i] = + wl->fw.fw_hdr[i]->size / (sizeof(struct firmware_hdr)); + } +Index: linux/drivers/net/wireless/intel/ipw2x00/ipw2100.c +=================================================================== +--- linux.orig/drivers/net/wireless/intel/ipw2x00/ipw2100.c ++++ linux/drivers/net/wireless/intel/ipw2x00/ipw2100.c +@@ -8410,12 +8410,8 @@ static int ipw2100_get_firmware(struct i + + rc = request_firmware(&fw->fw_entry, fw_name, &priv->pci_dev->dev); + +- if (rc < 0) { +- printk(KERN_ERR DRV_NAME ": " +- "%s: Firmware '%s' not available or load failed.\n", +- priv->net_dev->name, fw_name); ++ if (rc) + return rc; +- } + IPW_DEBUG_INFO("firmware data %p size %zd\n", fw->fw_entry->data, + fw->fw_entry->size); + +Index: linux/drivers/net/wireless/intel/ipw2x00/ipw2200.c +=================================================================== +--- linux.orig/drivers/net/wireless/intel/ipw2x00/ipw2200.c ++++ linux/drivers/net/wireless/intel/ipw2x00/ipw2200.c +@@ -3410,10 +3410,8 @@ static int ipw_get_fw(struct ipw_priv *p + + /* ask firmware_class module to get the boot firmware off disk */ + rc = request_firmware(raw, name, &priv->pci_dev->dev); +- if (rc < 0) { +- IPW_ERROR("%s request_firmware failed: Reason %d\n", name, rc); ++ if (rc) + return rc; +- } + + if ((*raw)->size < sizeof(*fw)) { + IPW_ERROR("%s is too small (%zd)\n", name, (*raw)->size); +Index: linux/drivers/net/wireless/intel/iwlegacy/3945-mac.c +=================================================================== +--- linux.orig/drivers/net/wireless/intel/iwlegacy/3945-mac.c ++++ linux/drivers/net/wireless/intel/iwlegacy/3945-mac.c +@@ -1854,7 +1854,6 @@ il3945_read_ucode(struct il_priv *il) + sprintf(buf, "%s%u%s", name_pre, idx, ".ucode"); + ret = request_firmware(&ucode_raw, buf, &il->pci_dev->dev); + if (ret < 0) { +- IL_ERR("%s firmware file req failed: %d\n", buf, ret); + if (ret == -ENOENT) + continue; + else +Index: linux/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +=================================================================== +--- linux.orig/drivers/net/wireless/intel/iwlwifi/iwl-drv.c ++++ linux/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +@@ -236,8 +236,6 @@ static int iwl_request_firmware(struct i + } + + if (drv->fw_index < cfg->ucode_api_min) { +- IWL_ERR(drv, "no suitable firmware found!\n"); +- + if (cfg->ucode_api_min == cfg->ucode_api_max) { + IWL_ERR(drv, "%s%d is required\n", fw_pre_name, + cfg->ucode_api_max); +Index: linux/drivers/net/wireless/marvell/libertas_tf/if_usb.c +=================================================================== +--- linux.orig/drivers/net/wireless/marvell/libertas_tf/if_usb.c ++++ linux/drivers/net/wireless/marvell/libertas_tf/if_usb.c +@@ -817,8 +817,6 @@ static int if_usb_prog_firmware(struct i + kernel_param_lock(THIS_MODULE); + ret = request_firmware(&cardp->fw, lbtf_fw_name, &cardp->udev->dev); + if (ret < 0) { +- pr_err("request_firmware() failed with %#x\n", ret); +- pr_err("firmware %s not found\n", lbtf_fw_name); + kernel_param_unlock(THIS_MODULE); + goto done; + } +Index: linux/drivers/net/wireless/marvell/mwifiex/main.c +=================================================================== +--- linux.orig/drivers/net/wireless/marvell/mwifiex/main.c ++++ linux/drivers/net/wireless/marvell/mwifiex/main.c +@@ -528,11 +528,8 @@ static int _mwifiex_fw_dpc(const struct + struct wireless_dev *wdev; + struct completion *fw_done = adapter->fw_done; + +- if (!firmware) { +- mwifiex_dbg(adapter, ERROR, +- "Failed to get firmware %s\n", adapter->fw_name); ++ if (!firmware) + goto err_dnld_fw; +- } + + memset(&fw, 0, sizeof(struct mwifiex_fw_image)); + adapter->firmware = firmware; +Index: linux/drivers/net/wireless/marvell/mwl8k.c +=================================================================== +--- linux.orig/drivers/net/wireless/marvell/mwl8k.c ++++ linux/drivers/net/wireless/marvell/mwl8k.c +@@ -5724,16 +5724,12 @@ static int mwl8k_firmware_load_success(s + static void mwl8k_fw_state_machine(const struct firmware *fw, void *context) + { + struct mwl8k_priv *priv = context; +- struct mwl8k_device_info *di = priv->device_info; + int rc; + + switch (priv->fw_state) { + case FW_STATE_INIT: +- if (!fw) { +- printk(KERN_ERR "%s: Error requesting helper fw %s\n", +- pci_name(priv->pdev), di->helper_image); ++ if (!fw) + goto fail; +- } + priv->fw_helper = fw; + rc = mwl8k_request_fw(priv, priv->fw_pref, &priv->fw_ucode, + true); +@@ -5768,11 +5764,8 @@ static void mwl8k_fw_state_machine(const + break; + + case FW_STATE_LOADING_ALT: +- if (!fw) { +- printk(KERN_ERR "%s: Error requesting alt fw %s\n", +- pci_name(priv->pdev), di->helper_image); ++ if (!fw) + goto fail; +- } + priv->fw_ucode = fw; + rc = mwl8k_firmware_load_success(priv); + if (rc) +@@ -5810,10 +5803,8 @@ retry: + + /* Ask userland hotplug daemon for the device firmware */ + rc = mwl8k_request_firmware(priv, fw_image, nowait); +- if (rc) { +- wiphy_err(hw->wiphy, "Firmware files not found\n"); ++ if (rc) + return rc; +- } + + if (nowait) + return rc; +Index: linux/drivers/net/wireless/intersil/orinoco/fw.c +=================================================================== +--- linux.orig/drivers/net/wireless/intersil/orinoco/fw.c ++++ linux/drivers/net/wireless/intersil/orinoco/fw.c +@@ -132,7 +132,6 @@ orinoco_dl_firmware(struct orinoco_priva + err = request_firmware(&fw_entry, firmware, priv->dev); + + if (err) { +- dev_err(dev, "Cannot find firmware %s\n", firmware); + err = -ENOENT; + goto free; + } +@@ -292,10 +291,8 @@ symbol_dl_firmware(struct orinoco_privat + const struct firmware *fw_entry; + + if (!orinoco_cached_fw_get(priv, true)) { +- if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) { +- dev_err(dev, "Cannot find firmware: %s\n", fw->pri_fw); ++ if (request_firmware(&fw_entry, fw->pri_fw, priv->dev) != 0) + return -ENOENT; +- } + } else + fw_entry = orinoco_cached_fw_get(priv, true); + +@@ -311,10 +308,8 @@ symbol_dl_firmware(struct orinoco_privat + } + + if (!orinoco_cached_fw_get(priv, false)) { +- if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) { +- dev_err(dev, "Cannot find firmware: %s\n", fw->sta_fw); ++ if (request_firmware(&fw_entry, fw->sta_fw, priv->dev) != 0) + return -ENOENT; +- } + } else + fw_entry = orinoco_cached_fw_get(priv, false); + +Index: linux/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +=================================================================== +--- linux.orig/drivers/net/wireless/intersil/orinoco/orinoco_usb.c ++++ linux/drivers/net/wireless/intersil/orinoco/orinoco_usb.c +@@ -1677,7 +1677,6 @@ static int ezusb_probe(struct usb_interf + if (ezusb_firmware_download(upriv, &firmware) < 0) + goto error; + } else { +- err("No firmware to download"); + goto error; + } + +Index: linux/drivers/net/wireless/intersil/p54/p54pci.c +=================================================================== +--- linux.orig/drivers/net/wireless/intersil/p54/p54pci.c ++++ linux/drivers/net/wireless/intersil/p54/p54pci.c +@@ -499,7 +499,6 @@ static void p54p_firmware_step2(const st + int err; + + if (!fw) { +- dev_err(&pdev->dev, "Cannot find firmware (isl3886pci)\n"); + err = -ENOENT; + goto out; + } +Index: linux/drivers/net/wireless/intersil/p54/p54spi.c +=================================================================== +--- linux.orig/drivers/net/wireless/intersil/p54/p54spi.c ++++ linux/drivers/net/wireless/intersil/p54/p54spi.c +@@ -170,10 +170,8 @@ static int p54spi_request_firmware(struc + /* FIXME: should driver use it's own struct device? */ + ret = request_firmware(&priv->firmware, "3826.arm", &priv->spi->dev); + +- if (ret < 0) { +- dev_err(&priv->spi->dev, "request_firmware() failed: %d", ret); ++ if (ret) + return ret; +- } + + ret = p54_parse_firmware(dev, priv->firmware); + if (ret) { +Index: linux/drivers/net/wireless/intersil/p54/p54usb.c +=================================================================== +--- linux.orig/drivers/net/wireless/intersil/p54/p54usb.c ++++ linux/drivers/net/wireless/intersil/p54/p54usb.c +@@ -931,7 +931,6 @@ static void p54u_load_firmware_cb(const + err = p54u_start_ops(priv); + } else { + err = -ENOENT; +- dev_err(&udev->dev, "Firmware not found.\n"); + } + + complete(&priv->fw_wait_load); +Index: linux/drivers/net/wireless/intersil/prism54/islpci_dev.c +=================================================================== +--- linux.orig/drivers/net/wireless/intersil/prism54/islpci_dev.c ++++ linux/drivers/net/wireless/intersil/prism54/islpci_dev.c +@@ -92,12 +92,9 @@ isl_upload_firmware(islpci_private *priv + const u32 *fw_ptr; + + rc = request_firmware(&fw_entry, priv->firmware, PRISM_FW_PDEV); +- if (rc) { +- printk(KERN_ERR +- "%s: request_firmware() failed for '%s'\n", +- "prism54", priv->firmware); ++ if (rc) + return rc; +- } ++ + /* prepare the Direct Memory Base register */ + reg = ISL38XX_DEV_FIRMWARE_ADDRES; + +Index: linux/drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c +=================================================================== +--- linux.orig/drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c ++++ linux/drivers/net/wireless/ralink/rt2x00/rt2x00firmware.c +@@ -49,10 +49,8 @@ static int rt2x00lib_request_firmware(st + rt2x00_info(rt2x00dev, "Loading firmware file '%s'\n", fw_name); + + retval = request_firmware(&fw, fw_name, device); +- if (retval) { +- rt2x00_err(rt2x00dev, "Failed to request Firmware\n"); ++ if (retval) + return retval; +- } + + if (!fw || !fw->size || !fw->data) { + rt2x00_err(rt2x00dev, "Failed to read Firmware\n"); +Index: linux/drivers/net/wireless/realtek/rtlwifi/core.c +=================================================================== +--- linux.orig/drivers/net/wireless/realtek/rtlwifi/core.c ++++ linux/drivers/net/wireless/realtek/rtlwifi/core.c +@@ -111,7 +111,6 @@ static void rtl_fw_do_work(const struct + if (!err) + goto found_alt; + } +- pr_err("Selected firmware is not available\n"); + rtlpriv->max_fw_size = 0; + return; + } +Index: linux/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +=================================================================== +--- linux.orig/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c ++++ linux/drivers/net/wireless/realtek/rtlwifi/rtl8192se/sw.c +@@ -86,13 +86,11 @@ static void rtl92se_fw_cb(const struct f + struct ieee80211_hw *hw = context; + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct rt_firmware *pfirmware = NULL; +- char *fw_name = "rtlwifi/rtl8192sefw.bin"; + + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "Firmware callback routine entered!\n"); + complete(&rtlpriv->firmware_loading_complete); + if (!firmware) { +- pr_err("Firmware %s not available\n", fw_name); + rtlpriv->max_fw_size = 0; + return; + } +Index: linux/drivers/net/wireless/ti/wl1251/main.c +=================================================================== +--- linux.orig/drivers/net/wireless/ti/wl1251/main.c ++++ linux/drivers/net/wireless/ti/wl1251/main.c +@@ -71,10 +71,8 @@ static int wl1251_fetch_firmware(struct + + ret = request_firmware(&fw, WL1251_FW_NAME, dev); + +- if (ret < 0) { +- wl1251_error("could not get firmware: %d", ret); ++ if (ret) + return ret; +- } + + if (fw->size % 4) { + wl1251_error("firmware size is not multiple of 32 bits: %zu", +@@ -110,10 +108,8 @@ static int wl1251_fetch_nvs(struct wl125 + + ret = request_firmware(&fw, WL1251_NVS_NAME, dev); + +- if (ret < 0) { +- wl1251_error("could not get nvs file: %d", ret); ++ if (ret) + return ret; +- } + + if (fw->size % 4) { + wl1251_error("nvs size is not multiple of 32 bits: %zu", +Index: linux/drivers/net/wireless/ti/wlcore/main.c +=================================================================== +--- linux.orig/drivers/net/wireless/ti/wlcore/main.c ++++ linux/drivers/net/wireless/ti/wlcore/main.c +@@ -768,10 +768,8 @@ static int wl12xx_fetch_firmware(struct + + ret = request_firmware(&fw, fw_name, wl->dev); + +- if (ret < 0) { +- wl1271_error("could not get firmware %s: %d", fw_name, ret); ++ if (ret) + return ret; +- } + + if (fw->size % 4) { + wl1271_error("firmware size is not multiple of 32 bits: %zu", +Index: linux/drivers/net/wireless/zydas/zd1201.c +=================================================================== +--- linux.orig/drivers/net/wireless/zydas/zd1201.c ++++ linux/drivers/net/wireless/zydas/zd1201.c +@@ -65,8 +65,6 @@ static int zd1201_fw_upload(struct usb_d + + err = request_firmware(&fw_entry, fwfile, &dev->dev); + if (err) { +- dev_err(&dev->dev, "Failed to load %s firmware file!\n", fwfile); +- dev_err(&dev->dev, "Make sure the hotplug firmware loader is installed.\n"); + dev_err(&dev->dev, "Goto http://linux-lc100020.sourceforge.net for more info.\n"); + return err; + } +Index: linux/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +=================================================================== +--- linux.orig/drivers/net/wireless/zydas/zd1211rw/zd_usb.c ++++ linux/drivers/net/wireless/zydas/zd1211rw/zd_usb.c +@@ -120,16 +120,9 @@ static void int_urb_complete(struct urb + static int request_fw_file( + const struct firmware **fw, const char *name, struct device *device) + { +- int r; +- + dev_dbg_f(device, "fw name %s\n", name); + +- r = request_firmware(fw, name, device); +- if (r) +- dev_err(device, +- "Could not load firmware file %s. Error number %d\n", +- name, r); +- return r; ++ return request_firmware(fw, name, device); + } + + static inline u16 get_bcdDevice(const struct usb_device *udev) +Index: linux/drivers/scsi/advansys.c +=================================================================== +--- linux.orig/drivers/scsi/advansys.c ++++ linux/drivers/scsi/advansys.c +@@ -4107,8 +4107,6 @@ static int AscInitAsc1000Driver(ASC_DVC_ + + err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; + return err; + } +@@ -4473,8 +4471,6 @@ static int AdvInitAsc3550Driver(ADV_DVC_ + + err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; + return err; + } +@@ -4973,8 +4969,6 @@ static int AdvInitAsc38C0800Driver(ADV_D + + err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; + return err; + } +@@ -5461,8 +5455,6 @@ static int AdvInitAsc38C1600Driver(ADV_D + + err = request_firmware(&fw, fwname, asc_dvc->drv_ptr->dev); + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + asc_dvc->err_code = ASC_IERR_MCODE_CHKSUM; + return err; + } +Index: linux/drivers/scsi/aic94xx/aic94xx_init.c +=================================================================== +--- linux.orig/drivers/scsi/aic94xx/aic94xx_init.c ++++ linux/drivers/scsi/aic94xx/aic94xx_init.c +@@ -384,8 +384,6 @@ static ssize_t asd_store_update_bios(str + filename_ptr, + &asd_ha->pcidev->dev); + if (err) { +- asd_printk("Failed to load bios image file %s, error %d\n", +- filename_ptr, err); + err = FAIL_OPEN_BIOS_FILE; + goto out1; + } +Index: linux/drivers/scsi/aic94xx/aic94xx_seq.c +=================================================================== +--- linux.orig/drivers/scsi/aic94xx/aic94xx_seq.c ++++ linux/drivers/scsi/aic94xx/aic94xx_seq.c +@@ -1317,11 +1317,8 @@ int asd_init_seqs(struct asd_ha_struct * + + err = asd_request_firmware(asd_ha); + +- if (err) { +- asd_printk("Failed to load sequencer firmware file %s, error %d\n", +- SAS_RAZOR_SEQUENCER_FW_FILE, err); ++ if (err) + return err; +- } + + err = asd_seq_download_seqs(asd_ha); + if (err) { +Index: linux/drivers/scsi/bfa/bfad.c +=================================================================== +--- linux.orig/drivers/scsi/bfa/bfad.c ++++ linux/drivers/scsi/bfa/bfad.c +@@ -1755,7 +1755,6 @@ bfad_read_firmware(struct pci_dev *pdev, + const struct firmware *fw; + + if (request_firmware(&fw, fw_name, &pdev->dev)) { +- printk(KERN_ALERT "Can't locate firmware %s\n", fw_name); + *bfi_image = NULL; + goto out; + } +Index: linux/drivers/scsi/ipr.c +=================================================================== +--- linux.orig/drivers/scsi/ipr.c ++++ linux/drivers/scsi/ipr.c +@@ -4102,10 +4102,8 @@ static ssize_t ipr_store_update_fw(struc + if (endline) + *endline = '\0'; + +- if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) { +- dev_err(&ioa_cfg->pdev->dev, "Firmware file %s not found\n", fname); ++ if (request_firmware(&fw_entry, fname, &ioa_cfg->pdev->dev)) + return -EIO; +- } + + image_hdr = (struct ipr_ucode_image_header *)fw_entry->data; + +Index: linux/drivers/scsi/pm8001/pm8001_ctl.c +=================================================================== +--- linux.orig/drivers/scsi/pm8001/pm8001_ctl.c ++++ linux/drivers/scsi/pm8001/pm8001_ctl.c +@@ -737,10 +737,6 @@ static ssize_t pm8001_store_update_fw(st + pm8001_ha->dev); + + if (ret) { +- PM8001_FAIL_DBG(pm8001_ha, +- pm8001_printk( +- "Failed to load firmware image file %s, error %d\n", +- filename_ptr, ret)); + pm8001_ha->fw_status = FAIL_OPEN_BIOS_FILE; + goto out; + } +Index: linux/drivers/scsi/qla1280.c +=================================================================== +--- linux.orig/drivers/scsi/qla1280.c ++++ linux/drivers/scsi/qla1280.c +@@ -1552,8 +1552,6 @@ qla1280_request_firmware(struct scsi_qla + err = request_firmware(&fw, fwname, &ha->pdev->dev); + + if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); + fw = ERR_PTR(err); + goto unlock; + } +Index: linux/drivers/scsi/qla2xxx/qla_init.c +=================================================================== +--- linux.orig/drivers/scsi/qla2xxx/qla_init.c ++++ linux/drivers/scsi/qla2xxx/qla_init.c +@@ -7470,8 +7470,6 @@ qla2x00_load_risc(scsi_qla_host_t *vha, + /* Load firmware blob. */ + blob = qla2x00_request_firmware(vha); + if (!blob) { +- ql_log(ql_log_info, vha, 0x0083, +- "Firmware image unavailable.\n"); + ql_log(ql_log_info, vha, 0x0084, + "Firmware images can be retrieved from: "QLA_FW_URL ".\n"); + return QLA_FUNCTION_FAILED; +@@ -7573,8 +7571,6 @@ qla24xx_load_risc_blob(scsi_qla_host_t * + /* Load firmware blob. */ + blob = qla2x00_request_firmware(vha); + if (!blob) { +- ql_log(ql_log_warn, vha, 0x0090, +- "Firmware image unavailable.\n"); + ql_log(ql_log_warn, vha, 0x0091, + "Firmware images can be retrieved from: " + QLA_FW_URL ".\n"); +Index: linux/drivers/scsi/qla2xxx/qla_nx.c +=================================================================== +--- linux.orig/drivers/scsi/qla2xxx/qla_nx.c ++++ linux/drivers/scsi/qla2xxx/qla_nx.c +@@ -2464,11 +2464,8 @@ try_blob_fw: + + /* Load firmware blob. */ + blob = ha->hablob = qla2x00_request_firmware(vha); +- if (!blob) { +- ql_log(ql_log_fatal, vha, 0x00a3, +- "Firmware image not present.\n"); ++ if (!blob) + goto fw_load_failed; +- } + + /* Validating firmware blob */ + if (qla82xx_validate_firmware_blob(vha, +Index: linux/drivers/scsi/qla2xxx/qla_os.c +=================================================================== +--- linux.orig/drivers/scsi/qla2xxx/qla_os.c ++++ linux/drivers/scsi/qla2xxx/qla_os.c +@@ -6543,8 +6543,6 @@ qla2x00_request_firmware(scsi_qla_host_t + goto out; + + if (request_firmware(&blob->fw, blob->name, &ha->pdev->dev)) { +- ql_log(ql_log_warn, vha, 0x0063, +- "Failed to load firmware image (%s).\n", blob->name); + blob->fw = NULL; + blob = NULL; + goto out; +Index: linux/drivers/scsi/qlogicpti.c +=================================================================== +--- linux.orig/drivers/scsi/qlogicpti.c ++++ linux/drivers/scsi/qlogicpti.c +@@ -475,11 +475,8 @@ static int qlogicpti_load_firmware(struc + int i, timeout; + + err = request_firmware(&fw, fwname, &qpti->op->dev); +- if (err) { +- printk(KERN_ERR "Failed to load image \"%s\" err %d\n", +- fwname, err); ++ if (err) + return err; +- } + if (fw->size % 2) { + printk(KERN_ERR "Bogus length %zu in image \"%s\"\n", + fw->size, fwname); +Index: linux/drivers/media/usb/go7007/go7007-driver.c +=================================================================== +--- linux.orig/drivers/media/usb/go7007/go7007-driver.c ++++ linux/drivers/media/usb/go7007/go7007-driver.c +@@ -92,10 +92,8 @@ static int go7007_load_encoder(struct go + u16 intr_val, intr_data; + + if (go->boot_fw == NULL) { +- if (request_firmware(&fw_entry, fw_name, go->dev)) { +- v4l2_err(go, "unable to load firmware from file \"%s\"\n", fw_name); ++ if (request_firmware(&fw_entry, fw_name, go->dev)) + return -1; +- } + if (fw_entry->size < 16 || memcmp(fw_entry->data, "WISGO7007FW", 11)) { + v4l2_err(go, "file \"%s\" does not appear to be go7007 firmware\n", fw_name); + release_firmware(fw_entry); +Index: linux/drivers/media/usb/go7007/go7007-fw.c +=================================================================== +--- linux.orig/drivers/media/usb/go7007/go7007-fw.c ++++ linux/drivers/media/usb/go7007/go7007-fw.c +@@ -1573,12 +1573,8 @@ int go7007_construct_fw_image(struct go7 + default: + return -1; + } +- if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev)) { +- dev_err(go->dev, +- "unable to load firmware from file \"%s\"\n", +- GO7007_FW_NAME); ++ if (request_firmware(&fw_entry, GO7007_FW_NAME, go->dev)) + return -1; +- } + code = kcalloc(codespace, 2, GFP_KERNEL); + if (code == NULL) + goto fw_failed; +Index: linux/drivers/media/usb/go7007/go7007-loader.c +=================================================================== +--- linux.orig/drivers/media/usb/go7007/go7007-loader.c ++++ linux/drivers/media/usb/go7007/go7007-loader.c +@@ -75,11 +75,8 @@ static int go7007_loader_probe(struct us + + dev_info(&interface->dev, "loading firmware %s\n", fw1); + +- if (request_firmware(&fw, fw1, &usbdev->dev)) { +- dev_err(&interface->dev, +- "unable to load firmware from file \"%s\"\n", fw1); ++ if (request_firmware(&fw, fw1, &usbdev->dev)) + goto failed2; +- } + ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + release_firmware(fw); + if (0 != ret) { +@@ -90,11 +87,8 @@ static int go7007_loader_probe(struct us + if (fw2 == NULL) + return 0; + +- if (request_firmware(&fw, fw2, &usbdev->dev)) { +- dev_err(&interface->dev, +- "unable to load firmware from file \"%s\"\n", fw2); ++ if (request_firmware(&fw, fw2, &usbdev->dev)) + goto failed2; +- } + ret = cypress_load_firmware(usbdev, fw, CYPRESS_FX2); + release_firmware(fw); + if (0 != ret) { +Index: linux/drivers/staging/rtl8192u/r819xU_firmware.c +=================================================================== +--- linux.orig/drivers/staging/rtl8192u/r819xU_firmware.c ++++ linux/drivers/staging/rtl8192u/r819xU_firmware.c +@@ -245,10 +245,8 @@ bool init_firmware(struct net_device *de + */ + if (rst_opt == OPT_SYSTEM_RESET) { + rc = request_firmware(&fw_entry, fw_name[init_step], &priv->udev->dev); +- if (rc < 0) { +- RT_TRACE(COMP_ERR, "request firmware fail!\n"); ++ if (rc) + goto download_firmware_fail; +- } + + if (fw_entry->size > sizeof(pfirmware->firmware_buf)) { + RT_TRACE(COMP_ERR, "img file size exceed the container buffer fail!\n"); +Index: linux/drivers/staging/rtl8712/hal_init.c +=================================================================== +--- linux.orig/drivers/staging/rtl8712/hal_init.c ++++ linux/drivers/staging/rtl8712/hal_init.c +@@ -67,8 +67,6 @@ int rtl871x_load_fw(struct _adapter *pad + dev_info(dev, "r8712u: Loading firmware from \"%s\"\n", firmware_file); + rc = request_firmware_nowait(THIS_MODULE, 1, firmware_file, dev, + GFP_KERNEL, padapter, rtl871x_load_fw_cb); +- if (rc) +- dev_err(dev, "r8712u: Firmware request error %d\n", rc); + return rc; + } + MODULE_FIRMWARE("rtlwifi/rtl8712u.bin"); +Index: linux/drivers/net/ethernet/alacritech/slicoss.c +=================================================================== +--- linux.orig/drivers/net/ethernet/alacritech/slicoss.c ++++ linux/drivers/net/ethernet/alacritech/slicoss.c +@@ -1063,11 +1063,8 @@ static int slic_load_rcvseq_firmware(str + file = (sdev->model == SLIC_MODEL_OASIS) ? SLIC_RCV_FIRMWARE_OASIS : + SLIC_RCV_FIRMWARE_MOJAVE; + err = request_firmware(&fw, file, &sdev->pdev->dev); +- if (err) { +- dev_err(&sdev->pdev->dev, +- "failed to load receive sequencer firmware %s\n", file); ++ if (err) + return err; +- } + /* Do an initial sanity check concerning firmware size now. A further + * check follows below. + */ +@@ -1138,10 +1135,8 @@ static int slic_load_firmware(struct sli + file = (sdev->model == SLIC_MODEL_OASIS) ? SLIC_FIRMWARE_OASIS : + SLIC_FIRMWARE_MOJAVE; + err = request_firmware(&fw, file, &sdev->pdev->dev); +- if (err) { +- dev_err(&sdev->pdev->dev, "failed to load firmware %s\n", file); ++ if (err) + return err; +- } + /* Do an initial sanity check concerning firmware size now. A further + * check follows below. + */ +Index: linux/drivers/staging/vt6656/firmware.c +=================================================================== +--- linux.orig/drivers/staging/vt6656/firmware.c ++++ linux/drivers/staging/vt6656/firmware.c +@@ -39,11 +39,8 @@ int vnt_download_firmware(struct vnt_pri + dev_dbg(dev, "---->Download firmware\n"); + + rc = request_firmware(&fw, FIRMWARE_NAME, dev); +- if (rc) { +- dev_err(dev, "firmware file %s request failed (%d)\n", +- FIRMWARE_NAME, rc); +- goto out; +- } ++ if (rc) ++ goto out; + + buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL); + if (!buffer) +Index: linux/drivers/tty/cyclades.c +=================================================================== +--- linux.orig/drivers/tty/cyclades.c ++++ linux/drivers/tty/cyclades.c +@@ -3489,10 +3489,8 @@ static int cyz_load_fw(struct pci_dev *p + int retval; + + retval = request_firmware(&fw, "cyzfirm.bin", &pdev->dev); +- if (retval) { +- dev_err(&pdev->dev, "can't get firmware\n"); ++ if (retval) + goto err; +- } + + /* Check whether the firmware is already loaded and running. If + positive, skip this board */ +Index: linux/drivers/tty/moxa.c +=================================================================== +--- linux.orig/drivers/tty/moxa.c ++++ linux/drivers/tty/moxa.c +@@ -862,13 +862,8 @@ static int moxa_init_board(struct moxa_b + } + + ret = request_firmware(&fw, file, dev); +- if (ret) { +- printk(KERN_ERR "MOXA: request_firmware failed. Make sure " +- "you've placed '%s' file into your firmware " +- "loader directory (e.g. /lib/firmware)\n", +- file); ++ if (ret) + goto err_free; +- } + + ret = moxa_load_fw(brd, fw); + +Index: linux/drivers/tty/serial/icom.c +=================================================================== +--- linux.orig/drivers/tty/serial/icom.c ++++ linux/drivers/tty/serial/icom.c +@@ -360,7 +360,6 @@ static void load_code(struct icom_port * + + /* Load Call Setup into Adapter */ + if (request_firmware(&fw, "icom_call_setup.bin", &dev->dev) < 0) { +- dev_err(&dev->dev,"Unable to load icom_call_setup.bin firmware image\n"); + status = -1; + goto load_code_exit; + } +@@ -380,7 +379,6 @@ static void load_code(struct icom_port * + + /* Load Resident DCE portion of Adapter */ + if (request_firmware(&fw, "icom_res_dce.bin", &dev->dev) < 0) { +- dev_err(&dev->dev,"Unable to load icom_res_dce.bin firmware image\n"); + status = -1; + goto load_code_exit; + } +@@ -425,7 +423,6 @@ static void load_code(struct icom_port * + } + + if (request_firmware(&fw, "icom_asc.bin", &dev->dev) < 0) { +- dev_err(&dev->dev,"Unable to load icom_asc.bin firmware image\n"); + status = -1; + goto load_code_exit; + } +Index: linux/drivers/tty/serial/ucc_uart.c +=================================================================== +--- linux.orig/drivers/tty/serial/ucc_uart.c ++++ linux/drivers/tty/serial/ucc_uart.c +@@ -1165,10 +1165,8 @@ static void uart_firmware_cont(const str + struct device *dev = context; + int ret; + +- if (!fw) { +- dev_err(dev, "firmware not found\n"); ++ if (!fw) + return; +- } + + firmware = (struct qe_firmware *) fw->data; + +Index: linux/drivers/usb/atm/cxacru.c +=================================================================== +--- linux.orig/drivers/usb/atm/cxacru.c ++++ linux/drivers/usb/atm/cxacru.c +@@ -1080,8 +1080,6 @@ static int cxacru_find_firmware(struct c + return -ENOENT; + } + +- usb_info(usbatm, "found firmware %s\n", buf); +- + return 0; + } + +Index: linux/drivers/usb/atm/ueagle-atm.c +=================================================================== +--- linux.orig/drivers/usb/atm/ueagle-atm.c ++++ linux/drivers/usb/atm/ueagle-atm.c +@@ -650,10 +650,8 @@ static void uea_upload_pre_firmware(cons + int ret, size; + + uea_enters(usb); +- if (!fw_entry) { +- uea_err(usb, "firmware is not available\n"); ++ if (!fw_entry) + goto err; +- } + + pfw = fw_entry->data; + size = fw_entry->size; +@@ -748,10 +746,6 @@ static int uea_load_firmware(struct usb_ + ret = request_firmware_nowait(THIS_MODULE, 1, fw_name, &usb->dev, + GFP_KERNEL, usb, + uea_upload_pre_firmware); +- if (ret) +- uea_err(usb, "firmware %s is not available\n", fw_name); +- else +- uea_info(usb, "loading firmware %s\n", fw_name); + + uea_leaves(usb); + return ret; +@@ -913,12 +907,8 @@ static int request_dsp(struct uea_softc + } + + ret = request_firmware(&sc->dsp_firm, dsp_name, &sc->usb_dev->dev); +- if (ret < 0) { +- uea_err(INS_TO_USBDEV(sc), +- "requesting firmware %s failed with error %d\n", +- dsp_name, ret); ++ if (ret) + return ret; +- } + + if (UEA_CHIP_VERSION(sc) == EAGLE_IV) + ret = check_dsp_e4(sc->dsp_firm->data, sc->dsp_firm->size); +@@ -1631,12 +1621,8 @@ static int request_cmvs_old(struct uea_s + + cmvs_file_name(sc, cmv_name, 1); + ret = request_firmware(fw, cmv_name, &sc->usb_dev->dev); +- if (ret < 0) { +- uea_err(INS_TO_USBDEV(sc), +- "requesting firmware %s failed with error %d\n", +- cmv_name, ret); ++ if (ret) + return ret; +- } + + data = (u8 *) (*fw)->data; + size = (*fw)->size; +@@ -1673,9 +1659,6 @@ static int request_cmvs(struct uea_softc + "try to get older cmvs\n", cmv_name); + return request_cmvs_old(sc, cmvs, fw); + } +- uea_err(INS_TO_USBDEV(sc), +- "requesting firmware %s failed with error %d\n", +- cmv_name, ret); + return ret; + } + +@@ -1958,11 +1941,8 @@ static int load_XILINX_firmware(struct u + uea_enters(INS_TO_USBDEV(sc)); + + ret = request_firmware(&fw_entry, fw_name, &sc->usb_dev->dev); +- if (ret) { +- uea_err(INS_TO_USBDEV(sc), "firmware %s is not available\n", +- fw_name); ++ if (ret) + goto err0; +- } + + pfw = fw_entry->data; + size = fw_entry->size; +Index: linux/drivers/usb/misc/emi26.c +=================================================================== +--- linux.orig/drivers/usb/misc/emi26.c ++++ linux/drivers/usb/misc/emi26.c +@@ -85,21 +85,17 @@ static int emi26_load_firmware (struct u + + err = request_ihex_firmware(&loader_fw, "emi26/loader.fw", &dev->dev); + if (err) +- goto nofw; ++ goto wraperr; + + err = request_ihex_firmware(&bitstream_fw, "emi26/bitstream.fw", + &dev->dev); + if (err) +- goto nofw; ++ goto wraperr; + + err = request_ihex_firmware(&firmware_fw, "emi26/firmware.fw", + &dev->dev); +- if (err) { +- nofw: +- dev_err(&dev->dev, "%s - request_firmware() failed\n", +- __func__); ++ if (err) + goto wraperr; +- } + + /* Assert reset (stop the CPU in the EMI) */ + err = emi26_set_reset(dev,1); +Index: linux/drivers/usb/misc/ezusb.c +=================================================================== +--- linux.orig/drivers/usb/misc/ezusb.c ++++ linux/drivers/usb/misc/ezusb.c +@@ -76,12 +76,8 @@ static int ezusb_ihex_firmware_download( + const struct ihex_binrec *record; + + if (request_ihex_firmware(&firmware, firmware_path, +- &dev->dev)) { +- dev_err(&dev->dev, +- "%s - request \"%s\" failed\n", +- __func__, firmware_path); ++ &dev->dev)) + goto out; +- } + + ret = ezusb_set_reset(dev, fx.cpucs_reg, 0); + if (ret < 0) +Index: linux/drivers/usb/misc/isight_firmware.c +=================================================================== +--- linux.orig/drivers/usb/misc/isight_firmware.c ++++ linux/drivers/usb/misc/isight_firmware.c +@@ -45,7 +45,6 @@ static int isight_firmware_load(struct u + return -ENOMEM; + + if (request_firmware(&firmware, "isight.fw", &dev->dev) != 0) { +- printk(KERN_ERR "Unable to load isight firmware\n"); + ret = -ENODEV; + goto out; + } +Index: linux/drivers/usb/serial/io_edgeport.c +=================================================================== +--- linux.orig/drivers/usb/serial/io_edgeport.c ++++ linux/drivers/usb/serial/io_edgeport.c +@@ -375,11 +375,8 @@ static void update_edgeport_E2PROM(struc + + response = request_ihex_firmware(&fw, fw_name, + &edge_serial->serial->dev->dev); +- if (response) { +- dev_err(dev, "Failed to load image \"%s\" err %d\n", +- fw_name, response); ++ if (response) + return; +- } + + rec = (const struct ihex_binrec *)fw->data; + BootMajorVersion = rec->data[0]; +Index: linux/drivers/usb/serial/io_ti.c +=================================================================== +--- linux.orig/drivers/usb/serial/io_ti.c ++++ linux/drivers/usb/serial/io_ti.c +@@ -1010,8 +1010,6 @@ static int download_fw(struct edgeport_s + + status = request_firmware(&fw, fw_name, dev); + if (status) { +- dev_err(dev, "Failed to load image \"%s\" err %d\n", +- fw_name, status); + return status; + } + +Index: linux/drivers/usb/serial/ti_usb_3410_5052.c +=================================================================== +--- linux.orig/drivers/usb/serial/ti_usb_3410_5052.c ++++ linux/drivers/usb/serial/ti_usb_3410_5052.c +@@ -1689,10 +1689,8 @@ static int ti_download_firmware(struct t + } + + check_firmware: +- if (status) { +- dev_err(&dev->dev, "%s - firmware not found\n", __func__); ++ if (status) + return -ENOENT; +- } + if (fw_p->size > TI_FIRMWARE_BUF_SIZE) { + dev_err(&dev->dev, "%s - firmware too large %zu\n", __func__, fw_p->size); + release_firmware(fw_p); +Index: linux/drivers/video/fbdev/broadsheetfb.c +=================================================================== +--- linux.orig/drivers/video/fbdev/broadsheetfb.c ++++ linux/drivers/video/fbdev/broadsheetfb.c +@@ -743,10 +743,8 @@ static ssize_t broadsheet_loadstore_wave + return -EINVAL; + + err = request_firmware(&fw_entry, "broadsheet.wbf", dev); +- if (err < 0) { +- dev_err(dev, "Failed to get broadsheet waveform\n"); ++ if (err) + goto err_failed; +- } + + /* try to enforce reasonable min max on waveform */ + if ((fw_entry->size < 8*1024) || (fw_entry->size > 64*1024)) { +Index: linux/drivers/video/fbdev/metronomefb.c +=================================================================== +--- linux.orig/drivers/video/fbdev/metronomefb.c ++++ linux/drivers/video/fbdev/metronomefb.c +@@ -679,10 +679,8 @@ static int metronomefb_probe(struct plat + a) request the waveform file from userspace + b) process waveform and decode into metromem */ + retval = request_firmware(&fw_entry, "metronome.wbf", &dev->dev); +- if (retval < 0) { +- dev_err(&dev->dev, "Failed to get waveform\n"); ++ if (retval) + goto err_csum_table; +- } + + retval = load_waveform((u8 *) fw_entry->data, fw_entry->size, 3, 31, + par); +Index: linux/sound/drivers/vx/vx_hwdep.c +=================================================================== +--- linux.orig/sound/drivers/vx/vx_hwdep.c ++++ linux/sound/drivers/vx/vx_hwdep.c +@@ -71,10 +71,8 @@ int snd_vx_setup_firmware(struct vx_core + if (! fw_files[chip->type][i]) + continue; + sprintf(path, "vx/%s", fw_files[chip->type][i]); +- if (request_firmware(&fw, path, chip->dev)) { +- snd_printk(KERN_ERR "vx: can't load firmware %s\n", path); ++ if (request_firmware(&fw, path, chip->dev)) + return -ENOENT; +- } + err = chip->ops->load_dsp(chip, i, fw); + if (err < 0) { + release_firmware(fw); +Index: linux/sound/isa/msnd/msnd_pinnacle.c +=================================================================== +--- linux.orig/sound/isa/msnd/msnd_pinnacle.c ++++ linux/sound/isa/msnd/msnd_pinnacle.c +@@ -390,15 +390,11 @@ static int upload_dsp_code(struct snd_ca + outb(HPBLKSEL_0, chip->io + HP_BLKS); + + err = request_firmware(&init_fw, INITCODEFILE, card->dev); +- if (err < 0) { +- printk(KERN_ERR LOGNAME ": Error loading " INITCODEFILE); ++ if (err) + goto cleanup1; +- } + err = request_firmware(&perm_fw, PERMCODEFILE, card->dev); +- if (err < 0) { +- printk(KERN_ERR LOGNAME ": Error loading " PERMCODEFILE); ++ if (err) + goto cleanup; +- } + + memcpy_toio(chip->mappedbase, perm_fw->data, perm_fw->size); + if (snd_msnd_upload_host(chip, init_fw->data, init_fw->size) < 0) { +Index: linux/sound/isa/sscape.c +=================================================================== +--- linux.orig/sound/isa/sscape.c ++++ linux/sound/isa/sscape.c +@@ -544,10 +544,8 @@ static int sscape_upload_bootblock(struc + int ret; + + ret = request_firmware(&init_fw, "scope.cod", card->dev); +- if (ret < 0) { +- snd_printk(KERN_ERR "sscape: Error loading scope.cod"); ++ if (ret) + return ret; +- } + ret = upload_dma_data(sscape, init_fw->data, init_fw->size); + + release_firmware(init_fw); +@@ -584,11 +582,8 @@ static int sscape_upload_microcode(struc + snprintf(name, sizeof(name), "sndscape.co%d", version); + + err = request_firmware(&init_fw, name, card->dev); +- if (err < 0) { +- snd_printk(KERN_ERR "sscape: Error loading sndscape.co%d", +- version); ++ if (err) + return err; +- } + err = upload_dma_data(sscape, init_fw->data, init_fw->size); + if (err == 0) + snd_printk(KERN_INFO "sscape: MIDI firmware loaded %zu KBs\n", +Index: linux/sound/isa/wavefront/wavefront_synth.c +=================================================================== +--- linux.orig/sound/isa/wavefront/wavefront_synth.c ++++ linux/sound/isa/wavefront/wavefront_synth.c +@@ -1957,10 +1957,8 @@ wavefront_download_firmware (snd_wavefro + const struct firmware *firmware; + + err = request_firmware(&firmware, path, dev->card->dev); +- if (err < 0) { +- snd_printk(KERN_ERR "firmware (%s) download failed!!!\n", path); ++ if (err) + return 1; +- } + + len = 0; + buf = firmware->data; +Index: linux/sound/pci/asihpi/hpidspcd.c +=================================================================== +--- linux.orig/sound/pci/asihpi/hpidspcd.c ++++ linux/sound/pci/asihpi/hpidspcd.c +@@ -46,8 +46,6 @@ short hpi_dsp_code_open(u32 adapter, voi + err = request_firmware(&firmware, fw_name, &dev->dev); + + if (err || !firmware) { +- dev_err(&dev->dev, "%d, request_firmware failed for %s\n", +- err, fw_name); + goto error1; + } + if (firmware->size < sizeof(header)) { +Index: linux/sound/pci/echoaudio/echoaudio.c +=================================================================== +--- linux.orig/sound/pci/echoaudio/echoaudio.c ++++ linux/sound/pci/echoaudio/echoaudio.c +@@ -60,11 +60,8 @@ static int get_firmware(const struct fir + "firmware requested: %s\n", card_fw[fw_index].data); + snprintf(name, sizeof(name), "ea/%s", card_fw[fw_index].data); + err = request_firmware(fw_entry, name, &chip->pci->dev); +- if (err < 0) +- dev_err(chip->card->dev, +- "get_firmware(): Firmware not available (%d)\n", err); + #ifdef CONFIG_PM_SLEEP +- else ++ if (!err) + chip->fw_cache[fw_index] = *fw_entry; + #endif + return err; +Index: linux/sound/pci/emu10k1/emu10k1_main.c +=================================================================== +--- linux.orig/sound/pci/emu10k1/emu10k1_main.c ++++ linux/sound/pci/emu10k1/emu10k1_main.c +@@ -888,10 +888,8 @@ static int snd_emu10k1_emu1010_init(stru + dev_info(emu->card->dev, "emu1010: EMU_HANA_ID = 0x%x\n", reg); + + err = snd_emu1010_load_firmware(emu, 0, &emu->firmware); +- if (err < 0) { +- dev_info(emu->card->dev, "emu1010: Loading Firmware failed\n"); ++ if (err < 0) + return err; +- } + + /* ID, should read & 0x7f = 0x55 when FPGA programmed. */ + snd_emu1010_fpga_read(emu, EMU_HANA_ID, ®); +Index: linux/sound/pci/hda/hda_intel.c +=================================================================== +--- linux.orig/sound/pci/hda/hda_intel.c ++++ linux/sound/pci/hda/hda_intel.c +@@ -2079,8 +2079,6 @@ static void azx_firmware_cb(const struct + + if (fw) + chip->fw = fw; +- else +- dev_err(card->dev, "Cannot load firmware, continue without patching\n"); + if (!chip->disabled) { + /* continue probing */ + azx_probe_continue(chip); +Index: linux/sound/pci/korg1212/korg1212.c +=================================================================== +--- linux.orig/sound/pci/korg1212/korg1212.c ++++ linux/sound/pci/korg1212/korg1212.c +@@ -2348,7 +2348,6 @@ static int snd_korg1212_create(struct sn + + err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); + if (err < 0) { +- snd_printk(KERN_ERR "firmware not available\n"); + snd_korg1212_free(korg1212); + return err; + } +Index: linux/sound/pci/mixart/mixart_hwdep.c +=================================================================== +--- linux.orig/sound/pci/mixart/mixart_hwdep.c ++++ linux/sound/pci/mixart/mixart_hwdep.c +@@ -571,11 +571,8 @@ int snd_mixart_setup_firmware(struct mix + + for (i = 0; i < 3; i++) { + sprintf(path, "mixart/%s", fw_files[i]); +- if (request_firmware(&fw_entry, path, &mgr->pci->dev)) { +- dev_err(&mgr->pci->dev, +- "miXart: can't load firmware %s\n", path); ++ if (request_firmware(&fw_entry, path, &mgr->pci->dev)) + return -ENOENT; +- } + /* fake hwdep dsp record */ + err = mixart_dsp_load(mgr, i, fw_entry); + release_firmware(fw_entry); +Index: linux/sound/pci/pcxhr/pcxhr_hwdep.c +=================================================================== +--- linux.orig/sound/pci/pcxhr/pcxhr_hwdep.c ++++ linux/sound/pci/pcxhr/pcxhr_hwdep.c +@@ -385,12 +385,8 @@ int pcxhr_setup_firmware(struct pcxhr_mg + if (!fw_files[fw_set][i]) + continue; + sprintf(path, "pcxhr/%s", fw_files[fw_set][i]); +- if (request_firmware(&fw_entry, path, &mgr->pci->dev)) { +- dev_err(&mgr->pci->dev, +- "pcxhr: can't load firmware %s\n", +- path); ++ if (request_firmware(&fw_entry, path, &mgr->pci->dev)) + return -ENOENT; +- } + /* fake hwdep dsp record */ + err = pcxhr_dsp_load(mgr, i, fw_entry); + release_firmware(fw_entry); +Index: linux/sound/pci/riptide/riptide.c +=================================================================== +--- linux.orig/sound/pci/riptide/riptide.c ++++ linux/sound/pci/riptide/riptide.c +@@ -1231,11 +1231,8 @@ static int try_to_load_firmware(struct c + if (!chip->fw_entry) { + err = request_firmware(&chip->fw_entry, "riptide.hex", + &chip->pci->dev); +- if (err) { +- snd_printk(KERN_ERR +- "Riptide: Firmware not available %d\n", err); ++ if (err) + return -EIO; +- } + } + err = loadfirmware(cif, chip->fw_entry->data, chip->fw_entry->size); + if (err) { +Index: linux/sound/pci/rme9652/hdsp.c +=================================================================== +--- linux.orig/sound/pci/rme9652/hdsp.c ++++ linux/sound/pci/rme9652/hdsp.c +@@ -5134,11 +5134,8 @@ static int hdsp_request_fw_loader(struct + return -EINVAL; + } + +- if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) { +- dev_err(hdsp->card->dev, +- "cannot load firmware %s\n", fwfile); ++ if (request_firmware(&fw, fwfile, &hdsp->pci->dev)) + return -ENOENT; +- } + if (fw->size < HDSP_FIRMWARE_SIZE) { + dev_err(hdsp->card->dev, + "too short firmware size %d (expected %d)\n", +Index: linux/sound/soc/codecs/wm2000.c +=================================================================== +--- linux.orig/sound/soc/codecs/wm2000.c ++++ linux/sound/soc/codecs/wm2000.c +@@ -891,10 +891,8 @@ static int wm2000_i2c_probe(struct i2c_c + } + + ret = request_firmware(&fw, filename, &i2c->dev); +- if (ret != 0) { +- dev_err(&i2c->dev, "Failed to acquire ANC data: %d\n", ret); ++ if (ret != 0) + goto err_supplies; +- } + + /* Pre-cook the concatenation of the register address onto the image */ + wm2000->anc_download_size = fw->size + 2; +Index: linux/sound/usb/6fire/firmware.c +=================================================================== +--- linux.orig/sound/usb/6fire/firmware.c ++++ linux/sound/usb/6fire/firmware.c +@@ -219,8 +219,6 @@ static int usb6fire_fw_ezusb_upload( + ret = request_firmware(&fw, fwname, &device->dev); + if (ret < 0) { + kfree(rec); +- dev_err(&intf->dev, +- "error requesting ezusb firmware %s.\n", fwname); + return ret; + } + ret = usb6fire_fw_ihex_init(fw, rec); +@@ -296,8 +294,6 @@ static int usb6fire_fw_fpga_upload( + + ret = request_firmware(&fw, fwname, &device->dev); + if (ret < 0) { +- dev_err(&intf->dev, "unable to get fpga firmware %s.\n", +- fwname); + kfree(buffer); + return -EIO; + } +Index: linux/sound/pci/cs46xx/cs46xx_lib.c +=================================================================== +--- linux.orig/sound/pci/cs46xx/cs46xx_lib.c ++++ linux/sound/pci/cs46xx/cs46xx_lib.c +@@ -3253,11 +3253,8 @@ int snd_cs46xx_start_dsp(struct snd_cs46 + #ifdef CONFIG_SND_CS46XX_NEW_DSP + for (i = 0; i < CS46XX_DSP_MODULES; i++) { + err = load_firmware(chip, &chip->modules[i], module_names[i]); +- if (err < 0) { +- dev_err(chip->card->dev, "firmware load error [%s]\n", +- module_names[i]); ++ if (err < 0) + return err; +- } + err = cs46xx_dsp_load_module(chip, chip->modules[i]); + if (err < 0) { + dev_err(chip->card->dev, "image download error [%s]\n", diff --git a/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch b/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch new file mode 100644 index 000000000..266688652 --- /dev/null +++ b/debian/patches/bugfix/all/firmware_class-log-every-success-and-failure.patch @@ -0,0 +1,70 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: firmware_class: Log every success and failure against given device +Date: Sun, 09 Dec 2012 16:02:00 +0000 +Forwarded: no + +The hundreds of users of request_firmware() have nearly as many +different log formats for reporting failures. They also have only the +vaguest hint as to what went wrong; only firmware_class really knows +that. Therefore, add specific log messages for the failure modes that +aren't currently logged. + +In case of a driver that tries multiple names, this may result in the +impression that it failed to initialise. Therefore, also log successes. + +This makes many error messages in drivers redundant, which will be +removed in later patches. + +This does not cover the case where we fall back to a user-mode helper +(which is no longer enabled in Debian). + +NOTE: hw-detect will depend on the "firmware: failed to load %s (%d)\n" +format to detect missing firmware. +--- +Index: linux/drivers/base/firmware_loader/main.c +=================================================================== +--- linux.orig/drivers/base/firmware_loader/main.c ++++ linux/drivers/base/firmware_loader/main.c +@@ -328,21 +328,22 @@ fw_get_filesystem_firmware(struct device + rc = kernel_read_file_from_path(path, &fw_priv->data, &size, + msize, id); + if (rc) { +- if (rc == -ENOENT) +- dev_dbg(device, "loading %s failed with error %d\n", +- path, rc); +- else +- dev_warn(device, "loading %s failed with error %d\n", +- path, rc); ++ dev_dbg(device, "loading %s failed with error %d\n", ++ path, rc); + continue; + } +- dev_dbg(device, "direct-loading %s\n", fw_priv->fw_name); ++ dev_info(device, "firmware: direct-loading firmware %s\n", ++ fw_priv->fw_name); + fw_priv->size = size; + fw_state_done(fw_priv); + break; + } + __putname(path); + ++ if (rc) ++ dev_err(device, "firmware: failed to load %s (%d)\n", ++ fw_priv->fw_name, rc); ++ + return rc; + } + +Index: linux/drivers/base/firmware_loader/fallback.c +=================================================================== +--- linux.orig/drivers/base/firmware_loader/fallback.c ++++ linux/drivers/base/firmware_loader/fallback.c +@@ -604,7 +604,7 @@ static int fw_load_from_user_helper(stru + if (opt_flags & FW_OPT_NOWAIT) { + timeout = usermodehelper_read_lock_wait(timeout); + if (!timeout) { +- dev_dbg(device, "firmware: %s loading timed out\n", ++ dev_err(device, "firmware: %s loading timed out\n", + name); + return -EBUSY; + } diff --git a/debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch b/debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch new file mode 100644 index 000000000..d6cb0ffac --- /dev/null +++ b/debian/patches/bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch @@ -0,0 +1,66 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 13 Apr 2016 21:48:06 +0100 +Subject: fs: Add MODULE_SOFTDEP declarations for hard-coded crypto drivers +Bug-Debian: https://bugs.debian.org/819725 +Forwarded: http://mid.gmane.org/20160517133631.GF7555@decadent.org.uk + +This helps initramfs builders and other tools to find the full +dependencies of a module. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream] +--- +--- a/fs/btrfs/super.c ++++ b/fs/btrfs/super.c +@@ -2536,3 +2536,4 @@ late_initcall(init_btrfs_fs); + module_exit(exit_btrfs_fs) + + MODULE_LICENSE("GPL"); ++MODULE_SOFTDEP("pre: crypto-crc32c"); +--- a/fs/crypto/crypto.c ++++ b/fs/crypto/crypto.c +@@ -504,3 +504,4 @@ static void __exit fscrypt_exit(void) + module_exit(fscrypt_exit); + + MODULE_LICENSE("GPL"); ++MODULE_SOFTDEP("pre: crypto-aes crypto-ecb"); +--- a/fs/ext4/super.c ++++ b/fs/ext4/super.c +@@ -6200,6 +6200,6 @@ static void __exit ext4_exit_fs(void) + MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); + MODULE_DESCRIPTION("Fourth Extended Filesystem"); + MODULE_LICENSE("GPL"); +-MODULE_SOFTDEP("pre: crc32c"); ++MODULE_SOFTDEP("pre: crypto-crc32c"); + module_init(ext4_init_fs) + module_exit(ext4_exit_fs) +--- a/fs/f2fs/super.c ++++ b/fs/f2fs/super.c +@@ -3373,5 +3373,5 @@ module_exit(exit_f2fs_fs) + MODULE_AUTHOR("Samsung Electronics's Praesto Team"); + MODULE_DESCRIPTION("Flash Friendly File System"); + MODULE_LICENSE("GPL"); +-MODULE_SOFTDEP("pre: crc32"); ++MODULE_SOFTDEP("pre: crypto-crc32"); + +--- a/fs/jbd2/journal.c ++++ b/fs/jbd2/journal.c +@@ -2744,6 +2744,7 @@ static void __exit journal_exit(void) + } + + MODULE_LICENSE("GPL"); ++MODULE_SOFTDEP("pre: crypto-crc32c"); + module_init(journal_init); + module_exit(journal_exit); + +--- a/fs/nfsd/nfsctl.c ++++ b/fs/nfsd/nfsctl.c +@@ -1337,5 +1337,8 @@ static void __exit exit_nfsd(void) + + MODULE_AUTHOR("Olaf Kirch <okir@monad.swb.de>"); + MODULE_LICENSE("GPL"); ++#ifdef CONFIG_NFSD_V4 ++MODULE_SOFTDEP("pre: crypto-md5"); ++#endif + module_init(init_nfsd) + module_exit(exit_nfsd) diff --git a/debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch b/debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch new file mode 100644 index 000000000..8e942af28 --- /dev/null +++ b/debian/patches/bugfix/all/kbuild-fix-recordmcount-dependency.patch @@ -0,0 +1,25 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: kbuild: Fix recordmcount dependency for OOT modules +Date: Mon, 08 Sep 2014 18:31:24 +0100 +Forwarded: no + +We never rebuild anything in-tree when building an out-of-tree +modules, so external modules should not depend on the recordmcount +sources. + +Index: linux/scripts/Makefile.build +=================================================================== +--- linux.orig/scripts/Makefile.build ++++ linux/scripts/Makefile.build +@@ -232,6 +232,11 @@ cmd_record_mcount = \ + endif # CC_USING_RECORD_MCOUNT + endif # CONFIG_FTRACE_MCOUNT_RECORD + ++# Don't require recordmcount source for an OOT build. ++ifdef KBUILD_EXTMOD ++recordmcount_source := ++endif ++ + ifdef CONFIG_STACK_VALIDATION + ifneq ($(SKIP_STACK_VALIDATION),1) + diff --git a/debian/patches/bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch b/debian/patches/bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch new file mode 100644 index 000000000..22ef11a3b --- /dev/null +++ b/debian/patches/bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch @@ -0,0 +1,42 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 04 Mar 2017 01:44:15 +0000 +Subject: Kbuild.include: addtree: Remove quotes before matching path +Bug-Debian: https://bugs.debian.org/856474 +Forwarded: https://marc.info/?l=linux-kbuild&m=148987677205629 + +systemtap currently fails to build modules when the kernel source and +object trees are separate. + +systemtap adds something like -I"/usr/share/systemtap/runtime" to +EXTRA_CFLAGS, and addtree should not adjust this as it's specifying an +absolute directory. But since make has no understanding of shell +quoting, it does anyway. + +For a long time this didn't matter, because addtree would still emit +the original -I option after the adjusted one. However, commit +db547ef19064 ("Kbuild: don't add obj tree in additional includes") +changed it to remove the original -I option. + +Remove quotes (both double and single) before matching against the +excluded patterns. + +References: https://bugs.debian.org/856474 +Reported-by: Jack Henschel <jackdev@mailbox.org> +Reported-by: Ritesh Raj Sarraf <rrs@debian.org> +Fixes: db547ef19064 ("Kbuild: don't add obj tree in additional includes") +Cc: stable@vger.kernel.org # 4.8+ +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/scripts/Kbuild.include +=================================================================== +--- linux.orig/scripts/Kbuild.include ++++ linux/scripts/Kbuild.include +@@ -211,7 +211,7 @@ hdr-inst := -f $(srctree)/scripts/Makefi + # Prefix -I with $(srctree) if it is not an absolute path. + # skip if -I has no parameter + addtree = $(if $(patsubst -I%,%,$(1)), \ +-$(if $(filter-out -I/% -I./% -I../%,$(1)),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1)),$(1)) ++$(if $(filter-out -I/% -I./% -I../%,$(subst $(quote),,$(subst $(squote),,$(1)))),$(patsubst -I%,-I$(srctree)/%,$(1)),$(1)),$(1)) + + # Find all -I options and call addtree + flags = $(foreach o,$($(1)),$(if $(filter -I%,$(o)),$(call addtree,$(o)),$(o))) diff --git a/debian/patches/bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch b/debian/patches/bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch new file mode 100644 index 000000000..61a4628a4 --- /dev/null +++ b/debian/patches/bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch @@ -0,0 +1,91 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 19 Oct 2013 19:43:35 +0100 +Subject: kbuild: Use -nostdinc in compile tests +Bug-Debian: https://bugs.debian.org/726861 +Bug-Debian: https://bugs.debian.org/717557 +Forwarded: https://marc.info/?l=linux-kbuild&m=141523555023625 + +gcc 4.8 and later include <stdc-predef.h> by default. In some +versions of eglibc that includes <bits/predefs.h>, but that may be +missing when building with a biarch compiler. Also <stdc-predef.h> +itself could be missing as we are only trying to build a kernel, not +userland. + +The -nostdinc option disables this, though it isn't explicitly +documented. This option is already used when actually building +the kernel, but not by cc-option and other tests. This can result +in silently miscompiling the kernel. + +References: https://bugs.debian.org/717557 +References: https://bugs.debian.org/726861 +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/scripts/Kbuild.include ++++ b/scripts/Kbuild.include +@@ -121,7 +121,7 @@ CC_OPTION_CFLAGS = $(filter-out $(GCC_PL + # Usage: cflags-y += $(call cc-option,-march=winchip-c6,-march=i586) + + cc-option = $(call __cc-option, $(CC),\ +- $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS),$(1),$(2)) ++ $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS),$(1),$(2)) + + # hostcc-option + # Usage: cflags-y += $(call hostcc-option,-march=winchip-c6,-march=i586) +@@ -131,23 +131,24 @@ hostcc-option = $(call __cc-option, $(HO + # cc-option-yn + # Usage: flag := $(call cc-option-yn,-march=winchip-c6) + cc-option-yn = $(call try-run,\ +- $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) ++ $(CC) -Werror $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) $(1) -c -x c /dev/null -o "$$TMP",y,n) + + # cc-disable-warning + # Usage: cflags-y += $(call cc-disable-warning,unused-but-set-variable) + cc-disable-warning = $(call try-run,\ +- $(CC) -Werror $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) ++ $(CC) -Werror $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -W$(strip $(1)) -c -x c /dev/null -o "$$TMP",-Wno-$(strip $(1))) + + # cc-name + # Expands to either gcc or clang + cc-name = $(shell $(CC) -v 2>&1 | grep -q "clang version" && echo clang || echo gcc) + + # cc-version +-cc-version = $(shell $(CONFIG_SHELL) $(srctree)/scripts/gcc-version.sh $(CC)) ++cc-version = $(shell $(CONFIG_SHELL) \ ++ $(srctree)/scripts/gcc-version.sh $(CC) $(NOSTDINC_FLAGS)) + + # cc-fullversion + cc-fullversion = $(shell $(CONFIG_SHELL) \ +- $(srctree)/scripts/gcc-version.sh -p $(CC)) ++ $(srctree)/scripts/gcc-version.sh -p $(CC) $(NOSTDINC_FLAGS)) + + # cc-ifversion + # Usage: EXTRA_CFLAGS += $(call cc-ifversion, -lt, 0402, -O1) +@@ -156,7 +157,7 @@ cc-ifversion = $(shell [ $(cc-version) $ + # cc-ldoption + # Usage: ldflags += $(call cc-ldoption, -Wl$(comma)--hash-style=both) + cc-ldoption = $(call try-run,\ +- $(CC) $(1) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2)) ++ $(CC) $(1) $(NOSTDINC_FLAGS) $(KBUILD_CPPFLAGS) $(CC_OPTION_CFLAGS) -nostdlib -x c /dev/null -o "$$TMP",$(1),$(2)) + + # ld-option + # Usage: KBUILD_LDFLAGS += $(call ld-option, -X, -Y) +--- a/Makefile ++++ b/Makefile +@@ -661,6 +661,8 @@ else + KBUILD_CFLAGS += -O2 + endif + ++NOSTDINC_FLAGS += -nostdinc ++ + # Tell gcc to never replace conditional load with a non-conditional one + KBUILD_CFLAGS += $(call cc-option,--param=allow-store-data-races=0) + KBUILD_CFLAGS += $(call cc-option,-fno-allow-store-data-races) +@@ -781,7 +783,7 @@ LDFLAGS_vmlinux += --gc-sections + endif + + # arch Makefile may override CC so keep this after arch Makefile is included +-NOSTDINC_FLAGS += -nostdinc -isystem $(shell $(CC) -print-file-name=include) ++NOSTDINC_FLAGS += -isystem $(shell $(CC) -print-file-name=include) + + # warn about C99 declaration after statement + KBUILD_CFLAGS += $(call cc-option,-Wdeclaration-after-statement,) diff --git a/debian/patches/bugfix/all/lib-genalloc-add-gen_pool_dma_zalloc-for-zeroed-DMA.patch b/debian/patches/bugfix/all/lib-genalloc-add-gen_pool_dma_zalloc-for-zeroed-DMA.patch new file mode 100644 index 000000000..360a16aa5 --- /dev/null +++ b/debian/patches/bugfix/all/lib-genalloc-add-gen_pool_dma_zalloc-for-zeroed-DMA.patch @@ -0,0 +1,77 @@ +From: Fredrik Noring <noring@nocrew.org> +Date: Wed, 29 May 2019 13:28:39 +0300 +Subject: lib/genalloc: add gen_pool_dma_zalloc() for zeroed DMA allocations +Origin: https://git.kernel.org/linus/da83a722959a82733c3ca60030cc364ca2318c5a + +gen_pool_dma_zalloc() is a zeroed memory variant of +gen_pool_dma_alloc(). Also document the return values of both, and +indicate NULL as a "%NULL" constant. + +Signed-off-by: Fredrik Noring <noring@nocrew.org> +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Christoph Hellwig <hch@lst.de> +--- + include/linux/genalloc.h | 1 + + lib/genalloc.c | 29 ++++++++++++++++++++++++++++- + 2 files changed, 29 insertions(+), 1 deletion(-) + +--- a/include/linux/genalloc.h ++++ b/include/linux/genalloc.h +@@ -121,6 +121,7 @@ + genpool_algo_t algo, void *data); + extern void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, + dma_addr_t *dma); ++void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma); + extern void gen_pool_free(struct gen_pool *, unsigned long, size_t); + extern void gen_pool_for_each_chunk(struct gen_pool *, + void (*)(struct gen_pool *, struct gen_pool_chunk *, void *), void *); +--- a/lib/genalloc.c ++++ b/lib/genalloc.c +@@ -337,12 +337,14 @@ + * gen_pool_dma_alloc - allocate special memory from the pool for DMA usage + * @pool: pool to allocate from + * @size: number of bytes to allocate from the pool +- * @dma: dma-view physical address return value. Use NULL if unneeded. ++ * @dma: dma-view physical address return value. Use %NULL if unneeded. + * + * Allocate the requested number of bytes from the specified pool. + * Uses the pool allocation function (with first-fit algorithm by default). + * Can not be used in NMI handler on architectures without + * NMI-safe cmpxchg implementation. ++ * ++ * Return: virtual address of the allocated memory, or %NULL on failure + */ + void *gen_pool_dma_alloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) + { +@@ -363,6 +365,31 @@ + EXPORT_SYMBOL(gen_pool_dma_alloc); + + /** ++ * gen_pool_dma_zalloc - allocate special zeroed memory from the pool for ++ * DMA usage ++ * @pool: pool to allocate from ++ * @size: number of bytes to allocate from the pool ++ * @dma: dma-view physical address return value. Use %NULL if unneeded. ++ * ++ * Allocate the requested number of zeroed bytes from the specified pool. ++ * Uses the pool allocation function (with first-fit algorithm by default). ++ * Can not be used in NMI handler on architectures without ++ * NMI-safe cmpxchg implementation. ++ * ++ * Return: virtual address of the allocated zeroed memory, or %NULL on failure ++ */ ++void *gen_pool_dma_zalloc(struct gen_pool *pool, size_t size, dma_addr_t *dma) ++{ ++ void *vaddr = gen_pool_dma_alloc(pool, size, dma); ++ ++ if (vaddr) ++ memset(vaddr, 0, size); ++ ++ return vaddr; ++} ++EXPORT_SYMBOL(gen_pool_dma_zalloc); ++ ++/** + * gen_pool_free - free allocated special memory back to the pool + * @pool: pool to free to + * @addr: starting address of memory to free back to pool diff --git a/debian/patches/bugfix/all/libbpf-add-soname-to-shared-object.patch b/debian/patches/bugfix/all/libbpf-add-soname-to-shared-object.patch new file mode 100644 index 000000000..40f2bcc1d --- /dev/null +++ b/debian/patches/bugfix/all/libbpf-add-soname-to-shared-object.patch @@ -0,0 +1,56 @@ +From: Hilko Bengen <bengen@debian.org> +Date: Sun, 02 Dec 2018 23:26:03 +0000 +Subject: libbpf: add SONAME to shared object + +tools/lib/bpf/libbpf: Add proper version to the shared object. + +Add versioning to the shared object to make it easier on distros to +distribute the library without having to watch for API/ABI versioning. + +This is similar to the change made to tools/lib/lockdep/Makefile in +be227b45fb228adff4371b8de9e3989904209ff4. + +Signed-off-by: Hilko Bengen <bengen@debian.org> +[bwh: Drop unnecessary changes] +--- +Index: linux/tools/lib/bpf/Makefile +=================================================================== +--- linux.orig/tools/lib/bpf/Makefile ++++ linux/tools/lib/bpf/Makefile +@@ -94,7 +94,7 @@ export prefix libdir src obj + libdir_SQ = $(subst ','\'',$(libdir)) + libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) + +-LIB_FILE = libbpf.a libbpf.so ++LIB_FILE = libbpf.a libbpf.so.$(LIBBPF_VERSION) + + VERSION = $(BPF_VERSION) + PATCHLEVEL = $(BPF_PATCHLEVEL) +@@ -103,7 +103,7 @@ EXTRAVERSION = $(BPF_EXTRAVERSION) + OBJ = $@ + N = + +-LIBBPF_VERSION = $(BPF_VERSION).$(BPF_PATCHLEVEL).$(BPF_EXTRAVERSION) ++LIBBPF_VERSION = $(shell make --no-print-directory -sC ../../.. kernelversion | cut -d. -f1,2) + + # Set compile option CFLAGS + ifdef EXTRA_CFLAGS +@@ -169,8 +169,8 @@ $(BPF_IN): force elfdep bpfdep + echo "Warning: Kernel ABI header at 'tools/include/uapi/linux/if_link.h' differs from latest version at 'include/uapi/linux/if_link.h'" >&2 )) || true + $(Q)$(MAKE) $(build)=libbpf + +-$(OUTPUT)libbpf.so: $(BPF_IN) +- $(QUIET_LINK)$(CC) --shared $^ -o $@ ++$(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN) ++ $(QUIET_LINK)$(CC) --shared $^ -Wl,-soname,$(@F) -o $@ + + $(OUTPUT)libbpf.a: $(BPF_IN) + $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ +@@ -185,6 +185,7 @@ endef + install_lib: all_cmd + $(call QUIET_INSTALL, $(LIB_FILE)) \ + $(call do_install,$(LIB_FILE),$(libdir_SQ)) ++ $(Q)ln -sf libbpf.so.$(LIBBPF_VERSION) $(DESTDIR_SQ)$(libdir_SQ)/libbpf.so + + install_headers: + $(call QUIET_INSTALL, headers) \ diff --git a/debian/patches/bugfix/all/libbpf-generate-pkg-config.patch b/debian/patches/bugfix/all/libbpf-generate-pkg-config.patch new file mode 100644 index 000000000..63ecffe5f --- /dev/null +++ b/debian/patches/bugfix/all/libbpf-generate-pkg-config.patch @@ -0,0 +1,90 @@ +Author: Luca Boccassi <bluca@debian.org> +Description: generate pkg-config file for libbpf + Generate a libbpf.pc file at build time so that users can rely + on pkg-config to find the library, its CFLAGS and LDFLAGS. +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git/commit/?id=dd399ac9e343c7573c47d6820e4a23013c54749d +Applied-Upstream: yes +Index: linux/tools/lib/bpf/.gitignore +=================================================================== +--- linux.orig/tools/lib/bpf/.gitignore ++++ linux/tools/lib/bpf/.gitignore +@@ -1,2 +1,3 @@ + libbpf_version.h ++libbpf.pc + FEATURE-DUMP.libbpf +Index: linux/tools/lib/bpf/Makefile +=================================================================== +--- linux.orig/tools/lib/bpf/Makefile ++++ linux/tools/lib/bpf/Makefile +@@ -95,6 +95,7 @@ libdir_SQ = $(subst ','\'',$(libdir)) + libdir_relative_SQ = $(subst ','\'',$(libdir_relative)) + + LIB_FILE = libbpf.a libbpf.so.$(LIBBPF_VERSION) ++PC_FILE = libbpf.pc + + VERSION = $(BPF_VERSION) + PATCHLEVEL = $(BPF_PATCHLEVEL) +@@ -144,8 +145,9 @@ include $(srctree)/tools/build/Makefile. + + BPF_IN := $(OUTPUT)libbpf-in.o + LIB_FILE := $(addprefix $(OUTPUT),$(LIB_FILE)) ++PC_FILE := $(addprefix $(OUTPUT),$(PC_FILE)) + +-CMD_TARGETS = $(LIB_FILE) ++CMD_TARGETS = $(LIB_FILE) $(PC_FILE) + + TARGETS = $(CMD_TARGETS) + +@@ -175,6 +177,12 @@ $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $( + $(OUTPUT)libbpf.a: $(BPF_IN) + $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ + ++$(OUTPUT)libbpf.pc: ++ $(QUIET_GEN)sed -e "s|@PREFIX@|$(prefix)|" \ ++ -e "s|@LIBDIR@|$(libdir_SQ)|" \ ++ -e "s|@VERSION@|$(LIBBPF_VERSION)|" \ ++ < libbpf.pc.template > $@ ++ + define do_install + if [ ! -d '$(DESTDIR_SQ)$2' ]; then \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$2'; \ +@@ -193,7 +201,12 @@ install_headers: + $(call do_install,libbpf.h,$(prefix)/include/bpf,644); + $(call do_install,btf.h,$(prefix)/include/bpf,644); + +-install: install_lib ++install_pkgconfig: $(PC_FILE) ++ $(call QUIET_INSTALL, $(PC_FILE)) \ ++ $(call do_install,$(PC_FILE),$(libdir_SQ)/pkgconfig,644) ++ ++ ++install: install_lib install_pkgconfig + + ### Cleaning rules + +@@ -202,7 +215,7 @@ config-clean: + $(Q)$(MAKE) -C $(srctree)/tools/build/feature/ clean >/dev/null + + clean: +- $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so .*.d .*.cmd \ ++ $(call QUIET_CLEAN, libbpf) $(RM) *.o *~ $(TARGETS) *.a *.so .*.d .*.cmd *.pc \ + $(RM) LIBBPF-CFLAGS + $(call QUIET_CLEAN, core-gen) $(RM) $(OUTPUT)FEATURE-DUMP.libbpf + +Index: linux/tools/lib/bpf/libbpf.pc.template +=================================================================== +--- /dev/null ++++ linux/tools/lib/bpf/libbpf.pc.template +@@ -0,0 +1,12 @@ ++# SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) ++ ++prefix=@PREFIX@ ++libdir=@LIBDIR@ ++includedir=${prefix}/include ++ ++Name: libbpf ++Description: BPF library ++Version: @VERSION@ ++Libs: -L${libdir} -lbpf ++Requires.private: libelf ++Cflags: -I${includedir} diff --git a/debian/patches/bugfix/all/libbpf-link-shared-object-with-libelf.patch b/debian/patches/bugfix/all/libbpf-link-shared-object-with-libelf.patch new file mode 100644 index 000000000..f02cb07e2 --- /dev/null +++ b/debian/patches/bugfix/all/libbpf-link-shared-object-with-libelf.patch @@ -0,0 +1,22 @@ +From: Hilko Bengen <bengen@debian.org> +Date: Sun, 02 Dec 2018 23:26:03 +0000 +Subject: libbpf: link shared object with libelf + +libbpf.so needs to be linked against libelf to avoid missing symbols. + +Signed-off-by: Hilko Bengen <bengen@debian.org> + +--- +Index: linux/tools/lib/bpf/Makefile +=================================================================== +--- linux.orig/tools/lib/bpf/Makefile ++++ linux/tools/lib/bpf/Makefile +@@ -170,7 +170,7 @@ $(BPF_IN): force elfdep bpfdep + $(Q)$(MAKE) $(build)=libbpf + + $(OUTPUT)libbpf.so.$(LIBBPF_VERSION): $(BPF_IN) +- $(QUIET_LINK)$(CC) --shared $^ -Wl,-soname,$(@F) -o $@ ++ $(QUIET_LINK)$(CC) --shared $^ -lelf -Wl,-soname,$(@F) -o $@ + + $(OUTPUT)libbpf.a: $(BPF_IN) + $(QUIET_LINK)$(RM) $@; $(AR) rcs $@ $^ diff --git a/debian/patches/bugfix/all/libcpupower-hide-private-function.patch b/debian/patches/bugfix/all/libcpupower-hide-private-function.patch new file mode 100644 index 000000000..dba71b64e --- /dev/null +++ b/debian/patches/bugfix/all/libcpupower-hide-private-function.patch @@ -0,0 +1,22 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 01 Dec 2018 19:22:50 +0000 +Subject: libcpupower: Hide private function + +cpupower_read_sysfs() (previously known as sysfs_read_file()) is an +internal function in libcpupower and should not be exported when +libcpupower is a shared library. Change its visibility to "hidden". + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/tools/power/cpupower/lib/cpupower.c +=================================================================== +--- linux.orig/tools/power/cpupower/lib/cpupower.c ++++ linux/tools/power/cpupower/lib/cpupower.c +@@ -15,6 +15,7 @@ + #include "cpupower.h" + #include "cpupower_intern.h" + ++__attribute__((visibility("hidden"))) + unsigned int cpupower_read_sysfs(const char *path, char *buf, size_t buflen) + { + int fd; diff --git a/debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch b/debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch new file mode 100644 index 000000000..9c3461019 --- /dev/null +++ b/debian/patches/bugfix/all/module-disable-matching-missing-version-crc.patch @@ -0,0 +1,25 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 02 Dec 2016 23:06:18 +0000 +Subject: module: Disable matching missing version CRC +Forwarded: not-needed + +This partly reverts commit cd3caefb4663e3811d37cc2afad3cce642d60061. +We want to fail closed if a symbol version CRC is missing, as the +alternative may allow subverting module signing. +--- +Index: linux/kernel/module.c +=================================================================== +--- linux.orig/kernel/module.c ++++ linux/kernel/module.c +@@ -1317,9 +1317,8 @@ static int check_version(const struct lo + goto bad_version; + } + +- /* Broken toolchain. Warn once, then let it go.. */ +- pr_warn_once("%s: no symbol version for %s\n", info->name, symname); +- return 1; ++ pr_warn("%s: no symbol version for %s\n", info->name, symname); ++ return 0; + + bad_version: + pr_warn("%s: disagrees about version of symbol %s\n", diff --git a/debian/patches/bugfix/all/mt76-use-the-correct-hweight8-function.patch b/debian/patches/bugfix/all/mt76-use-the-correct-hweight8-function.patch new file mode 100644 index 000000000..ce3b63af3 --- /dev/null +++ b/debian/patches/bugfix/all/mt76-use-the-correct-hweight8-function.patch @@ -0,0 +1,30 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 12 Feb 2019 15:20:48 +0000 +Subject: mt76: Use the correct hweight8() function +Forwarded: https://marc.info/?l=linux-wireless&m=154998579614180&w=2 + +mt76_init_stream_cap() and mt76_get_txpower() call __sw_hweight8() +directly, but that's only defined if CONFIG_GENERIC_HWEIGHT is +enabled. The function that works on all architectures is hweight8(). + +Fixes: 551e1ef4d291 ("mt76: add mt76_init_stream_cap routine") +Fixes: 9313faacbb4e ("mt76: move mt76x02_get_txpower to mt76 core") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +[bwh: For 4.19, drop change in mt76_get_txpower()] +--- + drivers/net/wireless/mediatek/mt76/mac80211.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/net/wireless/mediatek/mt76/mac80211.c +=================================================================== +--- linux.orig/drivers/net/wireless/mediatek/mt76/mac80211.c ++++ linux/drivers/net/wireless/mediatek/mt76/mac80211.c +@@ -124,7 +124,7 @@ static void mt76_init_stream_cap(struct + bool vht) + { + struct ieee80211_sta_ht_cap *ht_cap = &sband->ht_cap; +- int i, nstream = __sw_hweight8(dev->antenna_mask); ++ int i, nstream = hweight8(dev->antenna_mask); + struct ieee80211_sta_vht_cap *vht_cap; + u16 mcs_map = 0; + diff --git a/debian/patches/bugfix/all/net_sched-let-qdisc_put-accept-null-pointer.patch b/debian/patches/bugfix/all/net_sched-let-qdisc_put-accept-null-pointer.patch new file mode 100644 index 000000000..3f259ac4c --- /dev/null +++ b/debian/patches/bugfix/all/net_sched-let-qdisc_put-accept-null-pointer.patch @@ -0,0 +1,50 @@ +From: Diederik de Haas <didi.debian@cknow.org> +Date: Wed, 22 Jun 2022 11:44:05 +0200 +Subject: net_sched: let qdisc_put() accept NULL pointer +Bug-Debian: https://bugs.debian.org/1013299 + +In commit 92833e8b5db6c209e9311ac8c6a44d3bf1856659 titled +"net: sched: rename qdisc_destroy() to qdisc_put()" part of the +functionality of qdisc_destroy() was moved into a (for linux-4.19.y) +new function qdisk_put(), and the previous calls to qdisc_destroy() +were changed to qdisk_put(). +This made it similar to f.e. 5.10.y and current master. + +There was one part of qdisc_destroy() not moved over to qdisc_put() and +that was the check for a NULL value, causing oopses. +(See upstream commit: 6efb971ba8edfbd80b666f29de12882852f095ae) +This patch fixes that. + +Fixes: 92833e8b5db6c209e9311ac8c6a44d3bf1856659 +Reported-by: Thorsten Glaser <tg@mirbsd.de> +Link: https://bugs.debian.org/1013299 +--- + net/sched/sch_generic.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c +index 7c1b1eff84f4..cad2586c3473 100644 +--- a/net/sched/sch_generic.c ++++ b/net/sched/sch_generic.c +@@ -970,8 +970,6 @@ static void qdisc_destroy(struct Qdisc *qdisc) + const struct Qdisc_ops *ops; + struct sk_buff *skb, *tmp; + +- if (!qdisc) +- return; + ops = qdisc->ops; + + #ifdef CONFIG_NET_SCHED +@@ -1003,6 +1001,9 @@ static void qdisc_destroy(struct Qdisc *qdisc) + + void qdisc_put(struct Qdisc *qdisc) + { ++ if (!qdisc) ++ return; ++ + if (qdisc->flags & TCQ_F_BUILTIN || + !refcount_dec_and_test(&qdisc->refcnt)) + return; +-- +2.36.1 + diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-event_anal.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-event_anal.patch new file mode 100644 index 000000000..d50476bca --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-event_anal.patch @@ -0,0 +1,153 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 1 Mar 2019 17:19:00 -0800 +Subject: perf script python: Add Python3 support to event_analyzing_sample.py +Origin: https://git.kernel.org/linus/c253c72e9d6723c8b078beb362f050059ef5de39 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the event_analyzing_sample.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Cc: Feng Tang <feng.tang@intel.com> +Link: http://lkml.kernel.org/r/20190302011903.2416-5-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/event_analyzing_sample.py | 48 ++++++++++---------- + 1 file changed, 25 insertions(+), 23 deletions(-) + +--- a/tools/perf/scripts/python/event_analyzing_sample.py ++++ b/tools/perf/scripts/python/event_analyzing_sample.py +@@ -15,6 +15,8 @@ + # for a x86 HW PMU event: PEBS with load latency data. + # + ++from __future__ import print_function ++ + import os + import sys + import math +@@ -37,7 +39,7 @@ con = sqlite3.connect("/dev/shm/perf.db" + con.isolation_level = None + + def trace_begin(): +- print "In trace_begin:\n" ++ print("In trace_begin:\n") + + # + # Will create several tables at the start, pebs_ll is for PEBS data with +@@ -76,12 +78,12 @@ def process_event(param_dict): + name = param_dict["ev_name"] + + # Symbol and dso info are not always resolved +- if (param_dict.has_key("dso")): ++ if ("dso" in param_dict): + dso = param_dict["dso"] + else: + dso = "Unknown_dso" + +- if (param_dict.has_key("symbol")): ++ if ("symbol" in param_dict): + symbol = param_dict["symbol"] + else: + symbol = "Unknown_symbol" +@@ -102,7 +104,7 @@ def insert_db(event): + event.ip, event.status, event.dse, event.dla, event.lat)) + + def trace_end(): +- print "In trace_end:\n" ++ print("In trace_end:\n") + # We show the basic info for the 2 type of event classes + show_general_events() + show_pebs_ll() +@@ -123,29 +125,29 @@ def show_general_events(): + # Check the total record number in the table + count = con.execute("select count(*) from gen_events") + for t in count: +- print "There is %d records in gen_events table" % t[0] ++ print("There is %d records in gen_events table" % t[0]) + if t[0] == 0: + return + +- print "Statistics about the general events grouped by thread/symbol/dso: \n" ++ print("Statistics about the general events grouped by thread/symbol/dso: \n") + + # Group by thread + commq = con.execute("select comm, count(comm) from gen_events group by comm order by -count(comm)") +- print "\n%16s %8s %16s\n%s" % ("comm", "number", "histogram", "="*42) ++ print("\n%16s %8s %16s\n%s" % ("comm", "number", "histogram", "="*42)) + for row in commq: +- print "%16s %8d %s" % (row[0], row[1], num2sym(row[1])) ++ print("%16s %8d %s" % (row[0], row[1], num2sym(row[1]))) + + # Group by symbol +- print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histogram", "="*58) ++ print("\n%32s %8s %16s\n%s" % ("symbol", "number", "histogram", "="*58)) + symbolq = con.execute("select symbol, count(symbol) from gen_events group by symbol order by -count(symbol)") + for row in symbolq: +- print "%32s %8d %s" % (row[0], row[1], num2sym(row[1])) ++ print("%32s %8d %s" % (row[0], row[1], num2sym(row[1]))) + + # Group by dso +- print "\n%40s %8s %16s\n%s" % ("dso", "number", "histogram", "="*74) ++ print("\n%40s %8s %16s\n%s" % ("dso", "number", "histogram", "="*74)) + dsoq = con.execute("select dso, count(dso) from gen_events group by dso order by -count(dso)") + for row in dsoq: +- print "%40s %8d %s" % (row[0], row[1], num2sym(row[1])) ++ print("%40s %8d %s" % (row[0], row[1], num2sym(row[1]))) + + # + # This function just shows the basic info, and we could do more with the +@@ -156,35 +158,35 @@ def show_pebs_ll(): + + count = con.execute("select count(*) from pebs_ll") + for t in count: +- print "There is %d records in pebs_ll table" % t[0] ++ print("There is %d records in pebs_ll table" % t[0]) + if t[0] == 0: + return + +- print "Statistics about the PEBS Load Latency events grouped by thread/symbol/dse/latency: \n" ++ print("Statistics about the PEBS Load Latency events grouped by thread/symbol/dse/latency: \n") + + # Group by thread + commq = con.execute("select comm, count(comm) from pebs_ll group by comm order by -count(comm)") +- print "\n%16s %8s %16s\n%s" % ("comm", "number", "histogram", "="*42) ++ print("\n%16s %8s %16s\n%s" % ("comm", "number", "histogram", "="*42)) + for row in commq: +- print "%16s %8d %s" % (row[0], row[1], num2sym(row[1])) ++ print("%16s %8d %s" % (row[0], row[1], num2sym(row[1]))) + + # Group by symbol +- print "\n%32s %8s %16s\n%s" % ("symbol", "number", "histogram", "="*58) ++ print("\n%32s %8s %16s\n%s" % ("symbol", "number", "histogram", "="*58)) + symbolq = con.execute("select symbol, count(symbol) from pebs_ll group by symbol order by -count(symbol)") + for row in symbolq: +- print "%32s %8d %s" % (row[0], row[1], num2sym(row[1])) ++ print("%32s %8d %s" % (row[0], row[1], num2sym(row[1]))) + + # Group by dse + dseq = con.execute("select dse, count(dse) from pebs_ll group by dse order by -count(dse)") +- print "\n%32s %8s %16s\n%s" % ("dse", "number", "histogram", "="*58) ++ print("\n%32s %8s %16s\n%s" % ("dse", "number", "histogram", "="*58)) + for row in dseq: +- print "%32s %8d %s" % (row[0], row[1], num2sym(row[1])) ++ print("%32s %8d %s" % (row[0], row[1], num2sym(row[1]))) + + # Group by latency + latq = con.execute("select lat, count(lat) from pebs_ll group by lat order by lat") +- print "\n%32s %8s %16s\n%s" % ("latency", "number", "histogram", "="*58) ++ print("\n%32s %8s %16s\n%s" % ("latency", "number", "histogram", "="*58)) + for row in latq: +- print "%32s %8d %s" % (row[0], row[1], num2sym(row[1])) ++ print("%32s %8d %s" % (row[0], row[1], num2sym(row[1]))) + + def trace_unhandled(event_name, context, event_fields_dict): +- print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())]) ++ print (' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])) diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-.patch new file mode 100644 index 000000000..25633c098 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-.patch @@ -0,0 +1,214 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 8 Mar 2019 16:05:16 -0800 +Subject: perf script python: Add Python3 support to export-to-postgresql.py +Origin: https://git.kernel.org/linus/1937b0560c3ea43b1b0f7d3617949ca50de8f8c0 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the export-to-postgresql.py script. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Link: http://lkml.kernel.org/r/20190309000518.2438-3-tonyj@suse.de +Signed-off-by: Adrian Hunter <adrian.hunter@intel.com> +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/export-to-postgresql.py | 58 +++++++++++++++------- + 1 file changed, 41 insertions(+), 17 deletions(-) + +--- a/tools/perf/scripts/python/export-to-postgresql.py ++++ b/tools/perf/scripts/python/export-to-postgresql.py +@@ -10,6 +10,8 @@ + # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + # more details. + ++from __future__ import print_function ++ + import os + import sys + import struct +@@ -199,6 +201,18 @@ import datetime + + from PySide.QtSql import * + ++if sys.version_info < (3, 0): ++ def toserverstr(str): ++ return str ++ def toclientstr(str): ++ return str ++else: ++ # Assume UTF-8 server_encoding and client_encoding ++ def toserverstr(str): ++ return bytes(str, "UTF_8") ++ def toclientstr(str): ++ return bytes(str, "UTF_8") ++ + # Need to access PostgreSQL C library directly to use COPY FROM STDIN + from ctypes import * + libpq = CDLL("libpq.so.5") +@@ -234,12 +248,14 @@ perf_db_export_mode = True + perf_db_export_calls = False + perf_db_export_callchains = False + ++def printerr(*args, **kw_args): ++ print(*args, file=sys.stderr, **kw_args) + + def usage(): +- print >> sys.stderr, "Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]" +- print >> sys.stderr, "where: columns 'all' or 'branches'" +- print >> sys.stderr, " calls 'calls' => create calls and call_paths table" +- print >> sys.stderr, " callchains 'callchains' => create call_paths table" ++ printerr("Usage is: export-to-postgresql.py <database name> [<columns>] [<calls>] [<callchains>]") ++ printerr("where: columns 'all' or 'branches'") ++ printerr(" calls 'calls' => create calls and call_paths table") ++ printerr(" callchains 'callchains' => create call_paths table") + raise Exception("Too few arguments") + + if (len(sys.argv) < 2): +@@ -273,7 +289,7 @@ def do_query(q, s): + return + raise Exception("Query failed: " + q.lastError().text()) + +-print datetime.datetime.today(), "Creating database..." ++print(datetime.datetime.today(), "Creating database...") + + db = QSqlDatabase.addDatabase('QPSQL') + query = QSqlQuery(db) +@@ -504,12 +520,12 @@ do_query(query, 'CREATE VIEW samples_vie + ' FROM samples') + + +-file_header = struct.pack("!11sii", "PGCOPY\n\377\r\n\0", 0, 0) +-file_trailer = "\377\377" ++file_header = struct.pack("!11sii", b"PGCOPY\n\377\r\n\0", 0, 0) ++file_trailer = b"\377\377" + + def open_output_file(file_name): + path_name = output_dir_name + "/" + file_name +- file = open(path_name, "w+") ++ file = open(path_name, "wb+") + file.write(file_header) + return file + +@@ -524,13 +540,13 @@ def copy_output_file_direct(file, table_ + + # Use COPY FROM STDIN because security may prevent postgres from accessing the files directly + def copy_output_file(file, table_name): +- conn = PQconnectdb("dbname = " + dbname) ++ conn = PQconnectdb(toclientstr("dbname = " + dbname)) + if (PQstatus(conn)): + raise Exception("COPY FROM STDIN PQconnectdb failed") + file.write(file_trailer) + file.seek(0) + sql = "COPY " + table_name + " FROM STDIN (FORMAT 'binary')" +- res = PQexec(conn, sql) ++ res = PQexec(conn, toclientstr(sql)) + if (PQresultStatus(res) != 4): + raise Exception("COPY FROM STDIN PQexec failed") + data = file.read(65536) +@@ -564,7 +580,7 @@ if perf_db_export_calls: + call_file = open_output_file("call_table.bin") + + def trace_begin(): +- print datetime.datetime.today(), "Writing to intermediate files..." ++ print(datetime.datetime.today(), "Writing to intermediate files...") + # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs + evsel_table(0, "unknown") + machine_table(0, 0, "unknown") +@@ -579,7 +595,7 @@ def trace_begin(): + unhandled_count = 0 + + def trace_end(): +- print datetime.datetime.today(), "Copying to database..." ++ print(datetime.datetime.today(), "Copying to database...") + copy_output_file(evsel_file, "selected_events") + copy_output_file(machine_file, "machines") + copy_output_file(thread_file, "threads") +@@ -594,7 +610,7 @@ def trace_end(): + if perf_db_export_calls: + copy_output_file(call_file, "calls") + +- print datetime.datetime.today(), "Removing intermediate files..." ++ print(datetime.datetime.today(), "Removing intermediate files...") + remove_output_file(evsel_file) + remove_output_file(machine_file) + remove_output_file(thread_file) +@@ -609,7 +625,7 @@ def trace_end(): + if perf_db_export_calls: + remove_output_file(call_file) + os.rmdir(output_dir_name) +- print datetime.datetime.today(), "Adding primary keys" ++ print(datetime.datetime.today(), "Adding primary keys") + do_query(query, 'ALTER TABLE selected_events ADD PRIMARY KEY (id)') + do_query(query, 'ALTER TABLE machines ADD PRIMARY KEY (id)') + do_query(query, 'ALTER TABLE threads ADD PRIMARY KEY (id)') +@@ -624,7 +640,7 @@ def trace_end(): + if perf_db_export_calls: + do_query(query, 'ALTER TABLE calls ADD PRIMARY KEY (id)') + +- print datetime.datetime.today(), "Adding foreign keys" ++ print(datetime.datetime.today(), "Adding foreign keys") + do_query(query, 'ALTER TABLE threads ' + 'ADD CONSTRAINT machinefk FOREIGN KEY (machine_id) REFERENCES machines (id),' + 'ADD CONSTRAINT processfk FOREIGN KEY (process_id) REFERENCES threads (id)') +@@ -659,8 +675,8 @@ def trace_end(): + do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') + + if (unhandled_count): +- print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" +- print datetime.datetime.today(), "Done" ++ print(datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events") ++ print(datetime.datetime.today(), "Done") + + def trace_unhandled(event_name, context, event_fields_dict): + global unhandled_count +@@ -670,12 +686,14 @@ def sched__sched_switch(*x): + pass + + def evsel_table(evsel_id, evsel_name, *x): ++ evsel_name = toserverstr(evsel_name) + n = len(evsel_name) + fmt = "!hiqi" + str(n) + "s" + value = struct.pack(fmt, 2, 8, evsel_id, n, evsel_name) + evsel_file.write(value) + + def machine_table(machine_id, pid, root_dir, *x): ++ root_dir = toserverstr(root_dir) + n = len(root_dir) + fmt = "!hiqiii" + str(n) + "s" + value = struct.pack(fmt, 3, 8, machine_id, 4, pid, n, root_dir) +@@ -686,6 +704,7 @@ def thread_table(thread_id, machine_id, + thread_file.write(value) + + def comm_table(comm_id, comm_str, *x): ++ comm_str = toserverstr(comm_str) + n = len(comm_str) + fmt = "!hiqi" + str(n) + "s" + value = struct.pack(fmt, 2, 8, comm_id, n, comm_str) +@@ -697,6 +716,9 @@ def comm_thread_table(comm_thread_id, co + comm_thread_file.write(value) + + def dso_table(dso_id, machine_id, short_name, long_name, build_id, *x): ++ short_name = toserverstr(short_name) ++ long_name = toserverstr(long_name) ++ build_id = toserverstr(build_id) + n1 = len(short_name) + n2 = len(long_name) + n3 = len(build_id) +@@ -705,12 +727,14 @@ def dso_table(dso_id, machine_id, short_ + dso_file.write(value) + + def symbol_table(symbol_id, dso_id, sym_start, sym_end, binding, symbol_name, *x): ++ symbol_name = toserverstr(symbol_name) + n = len(symbol_name) + fmt = "!hiqiqiqiqiii" + str(n) + "s" + value = struct.pack(fmt, 6, 8, symbol_id, 8, dso_id, 8, sym_start, 8, sym_end, 4, binding, n, symbol_name) + symbol_file.write(value) + + def branch_type_table(branch_type, name, *x): ++ name = toserverstr(name) + n = len(name) + fmt = "!hiii" + str(n) + "s" + value = struct.pack(fmt, 2, 4, branch_type, n, name) diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-ebf6c5c181ab.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-ebf6c5c181ab.patch new file mode 100644 index 000000000..4301e54b6 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-export-to-ebf6c5c181ab.patch @@ -0,0 +1,85 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 8 Mar 2019 16:05:17 -0800 +Subject: perf script python: Add Python3 support to export-to-sqlite.py +Origin: https://git.kernel.org/linus/ebf6c5c181abe9309788c6241d39602a1ce18723 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the export-to-sqlite.py script + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Acked-by: Adrian Hunter <adrian.hunter@intel.com> +Link: http://lkml.kernel.org/r/20190309000518.2438-4-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/export-to-sqlite.py | 23 ++++++++++++++--------- + 1 file changed, 14 insertions(+), 9 deletions(-) + +--- a/tools/perf/scripts/python/export-to-sqlite.py ++++ b/tools/perf/scripts/python/export-to-sqlite.py +@@ -10,6 +10,8 @@ + # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + # more details. + ++from __future__ import print_function ++ + import os + import sys + import struct +@@ -60,11 +62,14 @@ perf_db_export_mode = True + perf_db_export_calls = False + perf_db_export_callchains = False + ++def printerr(*args, **keyword_args): ++ print(*args, file=sys.stderr, **keyword_args) ++ + def usage(): +- print >> sys.stderr, "Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>]" +- print >> sys.stderr, "where: columns 'all' or 'branches'" +- print >> sys.stderr, " calls 'calls' => create calls and call_paths table" +- print >> sys.stderr, " callchains 'callchains' => create call_paths table" ++ printerr("Usage is: export-to-sqlite.py <database name> [<columns>] [<calls>] [<callchains>]"); ++ printerr("where: columns 'all' or 'branches'"); ++ printerr(" calls 'calls' => create calls and call_paths table"); ++ printerr(" callchains 'callchains' => create call_paths table"); + raise Exception("Too few arguments") + + if (len(sys.argv) < 2): +@@ -100,7 +105,7 @@ def do_query_(q): + return + raise Exception("Query failed: " + q.lastError().text()) + +-print datetime.datetime.today(), "Creating database..." ++print(datetime.datetime.today(), "Creating database ...") + + db_exists = False + try: +@@ -376,7 +381,7 @@ if perf_db_export_calls: + call_query.prepare("INSERT INTO calls VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)") + + def trace_begin(): +- print datetime.datetime.today(), "Writing records..." ++ print(datetime.datetime.today(), "Writing records...") + do_query(query, 'BEGIN TRANSACTION') + # id == 0 means unknown. It is easier to create records for them than replace the zeroes with NULLs + evsel_table(0, "unknown") +@@ -394,13 +399,13 @@ unhandled_count = 0 + def trace_end(): + do_query(query, 'END TRANSACTION') + +- print datetime.datetime.today(), "Adding indexes" ++ print(datetime.datetime.today(), "Adding indexes") + if perf_db_export_calls: + do_query(query, 'CREATE INDEX pcpid_idx ON calls (parent_call_path_id)') + + if (unhandled_count): +- print datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events" +- print datetime.datetime.today(), "Done" ++ print(datetime.datetime.today(), "Warning: ", unhandled_count, " unhandled events") ++ print(datetime.datetime.today(), "Done") + + def trace_unhandled(event_name, context, event_fields_dict): + global unhandled_count diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-failed-sys.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-failed-sys.patch new file mode 100644 index 000000000..617145de6 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-failed-sys.patch @@ -0,0 +1,76 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:08 -0800 +Subject: perf script python: Add Python3 support to + failed-syscalls-by-pid.py +Origin: https://git.kernel.org/linus/9b2700efc57f46fe63beee5f64fcfe2746936b4e +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the failed-syscalls-by-pid.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Cc: Tom Zanussi <tzanussi@gmail.com> +Link: http://lkml.kernel.org/r/20190222230619.17887-5-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/failed-syscalls-by-pid.py | 21 ++++++++++---------- + 1 file changed, 11 insertions(+), 10 deletions(-) + +--- a/tools/perf/scripts/python/failed-syscalls-by-pid.py ++++ b/tools/perf/scripts/python/failed-syscalls-by-pid.py +@@ -5,6 +5,8 @@ + # Displays system-wide failed system call totals, broken down by pid. + # If a [comm] arg is specified, only syscalls called by [comm] are displayed. + ++from __future__ import print_function ++ + import os + import sys + +@@ -32,7 +34,7 @@ if len(sys.argv) > 1: + syscalls = autodict() + + def trace_begin(): +- print "Press control+C to stop and show the summary" ++ print("Press control+C to stop and show the summary") + + def trace_end(): + print_error_totals() +@@ -57,22 +59,21 @@ def syscalls__sys_exit(event_name, conte + + def print_error_totals(): + if for_comm is not None: +- print "\nsyscall errors for %s:\n\n" % (for_comm), ++ print("\nsyscall errors for %s:\n" % (for_comm)) + else: +- print "\nsyscall errors:\n\n", ++ print("\nsyscall errors:\n") + +- print "%-30s %10s\n" % ("comm [pid]", "count"), +- print "%-30s %10s\n" % ("------------------------------", \ +- "----------"), ++ print("%-30s %10s" % ("comm [pid]", "count")) ++ print("%-30s %10s" % ("------------------------------", "----------")) + + comm_keys = syscalls.keys() + for comm in comm_keys: + pid_keys = syscalls[comm].keys() + for pid in pid_keys: +- print "\n%s [%d]\n" % (comm, pid), ++ print("\n%s [%d]" % (comm, pid)) + id_keys = syscalls[comm][pid].keys() + for id in id_keys: +- print " syscall: %-16s\n" % syscall_name(id), ++ print(" syscall: %-16s" % syscall_name(id)) + ret_keys = syscalls[comm][pid][id].keys() +- for ret, val in sorted(syscalls[comm][pid][id].iteritems(), key = lambda(k, v): (v, k), reverse = True): +- print " err = %-20s %10d\n" % (strerror(ret), val), ++ for ret, val in sorted(syscalls[comm][pid][id].items(), key = lambda kv: (kv[1], kv[0]), reverse = True): ++ print(" err = %-20s %10d" % (strerror(ret), val)) diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-futex-cont.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-futex-cont.patch new file mode 100644 index 000000000..3fb8f1baf --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-futex-cont.patch @@ -0,0 +1,57 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 1 Mar 2019 17:18:58 -0800 +Subject: perf script python: Add Python3 support to futex-contention.py +Origin: https://git.kernel.org/linus/de2ec16bd438945813198d4de2339a396904c206 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the futex-contention.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Link: http://lkml.kernel.org/r/20190302011903.2416-3-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/futex-contention.py | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/tools/perf/scripts/python/futex-contention.py ++++ b/tools/perf/scripts/python/futex-contention.py +@@ -10,6 +10,8 @@ + # + # Measures futex contention + ++from __future__ import print_function ++ + import os, sys + sys.path.append(os.environ['PERF_EXEC_PATH'] + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') + from Util import * +@@ -33,18 +35,18 @@ def syscalls__sys_enter_futex(event, ctx + + def syscalls__sys_exit_futex(event, ctxt, cpu, s, ns, tid, comm, callchain, + nr, ret): +- if thread_blocktime.has_key(tid): ++ if tid in thread_blocktime: + elapsed = nsecs(s, ns) - thread_blocktime[tid] + add_stats(lock_waits, (tid, thread_thislock[tid]), elapsed) + del thread_blocktime[tid] + del thread_thislock[tid] + + def trace_begin(): +- print "Press control+C to stop and show the summary" ++ print("Press control+C to stop and show the summary") + + def trace_end(): + for (tid, lock) in lock_waits: + min, max, avg, count = lock_waits[tid, lock] +- print "%s[%d] lock %x contended %d times, %d avg ns" % \ +- (process_names[tid], tid, lock, count, avg) ++ print("%s[%d] lock %x contended %d times, %d avg ns" % ++ (process_names[tid], tid, lock, count, avg)) + diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-intel-pt-e.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-intel-pt-e.patch new file mode 100644 index 000000000..c9dd3a189 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-intel-pt-e.patch @@ -0,0 +1,133 @@ +From: Tony Jones <tonyj@suse.de> +Date: Tue, 5 Mar 2019 08:19:02 -0800 +Subject: perf script python: Add Python3 support to intel-pt-events.py +Origin: https://git.kernel.org/linus/fdf2460c297f1bb2f3bd20b3b52903b267af9050 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the intel-pt-events.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Acked-by: Adrian Hunter <adrian.hunter@intel.com> +Link: http://lkml.kernel.org/r/fd26acf9-0c0f-717f-9664-a3c33043ce19@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/intel-pt-events.py | 32 ++++++++++++++++----------- + 1 file changed, 19 insertions(+), 13 deletions(-) + +--- a/tools/perf/scripts/python/intel-pt-events.py ++++ b/tools/perf/scripts/python/intel-pt-events.py +@@ -10,6 +10,8 @@ + # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + # more details. + ++from __future__ import print_function ++ + import os + import sys + import struct +@@ -22,34 +24,34 @@ sys.path.append(os.environ['PERF_EXEC_PA + #from Core import * + + def trace_begin(): +- print "Intel PT Power Events and PTWRITE" ++ print("Intel PT Power Events and PTWRITE") + + def trace_end(): +- print "End" ++ print("End") + + def trace_unhandled(event_name, context, event_fields_dict): +- print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())]) ++ print(' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())])) + + def print_ptwrite(raw_buf): + data = struct.unpack_from("<IQ", raw_buf) + flags = data[0] + payload = data[1] + exact_ip = flags & 1 +- print "IP: %u payload: %#x" % (exact_ip, payload), ++ print("IP: %u payload: %#x" % (exact_ip, payload), end=' ') + + def print_cbr(raw_buf): + data = struct.unpack_from("<BBBBII", raw_buf) + cbr = data[0] + f = (data[4] + 500) / 1000 + p = ((cbr * 1000 / data[2]) + 5) / 10 +- print "%3u freq: %4u MHz (%3u%%)" % (cbr, f, p), ++ print("%3u freq: %4u MHz (%3u%%)" % (cbr, f, p), end=' ') + + def print_mwait(raw_buf): + data = struct.unpack_from("<IQ", raw_buf) + payload = data[1] + hints = payload & 0xff + extensions = (payload >> 32) & 0x3 +- print "hints: %#x extensions: %#x" % (hints, extensions), ++ print("hints: %#x extensions: %#x" % (hints, extensions), end=' ') + + def print_pwre(raw_buf): + data = struct.unpack_from("<IQ", raw_buf) +@@ -57,13 +59,14 @@ def print_pwre(raw_buf): + hw = (payload >> 7) & 1 + cstate = (payload >> 12) & 0xf + subcstate = (payload >> 8) & 0xf +- print "hw: %u cstate: %u sub-cstate: %u" % (hw, cstate, subcstate), ++ print("hw: %u cstate: %u sub-cstate: %u" % (hw, cstate, subcstate), ++ end=' ') + + def print_exstop(raw_buf): + data = struct.unpack_from("<I", raw_buf) + flags = data[0] + exact_ip = flags & 1 +- print "IP: %u" % (exact_ip), ++ print("IP: %u" % (exact_ip), end=' ') + + def print_pwrx(raw_buf): + data = struct.unpack_from("<IQ", raw_buf) +@@ -71,18 +74,21 @@ def print_pwrx(raw_buf): + deepest_cstate = payload & 0xf + last_cstate = (payload >> 4) & 0xf + wake_reason = (payload >> 8) & 0xf +- print "deepest cstate: %u last cstate: %u wake reason: %#x" % (deepest_cstate, last_cstate, wake_reason), ++ print("deepest cstate: %u last cstate: %u wake reason: %#x" % ++ (deepest_cstate, last_cstate, wake_reason), end=' ') + + def print_common_start(comm, sample, name): + ts = sample["time"] + cpu = sample["cpu"] + pid = sample["pid"] + tid = sample["tid"] +- print "%16s %5u/%-5u [%03u] %9u.%09u %7s:" % (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name), ++ print("%16s %5u/%-5u [%03u] %9u.%09u %7s:" % ++ (comm, pid, tid, cpu, ts / 1000000000, ts %1000000000, name), ++ end=' ') + + def print_common_ip(sample, symbol, dso): + ip = sample["ip"] +- print "%16x %s (%s)" % (ip, symbol, dso) ++ print("%16x %s (%s)" % (ip, symbol, dso)) + + def process_event(param_dict): + event_attr = param_dict["attr"] +@@ -92,12 +98,12 @@ def process_event(param_dict): + name = param_dict["ev_name"] + + # Symbol and dso info are not always resolved +- if (param_dict.has_key("dso")): ++ if "dso" in param_dict: + dso = param_dict["dso"] + else: + dso = "[unknown]" + +- if (param_dict.has_key("symbol")): ++ if "symbol" in param_dict: + symbol = param_dict["symbol"] + else: + symbol = "[unknown]" diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-mem-phys-a.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-mem-phys-a.patch new file mode 100644 index 000000000..3b9e39cc9 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-mem-phys-a.patch @@ -0,0 +1,76 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:11 -0800 +Subject: perf script python: Add Python3 support to mem-phys-addr.py +Origin: https://git.kernel.org/linus/e4d053ddb4c48cbde27b4c5edd3cc8f957684e4f +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the mem-phys-addr.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Link: http://lkml.kernel.org/r/20190222230619.17887-8-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/mem-phys-addr.py | 24 ++++++++++++++---------- + 1 file changed, 14 insertions(+), 10 deletions(-) + +--- a/tools/perf/scripts/python/mem-phys-addr.py ++++ b/tools/perf/scripts/python/mem-phys-addr.py +@@ -4,6 +4,8 @@ + # Copyright (c) 2018, Intel Corporation. + + from __future__ import division ++from __future__ import print_function ++ + import os + import sys + import struct +@@ -31,21 +33,23 @@ def parse_iomem(): + for i, j in enumerate(f): + m = re.split('-|:',j,2) + if m[2].strip() == 'System RAM': +- system_ram.append(long(m[0], 16)) +- system_ram.append(long(m[1], 16)) ++ system_ram.append(int(m[0], 16)) ++ system_ram.append(int(m[1], 16)) + if m[2].strip() == 'Persistent Memory': +- pmem.append(long(m[0], 16)) +- pmem.append(long(m[1], 16)) ++ pmem.append(int(m[0], 16)) ++ pmem.append(int(m[1], 16)) + + def print_memory_type(): +- print "Event: %s" % (event_name) +- print "%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), +- print "%-40s %10s %10s\n" % ("----------------------------------------", \ ++ print("Event: %s" % (event_name)) ++ print("%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), end='') ++ print("%-40s %10s %10s\n" % ("----------------------------------------", + "-----------", "-----------"), ++ end=''); + total = sum(load_mem_type_cnt.values()) + for mem_type, count in sorted(load_mem_type_cnt.most_common(), \ +- key = lambda(k, v): (v, k), reverse = True): +- print "%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total), ++ key = lambda kv: (kv[1], kv[0]), reverse = True): ++ print("%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total), ++ end='') + + def trace_begin(): + parse_iomem() +@@ -80,7 +84,7 @@ def find_memory_type(phys_addr): + f.seek(0, 0) + for j in f: + m = re.split('-|:',j,2) +- if long(m[0], 16) <= phys_addr <= long(m[1], 16): ++ if int(m[0], 16) <= phys_addr <= int(m[1], 16): + return m[2] + return "N/A" + diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-net_dropmo.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-net_dropmo.patch new file mode 100644 index 000000000..631a94449 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-net_dropmo.patch @@ -0,0 +1,59 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:12 -0800 +Subject: perf script python: Add Python3 support to net_dropmonitor.py +Origin: https://git.kernel.org/linus/8c42b9600e561666233b9c557a5209d0dc853ba1 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the net_dropmonitor.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Acked-by: Neil Horman <nhorman@tuxdriver.com> +Link: http://lkml.kernel.org/r/20190222230619.17887-9-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/net_dropmonitor.py | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/tools/perf/scripts/python/net_dropmonitor.py ++++ b/tools/perf/scripts/python/net_dropmonitor.py +@@ -1,6 +1,8 @@ + # Monitor the system for dropped packets and proudce a report of drop locations and counts + # SPDX-License-Identifier: GPL-2.0 + ++from __future__ import print_function ++ + import os + import sys + +@@ -50,19 +52,19 @@ def get_sym(sloc): + return (None, 0) + + def print_drop_table(): +- print "%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT") ++ print("%25s %25s %25s" % ("LOCATION", "OFFSET", "COUNT")) + for i in drop_log.keys(): + (sym, off) = get_sym(i) + if sym == None: + sym = i +- print "%25s %25s %25s" % (sym, off, drop_log[i]) ++ print("%25s %25s %25s" % (sym, off, drop_log[i])) + + + def trace_begin(): +- print "Starting trace (Ctrl-C to dump results)" ++ print("Starting trace (Ctrl-C to dump results)") + + def trace_end(): +- print "Gathering kallsyms data" ++ print("Gathering kallsyms data") + get_kallsyms_table() + print_drop_table() + diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-netdev-tim.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-netdev-tim.patch new file mode 100644 index 000000000..2d501dd4c --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-netdev-tim.patch @@ -0,0 +1,180 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:05 -0800 +Subject: perf script python: Add Python3 support to netdev-times.py +Origin: https://git.kernel.org/linus/02b03ec383e0c79d73aa4b402b3427a8b490ef9f +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the netdev-times.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 +version is now v2.6. + +Signed-off-by: Tony Jones <tonyj@suse.de> +Cc: Sanagi Koki <sanagi.koki@jp.fujitsu.com> +Link: http://lkml.kernel.org/r/20190222230619.17887-2-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/netdev-times.py | 82 +++++++++++++++--------------- + 1 file changed, 42 insertions(+), 40 deletions(-) + +--- a/tools/perf/scripts/python/netdev-times.py ++++ b/tools/perf/scripts/python/netdev-times.py +@@ -8,6 +8,8 @@ + # dev=: show only thing related to specified device + # debug: work with debug mode. It shows buffer status. + ++from __future__ import print_function ++ + import os + import sys + +@@ -17,6 +19,7 @@ sys.path.append(os.environ['PERF_EXEC_PA + from perf_trace_context import * + from Core import * + from Util import * ++from functools import cmp_to_key + + all_event_list = []; # insert all tracepoint event related with this script + irq_dic = {}; # key is cpu and value is a list which stacks irqs +@@ -61,12 +64,12 @@ def diff_msec(src, dst): + def print_transmit(hunk): + if dev != 0 and hunk['dev'].find(dev) < 0: + return +- print "%7s %5d %6d.%06dsec %12.3fmsec %12.3fmsec" % \ ++ print("%7s %5d %6d.%06dsec %12.3fmsec %12.3fmsec" % + (hunk['dev'], hunk['len'], + nsecs_secs(hunk['queue_t']), + nsecs_nsecs(hunk['queue_t'])/1000, + diff_msec(hunk['queue_t'], hunk['xmit_t']), +- diff_msec(hunk['xmit_t'], hunk['free_t'])) ++ diff_msec(hunk['xmit_t'], hunk['free_t']))) + + # Format for displaying rx packet processing + PF_IRQ_ENTRY= " irq_entry(+%.3fmsec irq=%d:%s)" +@@ -98,55 +101,55 @@ def print_receive(hunk): + if show_hunk == 0: + return + +- print "%d.%06dsec cpu=%d" % \ +- (nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu) ++ print("%d.%06dsec cpu=%d" % ++ (nsecs_secs(base_t), nsecs_nsecs(base_t)/1000, cpu)) + for i in range(len(irq_list)): +- print PF_IRQ_ENTRY % \ ++ print(PF_IRQ_ENTRY % + (diff_msec(base_t, irq_list[i]['irq_ent_t']), +- irq_list[i]['irq'], irq_list[i]['name']) +- print PF_JOINT ++ irq_list[i]['irq'], irq_list[i]['name'])) ++ print(PF_JOINT) + irq_event_list = irq_list[i]['event_list'] + for j in range(len(irq_event_list)): + irq_event = irq_event_list[j] + if irq_event['event'] == 'netif_rx': +- print PF_NET_RX % \ ++ print(PF_NET_RX % + (diff_msec(base_t, irq_event['time']), +- irq_event['skbaddr']) +- print PF_JOINT +- print PF_SOFT_ENTRY % \ +- diff_msec(base_t, hunk['sirq_ent_t']) +- print PF_JOINT ++ irq_event['skbaddr'])) ++ print(PF_JOINT) ++ print(PF_SOFT_ENTRY % ++ diff_msec(base_t, hunk['sirq_ent_t'])) ++ print(PF_JOINT) + event_list = hunk['event_list'] + for i in range(len(event_list)): + event = event_list[i] + if event['event_name'] == 'napi_poll': +- print PF_NAPI_POLL % \ +- (diff_msec(base_t, event['event_t']), event['dev']) ++ print(PF_NAPI_POLL % ++ (diff_msec(base_t, event['event_t']), event['dev'])) + if i == len(event_list) - 1: +- print "" ++ print("") + else: +- print PF_JOINT ++ print(PF_JOINT) + else: +- print PF_NET_RECV % \ ++ print(PF_NET_RECV % + (diff_msec(base_t, event['event_t']), event['skbaddr'], +- event['len']) ++ event['len'])) + if 'comm' in event.keys(): +- print PF_WJOINT +- print PF_CPY_DGRAM % \ ++ print(PF_WJOINT) ++ print(PF_CPY_DGRAM % + (diff_msec(base_t, event['comm_t']), +- event['pid'], event['comm']) ++ event['pid'], event['comm'])) + elif 'handle' in event.keys(): +- print PF_WJOINT ++ print(PF_WJOINT) + if event['handle'] == "kfree_skb": +- print PF_KFREE_SKB % \ ++ print(PF_KFREE_SKB % + (diff_msec(base_t, + event['comm_t']), +- event['location']) ++ event['location'])) + elif event['handle'] == "consume_skb": +- print PF_CONS_SKB % \ ++ print(PF_CONS_SKB % + diff_msec(base_t, +- event['comm_t']) +- print PF_JOINT ++ event['comm_t'])) ++ print(PF_JOINT) + + def trace_begin(): + global show_tx +@@ -172,8 +175,7 @@ def trace_begin(): + + def trace_end(): + # order all events in time +- all_event_list.sort(lambda a,b :cmp(a[EINFO_IDX_TIME], +- b[EINFO_IDX_TIME])) ++ all_event_list.sort(key=cmp_to_key(lambda a,b :a[EINFO_IDX_TIME] < b[EINFO_IDX_TIME])) + # process all events + for i in range(len(all_event_list)): + event_info = all_event_list[i] +@@ -210,19 +212,19 @@ def trace_end(): + print_receive(receive_hunk_list[i]) + # display transmit hunks + if show_tx: +- print " dev len Qdisc " \ +- " netdevice free" ++ print(" dev len Qdisc " ++ " netdevice free") + for i in range(len(tx_free_list)): + print_transmit(tx_free_list[i]) + if debug: +- print "debug buffer status" +- print "----------------------------" +- print "xmit Qdisc:remain:%d overflow:%d" % \ +- (len(tx_queue_list), of_count_tx_queue_list) +- print "xmit netdevice:remain:%d overflow:%d" % \ +- (len(tx_xmit_list), of_count_tx_xmit_list) +- print "receive:remain:%d overflow:%d" % \ +- (len(rx_skb_list), of_count_rx_skb_list) ++ print("debug buffer status") ++ print("----------------------------") ++ print("xmit Qdisc:remain:%d overflow:%d" % ++ (len(tx_queue_list), of_count_tx_queue_list)) ++ print("xmit netdevice:remain:%d overflow:%d" % ++ (len(tx_xmit_list), of_count_tx_xmit_list)) ++ print("receive:remain:%d overflow:%d" % ++ (len(rx_skb_list), of_count_rx_skb_list)) + + # called from perf, when it finds a correspoinding event + def irq__softirq_entry(name, context, cpu, sec, nsec, pid, comm, callchain, vec): diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-powerpc-hc.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-powerpc-hc.patch new file mode 100644 index 000000000..1c8fdc5a1 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-powerpc-hc.patch @@ -0,0 +1,87 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:13 -0800 +Subject: perf script python: Add Python3 support to powerpc-hcalls.py +Origin: https://git.kernel.org/linus/118af5bf799bd1876c3999766d1d2f845d45f019 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the powerpc-hcalls.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Cc: Ravi Bangoria <ravi.bangoria@linux.ibm.com> +Link: http://lkml.kernel.org/r/20190222230619.17887-10-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/powerpc-hcalls.py | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/tools/perf/scripts/python/powerpc-hcalls.py ++++ b/tools/perf/scripts/python/powerpc-hcalls.py +@@ -4,6 +4,8 @@ + # + # Hypervisor call statisics + ++from __future__ import print_function ++ + import os + import sys + +@@ -149,7 +151,7 @@ hcall_table = { + } + + def hcall_table_lookup(opcode): +- if (hcall_table.has_key(opcode)): ++ if (opcode in hcall_table): + return hcall_table[opcode] + else: + return opcode +@@ -157,8 +159,8 @@ def hcall_table_lookup(opcode): + print_ptrn = '%-28s%10s%10s%10s%10s' + + def trace_end(): +- print print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)') +- print '-' * 68 ++ print(print_ptrn % ('hcall', 'count', 'min(ns)', 'max(ns)', 'avg(ns)')) ++ print('-' * 68) + for opcode in output: + h_name = hcall_table_lookup(opcode) + time = output[opcode]['time'] +@@ -166,14 +168,14 @@ def trace_end(): + min_t = output[opcode]['min'] + max_t = output[opcode]['max'] + +- print print_ptrn % (h_name, cnt, min_t, max_t, time/cnt) ++ print(print_ptrn % (h_name, cnt, min_t, max_t, time//cnt)) + + def powerpc__hcall_exit(name, context, cpu, sec, nsec, pid, comm, callchain, + opcode, retval): +- if (d_enter.has_key(cpu) and d_enter[cpu].has_key(opcode)): ++ if (cpu in d_enter and opcode in d_enter[cpu]): + diff = nsecs(sec, nsec) - d_enter[cpu][opcode] + +- if (output.has_key(opcode)): ++ if (opcode in output): + output[opcode]['time'] += diff + output[opcode]['cnt'] += 1 + if (output[opcode]['min'] > diff): +@@ -190,11 +192,11 @@ def powerpc__hcall_exit(name, context, c + + del d_enter[cpu][opcode] + # else: +-# print "Can't find matching hcall_enter event. Ignoring sample" ++# print("Can't find matching hcall_enter event. Ignoring sample") + + def powerpc__hcall_entry(event_name, context, cpu, sec, nsec, pid, comm, + callchain, opcode): +- if (d_enter.has_key(cpu)): ++ if (cpu in d_enter): + d_enter[cpu][opcode] = nsecs(sec, nsec) + else: + d_enter[cpu] = {opcode: nsecs(sec, nsec)} diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-sctop.py.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-sctop.py.patch new file mode 100644 index 000000000..fa90ed99a --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-sctop.py.patch @@ -0,0 +1,69 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:14 -0800 +Subject: perf script python: Add Python3 support to sctop.py +Origin: https://git.kernel.org/linus/ee75a896ae535d4219a82cc361be96394536f3ba +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the sctop.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Cc: Tom Zanussi <tzanussi@gmail.com> +Link: http://lkml.kernel.org/r/20190222230619.17887-11-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/sctop.py | 24 ++++++++++++++++-------- + 1 file changed, 16 insertions(+), 8 deletions(-) + +--- a/tools/perf/scripts/python/sctop.py ++++ b/tools/perf/scripts/python/sctop.py +@@ -8,7 +8,14 @@ + # will be refreshed every [interval] seconds. The default interval is + # 3 seconds. + +-import os, sys, thread, time ++from __future__ import print_function ++ ++import os, sys, time ++ ++try: ++ import thread ++except ImportError: ++ import _thread as thread + + sys.path.append(os.environ['PERF_EXEC_PATH'] + \ + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') +@@ -62,18 +69,19 @@ def print_syscall_totals(interval): + while 1: + clear_term() + if for_comm is not None: +- print "\nsyscall events for %s:\n\n" % (for_comm), ++ print("\nsyscall events for %s:\n" % (for_comm)) + else: +- print "\nsyscall events:\n\n", ++ print("\nsyscall events:\n") + +- print "%-40s %10s\n" % ("event", "count"), +- print "%-40s %10s\n" % ("----------------------------------------", \ +- "----------"), ++ print("%-40s %10s" % ("event", "count")) ++ print("%-40s %10s" % ++ ("----------------------------------------", ++ "----------")) + +- for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ ++ for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \ + reverse = True): + try: +- print "%-40s %10d\n" % (syscall_name(id), val), ++ print("%-40s %10d" % (syscall_name(id), val)) + except TypeError: + pass + syscalls.clear() diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stackcolla.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stackcolla.patch new file mode 100644 index 000000000..ff41b4a20 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stackcolla.patch @@ -0,0 +1,45 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:15 -0800 +Subject: perf script python: Add Python3 support to stackcollapse.py +Origin: https://git.kernel.org/linus/6d22d9991cf37edfe861569e2433342ad56206a7 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the stackcollapse.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Cc: Paolo Bonzini <pbonzini@redhat.com> <pbonzini@redhat.com> +Link: http://lkml.kernel.org/r/20190222230619.17887-12-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/stackcollapse.py | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +--- a/tools/perf/scripts/python/stackcollapse.py ++++ b/tools/perf/scripts/python/stackcollapse.py +@@ -19,6 +19,8 @@ + # Written by Paolo Bonzini <pbonzini@redhat.com> + # Based on Brendan Gregg's stackcollapse-perf.pl script. + ++from __future__ import print_function ++ + import os + import sys + from collections import defaultdict +@@ -120,7 +122,6 @@ def process_event(param_dict): + lines[stack_string] = lines[stack_string] + 1 + + def trace_end(): +- list = lines.keys() +- list.sort() ++ list = sorted(lines) + for stack in list: +- print "%s %d" % (stack, lines[stack]) ++ print("%s %d" % (stack, lines[stack])) diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stat-cpi.p.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stat-cpi.p.patch new file mode 100644 index 000000000..8ef6fa8b5 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-stat-cpi.p.patch @@ -0,0 +1,61 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:16 -0800 +Subject: perf script python: Add Python3 support to stat-cpi.py +Origin: https://git.kernel.org/linus/e985bf761db7646cebcd236249da08bd264069de +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the stat-cpi.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Cc: Jiri Olsa <jolsa@kernel.org> +Link: http://lkml.kernel.org/r/20190222230619.17887-13-tonyj@suse.de +Signed-off-by: Tony Jones <tonyj@suse.de> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/stat-cpi.py | 10 ++++++---- + 1 file changed, 6 insertions(+), 4 deletions(-) + +--- a/tools/perf/scripts/python/stat-cpi.py ++++ b/tools/perf/scripts/python/stat-cpi.py +@@ -1,6 +1,8 @@ + #!/usr/bin/env python + # SPDX-License-Identifier: GPL-2.0 + ++from __future__ import print_function ++ + data = {} + times = [] + threads = [] +@@ -20,8 +22,8 @@ def store_key(time, cpu, thread): + threads.append(thread) + + def store(time, event, cpu, thread, val, ena, run): +- #print "event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % \ +- # (event, cpu, thread, time, val, ena, run) ++ #print("event %s cpu %d, thread %d, time %d, val %d, ena %d, run %d" % ++ # (event, cpu, thread, time, val, ena, run)) + + store_key(time, cpu, thread) + key = get_key(time, event, cpu, thread) +@@ -59,7 +61,7 @@ def stat__interval(time): + if ins != 0: + cpi = cyc/float(ins) + +- print "%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins) ++ print("%15f: cpu %d, thread %d -> cpi %f (%d/%d)" % (time/(float(1000000000)), cpu, thread, cpi, cyc, ins)) + + def trace_end(): + pass +@@ -75,4 +77,4 @@ def trace_end(): + # if ins != 0: + # cpi = cyc/float(ins) + # +-# print "time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi) ++# print("time %.9f, cpu %d, thread %d -> cpi %f" % (time/(float(1000000000)), cpu, thread, cpi)) diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co-de667cce7f4f.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co-de667cce7f4f.patch new file mode 100644 index 000000000..9dc84ceac --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co-de667cce7f4f.patch @@ -0,0 +1,74 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:18 -0800 +Subject: perf script python: Add Python3 support to + syscall-counts-by-pid.py +Origin: https://git.kernel.org/linus/de667cce7f4f96b6e22da8fd9c065b961f355080 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the syscall-counts-by-pid.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Link: http://lkml.kernel.org/r/20190222230619.17887-15-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/syscall-counts-by-pid.py | 22 +++++++++++---------- + 1 file changed, 12 insertions(+), 10 deletions(-) + +--- a/tools/perf/scripts/python/syscall-counts-by-pid.py ++++ b/tools/perf/scripts/python/syscall-counts-by-pid.py +@@ -5,6 +5,8 @@ + # Displays system-wide system call totals, broken down by syscall. + # If a [comm] arg is specified, only syscalls called by [comm] are displayed. + ++from __future__ import print_function ++ + import os, sys + + sys.path.append(os.environ['PERF_EXEC_PATH'] + \ +@@ -31,7 +33,7 @@ if len(sys.argv) > 1: + syscalls = autodict() + + def trace_begin(): +- print "Press control+C to stop and show the summary" ++ print("Press control+C to stop and show the summary") + + def trace_end(): + print_syscall_totals() +@@ -55,20 +57,20 @@ def syscalls__sys_enter(event_name, cont + + def print_syscall_totals(): + if for_comm is not None: +- print "\nsyscall events for %s:\n\n" % (for_comm), ++ print("\nsyscall events for %s:\n" % (for_comm)) + else: +- print "\nsyscall events by comm/pid:\n\n", ++ print("\nsyscall events by comm/pid:\n") + +- print "%-40s %10s\n" % ("comm [pid]/syscalls", "count"), +- print "%-40s %10s\n" % ("----------------------------------------", \ +- "----------"), ++ print("%-40s %10s" % ("comm [pid]/syscalls", "count")) ++ print("%-40s %10s" % ("----------------------------------------", ++ "----------")) + + comm_keys = syscalls.keys() + for comm in comm_keys: + pid_keys = syscalls[comm].keys() + for pid in pid_keys: +- print "\n%s [%d]\n" % (comm, pid), ++ print("\n%s [%d]" % (comm, pid)) + id_keys = syscalls[comm][pid].keys() +- for id, val in sorted(syscalls[comm][pid].iteritems(), \ +- key = lambda(k, v): (v, k), reverse = True): +- print " %-38s %10d\n" % (syscall_name(id), val), ++ for id, val in sorted(syscalls[comm][pid].items(), \ ++ key = lambda kv: (kv[1], kv[0]), reverse = True): ++ print(" %-38s %10d" % (syscall_name(id), val)) diff --git a/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co.patch b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co.patch new file mode 100644 index 000000000..59c654479 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co.patch @@ -0,0 +1,65 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 22 Feb 2019 15:06:17 -0800 +Subject: perf script python: Add Python3 support to syscall-counts.py +Origin: https://git.kernel.org/linus/1d1b0dbb859d175eb512a9f0e1ca7e44bd0192cd +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python2 and Python3 in the syscall-counts.py script + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of 'from __future__' implies the minimum supported Python2 version +is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Link: http://lkml.kernel.org/r/20190222230619.17887-14-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/syscall-counts.py | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +--- a/tools/perf/scripts/python/syscall-counts.py ++++ b/tools/perf/scripts/python/syscall-counts.py +@@ -5,6 +5,8 @@ + # Displays system-wide system call totals, broken down by syscall. + # If a [comm] arg is specified, only syscalls called by [comm] are displayed. + ++from __future__ import print_function ++ + import os + import sys + +@@ -28,7 +30,7 @@ if len(sys.argv) > 1: + syscalls = autodict() + + def trace_begin(): +- print "Press control+C to stop and show the summary" ++ print("Press control+C to stop and show the summary") + + def trace_end(): + print_syscall_totals() +@@ -51,14 +53,14 @@ def syscalls__sys_enter(event_name, cont + + def print_syscall_totals(): + if for_comm is not None: +- print "\nsyscall events for %s:\n\n" % (for_comm), ++ print("\nsyscall events for %s:\n" % (for_comm)) + else: +- print "\nsyscall events:\n\n", ++ print("\nsyscall events:\n") + +- print "%-40s %10s\n" % ("event", "count"), +- print "%-40s %10s\n" % ("----------------------------------------", \ +- "-----------"), ++ print("%-40s %10s" % ("event", "count")) ++ print("%-40s %10s" % ("----------------------------------------", ++ "-----------")) + +- for id, val in sorted(syscalls.iteritems(), key = lambda(k, v): (v, k), \ ++ for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \ + reverse = True): +- print "%-40s %10d\n" % (syscall_name(id), val), ++ print("%-40s %10d" % (syscall_name(id), val)) diff --git a/debian/patches/bugfix/all/perf-script-python-Remove-mixed-indentation.patch b/debian/patches/bugfix/all/perf-script-python-Remove-mixed-indentation.patch new file mode 100644 index 000000000..b18ceaea8 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-Remove-mixed-indentation.patch @@ -0,0 +1,511 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 1 Mar 2019 17:18:57 -0800 +Subject: perf script python: Remove mixed indentation +Origin: https://git.kernel.org/linus/b504d7f6876515b74c8e27a44ccdb22372616d97 +Bug-Debian: https://bugs.debian.org/944641 + +Remove mixed indentation in Python scripts. Revert to either all tabs +(most common form) or all spaces (4 or 8) depending on what was the +intent of the original commit. This is necessary to complete Python3 +support as it will flag an error if it encounters mixed indentation. + +Signed-off-by: Tony Jones <tonyj@suse.de> +Link: http://lkml.kernel.org/r/20190302011903.2416-2-tonyj@suse.de +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/check-perf-trace.py | 69 +++++++++----------- + tools/perf/scripts/python/compaction-times.py | 8 +- + tools/perf/scripts/python/event_analyzing_sample.py | 6 - + tools/perf/scripts/python/failed-syscalls-by-pid.py | 34 ++++----- + tools/perf/scripts/python/futex-contention.py | 2 + tools/perf/scripts/python/intel-pt-events.py | 28 ++++---- + tools/perf/scripts/python/mem-phys-addr.py | 7 +- + tools/perf/scripts/python/net_dropmonitor.py | 2 + tools/perf/scripts/python/netdev-times.py | 12 ++- + tools/perf/scripts/python/sched-migration.py | 6 - + tools/perf/scripts/python/sctop.py | 13 ++- + tools/perf/scripts/python/stackcollapse.py | 2 + tools/perf/scripts/python/syscall-counts-by-pid.py | 47 ++++++------- + tools/perf/scripts/python/syscall-counts.py | 27 +++---- + 14 files changed, 132 insertions(+), 131 deletions(-) + +--- a/tools/perf/scripts/python/check-perf-trace.py ++++ b/tools/perf/scripts/python/check-perf-trace.py +@@ -23,60 +23,59 @@ def trace_begin(): + pass + + def trace_end(): +- print_unhandled() ++ print_unhandled() + + def irq__softirq_entry(event_name, context, common_cpu, +- common_secs, common_nsecs, common_pid, common_comm, +- common_callchain, vec): +- print_header(event_name, common_cpu, common_secs, common_nsecs, +- common_pid, common_comm) ++ common_secs, common_nsecs, common_pid, common_comm, ++ common_callchain, vec): ++ print_header(event_name, common_cpu, common_secs, common_nsecs, ++ common_pid, common_comm) + +- print_uncommon(context) ++ print_uncommon(context) + +- print "vec=%s\n" % \ +- (symbol_str("irq__softirq_entry", "vec", vec)), ++ print "vec=%s\n" % (symbol_str("irq__softirq_entry", "vec", vec)), + + def kmem__kmalloc(event_name, context, common_cpu, +- common_secs, common_nsecs, common_pid, common_comm, +- common_callchain, call_site, ptr, bytes_req, bytes_alloc, +- gfp_flags): +- print_header(event_name, common_cpu, common_secs, common_nsecs, +- common_pid, common_comm) ++ common_secs, common_nsecs, common_pid, common_comm, ++ common_callchain, call_site, ptr, bytes_req, bytes_alloc, ++ gfp_flags): ++ print_header(event_name, common_cpu, common_secs, common_nsecs, ++ common_pid, common_comm) + +- print_uncommon(context) ++ print_uncommon(context) + +- print "call_site=%u, ptr=%u, bytes_req=%u, " \ ++ print "call_site=%u, ptr=%u, bytes_req=%u, " \ + "bytes_alloc=%u, gfp_flags=%s\n" % \ + (call_site, ptr, bytes_req, bytes_alloc, +- + flag_str("kmem__kmalloc", "gfp_flags", gfp_flags)), + + def trace_unhandled(event_name, context, event_fields_dict): +- try: +- unhandled[event_name] += 1 +- except TypeError: +- unhandled[event_name] = 1 ++ try: ++ unhandled[event_name] += 1 ++ except TypeError: ++ unhandled[event_name] = 1 + + def print_header(event_name, cpu, secs, nsecs, pid, comm): + print "%-20s %5u %05u.%09u %8u %-20s " % \ +- (event_name, cpu, secs, nsecs, pid, comm), ++ (event_name, cpu, secs, nsecs, pid, comm), + + # print trace fields not included in handler args + def print_uncommon(context): +- print "common_preempt_count=%d, common_flags=%s, common_lock_depth=%d, " \ +- % (common_pc(context), trace_flag_str(common_flags(context)), \ +- common_lock_depth(context)) ++ print "common_preempt_count=%d, common_flags=%s, " \ ++ "common_lock_depth=%d, " % \ ++ (common_pc(context), trace_flag_str(common_flags(context)), ++ common_lock_depth(context)) + + def print_unhandled(): +- keys = unhandled.keys() +- if not keys: +- return +- +- print "\nunhandled events:\n\n", +- +- print "%-40s %10s\n" % ("event", "count"), +- print "%-40s %10s\n" % ("----------------------------------------", \ +- "-----------"), ++ keys = unhandled.keys() ++ if not keys: ++ return ++ ++ print "\nunhandled events:\n\n", ++ ++ print "%-40s %10s\n" % ("event", "count"), ++ print "%-40s %10s\n" % ("----------------------------------------", \ ++ "-----------"), + +- for event_name in keys: +- print "%-40s %10d\n" % (event_name, unhandled[event_name]) ++ for event_name in keys: ++ print "%-40s %10d\n" % (event_name, unhandled[event_name]) +--- a/tools/perf/scripts/python/compaction-times.py ++++ b/tools/perf/scripts/python/compaction-times.py +@@ -216,15 +216,15 @@ def compaction__mm_compaction_migratepag + pair(nr_migrated, nr_failed), None, None) + + def compaction__mm_compaction_isolate_freepages(event_name, context, common_cpu, +- common_secs, common_nsecs, common_pid, common_comm, +- common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken): ++ common_secs, common_nsecs, common_pid, common_comm, ++ common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken): + + chead.increment_pending(common_pid, + None, pair(nr_scanned, nr_taken), None) + + def compaction__mm_compaction_isolate_migratepages(event_name, context, common_cpu, +- common_secs, common_nsecs, common_pid, common_comm, +- common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken): ++ common_secs, common_nsecs, common_pid, common_comm, ++ common_callchain, start_pfn, end_pfn, nr_scanned, nr_taken): + + chead.increment_pending(common_pid, + None, None, pair(nr_scanned, nr_taken)) +--- a/tools/perf/scripts/python/event_analyzing_sample.py ++++ b/tools/perf/scripts/python/event_analyzing_sample.py +@@ -37,7 +37,7 @@ con = sqlite3.connect("/dev/shm/perf.db" + con.isolation_level = None + + def trace_begin(): +- print "In trace_begin:\n" ++ print "In trace_begin:\n" + + # + # Will create several tables at the start, pebs_ll is for PEBS data with +@@ -102,7 +102,7 @@ def insert_db(event): + event.ip, event.status, event.dse, event.dla, event.lat)) + + def trace_end(): +- print "In trace_end:\n" ++ print "In trace_end:\n" + # We show the basic info for the 2 type of event classes + show_general_events() + show_pebs_ll() +@@ -187,4 +187,4 @@ def show_pebs_ll(): + print "%32s %8d %s" % (row[0], row[1], num2sym(row[1])) + + def trace_unhandled(event_name, context, event_fields_dict): +- print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())]) ++ print ' '.join(['%s=%s'%(k,str(v))for k,v in sorted(event_fields_dict.items())]) +--- a/tools/perf/scripts/python/failed-syscalls-by-pid.py ++++ b/tools/perf/scripts/python/failed-syscalls-by-pid.py +@@ -58,22 +58,22 @@ def syscalls__sys_exit(event_name, conte + raw_syscalls__sys_exit(**locals()) + + def print_error_totals(): +- if for_comm is not None: +- print("\nsyscall errors for %s:\n" % (for_comm)) +- else: +- print("\nsyscall errors:\n") ++ if for_comm is not None: ++ print("\nsyscall errors for %s:\n" % (for_comm)) ++ else: ++ print("\nsyscall errors:\n") + +- print("%-30s %10s" % ("comm [pid]", "count")) +- print("%-30s %10s" % ("------------------------------", "----------")) ++ print("%-30s %10s" % ("comm [pid]", "count")) ++ print("%-30s %10s" % ("------------------------------", "----------")) + +- comm_keys = syscalls.keys() +- for comm in comm_keys: +- pid_keys = syscalls[comm].keys() +- for pid in pid_keys: +- print("\n%s [%d]" % (comm, pid)) +- id_keys = syscalls[comm][pid].keys() +- for id in id_keys: +- print(" syscall: %-16s" % syscall_name(id)) +- ret_keys = syscalls[comm][pid][id].keys() +- for ret, val in sorted(syscalls[comm][pid][id].items(), key = lambda kv: (kv[1], kv[0]), reverse = True): +- print(" err = %-20s %10d" % (strerror(ret), val)) ++ comm_keys = syscalls.keys() ++ for comm in comm_keys: ++ pid_keys = syscalls[comm].keys() ++ for pid in pid_keys: ++ print("\n%s [%d]" % (comm, pid)) ++ id_keys = syscalls[comm][pid].keys() ++ for id in id_keys: ++ print(" syscall: %-16s" % syscall_name(id)) ++ ret_keys = syscalls[comm][pid][id].keys() ++ for ret, val in sorted(syscalls[comm][pid][id].items(), key = lambda kv: (kv[1], kv[0]), reverse = True): ++ print(" err = %-20s %10d" % (strerror(ret), val)) +--- a/tools/perf/scripts/python/futex-contention.py ++++ b/tools/perf/scripts/python/futex-contention.py +@@ -46,5 +46,5 @@ def trace_end(): + for (tid, lock) in lock_waits: + min, max, avg, count = lock_waits[tid, lock] + print "%s[%d] lock %x contended %d times, %d avg ns" % \ +- (process_names[tid], tid, lock, count, avg) ++ (process_names[tid], tid, lock, count, avg) + +--- a/tools/perf/scripts/python/intel-pt-events.py ++++ b/tools/perf/scripts/python/intel-pt-events.py +@@ -85,22 +85,22 @@ def print_common_ip(sample, symbol, dso) + print "%16x %s (%s)" % (ip, symbol, dso) + + def process_event(param_dict): +- event_attr = param_dict["attr"] +- sample = param_dict["sample"] +- raw_buf = param_dict["raw_buf"] +- comm = param_dict["comm"] +- name = param_dict["ev_name"] ++ event_attr = param_dict["attr"] ++ sample = param_dict["sample"] ++ raw_buf = param_dict["raw_buf"] ++ comm = param_dict["comm"] ++ name = param_dict["ev_name"] + +- # Symbol and dso info are not always resolved +- if (param_dict.has_key("dso")): +- dso = param_dict["dso"] +- else: +- dso = "[unknown]" ++ # Symbol and dso info are not always resolved ++ if (param_dict.has_key("dso")): ++ dso = param_dict["dso"] ++ else: ++ dso = "[unknown]" + +- if (param_dict.has_key("symbol")): +- symbol = param_dict["symbol"] +- else: +- symbol = "[unknown]" ++ if (param_dict.has_key("symbol")): ++ symbol = param_dict["symbol"] ++ else: ++ symbol = "[unknown]" + + if name == "ptwrite": + print_common_start(comm, sample, name) +--- a/tools/perf/scripts/python/mem-phys-addr.py ++++ b/tools/perf/scripts/python/mem-phys-addr.py +@@ -44,12 +44,13 @@ def print_memory_type(): + print("%-40s %10s %10s\n" % ("Memory type", "count", "percentage"), end='') + print("%-40s %10s %10s\n" % ("----------------------------------------", + "-----------", "-----------"), +- end=''); ++ end=''); + total = sum(load_mem_type_cnt.values()) + for mem_type, count in sorted(load_mem_type_cnt.most_common(), \ + key = lambda kv: (kv[1], kv[0]), reverse = True): +- print("%-40s %10d %10.1f%%\n" % (mem_type, count, 100 * count / total), +- end='') ++ print("%-40s %10d %10.1f%%\n" % ++ (mem_type, count, 100 * count / total), ++ end='') + + def trace_begin(): + parse_iomem() +--- a/tools/perf/scripts/python/net_dropmonitor.py ++++ b/tools/perf/scripts/python/net_dropmonitor.py +@@ -7,7 +7,7 @@ import os + import sys + + sys.path.append(os.environ['PERF_EXEC_PATH'] + \ +- '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') ++ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') + + from perf_trace_context import * + from Core import * +--- a/tools/perf/scripts/python/netdev-times.py ++++ b/tools/perf/scripts/python/netdev-times.py +@@ -124,14 +124,16 @@ def print_receive(hunk): + event = event_list[i] + if event['event_name'] == 'napi_poll': + print(PF_NAPI_POLL % +- (diff_msec(base_t, event['event_t']), event['dev'])) ++ (diff_msec(base_t, event['event_t']), ++ event['dev'])) + if i == len(event_list) - 1: + print("") + else: + print(PF_JOINT) + else: + print(PF_NET_RECV % +- (diff_msec(base_t, event['event_t']), event['skbaddr'], ++ (diff_msec(base_t, event['event_t']), ++ event['skbaddr'], + event['len'])) + if 'comm' in event.keys(): + print(PF_WJOINT) +@@ -256,7 +258,7 @@ def irq__irq_handler_exit(name, context, + all_event_list.append(event_info) + + def napi__napi_poll(name, context, cpu, sec, nsec, pid, comm, callchain, napi, +- dev_name, work=None, budget=None): ++ dev_name, work=None, budget=None): + event_info = (name, context, cpu, nsecs(sec, nsec), pid, comm, + napi, dev_name, work, budget) + all_event_list.append(event_info) +@@ -353,7 +355,7 @@ def handle_irq_softirq_exit(event_info): + if irq_list == [] or event_list == 0: + return + rec_data = {'sirq_ent_t':sirq_ent_t, 'sirq_ext_t':time, +- 'irq_list':irq_list, 'event_list':event_list} ++ 'irq_list':irq_list, 'event_list':event_list} + # merge information realted to a NET_RX softirq + receive_hunk_list.append(rec_data) + +@@ -390,7 +392,7 @@ def handle_netif_receive_skb(event_info) + skbaddr, skblen, dev_name) = event_info + if cpu in net_rx_dic.keys(): + rec_data = {'event_name':'netif_receive_skb', +- 'event_t':time, 'skbaddr':skbaddr, 'len':skblen} ++ 'event_t':time, 'skbaddr':skbaddr, 'len':skblen} + event_list = net_rx_dic[cpu]['event_list'] + event_list.append(rec_data) + rx_skb_list.insert(0, rec_data) +--- a/tools/perf/scripts/python/sched-migration.py ++++ b/tools/perf/scripts/python/sched-migration.py +@@ -16,10 +16,10 @@ import sys + + from collections import defaultdict + try: +- from UserList import UserList ++ from UserList import UserList + except ImportError: +- # Python 3: UserList moved to the collections package +- from collections import UserList ++ # Python 3: UserList moved to the collections package ++ from collections import UserList + + sys.path.append(os.environ['PERF_EXEC_PATH'] + \ + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') +--- a/tools/perf/scripts/python/sctop.py ++++ b/tools/perf/scripts/python/sctop.py +@@ -13,9 +13,9 @@ from __future__ import print_function + import os, sys, time + + try: +- import thread ++ import thread + except ImportError: +- import _thread as thread ++ import _thread as thread + + sys.path.append(os.environ['PERF_EXEC_PATH'] + \ + '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') +@@ -75,11 +75,12 @@ def print_syscall_totals(interval): + + print("%-40s %10s" % ("event", "count")) + print("%-40s %10s" % +- ("----------------------------------------", +- "----------")) ++ ("----------------------------------------", ++ "----------")) + +- for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \ +- reverse = True): ++ for id, val in sorted(syscalls.items(), ++ key = lambda kv: (kv[1], kv[0]), ++ reverse = True): + try: + print("%-40s %10d" % (syscall_name(id), val)) + except TypeError: +--- a/tools/perf/scripts/python/stackcollapse.py ++++ b/tools/perf/scripts/python/stackcollapse.py +@@ -27,7 +27,7 @@ from collections import defaultdict + from optparse import OptionParser, make_option + + sys.path.append(os.environ['PERF_EXEC_PATH'] + \ +- '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') ++ '/scripts/python/Perf-Trace-Util/lib/Perf/Trace') + + from perf_trace_context import * + from Core import * +--- a/tools/perf/scripts/python/syscall-counts-by-pid.py ++++ b/tools/perf/scripts/python/syscall-counts-by-pid.py +@@ -39,11 +39,10 @@ def trace_end(): + print_syscall_totals() + + def raw_syscalls__sys_enter(event_name, context, common_cpu, +- common_secs, common_nsecs, common_pid, common_comm, +- common_callchain, id, args): +- ++ common_secs, common_nsecs, common_pid, common_comm, ++ common_callchain, id, args): + if (for_comm and common_comm != for_comm) or \ +- (for_pid and common_pid != for_pid ): ++ (for_pid and common_pid != for_pid ): + return + try: + syscalls[common_comm][common_pid][id] += 1 +@@ -51,26 +50,26 @@ def raw_syscalls__sys_enter(event_name, + syscalls[common_comm][common_pid][id] = 1 + + def syscalls__sys_enter(event_name, context, common_cpu, +- common_secs, common_nsecs, common_pid, common_comm, +- id, args): ++ common_secs, common_nsecs, common_pid, common_comm, ++ id, args): + raw_syscalls__sys_enter(**locals()) + + def print_syscall_totals(): +- if for_comm is not None: +- print("\nsyscall events for %s:\n" % (for_comm)) +- else: +- print("\nsyscall events by comm/pid:\n") +- +- print("%-40s %10s" % ("comm [pid]/syscalls", "count")) +- print("%-40s %10s" % ("----------------------------------------", +- "----------")) +- +- comm_keys = syscalls.keys() +- for comm in comm_keys: +- pid_keys = syscalls[comm].keys() +- for pid in pid_keys: +- print("\n%s [%d]" % (comm, pid)) +- id_keys = syscalls[comm][pid].keys() +- for id, val in sorted(syscalls[comm][pid].items(), \ +- key = lambda kv: (kv[1], kv[0]), reverse = True): +- print(" %-38s %10d" % (syscall_name(id), val)) ++ if for_comm is not None: ++ print("\nsyscall events for %s:\n" % (for_comm)) ++ else: ++ print("\nsyscall events by comm/pid:\n") ++ ++ print("%-40s %10s" % ("comm [pid]/syscalls", "count")) ++ print("%-40s %10s" % ("----------------------------------------", ++ "----------")) ++ ++ comm_keys = syscalls.keys() ++ for comm in comm_keys: ++ pid_keys = syscalls[comm].keys() ++ for pid in pid_keys: ++ print("\n%s [%d]" % (comm, pid)) ++ id_keys = syscalls[comm][pid].keys() ++ for id, val in sorted(syscalls[comm][pid].items(), ++ key = lambda kv: (kv[1], kv[0]), reverse = True): ++ print(" %-38s %10d" % (syscall_name(id), val)) +--- a/tools/perf/scripts/python/syscall-counts.py ++++ b/tools/perf/scripts/python/syscall-counts.py +@@ -36,8 +36,8 @@ def trace_end(): + print_syscall_totals() + + def raw_syscalls__sys_enter(event_name, context, common_cpu, +- common_secs, common_nsecs, common_pid, common_comm, +- common_callchain, id, args): ++ common_secs, common_nsecs, common_pid, common_comm, ++ common_callchain, id, args): + if for_comm is not None: + if common_comm != for_comm: + return +@@ -47,20 +47,19 @@ def raw_syscalls__sys_enter(event_name, + syscalls[id] = 1 + + def syscalls__sys_enter(event_name, context, common_cpu, +- common_secs, common_nsecs, common_pid, common_comm, +- id, args): ++ common_secs, common_nsecs, common_pid, common_comm, id, args): + raw_syscalls__sys_enter(**locals()) + + def print_syscall_totals(): +- if for_comm is not None: +- print("\nsyscall events for %s:\n" % (for_comm)) +- else: +- print("\nsyscall events:\n") ++ if for_comm is not None: ++ print("\nsyscall events for %s:\n" % (for_comm)) ++ else: ++ print("\nsyscall events:\n") + +- print("%-40s %10s" % ("event", "count")) +- print("%-40s %10s" % ("----------------------------------------", +- "-----------")) ++ print("%-40s %10s" % ("event", "count")) ++ print("%-40s %10s" % ("----------------------------------------", ++ "-----------")) + +- for id, val in sorted(syscalls.items(), key = lambda kv: (kv[1], kv[0]), \ +- reverse = True): +- print("%-40s %10d" % (syscall_name(id), val)) ++ for id, val in sorted(syscalls.items(), ++ key = lambda kv: (kv[1], kv[0]), reverse = True): ++ print("%-40s %10d" % (syscall_name(id), val)) diff --git a/debian/patches/bugfix/all/perf-script-python-add-Python3-support-to-check-perf.patch b/debian/patches/bugfix/all/perf-script-python-add-Python3-support-to-check-perf.patch new file mode 100644 index 000000000..90c7aa835 --- /dev/null +++ b/debian/patches/bugfix/all/perf-script-python-add-Python3-support-to-check-perf.patch @@ -0,0 +1,104 @@ +From: Tony Jones <tonyj@suse.de> +Date: Fri, 1 Mar 2019 17:18:59 -0800 +Subject: perf script python: add Python3 support to check-perf-trace.py +Origin: https://git.kernel.org/linus/57e604b16362273af6a517abaa6cd1133a7fc732 +Bug-Debian: https://bugs.debian.org/944641 + +Support both Python 2 and Python 3 in the check-perf-trace.py script. + +There may be differences in the ordering of output lines due to +differences in dictionary ordering etc. However the format within lines +should be unchanged. + +The use of from __future__ implies the minimum supported version of +Python2 is now v2.6 + +Signed-off-by: Tony Jones <tonyj@suse.de> +Cc: Tom Zanussi <tzanussi@gmail.com> +Link: http://lkml.kernel.org/r/20190302011903.2416-4-tonyj@suse.de +Signed-off-by: Seeteena Thoufeek <s1seetee@linux.vnet.ibm.com> +Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com> +--- + tools/perf/scripts/python/check-perf-trace.py | 31 ++++++++++++++------------ + 1 file changed, 17 insertions(+), 14 deletions(-) + +--- a/tools/perf/scripts/python/check-perf-trace.py ++++ b/tools/perf/scripts/python/check-perf-trace.py +@@ -7,6 +7,8 @@ + # events, etc. Basically, if this script runs successfully and + # displays expected results, Python scripting support should be ok. + ++from __future__ import print_function ++ + import os + import sys + +@@ -19,7 +21,7 @@ from perf_trace_context import * + unhandled = autodict() + + def trace_begin(): +- print "trace_begin" ++ print("trace_begin") + pass + + def trace_end(): +@@ -33,7 +35,7 @@ def irq__softirq_entry(event_name, conte + + print_uncommon(context) + +- print "vec=%s\n" % (symbol_str("irq__softirq_entry", "vec", vec)), ++ print("vec=%s" % (symbol_str("irq__softirq_entry", "vec", vec))) + + def kmem__kmalloc(event_name, context, common_cpu, + common_secs, common_nsecs, common_pid, common_comm, +@@ -44,10 +46,10 @@ def kmem__kmalloc(event_name, context, c + + print_uncommon(context) + +- print "call_site=%u, ptr=%u, bytes_req=%u, " \ +- "bytes_alloc=%u, gfp_flags=%s\n" % \ ++ print("call_site=%u, ptr=%u, bytes_req=%u, " ++ "bytes_alloc=%u, gfp_flags=%s" % + (call_site, ptr, bytes_req, bytes_alloc, +- flag_str("kmem__kmalloc", "gfp_flags", gfp_flags)), ++ flag_str("kmem__kmalloc", "gfp_flags", gfp_flags))) + + def trace_unhandled(event_name, context, event_fields_dict): + try: +@@ -56,26 +58,27 @@ def trace_unhandled(event_name, context, + unhandled[event_name] = 1 + + def print_header(event_name, cpu, secs, nsecs, pid, comm): +- print "%-20s %5u %05u.%09u %8u %-20s " % \ ++ print("%-20s %5u %05u.%09u %8u %-20s " % + (event_name, cpu, secs, nsecs, pid, comm), ++ end=' ') + + # print trace fields not included in handler args + def print_uncommon(context): +- print "common_preempt_count=%d, common_flags=%s, " \ +- "common_lock_depth=%d, " % \ ++ print("common_preempt_count=%d, common_flags=%s, " ++ "common_lock_depth=%d, " % + (common_pc(context), trace_flag_str(common_flags(context)), +- common_lock_depth(context)) ++ common_lock_depth(context))) + + def print_unhandled(): + keys = unhandled.keys() + if not keys: + return + +- print "\nunhandled events:\n\n", ++ print("\nunhandled events:\n") + +- print "%-40s %10s\n" % ("event", "count"), +- print "%-40s %10s\n" % ("----------------------------------------", \ +- "-----------"), ++ print("%-40s %10s" % ("event", "count")) ++ print("%-40s %10s" % ("----------------------------------------", ++ "-----------")) + + for event_name in keys: +- print "%-40s %10d\n" % (event_name, unhandled[event_name]) ++ print("%-40s %10d\n" % (event_name, unhandled[event_name])) diff --git a/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch b/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch new file mode 100644 index 000000000..cd2ba2e9e --- /dev/null +++ b/debian/patches/bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch @@ -0,0 +1,135 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: radeon, amdgpu: Firmware is required for DRM and KMS on R600 onward +Date: Tue, 08 Jan 2013 03:25:52 +0000 +Bug-Debian: https://bugs.debian.org/607194 +Bug-Debian: https://bugs.debian.org/607471 +Bug-Debian: https://bugs.debian.org/610851 +Bug-Debian: https://bugs.debian.org/627497 +Bug-Debian: https://bugs.debian.org/632212 +Bug-Debian: https://bugs.debian.org/637943 +Bug-Debian: https://bugs.debian.org/649448 +Bug-Debian: https://bugs.debian.org/697229 +Forwarded: no + +radeon requires firmware/microcode for the GPU in all chips, but for +newer chips (apparently R600 'Evergreen' onward) it also expects +firmware for the memory controller and other sub-blocks. + +radeon attempts to gracefully fall back and disable some features if +the firmware is not available, but becomes unstable - the framebuffer +and/or system memory may be corrupted, or the display may stay black. + +Therefore, perform a basic check for the existence of +/lib/firmware/{radeon,amdgpu} when a device is probed, and abort if it +is missing, except for the pre-R600 case. + +--- +Index: linux/drivers/gpu/drm/radeon/radeon_drv.c +=================================================================== +--- linux.orig/drivers/gpu/drm/radeon/radeon_drv.c ++++ linux/drivers/gpu/drm/radeon/radeon_drv.c +@@ -43,6 +43,8 @@ + #include <drm/drm_fb_helper.h> + + #include <drm/drm_crtc_helper.h> ++#include <linux/namei.h> ++#include <linux/path.h> + + /* + * KMS wrapper. +@@ -316,6 +318,28 @@ static struct drm_driver kms_driver; + + bool radeon_device_is_virtual(void); + ++/* Test that /lib/firmware/radeon is a directory (or symlink to a ++ * directory). We could try to match the udev search path, but let's ++ * keep it simple. ++ */ ++static bool radeon_firmware_installed(void) ++{ ++#if IS_BUILTIN(CONFIG_DRM_RADEON) ++ /* It may be too early to tell. Assume it's there. */ ++ return true; ++#else ++ struct path path; ++ ++ if (kern_path("/lib/firmware/radeon", LOOKUP_DIRECTORY | LOOKUP_FOLLOW, ++ &path) == 0) { ++ path_put(&path); ++ return true; ++ } ++ ++ return false; ++#endif ++} ++ + static int radeon_kick_out_firmware_fb(struct pci_dev *pdev) + { + struct apertures_struct *ap; +@@ -376,6 +400,12 @@ static int radeon_pci_probe(struct pci_d + if (vga_switcheroo_client_probe_defer(pdev)) + return -EPROBE_DEFER; + ++ if ((ent->driver_data & RADEON_FAMILY_MASK) >= CHIP_R600 && ++ !radeon_firmware_installed()) { ++ DRM_ERROR("radeon kernel modesetting for R600 or later requires firmware installed\n"); ++ return -ENODEV; ++ } ++ + /* Get rid of things like offb */ + ret = radeon_kick_out_firmware_fb(pdev); + if (ret) +Index: linux/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +=================================================================== +--- linux.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ linux/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -33,6 +33,8 @@ + #include <linux/pm_runtime.h> + #include <linux/vga_switcheroo.h> + #include <drm/drm_crtc_helper.h> ++#include <linux/namei.h> ++#include <linux/path.h> + + #include "amdgpu.h" + #include "amdgpu_irq.h" +@@ -793,6 +795,28 @@ MODULE_DEVICE_TABLE(pci, pciidlist); + + static struct drm_driver kms_driver; + ++/* Test that /lib/firmware/amdgpu is a directory (or symlink to a ++ * directory). We could try to match the udev search path, but let's ++ * keep it simple. ++ */ ++static bool amdgpu_firmware_installed(void) ++{ ++#if IS_BUILTIN(CONFIG_DRM_AMDGPU) ++ /* It may be too early to tell. Assume it's there. */ ++ return true; ++#else ++ struct path path; ++ ++ if (kern_path("/lib/firmware/amdgpu", LOOKUP_DIRECTORY | LOOKUP_FOLLOW, ++ &path) == 0) { ++ path_put(&path); ++ return true; ++ } ++ ++ return false; ++#endif ++} ++ + static int amdgpu_kick_out_firmware_fb(struct pci_dev *pdev) + { + struct apertures_struct *ap; +@@ -833,6 +857,11 @@ static int amdgpu_pci_probe(struct pci_d + return -ENODEV; + } + ++ if (!amdgpu_firmware_installed()) { ++ DRM_ERROR("amdgpu requires firmware installed\n"); ++ return -ENODEV; ++ } ++ + /* + * Initialize amdkfd before starting radeon. If it was not loaded yet, + * defer radeon probing diff --git a/debian/patches/bugfix/all/rtc-s35390a-set-uie_unsupported.patch b/debian/patches/bugfix/all/rtc-s35390a-set-uie_unsupported.patch new file mode 100644 index 000000000..b3261d952 --- /dev/null +++ b/debian/patches/bugfix/all/rtc-s35390a-set-uie_unsupported.patch @@ -0,0 +1,40 @@ +From: Richard Leitner <richard.leitner@skidata.com> +Date: Thu, 23 May 2019 13:54:49 +0200 +Subject: [PATCH] rtc: s35390a: set uie_unsupported +Origin: https://git.kernel.org/linus/c0e12848be091e8410fb427f080f2e0149123443 +Bug-Debian: https://bugs.debian.org/932845 + +Alarms are only supported on a per minute basis. This is why +uie_unsupported is set. Furthermore issue a warning when a second based +alarm is requested. + +Signed-off-by: Richard Leitner <richard.leitner@skidata.com> +Signed-off-by: Alexandre Belloni <alexandre.belloni@bootlin.com> +--- + drivers/rtc/rtc-s35390a.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +Index: linux/drivers/rtc/rtc-s35390a.c +=================================================================== +--- linux.orig/drivers/rtc/rtc-s35390a.c ++++ linux/drivers/rtc/rtc-s35390a.c +@@ -288,6 +288,9 @@ static int s35390a_rtc_set_alarm(struct + alm->time.tm_min, alm->time.tm_hour, alm->time.tm_mday, + alm->time.tm_mon, alm->time.tm_year, alm->time.tm_wday); + ++ if (alm->time.tm_sec != 0) ++ dev_warn(&client->dev, "Alarms are only supported on a per minute basis!\n"); ++ + /* disable interrupt (which deasserts the irq line) */ + err = s35390a_set_reg(s35390a, S35390A_CMD_STATUS2, &sts, sizeof(sts)); + if (err < 0) +@@ -502,6 +505,9 @@ static int s35390a_probe(struct i2c_clie + goto exit_dummy; + } + ++ /* supports per-minute alarms only, therefore set uie_unsupported */ ++ s35390a->rtc->uie_unsupported = 1; ++ + if (status1 & S35390A_FLAG_INT2) + rtc_update_irq(s35390a->rtc, 1, RTC_AF); + diff --git a/debian/patches/bugfix/all/swiotlb-skip-swiotlb_bounce-when-orig_addr-is-zero.patch b/debian/patches/bugfix/all/swiotlb-skip-swiotlb_bounce-when-orig_addr-is-zero.patch new file mode 100644 index 000000000..df77ca0b2 --- /dev/null +++ b/debian/patches/bugfix/all/swiotlb-skip-swiotlb_bounce-when-orig_addr-is-zero.patch @@ -0,0 +1,47 @@ +From: Liu Shixin <liushixin2@huawei.com> +Date: Thu, 30 Jun 2022 19:33:31 +0800 +Subject: swiotlb: skip swiotlb_bounce when orig_addr is zero +Origin: https://lore.kernel.org/stable/20220630113331.1544886-1-liushixin2@huawei.com/ + +After patch ddbd89deb7d3 ("swiotlb: fix info leak with DMA_FROM_DEVICE"), +swiotlb_bounce will be called in swiotlb_tbl_map_single unconditionally. +This requires that the physical address must be valid, which is not always +true on stable-4.19 or earlier version. +On stable-4.19, swiotlb_alloc_buffer will call swiotlb_tbl_map_single with +orig_addr equal to zero, which cause such a panic: + +Unable to handle kernel paging request at virtual address ffffb77a40000000 +... +pc : __memcpy+0x100/0x180 +lr : swiotlb_bounce+0x74/0x88 +... +Call trace: + __memcpy+0x100/0x180 + swiotlb_tbl_map_single+0x2c8/0x338 + swiotlb_alloc+0xb4/0x198 + __dma_alloc+0x84/0x1d8 + ... + +On stable-4.9 and stable-4.14, swiotlb_alloc_coherent wille call map_single +with orig_addr equal to zero, which can cause same panic. + +Fix this by skipping swiotlb_bounce when orig_addr is zero. + +Fixes: ddbd89deb7d3 ("swiotlb: fix info leak with DMA_FROM_DEVICE") +Signed-off-by: Liu Shixin <liushixin2@huawei.com> +--- + kernel/dma/swiotlb.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/kernel/dma/swiotlb.c ++++ b/kernel/dma/swiotlb.c +@@ -594,7 +594,8 @@ found: + * unconditional bounce may prevent leaking swiotlb content (i.e. + * kernel memory) to user-space. + */ +- swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE); ++ if (orig_addr) ++ swiotlb_bounce(orig_addr, tlb_addr, size, DMA_TO_DEVICE); + return tlb_addr; + } + diff --git a/debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch b/debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch new file mode 100644 index 000000000..39044c390 --- /dev/null +++ b/debian/patches/bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 21 Feb 2016 15:33:15 +0000 +Subject: tools/build: Remove bpf() run-time check at build time +Forwarded: no + +It is not correct to test that a syscall works on the build system's +kernel. We might be building on an earlier kernel version or with +security restrictions that block bpf(). + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/tools/build/feature/test-bpf.c +=================================================================== +--- linux.orig/tools/build/feature/test-bpf.c ++++ linux/tools/build/feature/test-bpf.c +@@ -35,8 +35,10 @@ int main(void) + attr.prog_flags = 0; + + /* +- * Test existence of __NR_bpf and BPF_PROG_LOAD. +- * This call should fail if we run the testcase. ++ * bwh: Don't use the bpf() syscall as we might be building on a ++ * much older kernel. Do "use" the attr structure here to avoid ++ * a "set but not used" warning. + */ +- return syscall(__NR_bpf, BPF_PROG_LOAD, &attr, sizeof(attr)); ++ (void)&attr; ++ return 0; + } diff --git a/debian/patches/bugfix/all/tools-lib-traceevent-use-ldflags.patch b/debian/patches/bugfix/all/tools-lib-traceevent-use-ldflags.patch new file mode 100644 index 000000000..ae303f360 --- /dev/null +++ b/debian/patches/bugfix/all/tools-lib-traceevent-use-ldflags.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 25 Sep 2015 21:26:48 +0100 +Subject: tools/lib/traceevent: Use LDFLAGS +Forwarded: no + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/tools/lib/traceevent/Makefile +=================================================================== +--- linux.orig/tools/lib/traceevent/Makefile ++++ linux/tools/lib/traceevent/Makefile +@@ -174,7 +174,7 @@ $(TE_IN): force + $(Q)$(MAKE) $(build)=libtraceevent + + $(OUTPUT)libtraceevent.so.$(EVENT_PARSE_VERSION): $(TE_IN) +- $(QUIET_LINK)$(CC) --shared $^ -Wl,-soname,libtraceevent.so.$(EP_VERSION) -o $@ ++ $(QUIET_LINK)$(CC) $(LDFLAGS) --shared $^ -Wl,-soname,libtraceevent.so.$(EP_VERSION) -o $@ + @ln -sf $(@F) $(OUTPUT)libtraceevent.so + @ln -sf $(@F) $(OUTPUT)libtraceevent.so.$(EP_VERSION) + +@@ -193,7 +193,7 @@ $(PLUGINS_IN): force + $(Q)$(MAKE) $(build)=$(plugin_obj) + + $(OUTPUT)%.so: $(OUTPUT)%-in.o +- $(QUIET_LINK)$(CC) $(CFLAGS) -shared -nostartfiles -o $@ $^ ++ $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) -shared -nostartfiles -o $@ $^ + + define make_version.h + (echo '/* This file is automatically generated. Do not modify. */'; \ diff --git a/debian/patches/bugfix/all/tools-perf-man-date.patch b/debian/patches/bugfix/all/tools-perf-man-date.patch new file mode 100644 index 000000000..4515c703c --- /dev/null +++ b/debian/patches/bugfix/all/tools-perf-man-date.patch @@ -0,0 +1,37 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 13 Jul 2015 20:29:20 +0100 +Subject: perf tools: Use $KBUILD_BUILD_TIMESTAMP as man page date +Forwarded: http://mid.gmane.org/20160517132809.GE7555@decadent.org.uk + +This allows man pages to be built reproducibly. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/tools/perf/Documentation/Makefile +=================================================================== +--- linux.orig/tools/perf/Documentation/Makefile ++++ linux/tools/perf/Documentation/Makefile +@@ -131,6 +131,9 @@ endif + ifdef DOCBOOK_SUPPRESS_SP + XMLTO_EXTRA += -m manpage-suppress-sp.xsl + endif ++ifdef KBUILD_BUILD_TIMESTAMP ++ASCIIDOC_EXTRA += -a revdate=$(shell date -u -d '$(KBUILD_BUILD_TIMESTAMP)' +%Y-%m-%d) ++endif + + SHELL_PATH ?= $(SHELL) + # Shell quote; +Index: linux/tools/perf/Documentation/asciidoc.conf +=================================================================== +--- linux.orig/tools/perf/Documentation/asciidoc.conf ++++ linux/tools/perf/Documentation/asciidoc.conf +@@ -71,6 +71,9 @@ ifdef::backend-docbook[] + [header] + template::[header-declarations] + <refentry> ++<refentryinfo> ++template::[docinfo] ++</refentryinfo> + <refmeta> + <refentrytitle>{mantitle}</refentrytitle> + <manvolnum>{manvolnum}</manvolnum> diff --git a/debian/patches/bugfix/all/tools-perf-remove-shebangs.patch b/debian/patches/bugfix/all/tools-perf-remove-shebangs.patch new file mode 100644 index 000000000..d01140709 --- /dev/null +++ b/debian/patches/bugfix/all/tools-perf-remove-shebangs.patch @@ -0,0 +1,47 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 25 Sep 2015 20:09:23 +0100 +Subject: tools/perf: Remove shebang lines from perf scripts +Forwarded: no + +perf scripts need to be invoked through perf, not directly through +perl (or other language interpreter). So including shebang lines in +them is useless and possibly misleading. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/tools/perf/scripts/perl/rw-by-file.pl +=================================================================== +--- linux.orig/tools/perf/scripts/perl/rw-by-file.pl ++++ linux/tools/perf/scripts/perl/rw-by-file.pl +@@ -1,4 +1,3 @@ +-#!/usr/bin/perl -w + # (c) 2009, Tom Zanussi <tzanussi@gmail.com> + # Licensed under the terms of the GNU GPL License version 2 + +Index: linux/tools/perf/scripts/perl/rw-by-pid.pl +=================================================================== +--- linux.orig/tools/perf/scripts/perl/rw-by-pid.pl ++++ linux/tools/perf/scripts/perl/rw-by-pid.pl +@@ -1,4 +1,3 @@ +-#!/usr/bin/perl -w + # (c) 2009, Tom Zanussi <tzanussi@gmail.com> + # Licensed under the terms of the GNU GPL License version 2 + +Index: linux/tools/perf/scripts/perl/rwtop.pl +=================================================================== +--- linux.orig/tools/perf/scripts/perl/rwtop.pl ++++ linux/tools/perf/scripts/perl/rwtop.pl +@@ -1,4 +1,3 @@ +-#!/usr/bin/perl -w + # (c) 2010, Tom Zanussi <tzanussi@gmail.com> + # Licensed under the terms of the GNU GPL License version 2 + +Index: linux/tools/perf/scripts/perl/wakeup-latency.pl +=================================================================== +--- linux.orig/tools/perf/scripts/perl/wakeup-latency.pl ++++ linux/tools/perf/scripts/perl/wakeup-latency.pl +@@ -1,4 +1,3 @@ +-#!/usr/bin/perl -w + # (c) 2009, Tom Zanussi <tzanussi@gmail.com> + # Licensed under the terms of the GNU GPL License version 2 + diff --git a/debian/patches/bugfix/all/usb-add-a-hcd_uses_dma-helper.patch b/debian/patches/bugfix/all/usb-add-a-hcd_uses_dma-helper.patch new file mode 100644 index 000000000..341018e58 --- /dev/null +++ b/debian/patches/bugfix/all/usb-add-a-hcd_uses_dma-helper.patch @@ -0,0 +1,110 @@ +From: Christoph Hellwig <hch@lst.de> +Date: Sun, 11 Aug 2019 10:05:16 +0200 +Subject: usb: add a hcd_uses_dma helper +Origin: https://git.kernel.org/linus/edfbcb321faf07ca970e4191abe061deeb7d3788 + +The USB buffer allocation code is the only place in the usb core (and in +fact the whole kernel) that uses is_device_dma_capable, while the URB +mapping code uses the uses_dma flag in struct usb_bus. Switch the buffer +allocation to use the uses_dma flag used by the rest of the USB code, +and create a helper in hcd.h that checks this flag as well as the +CONFIG_HAS_DMA to simplify the caller a bit. + +Signed-off-by: Christoph Hellwig <hch@lst.de> +Link: https://lore.kernel.org/r/20190811080520.21712-3-hch@lst.de +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/usb/core/buffer.c | 10 +++------- + drivers/usb/core/hcd.c | 4 ++-- + drivers/usb/dwc2/hcd.c | 2 +- + include/linux/usb.h | 2 +- + include/linux/usb/hcd.h | 3 +++ + 5 files changed, 10 insertions(+), 11 deletions(-) + +--- a/drivers/usb/core/buffer.c ++++ b/drivers/usb/core/buffer.c +@@ -66,9 +66,7 @@ + char name[16]; + int i, size; + +- if (hcd->localmem_pool || +- !IS_ENABLED(CONFIG_HAS_DMA) || +- !is_device_dma_capable(hcd->self.sysdev)) ++ if (hcd->localmem_pool || !hcd_uses_dma(hcd)) + return 0; + + for (i = 0; i < HCD_BUFFER_POOLS; i++) { +@@ -133,8 +131,7 @@ + return gen_pool_dma_alloc(hcd->localmem_pool, size, dma); + + /* some USB hosts just use PIO */ +- if (!IS_ENABLED(CONFIG_HAS_DMA) || +- !is_device_dma_capable(bus->sysdev)) { ++ if (!hcd_uses_dma(hcd)) { + *dma = ~(dma_addr_t) 0; + return kmalloc(size, mem_flags); + } +@@ -164,8 +161,7 @@ + return; + } + +- if (!IS_ENABLED(CONFIG_HAS_DMA) || +- !is_device_dma_capable(bus->sysdev)) { ++ if (!hcd_uses_dma(hcd)) { + kfree(addr); + return; + } +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -1511,7 +1511,7 @@ + if (usb_endpoint_xfer_control(&urb->ep->desc)) { + if (hcd->self.uses_pio_for_control) + return ret; +- if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) { ++ if (hcd_uses_dma(hcd)) { + if (is_vmalloc_addr(urb->setup_packet)) { + WARN_ONCE(1, "setup packet is not dma capable\n"); + return -EAGAIN; +@@ -1545,7 +1545,7 @@ + dir = usb_urb_dir_in(urb) ? DMA_FROM_DEVICE : DMA_TO_DEVICE; + if (urb->transfer_buffer_length != 0 + && !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)) { +- if (IS_ENABLED(CONFIG_HAS_DMA) && hcd->self.uses_dma) { ++ if (hcd_uses_dma(hcd)) { + if (urb->num_sgs) { + int n; + +--- a/drivers/usb/dwc2/hcd.c ++++ b/drivers/usb/dwc2/hcd.c +@@ -4770,7 +4770,7 @@ + + buf = urb->transfer_buffer; + +- if (hcd->self.uses_dma) { ++ if (hcd_uses_dma(hcd)) { + if (!buf && (urb->transfer_dma & 3)) { + dev_err(hsotg->dev, + "%s: unaligned transfer with no transfer_buffer", +--- a/include/linux/usb.h ++++ b/include/linux/usb.h +@@ -1455,7 +1455,7 @@ + * field rather than determining a dma address themselves. + * + * Note that transfer_buffer must still be set if the controller +- * does not support DMA (as indicated by bus.uses_dma) and when talking ++ * does not support DMA (as indicated by hcd_uses_dma()) and when talking + * to root hub. If you have to trasfer between highmem zone and the device + * on such controller, create a bounce buffer or bail out with an error. + * If transfer_buffer cannot be set (is in highmem) and the controller is DMA +--- a/include/linux/usb/hcd.h ++++ b/include/linux/usb/hcd.h +@@ -422,6 +422,9 @@ + return hcd->high_prio_bh.completing_ep == ep; + } + ++#define hcd_uses_dma(hcd) \ ++ (IS_ENABLED(CONFIG_HAS_DMA) && (hcd)->self.uses_dma) ++ + extern int usb_hcd_link_urb_to_ep(struct usb_hcd *hcd, struct urb *urb); + extern int usb_hcd_check_unlink_urb(struct usb_hcd *hcd, struct urb *urb, + int status); diff --git a/debian/patches/bugfix/all/usb-dont-create-dma-pools-for-HCD.patch b/debian/patches/bugfix/all/usb-dont-create-dma-pools-for-HCD.patch new file mode 100644 index 000000000..197a4fadb --- /dev/null +++ b/debian/patches/bugfix/all/usb-dont-create-dma-pools-for-HCD.patch @@ -0,0 +1,31 @@ +From: Christoph Hellwig <hch@lst.de> +Date: Sun, 11 Aug 2019 10:05:15 +0200 +Subject: usb: don't create dma pools for HCDs with a localmem_pool +Origin: https://git.kernel.org/linus/dd3ecf17ba70a70d2c9ef9ba725281b84f8eef12 + +If the HCD provides a localmem pool we will never use the DMA pools, so +don't create them. + +Fixes: b0310c2f09bb ("USB: use genalloc for USB HCs with local memory") +Signed-off-by: Christoph Hellwig <hch@lst.de> +Link: https://lore.kernel.org/r/20190811080520.21712-2-hch@lst.de +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/usb/core/buffer.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/usb/core/buffer.c ++++ b/drivers/usb/core/buffer.c +@@ -66,9 +66,9 @@ + char name[16]; + int i, size; + +- if (!IS_ENABLED(CONFIG_HAS_DMA) || +- (!is_device_dma_capable(hcd->self.sysdev) && +- !hcd->localmem_pool)) ++ if (hcd->localmem_pool || ++ !IS_ENABLED(CONFIG_HAS_DMA) || ++ !is_device_dma_capable(hcd->self.sysdev)) + return 0; + + for (i = 0; i < HCD_BUFFER_POOLS; i++) { diff --git a/debian/patches/bugfix/all/usb-hcd-Fix-a-NULL-vs-IS_ERR-bug-in-usb_hcd_setup_lo.patch b/debian/patches/bugfix/all/usb-hcd-Fix-a-NULL-vs-IS_ERR-bug-in-usb_hcd_setup_lo.patch new file mode 100644 index 000000000..920b0b780 --- /dev/null +++ b/debian/patches/bugfix/all/usb-hcd-Fix-a-NULL-vs-IS_ERR-bug-in-usb_hcd_setup_lo.patch @@ -0,0 +1,35 @@ +From: Dan Carpenter <dan.carpenter@oracle.com> +Date: Fri, 7 Jun 2019 16:57:09 +0300 +Subject: usb/hcd: Fix a NULL vs IS_ERR() bug in usb_hcd_setup_local_mem() +Origin: https://git.kernel.org/linus/94b9a70d32db0d1e8eeaeb27d74a5ae712644da9 + +The devm_memremap() function doesn't return NULL, it returns error +pointers. + +Fixes: b0310c2f09bb ("USB: use genalloc for USB HCs with local memory") +Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com> +Acked-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Link: https://lore.kernel.org/r/20190607135709.GC16718@mwanda +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + drivers/usb/core/hcd.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c +index 8b8ec0c7325d..a84b201dd844 100644 +--- a/drivers/usb/core/hcd.c ++++ b/drivers/usb/core/hcd.c +@@ -3038,8 +3038,8 @@ int usb_hcd_setup_local_mem(struct usb_hcd *hcd, phys_addr_t phys_addr, + + local_mem = devm_memremap(hcd->self.sysdev, phys_addr, + size, MEMREMAP_WC); +- if (!local_mem) +- return -ENOMEM; ++ if (IS_ERR(local_mem)) ++ return PTR_ERR(local_mem); + + /* + * Here we pass a dma_addr_t but the arg type is a phys_addr_t. +-- +2.26.2 + diff --git a/debian/patches/bugfix/all/usb-host-ohci-sm501-init-genalloc-for-local-memory.patch b/debian/patches/bugfix/all/usb-host-ohci-sm501-init-genalloc-for-local-memory.patch new file mode 100644 index 000000000..39d46e009 --- /dev/null +++ b/debian/patches/bugfix/all/usb-host-ohci-sm501-init-genalloc-for-local-memory.patch @@ -0,0 +1,105 @@ +From: Laurentiu Tudor <laurentiu.tudor@nxp.com> +Date: Wed, 29 May 2019 13:28:41 +0300 +Subject: usb: host: ohci-sm501: init genalloc for local memory +Origin: https://git.kernel.org/linus/7d9e6f5aebe8c03f1a5199ca5c30f0c53042af23 + +In preparation for dropping the existing "coherent" dma mem declaration +APIs, replace the current dma_declare_coherent_memory() based mechanism +with the creation of a genalloc pool that will be used in the OHCI +subsystem as replacement for the DMA APIs. + +Signed-off-by: Laurentiu Tudor <laurentiu.tudor@nxp.com> +Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: Christoph Hellwig <hch@lst.de> +--- + drivers/usb/host/ohci-sm501.c | 47 +++++++++++++++-------------------- + 1 file changed, 20 insertions(+), 27 deletions(-) + +--- a/drivers/usb/host/ohci-sm501.c ++++ b/drivers/usb/host/ohci-sm501.c +@@ -110,41 +110,18 @@ + goto err0; + } + +- /* The sm501 chip is equipped with local memory that may be used +- * by on-chip devices such as the video controller and the usb host. +- * This driver uses dma_declare_coherent_memory() to make sure +- * usb allocations with dma_alloc_coherent() allocate from +- * this local memory. The dma_handle returned by dma_alloc_coherent() +- * will be an offset starting from 0 for the first local memory byte. +- * +- * So as long as data is allocated using dma_alloc_coherent() all is +- * fine. This is however not always the case - buffers may be allocated +- * using kmalloc() - so the usb core needs to be told that it must copy +- * data into our local memory if the buffers happen to be placed in +- * regular memory. The HCD_LOCAL_MEM flag does just that. +- */ +- +- retval = dma_declare_coherent_memory(dev, mem->start, +- mem->start - mem->parent->start, +- resource_size(mem), +- DMA_MEMORY_EXCLUSIVE); +- if (retval) { +- dev_err(dev, "cannot declare coherent memory\n"); +- goto err1; +- } +- + /* allocate, reserve and remap resources for registers */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(dev, "no resource definition for registers\n"); + retval = -ENOENT; +- goto err2; ++ goto err1; + } + + hcd = usb_create_hcd(driver, &pdev->dev, dev_name(&pdev->dev)); + if (!hcd) { + retval = -ENOMEM; +- goto err2; ++ goto err1; + } + + hcd->rsrc_start = res->start; +@@ -165,6 +142,24 @@ + + ohci_hcd_init(hcd_to_ohci(hcd)); + ++ /* The sm501 chip is equipped with local memory that may be used ++ * by on-chip devices such as the video controller and the usb host. ++ * This driver uses genalloc so that usb allocations with ++ * gen_pool_dma_alloc() allocate from this local memory. The dma_handle ++ * returned by gen_pool_dma_alloc() will be an offset starting from 0 ++ * for the first local memory byte. ++ * ++ * So as long as data is allocated using gen_pool_dma_alloc() all is ++ * fine. This is however not always the case - buffers may be allocated ++ * using kmalloc() - so the usb core needs to be told that it must copy ++ * data into our local memory if the buffers happen to be placed in ++ * regular memory. The HCD_LOCAL_MEM flag does just that. ++ */ ++ ++ if (usb_hcd_setup_local_mem(hcd, mem->start, ++ mem->start - mem->parent->start, ++ resource_size(mem)) < 0) ++ goto err5; + retval = usb_add_hcd(hcd, irq, IRQF_SHARED); + if (retval) + goto err5; +@@ -182,8 +177,6 @@ + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + err3: + usb_put_hcd(hcd); +-err2: +- dma_release_declared_memory(dev); + err1: + release_mem_region(mem->start, resource_size(mem)); + err0: +@@ -199,7 +192,6 @@ + iounmap(hcd->regs); + release_mem_region(hcd->rsrc_start, hcd->rsrc_len); + usb_put_hcd(hcd); +- dma_release_declared_memory(&pdev->dev); + mem = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (mem) + release_mem_region(mem->start, resource_size(mem)); diff --git a/debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch b/debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch new file mode 100644 index 000000000..0943df590 --- /dev/null +++ b/debian/patches/bugfix/all/usbip-document-tcp-wrappers.patch @@ -0,0 +1,31 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 24 Jun 2012 02:51:39 +0100 +Subject: usbip: Document TCP wrappers +Forwarded: no + +Add references to TCP wrappers configuration in the manual page. + +Index: linux/tools/usb/usbip/doc/usbipd.8 +=================================================================== +--- linux.orig/tools/usb/usbip/doc/usbipd.8 ++++ linux/tools/usb/usbip/doc/usbipd.8 +@@ -14,7 +14,8 @@ Devices have to explicitly be exported u + before usbipd makes them available to other hosts. + + The daemon accepts connections from USB/IP clients +-on TCP port 3240 by default. ++on TCP port 3240 by default. The clients authorised to connect may be ++configured as documented in hosts_access(5). + + .SH OPTIONS + .HP +@@ -69,7 +70,8 @@ Show version. + + .B usbipd + offers no authentication or authorization for USB/IP. Any +-USB/IP client can connect and use exported devices. ++USB/IP client running on an authorised host can connect and ++use exported devices. + + .SH EXAMPLES + diff --git a/debian/patches/bugfix/all/usbip-fix-misuse-of-strncpy.patch b/debian/patches/bugfix/all/usbip-fix-misuse-of-strncpy.patch new file mode 100644 index 000000000..b98025b8a --- /dev/null +++ b/debian/patches/bugfix/all/usbip-fix-misuse-of-strncpy.patch @@ -0,0 +1,61 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 20 Jul 2018 01:30:24 +0100 +Subject: usbip: Fix misuse of strncpy() +Bug-Debian: https://bugs.debian.org/897802 +Forwarded: https://marc.info/?l=linux-usb&m=153213915806258 + +gcc 8 reports: + +usbip_device_driver.c: In function ‘read_usb_vudc_device’: +usbip_device_driver.c:106:2: error: ‘strncpy’ specified bound 256 equals destination size [-Werror=stringop-truncation] + strncpy(dev->path, path, SYSFS_PATH_MAX); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +usbip_device_driver.c:125:2: error: ‘strncpy’ specified bound 32 equals destination size [-Werror=stringop-truncation] + strncpy(dev->busid, name, SYSFS_BUS_ID_SIZE); + ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +I'm not convinced it makes sense to truncate the copied strings here, +but since we're already doing so let's ensure they're still null- +terminated. We can't easily use strlcpy() here, so use snprintf(). + +usbip_common.c has the same problem. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/tools/usb/usbip/libsrc/usbip_common.c +=================================================================== +--- linux.orig/tools/usb/usbip/libsrc/usbip_common.c ++++ linux/tools/usb/usbip/libsrc/usbip_common.c +@@ -226,8 +226,8 @@ int read_usb_device(struct udev_device * + path = udev_device_get_syspath(sdev); + name = udev_device_get_sysname(sdev); + +- strncpy(udev->path, path, SYSFS_PATH_MAX); +- strncpy(udev->busid, name, SYSFS_BUS_ID_SIZE); ++ snprintf(udev->path, SYSFS_PATH_MAX, "%s", path); ++ snprintf(udev->busid, SYSFS_BUS_ID_SIZE, "%s", name); + + sscanf(name, "%u-%u", &busnum, &devnum); + udev->busnum = busnum; +Index: linux/tools/usb/usbip/libsrc/usbip_device_driver.c +=================================================================== +--- linux.orig/tools/usb/usbip/libsrc/usbip_device_driver.c ++++ linux/tools/usb/usbip/libsrc/usbip_device_driver.c +@@ -103,7 +103,7 @@ int read_usb_vudc_device(struct udev_dev + copy_descr_attr16(dev, &descr, idProduct); + copy_descr_attr16(dev, &descr, bcdDevice); + +- strncpy(dev->path, path, SYSFS_PATH_MAX); ++ snprintf(dev->path, SYSFS_PATH_MAX, "%s", path); + + dev->speed = USB_SPEED_UNKNOWN; + speed = udev_device_get_sysattr_value(sdev, "current_speed"); +@@ -122,7 +122,7 @@ int read_usb_vudc_device(struct udev_dev + dev->busnum = 0; + + name = udev_device_get_sysname(plat); +- strncpy(dev->busid, name, SYSFS_BUS_ID_SIZE); ++ snprintf(dev->busid, SYSFS_BUS_ID_SIZE, "%s", name); + return 0; + err: + fclose(fd); diff --git a/debian/patches/bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch b/debian/patches/bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch new file mode 100644 index 000000000..1329c9390 --- /dev/null +++ b/debian/patches/bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch @@ -0,0 +1,77 @@ +From: Jorik Jonker <jorik@kippendief.biz> +Date: Sat, 29 Sep 2018 15:18:30 +0200 +Subject: ARM: dts: sun8i-h3: add sy8106a to orange pi plus +Origin: https://git.kernel.org/linus/e98d72d98a25890308941080d3a17b4c77e3f460 + +The Orange Pi Plus board lacks voltage scaling capabilities in its +current form. This results in random freezes during boot when cpufreq is +enabled, probably due to wrong voltages. + +This patch (more or less copy/paste from 06139c) does the following +things on this board: +- enable r_i2c +- add sy8106a to the r_i2c bus +- have the sy8106a regulate VDD of cpu + +Since the Orange Pi Plus has the same PMU setup as the Orange Pi PC, I +simply took min/max/fixed/ramp from the latter DTS. In that file the +origin of the values are described by the following comment: + + "The datasheet uses 1.1V as the minimum value of VDD-CPUX, + however both the Armbian DVFS table and the official one + have operating points with voltage under 1.1V, and both + DVFS table are known to work properly at the lowest + operating point. + Use 1.0V as the minimum voltage instead." + +I have tested this on patch two Orange Pi Plus boards, by running a +kernel with this patch and do intermettent runs of cpuburn while +monitoring voltage, frequency and temperature. The board runs stable +across its operatiing points while showing a reasonable (< 40C) +temperature. My Orange Pi PC, when put to the same test, yields similar +stable results. + +Signed-off-by: Jorik Jonker <jorik@kippendief.biz> +Signed-off-by: Maxime Ripard <maxime.ripard@bootlin.com> +--- + arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts | 20 ++++++++++++++++++++ + 1 file changed, 20 insertions(+) + +Index: linux/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts +=================================================================== +--- linux.orig/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts ++++ linux/arch/arm/boot/dts/sun8i-h3-orangepi-plus.dts +@@ -74,6 +74,10 @@ + }; + }; + ++&cpu0 { ++ cpu-supply = <®_vdd_cpux>; ++}; ++ + &ehci3 { + status = "okay"; + }; +@@ -119,6 +123,22 @@ + }; + }; + ++&r_i2c { ++ status = "okay"; ++ ++ reg_vdd_cpux: regulator@65 { ++ compatible = "silergy,sy8106a"; ++ reg = <0x65>; ++ regulator-name = "vdd-cpux"; ++ silergy,fixed-microvolt = <1200000>; ++ regulator-min-microvolt = <1000000>; ++ regulator-max-microvolt = <1400000>; ++ regulator-ramp-delay = <200>; ++ regulator-boot-on; ++ regulator-always-on; ++ }; ++}; ++ + &usbphy { + usb3_vbus-supply = <®_usb3_vbus>; + }; diff --git a/debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch b/debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch new file mode 100644 index 000000000..a8fc875a3 --- /dev/null +++ b/debian/patches/bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch @@ -0,0 +1,37 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 17 Feb 2017 01:30:30 +0000 +Subject: ARM: dts: kirkwood: Fix SATA pinmux-ing for TS419 +Forwarded: https://www.spinics.net/lists/arm-kernel/msg563610.html +Bug-Debian: https://bugs.debian.org/855017 + +The old board code for the TS419 assigns MPP pins 15 and 16 as SATA +activity signals (and none as SATA presence signals). Currently the +device tree assigns the SoC's default pinmux groups for SATA, which +conflict with the second Ethernet port. + +Reported-by: gmbh@gazeta.pl +Tested-by: gmbh@gazeta.pl +References: https://bugs.debian.org/855017 +Cc: stable@vger.kernel.org # 3.15+ +Fixes: 934b524b3f49 ("ARM: Kirkwood: Add DT description of QNAP 419") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arm/boot/dts/kirkwood-ts419.dtsi | 8 ++++++++ + 1 file changed, 8 insertions(+) + +Index: linux/arch/arm/boot/dts/kirkwood-ts419.dtsi +=================================================================== +--- linux.orig/arch/arm/boot/dts/kirkwood-ts419.dtsi ++++ linux/arch/arm/boot/dts/kirkwood-ts419.dtsi +@@ -69,3 +69,11 @@ + phy-handle = <ðphy1>; + }; + }; ++ ++&pmx_sata0 { ++ marvell,pins = "mpp15"; ++}; ++ ++&pmx_sata1 { ++ marvell,pins = "mpp16"; ++}; diff --git a/debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch b/debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch new file mode 100644 index 000000000..2e8771b55 --- /dev/null +++ b/debian/patches/bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch @@ -0,0 +1,31 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 11 Jul 2018 23:40:55 +0100 +Subject: ARM: mm: Export __sync_icache_dcache() for xen-privcmd +Forwarded: https://marc.info/?l=linux-arm-kernel&m=153134944429241 + +The xen-privcmd driver, which can be modular, calls set_pte_at() +which in turn may call __sync_icache_dcache(). + +The call to __sync_icache_dcache() may be optimised out because it is +conditional on !pte_special(), and xen-privcmd calls pte_mkspecial(). +However, in a non-LPAE configuration there is no "special" bit and the +call is really unconditional. + +Fixes: 3ad0876554ca ("xen/privcmd: add IOCTL_PRIVCMD_MMAP_RESOURCE") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/arm/mm/flush.c | 1 + + 1 file changed, 1 insertion(+) + +Index: linux/arch/arm/mm/flush.c +=================================================================== +--- linux.orig/arch/arm/mm/flush.c ++++ linux/arch/arm/mm/flush.c +@@ -295,6 +295,7 @@ void __sync_icache_dcache(pte_t pteval) + if (pte_exec(pteval)) + __flush_icache_all(); + } ++EXPORT_SYMBOL_GPL(__sync_icache_dcache); + #endif + + /* diff --git a/debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch b/debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch new file mode 100644 index 000000000..55fbe10b5 --- /dev/null +++ b/debian/patches/bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch @@ -0,0 +1,47 @@ +From: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Date: Sat, 15 Jun 2019 10:23:56 +1000 +Subject: [PATCH 3/4] arm64: PCI: Allow resource reallocation if necessary +Origin: https://git.kernel.org/linus/3e8ba9686600e5f77e692126bf0293edf162989a + +Call pci_assign_unassigned_root_bus_resources() instead of the simpler: + + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + +pci_assign_unassigned_root_bus_resources() calls: + + __pci_bus_size_bridges(bus, add_list); + __pci_bus_assign_resources(bus, add_list, &fail_head); + +so this should be equivalent as long as we're able to assign everything. +If we were unable to assign something, previously we did nothing and left +it unassigned, but after this patch, we will attempt to do some +reallocation. + +Once we start honoring FW resource allocations, this will bring up the +"reallocation" feature which can help making room for SR-IOV when +necessary. + +Link: https://lore.kernel.org/r/20190615002359.29577-1-benh@kernel.crashing.org +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +[bhelgaas: commit log] +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +--- + arch/arm64/kernel/pci.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +Index: linux/arch/arm64/kernel/pci.c +=================================================================== +--- linux.orig/arch/arm64/kernel/pci.c ++++ linux/arch/arm64/kernel/pci.c +@@ -194,8 +194,7 @@ struct pci_bus *pci_acpi_scan_root(struc + if (!bus) + return NULL; + +- pci_bus_size_bridges(bus); +- pci_bus_assign_resources(bus); ++ pci_assign_unassigned_root_bus_resources(bus); + + list_for_each_entry(child, &bus->children, node) + pcie_bus_configure_settings(child); diff --git a/debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch b/debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch new file mode 100644 index 000000000..37bc6e0c8 --- /dev/null +++ b/debian/patches/bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch @@ -0,0 +1,46 @@ +From: Benjamin Herrenschmidt <benh@kernel.crashing.org> +Date: Sat, 15 Jun 2019 10:23:59 +1000 +Subject: [PATCH 4/4] arm64: PCI: Preserve firmware configuration when desired +Origin: https://git.kernel.org/linus/85dc04136e86680378546afb808357a58c06061c + +If we must preserve the firmware resource assignments, claim the existing +resources rather than reassigning everything. + +Link: https://lore.kernel.org/r/20190615002359.29577-4-benh@kernel.crashing.org +Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org> +[bhelgaas: commit log] +Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> +Acked-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> +Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +--- + arch/arm64/kernel/pci.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +Index: linux/arch/arm64/kernel/pci.c +=================================================================== +--- linux.orig/arch/arm64/kernel/pci.c ++++ linux/arch/arm64/kernel/pci.c +@@ -169,6 +169,7 @@ struct pci_bus *pci_acpi_scan_root(struc + struct acpi_pci_generic_root_info *ri; + struct pci_bus *bus, *child; + struct acpi_pci_root_ops *root_ops; ++ struct pci_host_bridge *host; + + ri = kzalloc_node(sizeof(*ri), GFP_KERNEL, node); + if (!ri) +@@ -194,6 +195,15 @@ struct pci_bus *pci_acpi_scan_root(struc + if (!bus) + return NULL; + ++ /* If we must preserve the resource configuration, claim now */ ++ host = pci_find_host_bridge(bus); ++ if (host->preserve_config) ++ pci_bus_claim_resources(bus); ++ ++ /* ++ * Assign whatever was left unassigned. If we didn't claim above, ++ * this will reassign everything. ++ */ + pci_assign_unassigned_root_bus_resources(bus); + + list_for_each_entry(child, &bus->children, node) diff --git a/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch b/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch new file mode 100644 index 000000000..50098d001 --- /dev/null +++ b/debian/patches/bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch @@ -0,0 +1,92 @@ +From: Geoff Levand <geoff@infradead.org> +Date: Wed, 13 Jun 2018 10:56:08 -0700 +Subject: arm64/acpi: Add fixup for HPE m400 quirks +Forwarded: https://patchwork.codeaurora.org/patch/547277/ + +Adds a new ACPI init routine acpi_fixup_m400_quirks that adds +a work-around for HPE ProLiant m400 APEI firmware problems. + +The work-around disables APEI when CONFIG_ACPI_APEI is set and +m400 firmware is detected. Without this fixup m400 systems +experience errors like these on startup: + + [Hardware Error]: Hardware error from APEI Generic Hardware Error Source: 2 + [Hardware Error]: event severity: fatal + [Hardware Error]: Error 0, type: fatal + [Hardware Error]: section_type: memory error + [Hardware Error]: error_status: 0x0000000000001300 + [Hardware Error]: error_type: 10, invalid address + Kernel panic - not syncing: Fatal hardware error! + +Signed-off-by: Geoff Levand <geoff@infradead.org> +[bwh: Adjust context to apply to Linux 4.19] +--- + arch/arm64/kernel/acpi.c | 40 ++++++++++++++++++++++++++++++++++++---- + 1 file changed, 36 insertions(+), 4 deletions(-) + +Index: linux/arch/arm64/kernel/acpi.c +=================================================================== +--- linux.orig/arch/arm64/kernel/acpi.c ++++ linux/arch/arm64/kernel/acpi.c +@@ -33,6 +33,8 @@ + #include <asm/pgtable.h> + #include <asm/smp_plat.h> + ++#include <acpi/apei.h> ++ + int acpi_noirq = 1; /* skip ACPI IRQ initialization */ + int acpi_disabled = 1; + EXPORT_SYMBOL(acpi_disabled); +@@ -179,6 +181,33 @@ out: + } + + /* ++ * acpi_fixup_m400_quirks - Work-around for HPE ProLiant m400 APEI firmware ++ * problems. ++ */ ++static void __init acpi_fixup_m400_quirks(void) ++{ ++ acpi_status status; ++ struct acpi_table_header *header; ++#if !defined(CONFIG_ACPI_APEI) ++ int hest_disable = HEST_DISABLED; ++#endif ++ ++ if (!IS_ENABLED(CONFIG_ACPI_APEI) || hest_disable != HEST_ENABLED) ++ return; ++ ++ status = acpi_get_table(ACPI_SIG_HEST, 0, &header); ++ ++ if (ACPI_SUCCESS(status) && !strncmp(header->oem_id, "HPE ", 6) && ++ !strncmp(header->oem_table_id, "ProLiant", 8) && ++ MIDR_IMPLEMENTOR(read_cpuid_id()) == ARM_CPU_IMP_APM) { ++ hest_disable = HEST_DISABLED; ++ pr_info("Disabled APEI for m400.\n"); ++ } ++ ++ acpi_put_table(header); ++} ++ ++/* + * acpi_boot_table_init() called from setup_arch(), always. + * 1. find RSDP and get its address, and then find XSDT + * 2. extract all tables and checksums them all +@@ -233,11 +262,14 @@ done: + if (acpi_disabled) { + if (earlycon_acpi_spcr_enable) + early_init_dt_scan_chosen_stdout(); +- } else { +- acpi_parse_spcr(earlycon_acpi_spcr_enable, true); +- if (IS_ENABLED(CONFIG_ACPI_BGRT)) +- acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); ++ return; + } ++ ++ acpi_parse_spcr(earlycon_acpi_spcr_enable, true); ++ if (IS_ENABLED(CONFIG_ACPI_BGRT)) ++ acpi_table_parse(ACPI_SIG_BGRT, acpi_parse_bgrt); ++ ++ acpi_fixup_m400_quirks(); + } + + pgprot_t __acpi_get_mem_attribute(phys_addr_t addr) diff --git a/debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch b/debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch new file mode 100644 index 000000000..543364416 --- /dev/null +++ b/debian/patches/bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch @@ -0,0 +1,28 @@ +From: Samuel Holland <samuel@sholland.org> +Date: Sat, 12 Jan 2019 20:17:19 -0600 +Subject: arm64: dts: allwinner: a64: Enable A64 timer workaround +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux.git/commit?id=55ec26d6a4241363fa94f15377ebd8f1116fbfd7 + +As instability in the architectural timer has been observed on multiple +devices using this SoC, inluding the Pine64 and the Orange Pi Win, +enable the workaround in the SoC's device tree. + +Acked-by: Maxime Ripard <maxime.ripard@bootlin.com> +Signed-off-by: Samuel Holland <samuel@sholland.org> +Signed-off-by: Chen-Yu Tsai <wens@csie.org> +--- + arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi | 1 + + 1 file changed, 1 insertion(+) + +Index: linux/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +=================================================================== +--- linux.orig/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi ++++ linux/arch/arm64/boot/dts/allwinner/sun50i-a64.dtsi +@@ -159,6 +159,7 @@ + + timer { + compatible = "arm,armv8-timer"; ++ allwinner,erratum-unknown1; + interrupts = <GIC_PPI 13 + (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>, + <GIC_PPI 14 diff --git a/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch b/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch new file mode 100644 index 000000000..4116ab598 --- /dev/null +++ b/debian/patches/bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch @@ -0,0 +1,42 @@ +From: Heinrich Schuchardt <xypron.glpk@gmx.de> +Date: Mon, 4 Jun 2018 19:15:23 +0200 +Subject: arm64: dts: rockchip: correct voltage selector on Firefly-RK3399 +Bug-Debian: https://bugs.debian.org/900799 +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/mmind/linux-rockchip.git/patch/?id=710e8c4a54be82ee8a97324e7b4330bf191e08bf + +Without this patch the Firefly-RK3399 board boot process hangs after these +lines: + + fan53555-regulator 0-0040: FAN53555 Option[8] Rev[1] Detected! + fan53555-reg: supplied by vcc_sys + vcc1v8_s3: supplied by vcc_1v8 + +Blacklisting driver fan53555 allows booting. + +The device tree uses a value of fcs,suspend-voltage-selector different to +any other board. + +Changing this setting to the usual value is sufficient to enable booting +and also matches the value used in the vendor kernel. + +Fixes: 171582e00db1 ("arm64: dts: rockchip: add support for firefly-rk3399 board") +Cc: stable@vger.kernel.org +Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> +Signed-off-by: Heiko Stuebner <heiko@sntech.de> +--- + arch/arm64/boot/dts/rockchip/rk3399-firefly.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +=================================================================== +--- linux.orig/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts ++++ linux/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +@@ -455,7 +455,7 @@ + vdd_cpu_b: regulator@40 { + compatible = "silergy,syr827"; + reg = <0x40>; +- fcs,suspend-voltage-selector = <0>; ++ fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_b"; + regulator-min-microvolt = <712500>; + regulator-max-microvolt = <1500000>; diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch b/debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch new file mode 100644 index 000000000..98b6e734e --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch @@ -0,0 +1,47 @@ +From bbd24b8bdc501fb5dacb43e847b6eeb9a12829f5 Mon Sep 17 00:00:00 2001 +From: Luo Jiaxing <luojiaxing@huawei.com> +Date: Mon, 24 Sep 2018 23:06:29 +0800 +Subject: [PATCH 02/31] scsi: hisi_sas: Move evaluation of hisi_hba in + hisi_sas_task_prep() +Origin: https://git.kernel.org/linus/1668e3b6f8f8ed2ce685691c92b90dfadeaa3f2f + +In evaluating hisi_hba, the sas_port may be NULL, so for safety relocate +the the check to value possible NULL deference. + +Signed-off-by: Luo Jiaxing <luojiaxing@huawei.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -288,13 +288,13 @@ static int hisi_sas_task_prep(struct sas + int *pass) + { + struct domain_device *device = task->dev; +- struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); ++ struct hisi_hba *hisi_hba; + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_sas_port *port; + struct hisi_sas_slot *slot; + struct hisi_sas_cmd_hdr *cmd_hdr_base; + struct asd_sas_port *sas_port = device->port; +- struct device *dev = hisi_hba->dev; ++ struct device *dev; + int dlvry_queue_slot, dlvry_queue, rc, slot_idx; + int n_elem = 0, n_elem_req = 0, n_elem_resp = 0; + struct hisi_sas_dq *dq; +@@ -315,6 +315,9 @@ static int hisi_sas_task_prep(struct sas + return -ECOMM; + } + ++ hisi_hba = dev_to_hisi_hba(device); ++ dev = hisi_hba->dev; ++ + if (DEV_IS_GONE(sas_dev)) { + if (sas_dev) + dev_info(dev, "task prep: device %d not ready\n", diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch b/debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch new file mode 100644 index 000000000..a25ca7885 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch @@ -0,0 +1,29 @@ +From de1d5713a20562acdb3f94466232432c9dd1d95c Mon Sep 17 00:00:00 2001 +From: Xiang Chen <chenxiang66@hisilicon.com> +Date: Mon, 24 Sep 2018 23:06:32 +0800 +Subject: [PATCH 05/31] scsi: hisi_sas: unmask interrupts ent72 and ent74 +Origin: https://git.kernel.org/linus/6ecf5ba13cd5959eb75f617ff32c93bb67790e48 + +The interrupts of ent72 and ent74 are not processed by PCIe AER handling, +so we need to unmask the interrupts and process them first in the driver. + +Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -441,7 +441,7 @@ static void init_reg_v3_hw(struct hisi_h + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK1, 0xfefefefe); + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK2, 0xfefefefe); + if (pdev->revision >= 0x21) +- hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7fff); ++ hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xffff7aff); + else + hisi_sas_write32(hisi_hba, ENT_INT_SRC_MSK3, 0xfffe20ff); + hisi_sas_write32(hisi_hba, CHNL_PHYUPDOWN_INT_MSK, 0x0); diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch b/debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch new file mode 100644 index 000000000..15a26a35a --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch @@ -0,0 +1,308 @@ +From d35bf6fccf7d4064065c078d3d369ffeaad6c731 Mon Sep 17 00:00:00 2001 +From: Xiang Chen <chenxiang66@hisilicon.com> +Date: Mon, 24 Sep 2018 23:06:33 +0800 +Subject: [PATCH 06/31] scsi: hisi_sas: Use block layer tag instead for IPTT +Origin: https://git.kernel.org/linus/784b46b7cba0ae914dd293f23848c5057c6ba017 + +Currently we use the IPTT defined in LLDD to identify IOs. Actually for +IOs which are from the block layer, they have tags to identify them. So +for those IOs, use tag of the block layer directly, and for IOs which is +not from the block layer (such as internal IOs from libsas/LLDD), reserve +96 IPTTs for them. + +Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas.h | 3 +- + drivers/scsi/hisi_sas/hisi_sas_main.c | 89 +++++++++++++++++--------- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 1 - + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 9 +-- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 8 ++- + 5 files changed, 70 insertions(+), 40 deletions(-) + +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -34,6 +34,7 @@ + #define HISI_SAS_MAX_DEVICES HISI_SAS_MAX_ITCT_ENTRIES + #define HISI_SAS_RESET_BIT 0 + #define HISI_SAS_REJECT_CMD_BIT 1 ++#define HISI_SAS_RESERVED_IPTT_CNT 96 + + #define HISI_SAS_STATUS_BUF_SZ (sizeof(struct hisi_sas_status_buffer)) + #define HISI_SAS_COMMAND_TABLE_SZ (sizeof(union hisi_sas_command_table)) +@@ -217,7 +218,7 @@ struct hisi_sas_hw { + int (*hw_init)(struct hisi_hba *hisi_hba); + void (*setup_itct)(struct hisi_hba *hisi_hba, + struct hisi_sas_device *device); +- int (*slot_index_alloc)(struct hisi_hba *hisi_hba, int *slot_idx, ++ int (*slot_index_alloc)(struct hisi_hba *hisi_hba, + struct domain_device *device); + struct hisi_sas_device *(*alloc_dev)(struct domain_device *device); + void (*sl_notify_ssp)(struct hisi_hba *hisi_hba, int phy_no); +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -184,7 +184,14 @@ static void hisi_sas_slot_index_clear(st + + static void hisi_sas_slot_index_free(struct hisi_hba *hisi_hba, int slot_idx) + { +- hisi_sas_slot_index_clear(hisi_hba, slot_idx); ++ unsigned long flags; ++ ++ if (hisi_hba->hw->slot_index_alloc || (slot_idx >= ++ hisi_hba->hw->max_command_entries - HISI_SAS_RESERVED_IPTT_CNT)) { ++ spin_lock_irqsave(&hisi_hba->lock, flags); ++ hisi_sas_slot_index_clear(hisi_hba, slot_idx); ++ spin_unlock_irqrestore(&hisi_hba->lock, flags); ++ } + } + + static void hisi_sas_slot_index_set(struct hisi_hba *hisi_hba, int slot_idx) +@@ -194,24 +201,34 @@ static void hisi_sas_slot_index_set(stru + set_bit(slot_idx, bitmap); + } + +-static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, int *slot_idx) ++static int hisi_sas_slot_index_alloc(struct hisi_hba *hisi_hba, ++ struct scsi_cmnd *scsi_cmnd) + { +- unsigned int index; ++ int index; + void *bitmap = hisi_hba->slot_index_tags; ++ unsigned long flags; + ++ if (scsi_cmnd) ++ return scsi_cmnd->request->tag; ++ ++ spin_lock_irqsave(&hisi_hba->lock, flags); + index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count, +- hisi_hba->last_slot_index + 1); ++ hisi_hba->last_slot_index + 1); + if (index >= hisi_hba->slot_index_count) { +- index = find_next_zero_bit(bitmap, hisi_hba->slot_index_count, +- 0); +- if (index >= hisi_hba->slot_index_count) ++ index = find_next_zero_bit(bitmap, ++ hisi_hba->slot_index_count, ++ hisi_hba->hw->max_command_entries - ++ HISI_SAS_RESERVED_IPTT_CNT); ++ if (index >= hisi_hba->slot_index_count) { ++ spin_unlock_irqrestore(&hisi_hba->lock, flags); + return -SAS_QUEUE_FULL; ++ } + } + hisi_sas_slot_index_set(hisi_hba, index); +- *slot_idx = index; + hisi_hba->last_slot_index = index; ++ spin_unlock_irqrestore(&hisi_hba->lock, flags); + +- return 0; ++ return index; + } + + static void hisi_sas_slot_index_init(struct hisi_hba *hisi_hba) +@@ -250,9 +267,7 @@ void hisi_sas_slot_task_free(struct hisi + + memset(slot, 0, offsetof(struct hisi_sas_slot, buf)); + +- spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_slot_index_free(hisi_hba, slot->idx); +- spin_unlock_irqrestore(&hisi_hba->lock, flags); + } + EXPORT_SYMBOL_GPL(hisi_sas_slot_task_free); + +@@ -385,16 +400,27 @@ static int hisi_sas_task_prep(struct sas + goto err_out_dma_unmap; + } + +- spin_lock_irqsave(&hisi_hba->lock, flags); + if (hisi_hba->hw->slot_index_alloc) +- rc = hisi_hba->hw->slot_index_alloc(hisi_hba, &slot_idx, +- device); +- else +- rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx); +- spin_unlock_irqrestore(&hisi_hba->lock, flags); +- if (rc) ++ rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device); ++ else { ++ struct scsi_cmnd *scsi_cmnd = NULL; ++ ++ if (task->uldd_task) { ++ struct ata_queued_cmd *qc; ++ ++ if (dev_is_sata(device)) { ++ qc = task->uldd_task; ++ scsi_cmnd = qc->scsicmd; ++ } else { ++ scsi_cmnd = task->uldd_task; ++ } ++ } ++ rc = hisi_sas_slot_index_alloc(hisi_hba, scsi_cmnd); ++ } ++ if (rc < 0) + goto err_out_dma_unmap; + ++ slot_idx = rc; + slot = &hisi_hba->slot_info[slot_idx]; + + spin_lock_irqsave(&dq->lock, flags); +@@ -455,9 +481,7 @@ static int hisi_sas_task_prep(struct sas + return 0; + + err_out_tag: +- spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_slot_index_free(hisi_hba, slot_idx); +- spin_unlock_irqrestore(&hisi_hba->lock, flags); + err_out_dma_unmap: + if (!sas_protocol_ata(task->task_proto)) { + if (task->num_scatter) { +@@ -1747,14 +1771,11 @@ hisi_sas_internal_abort_task_exec(struct + port = to_hisi_sas_port(sas_port); + + /* simply get a slot and send abort command */ +- spin_lock_irqsave(&hisi_hba->lock, flags); +- rc = hisi_sas_slot_index_alloc(hisi_hba, &slot_idx); +- if (rc) { +- spin_unlock_irqrestore(&hisi_hba->lock, flags); ++ rc = hisi_sas_slot_index_alloc(hisi_hba, NULL); ++ if (rc < 0) + goto err_out; +- } +- spin_unlock_irqrestore(&hisi_hba->lock, flags); + ++ slot_idx = rc; + slot = &hisi_hba->slot_info[slot_idx]; + + spin_lock_irqsave(&dq->lock, flags_dq); +@@ -1790,7 +1811,6 @@ hisi_sas_internal_abort_task_exec(struct + spin_lock_irqsave(&task->task_state_lock, flags); + task->task_state_flags |= SAS_TASK_AT_INITIATOR; + spin_unlock_irqrestore(&task->task_state_lock, flags); +- + WRITE_ONCE(slot->ready, 1); + /* send abort command to the chip */ + spin_lock_irqsave(&dq->lock, flags); +@@ -1801,9 +1821,7 @@ hisi_sas_internal_abort_task_exec(struct + return 0; + + err_out_tag: +- spin_lock_irqsave(&hisi_hba->lock, flags); + hisi_sas_slot_index_free(hisi_hba, slot_idx); +- spin_unlock_irqrestore(&hisi_hba->lock, flags); + err_out: + dev_err(dev, "internal abort task prep: failed[%d]!\n", rc); + +@@ -2179,6 +2197,8 @@ int hisi_sas_alloc(struct hisi_hba *hisi + hisi_sas_init_mem(hisi_hba); + + hisi_sas_slot_index_init(hisi_hba); ++ hisi_hba->last_slot_index = hisi_hba->hw->max_command_entries - ++ HISI_SAS_RESERVED_IPTT_CNT; + + hisi_hba->wq = create_singlethread_workqueue(dev_name(dev)); + if (!hisi_hba->wq) { +@@ -2382,8 +2402,15 @@ int hisi_sas_probe(struct platform_devic + shost->max_channel = 1; + shost->max_cmd_len = 16; + shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT); +- shost->can_queue = hisi_hba->hw->max_command_entries; +- shost->cmd_per_lun = hisi_hba->hw->max_command_entries; ++ if (hisi_hba->hw->slot_index_alloc) { ++ shost->can_queue = hisi_hba->hw->max_command_entries; ++ shost->cmd_per_lun = hisi_hba->hw->max_command_entries; ++ } else { ++ shost->can_queue = hisi_hba->hw->max_command_entries - ++ HISI_SAS_RESERVED_IPTT_CNT; ++ shost->cmd_per_lun = hisi_hba->hw->max_command_entries - ++ HISI_SAS_RESERVED_IPTT_CNT; ++ } + + sha->sas_ha_name = DRV_NAME; + sha->dev = hisi_hba->dev; +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1807,7 +1807,6 @@ static struct scsi_host_template sht_v1_ + .scan_start = hisi_sas_scan_start, + .change_queue_depth = sas_change_queue_depth, + .bios_param = sas_bios_param, +- .can_queue = 1, + .this_id = -1, + .sg_tablesize = SG_ALL, + .max_sectors = SCSI_DEFAULT_MAX_SECTORS, +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -770,7 +770,7 @@ static u32 hisi_sas_phy_read32(struct hi + + /* This function needs to be protected from pre-emption. */ + static int +-slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba, int *slot_idx, ++slot_index_alloc_quirk_v2_hw(struct hisi_hba *hisi_hba, + struct domain_device *device) + { + int sata_dev = dev_is_sata(device); +@@ -778,6 +778,7 @@ slot_index_alloc_quirk_v2_hw(struct hisi + struct hisi_sas_device *sas_dev = device->lldd_dev; + int sata_idx = sas_dev->sata_idx; + int start, end; ++ unsigned long flags; + + if (!sata_dev) { + /* +@@ -801,6 +802,7 @@ slot_index_alloc_quirk_v2_hw(struct hisi + end = 64 * (sata_idx + 2); + } + ++ spin_lock_irqsave(&hisi_hba->lock, flags); + while (1) { + start = find_next_zero_bit(bitmap, + hisi_hba->slot_index_count, start); +@@ -815,8 +817,8 @@ slot_index_alloc_quirk_v2_hw(struct hisi + } + + set_bit(start, bitmap); +- *slot_idx = start; +- return 0; ++ spin_unlock_irqrestore(&hisi_hba->lock, flags); ++ return start; + } + + static bool sata_index_alloc_v2_hw(struct hisi_hba *hisi_hba, int *idx) +@@ -3558,7 +3560,6 @@ static struct scsi_host_template sht_v2_ + .scan_start = hisi_sas_scan_start, + .change_queue_depth = sas_change_queue_depth, + .bios_param = sas_bios_param, +- .can_queue = 1, + .this_id = -1, + .sg_tablesize = SG_ALL, + .max_sectors = SCSI_DEFAULT_MAX_SECTORS, +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2108,7 +2108,6 @@ static struct scsi_host_template sht_v3_ + .scan_start = hisi_sas_scan_start, + .change_queue_depth = sas_change_queue_depth, + .bios_param = sas_bios_param, +- .can_queue = 1, + .this_id = -1, + .sg_tablesize = SG_ALL, + .max_sectors = SCSI_DEFAULT_MAX_SECTORS, +@@ -2118,6 +2117,7 @@ static struct scsi_host_template sht_v3_ + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, + .shost_attrs = host_attrs, ++ .tag_alloc_policy = BLK_TAG_ALLOC_RR, + }; + + static const struct hisi_sas_hw hisi_sas_v3_hw = { +@@ -2255,8 +2255,10 @@ hisi_sas_v3_probe(struct pci_dev *pdev, + shost->max_channel = 1; + shost->max_cmd_len = 16; + shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT); +- shost->can_queue = hisi_hba->hw->max_command_entries; +- shost->cmd_per_lun = hisi_hba->hw->max_command_entries; ++ shost->can_queue = hisi_hba->hw->max_command_entries - ++ HISI_SAS_RESERVED_IPTT_CNT; ++ shost->cmd_per_lun = hisi_hba->hw->max_command_entries - ++ HISI_SAS_RESERVED_IPTT_CNT; + + sha->sas_ha_name = DRV_NAME; + sha->dev = dev; diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch b/debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch new file mode 100644 index 000000000..440ad1a4a --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch @@ -0,0 +1,54 @@ +From 4fdcfb8a09d75fbabf4454a60001224b89245c82 Mon Sep 17 00:00:00 2001 +From: Xiang Chen <chenxiang66@hisilicon.com> +Date: Mon, 24 Sep 2018 23:06:34 +0800 +Subject: [PATCH 07/31] scsi: hisi_sas: Update v3 hw AIP_LIMIT and + CFG_AGING_TIME register values +Origin: https://git.kernel.org/linus/3bccfba8312762becfb05b35d698ba8cffd440f2 + +Update registers as follows: +- Default value of AIP timer is 1ms, and it is easy for some expanders to + cause IO error. Change the value to max value 65ms to avoid IO error for + those expanders. + +- A CQ completion will be reported by HW when 4 CQs have occurred or the + aging timer expires, whichever happens first. Sor serial IO scenario, it + will still wait 8us for every IO before it is reported. So in the + situation, the performance is poor. So to improve it, change the limit + time to the least value. + For other scenario, it does little affect to the performance. + +Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -127,6 +127,7 @@ + #define PHY_CTRL_RESET_OFF 0 + #define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF) + #define SL_CFG (PORT_BASE + 0x84) ++#define AIP_LIMIT (PORT_BASE + 0x90) + #define SL_CONTROL (PORT_BASE + 0x94) + #define SL_CONTROL_NOTIFY_EN_OFF 0 + #define SL_CONTROL_NOTIFY_EN_MSK (0x1 << SL_CONTROL_NOTIFY_EN_OFF) +@@ -431,6 +432,7 @@ static void init_reg_v3_hw(struct hisi_h + (u32)((1ULL << hisi_hba->queue_count) - 1)); + hisi_sas_write32(hisi_hba, CFG_MAX_TAG, 0xfff0400); + hisi_sas_write32(hisi_hba, HGC_SAS_TXFAIL_RETRY_CTRL, 0x108); ++ hisi_sas_write32(hisi_hba, CFG_AGING_TIME, 0x1); + hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1); + hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1); + hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1); +@@ -495,6 +497,7 @@ static void init_reg_v3_hw(struct hisi_h + hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, 0x32); + /* used for 12G negotiate */ + hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e); ++ hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff); + } + + for (i = 0; i < hisi_hba->queue_count; i++) { diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch b/debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch new file mode 100644 index 000000000..1dbe7390b --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch @@ -0,0 +1,33 @@ +From f27f6edaf4983b00a3c0e2f6ab720cfa3150a147 Mon Sep 17 00:00:00 2001 +From: John Garry <john.garry@huawei.com> +Date: Tue, 16 Oct 2018 23:00:36 +0800 +Subject: [PATCH 08/31] scsi: hisi_sas: Fix spin lock management in + slot_index_alloc_quirk_v2_hw() +Origin: https://git.kernel.org/linus/fe5fb42de36227c1c2dbb1e7403329ec8a915c20 + +Currently a spin_unlock_irqrestore() call is missing on the error path, +so add it. + +Reported-by: Julia Lawall <julia.lawall@lip6.fr> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -806,8 +806,10 @@ slot_index_alloc_quirk_v2_hw(struct hisi + while (1) { + start = find_next_zero_bit(bitmap, + hisi_hba->slot_index_count, start); +- if (start >= end) ++ if (start >= end) { ++ spin_unlock_irqrestore(&hisi_hba->lock, flags); + return -SAS_QUEUE_FULL; ++ } + /* + * SAS IPTT bit0 should be 1, and SATA IPTT bit0 should be 0. + */ diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch b/debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch new file mode 100644 index 000000000..9e466ba4c --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch @@ -0,0 +1,40 @@ +From 59bc5f2f2492ef9949cd723fc98bafa7d8a6c287 Mon Sep 17 00:00:00 2001 +From: Christoph Hellwig <hch@lst.de> +Date: Thu, 18 Oct 2018 15:10:17 +0200 +Subject: [PATCH 09/31] scsi: hisi_sas: use dma_set_mask_and_coherent +Origin: https://git.kernel.org/linus/e4db40e7a1a2cd6af3b6d5f8f3fba15533872398 + +The driver currently uses pci_set_dma_mask despite otherwise using the +generic DMA API. Switch it over to the better generic DMA API. + +Signed-off-by: Christoph Hellwig <hch@lst.de> +Acked-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 13 +++++-------- + 1 file changed, 5 insertions(+), 8 deletions(-) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2199,14 +2199,11 @@ hisi_sas_v3_probe(struct pci_dev *pdev, + if (rc) + goto err_out_disable_device; + +- if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) || +- (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)) { +- if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) || +- (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) { +- dev_err(dev, "No usable DMA addressing method\n"); +- rc = -EIO; +- goto err_out_regions; +- } ++ if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) || ++ dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) { ++ dev_err(dev, "No usable DMA addressing method\n"); ++ rc = -EIO; ++ goto err_out_regions; + } + + shost = hisi_sas_shost_alloc_pci(pdev); diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch b/debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch new file mode 100644 index 000000000..5bbf33aa2 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch @@ -0,0 +1,116 @@ +From 4e63bca6e8c3a7fac800ee6c27f9afab13774fde Mon Sep 17 00:00:00 2001 +From: Xiang Chen <chenxiang66@hisilicon.com> +Date: Fri, 9 Nov 2018 22:06:32 +0800 +Subject: [PATCH 10/31] scsi: hisi_sas: Create separate host attributes per HBA +Origin: https://git.kernel.org/linus/c3566f9a617de3288739fd3b8e7539951bf2b04d + +Currently all the three HBA (v1/v2/v3 HW) share the same host attributes. + +To support each HBA having separate attributes in future, create per-HBA +attributes. + +Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas.h | 1 - + drivers/scsi/hisi_sas/hisi_sas_main.c | 6 ------ + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 7 ++++++- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 7 ++++++- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 7 ++++++- + 5 files changed, 18 insertions(+), 10 deletions(-) + +--- a/drivers/scsi/hisi_sas/hisi_sas.h ++++ b/drivers/scsi/hisi_sas/hisi_sas.h +@@ -468,7 +468,6 @@ extern int hisi_sas_remove(struct platfo + extern int hisi_sas_slave_configure(struct scsi_device *sdev); + extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time); + extern void hisi_sas_scan_start(struct Scsi_Host *shost); +-extern struct device_attribute *host_attrs[]; + extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type); + extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy); + extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2021,12 +2021,6 @@ EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets + struct scsi_transport_template *hisi_sas_stt; + EXPORT_SYMBOL_GPL(hisi_sas_stt); + +-struct device_attribute *host_attrs[] = { +- &dev_attr_phy_event_threshold, +- NULL, +-}; +-EXPORT_SYMBOL_GPL(host_attrs); +- + static struct sas_domain_function_template hisi_sas_transport_ops = { + .lldd_dev_found = hisi_sas_dev_found, + .lldd_dev_gone = hisi_sas_dev_gone, +--- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1797,6 +1797,11 @@ static int hisi_sas_v1_init(struct hisi_ + return 0; + } + ++static struct device_attribute *host_attrs_v1_hw[] = { ++ &dev_attr_phy_event_threshold, ++ NULL ++}; ++ + static struct scsi_host_template sht_v1_hw = { + .name = DRV_NAME, + .module = THIS_MODULE, +@@ -1816,7 +1821,7 @@ static struct scsi_host_template sht_v1_ + .slave_alloc = sas_slave_alloc, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, +- .shost_attrs = host_attrs, ++ .shost_attrs = host_attrs_v1_hw, + }; + + static const struct hisi_sas_hw hisi_sas_v1_hw = { +--- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3552,6 +3552,11 @@ static void wait_cmds_complete_timeout_v + dev_dbg(dev, "wait commands complete %dms\n", time); + } + ++struct device_attribute *host_attrs_v2_hw[] = { ++ &dev_attr_phy_event_threshold, ++ NULL ++}; ++ + static struct scsi_host_template sht_v2_hw = { + .name = DRV_NAME, + .module = THIS_MODULE, +@@ -3571,7 +3576,7 @@ static struct scsi_host_template sht_v2_ + .slave_alloc = sas_slave_alloc, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, +- .shost_attrs = host_attrs, ++ .shost_attrs = host_attrs_v2_hw, + }; + + static const struct hisi_sas_hw hisi_sas_v2_hw = { +--- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2101,6 +2101,11 @@ static void wait_cmds_complete_timeout_v + dev_dbg(dev, "wait commands complete %dms\n", time); + } + ++struct device_attribute *host_attrs_v3_hw[] = { ++ &dev_attr_phy_event_threshold, ++ NULL ++}; ++ + static struct scsi_host_template sht_v3_hw = { + .name = DRV_NAME, + .module = THIS_MODULE, +@@ -2120,7 +2125,7 @@ static struct scsi_host_template sht_v3_ + .slave_alloc = sas_slave_alloc, + .target_destroy = sas_target_destroy, + .ioctl = sas_ioctl, +- .shost_attrs = host_attrs, ++ .shost_attrs = host_attrs_v3_hw, + .tag_alloc_policy = BLK_TAG_ALLOC_RR, + }; + diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch b/debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch new file mode 100644 index 000000000..ae1b2d718 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch @@ -0,0 +1,113 @@ +From 7e5e4c2dfd67e156956e46c4d503466726a5359c Mon Sep 17 00:00:00 2001 +From: Xiang Chen <chenxiang66@hisilicon.com> +Date: Fri, 9 Nov 2018 22:06:33 +0800 +Subject: [PATCH 11/31] scsi: hisi_sas: Add support for interrupt converge for + v3 hw +Origin: https://git.kernel.org/linus/488cf558e3d7c95daf737d9cae165019ee3f2840 + +If CQ_INT_CONVERGE_EN is enabled, the interrupts of all the 16 CQ queues +will be reported by CQ0. + +So we need to change the process of CQ tasklet for this situation. + +Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 29 +++++++++++++++++++++----- + 1 file changed, 24 insertions(+), 5 deletions(-) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -42,6 +42,7 @@ + #define MAX_CON_TIME_LIMIT_TIME 0xa4 + #define BUS_INACTIVE_LIMIT_TIME 0xa8 + #define REJECT_TO_OPEN_LIMIT_TIME 0xac ++#define CQ_INT_CONVERGE_EN 0xb0 + #define CFG_AGING_TIME 0xbc + #define HGC_DFX_CFG2 0xc0 + #define CFG_ABT_SET_QUERY_IPTT 0xd4 +@@ -371,6 +372,9 @@ struct hisi_sas_err_record_v3 { + ((fis.command == ATA_CMD_DEV_RESET) && \ + ((fis.control & ATA_SRST) != 0))) + ++static bool hisi_sas_intr_conv; ++MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)"); ++ + static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) + { + void __iomem *regs = hisi_hba->regs + off; +@@ -436,6 +440,8 @@ static void init_reg_v3_hw(struct hisi_h + hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1); + hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1); + hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1); ++ hisi_sas_write32(hisi_hba, CQ_INT_CONVERGE_EN, ++ hisi_sas_intr_conv); + hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff); + hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff); +@@ -1878,10 +1884,12 @@ static int interrupt_init_v3_hw(struct h + for (i = 0; i < hisi_hba->queue_count; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; + struct tasklet_struct *t = &cq->tasklet; ++ int nr = hisi_sas_intr_conv ? 16 : 16 + i; ++ unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0; + +- rc = devm_request_irq(dev, pci_irq_vector(pdev, i+16), +- cq_interrupt_v3_hw, 0, +- DRV_NAME " cq", cq); ++ rc = devm_request_irq(dev, pci_irq_vector(pdev, nr), ++ cq_interrupt_v3_hw, irqflags, ++ DRV_NAME " cq", cq); + if (rc) { + dev_err(dev, + "could not request cq%d interrupt, rc=%d\n", +@@ -1898,8 +1906,9 @@ static int interrupt_init_v3_hw(struct h + free_cq_irqs: + for (k = 0; k < i; k++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[k]; ++ int nr = hisi_sas_intr_conv ? 16 : 16 + k; + +- free_irq(pci_irq_vector(pdev, k+16), cq); ++ free_irq(pci_irq_vector(pdev, nr), cq); + } + free_irq(pci_irq_vector(pdev, 11), hisi_hba); + free_chnl_interrupt: +@@ -2089,8 +2098,16 @@ static void wait_cmds_complete_timeout_v + dev_dbg(dev, "wait commands complete %dms\n", time); + } + ++static ssize_t intr_conv_v3_hw_show(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return scnprintf(buf, PAGE_SIZE, "%u\n", hisi_sas_intr_conv); ++} ++static DEVICE_ATTR_RO(intr_conv_v3_hw); ++ + struct device_attribute *host_attrs_v3_hw[] = { + &dev_attr_phy_event_threshold, ++ &dev_attr_intr_conv_v3_hw, + NULL + }; + +@@ -2303,8 +2320,9 @@ hisi_sas_v3_destroy_irqs(struct pci_dev + free_irq(pci_irq_vector(pdev, 11), hisi_hba); + for (i = 0; i < hisi_hba->queue_count; i++) { + struct hisi_sas_cq *cq = &hisi_hba->cq[i]; ++ int nr = hisi_sas_intr_conv ? 16 : 16 + i; + +- free_irq(pci_irq_vector(pdev, i+16), cq); ++ free_irq(pci_irq_vector(pdev, nr), cq); + } + pci_free_irq_vectors(pdev); + } +@@ -2626,6 +2644,7 @@ static struct pci_driver sas_v3_pci_driv + }; + + module_pci_driver(sas_v3_pci_driver); ++module_param_named(intr_conv, hisi_sas_intr_conv, bool, 0444); + + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("John Garry <john.garry@huawei.com>"); diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch b/debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch new file mode 100644 index 000000000..4595633a2 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch @@ -0,0 +1,150 @@ +From 20ca5e4f2c4a2c08340225f074c56f7be1c86f5b Mon Sep 17 00:00:00 2001 +From: Xiang Chen <chenxiang66@hisilicon.com> +Date: Fri, 9 Nov 2018 22:06:34 +0800 +Subject: [PATCH 12/31] scsi: hisi_sas: Add support for interrupt coalescing + for v3 hw +Origin: https://git.kernel.org/linus/37359798ec44ae03fab383a9bef3b7c9df819063 + +If INT_COAL_EN is enabled, configure time and count of interrupt +coalescing. Then if CQ collects count of CQ entries in time, it will +report the interrupt. Or if CQ doesn't collect enough CQ entries in time, +it will report the interrupt at timeout. + +As all the registers are not supported to be changed dynamically, we need +to config those register between disable and enable PHYs. + +Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas.h | 2 + + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 100 +++++++++++++++++++++++++ + 2 files changed, 102 insertions(+) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas.h +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas.h ++++ linux/drivers/scsi/hisi_sas/hisi_sas.h +@@ -322,6 +322,8 @@ struct hisi_hba { + unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)]; + struct work_struct rst_work; + u32 phy_state; ++ u32 intr_coal_ticks; /* Time of interrupt coalesce in us */ ++ u32 intr_coal_count; /* Interrupt count to coalesce */ + }; + + /* Generic HW DMA host memory structures */ +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2105,9 +2105,109 @@ static ssize_t intr_conv_v3_hw_show(stru + } + static DEVICE_ATTR_RO(intr_conv_v3_hw); + ++static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba) ++{ ++ /* config those registers between enable and disable PHYs */ ++ hisi_sas_stop_phys(hisi_hba); ++ ++ if (hisi_hba->intr_coal_ticks == 0 || ++ hisi_hba->intr_coal_count == 0) { ++ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1); ++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1); ++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1); ++ } else { ++ hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3); ++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, ++ hisi_hba->intr_coal_ticks); ++ hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, ++ hisi_hba->intr_coal_count); ++ } ++ phys_init_v3_hw(hisi_hba); ++} ++ ++static ssize_t intr_coal_ticks_v3_hw_show(struct device *dev, ++ struct device_attribute *attr, ++ char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct hisi_hba *hisi_hba = shost_priv(shost); ++ ++ return scnprintf(buf, PAGE_SIZE, "%u\n", ++ hisi_hba->intr_coal_ticks); ++} ++ ++static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev, ++ struct device_attribute *attr, ++ const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct hisi_hba *hisi_hba = shost_priv(shost); ++ u32 intr_coal_ticks; ++ int ret; ++ ++ ret = kstrtou32(buf, 10, &intr_coal_ticks); ++ if (ret) { ++ dev_err(dev, "Input data of interrupt coalesce unmatch\n"); ++ return -EINVAL; ++ } ++ ++ if (intr_coal_ticks >= BIT(24)) { ++ dev_err(dev, "intr_coal_ticks must be less than 2^24!\n"); ++ return -EINVAL; ++ } ++ ++ hisi_hba->intr_coal_ticks = intr_coal_ticks; ++ ++ config_intr_coal_v3_hw(hisi_hba); ++ ++ return count; ++} ++static DEVICE_ATTR_RW(intr_coal_ticks_v3_hw); ++ ++static ssize_t intr_coal_count_v3_hw_show(struct device *dev, ++ struct device_attribute ++ *attr, char *buf) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct hisi_hba *hisi_hba = shost_priv(shost); ++ ++ return scnprintf(buf, PAGE_SIZE, "%u\n", ++ hisi_hba->intr_coal_count); ++} ++ ++static ssize_t intr_coal_count_v3_hw_store(struct device *dev, ++ struct device_attribute ++ *attr, const char *buf, size_t count) ++{ ++ struct Scsi_Host *shost = class_to_shost(dev); ++ struct hisi_hba *hisi_hba = shost_priv(shost); ++ u32 intr_coal_count; ++ int ret; ++ ++ ret = kstrtou32(buf, 10, &intr_coal_count); ++ if (ret) { ++ dev_err(dev, "Input data of interrupt coalesce unmatch\n"); ++ return -EINVAL; ++ } ++ ++ if (intr_coal_count >= BIT(8)) { ++ dev_err(dev, "intr_coal_count must be less than 2^8!\n"); ++ return -EINVAL; ++ } ++ ++ hisi_hba->intr_coal_count = intr_coal_count; ++ ++ config_intr_coal_v3_hw(hisi_hba); ++ ++ return count; ++} ++static DEVICE_ATTR_RW(intr_coal_count_v3_hw); ++ + struct device_attribute *host_attrs_v3_hw[] = { + &dev_attr_phy_event_threshold, + &dev_attr_intr_conv_v3_hw, ++ &dev_attr_intr_coal_ticks_v3_hw, ++ &dev_attr_intr_coal_count_v3_hw, + NULL + }; + diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch b/debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch new file mode 100644 index 000000000..060fbcfb8 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch @@ -0,0 +1,92 @@ +From 22834ed6cec2690817120e960d43bbf76ddfda17 Mon Sep 17 00:00:00 2001 +From: Xiang Chen <chenxiang66@hisilicon.com> +Date: Fri, 9 Nov 2018 22:06:35 +0800 +Subject: [PATCH 13/31] scsi: hisi_sas: Relocate some codes to avoid an unused + check +Origin: https://git.kernel.org/linus/745b6847634c11dda1079d0290781a443eddb4b7 + +In function hisi_sas_task_prep(), we check asd_sas_port, but in function +hisi_sas_task_exec(), we already refer to asd_sas_port by using function +dev_to_hisi_hba() implicitly. So to avoid this possible invalid +dereference, relocate the check to function hisi_sas_task_prep(). + +Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 44 ++++++++++++++------------- + 1 file changed, 23 insertions(+), 21 deletions(-) + +--- a/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ b/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -303,36 +303,19 @@ static int hisi_sas_task_prep(struct sas + int *pass) + { + struct domain_device *device = task->dev; +- struct hisi_hba *hisi_hba; ++ struct hisi_hba *hisi_hba = dev_to_hisi_hba(device); + struct hisi_sas_device *sas_dev = device->lldd_dev; + struct hisi_sas_port *port; + struct hisi_sas_slot *slot; + struct hisi_sas_cmd_hdr *cmd_hdr_base; + struct asd_sas_port *sas_port = device->port; +- struct device *dev; ++ struct device *dev = hisi_hba->dev; + int dlvry_queue_slot, dlvry_queue, rc, slot_idx; + int n_elem = 0, n_elem_req = 0, n_elem_resp = 0; + struct hisi_sas_dq *dq; + unsigned long flags; + int wr_q_index; + +- if (!sas_port) { +- struct task_status_struct *ts = &task->task_status; +- +- ts->resp = SAS_TASK_UNDELIVERED; +- ts->stat = SAS_PHY_DOWN; +- /* +- * libsas will use dev->port, should +- * not call task_done for sata +- */ +- if (device->dev_type != SAS_SATA_DEV) +- task->task_done(task); +- return -ECOMM; +- } +- +- hisi_hba = dev_to_hisi_hba(device); +- dev = hisi_hba->dev; +- + if (DEV_IS_GONE(sas_dev)) { + if (sas_dev) + dev_info(dev, "task prep: device %d not ready\n", +@@ -507,10 +490,29 @@ static int hisi_sas_task_exec(struct sas + u32 rc; + u32 pass = 0; + unsigned long flags; +- struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev); +- struct device *dev = hisi_hba->dev; ++ struct hisi_hba *hisi_hba; ++ struct device *dev; ++ struct domain_device *device = task->dev; ++ struct asd_sas_port *sas_port = device->port; + struct hisi_sas_dq *dq = NULL; + ++ if (!sas_port) { ++ struct task_status_struct *ts = &task->task_status; ++ ++ ts->resp = SAS_TASK_UNDELIVERED; ++ ts->stat = SAS_PHY_DOWN; ++ /* ++ * libsas will use dev->port, should ++ * not call task_done for sata ++ */ ++ if (device->dev_type != SAS_SATA_DEV) ++ task->task_done(task); ++ return -ECOMM; ++ } ++ ++ hisi_hba = dev_to_hisi_hba(device); ++ dev = hisi_hba->dev; ++ + if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) { + /* + * For IOs from upper layer, it may already disable preempt diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch b/debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch new file mode 100644 index 000000000..1f9ed71c0 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch @@ -0,0 +1,429 @@ +From 13dda01985003ca1b930b42bb3927f7522f4ce69 Mon Sep 17 00:00:00 2001 +From: John Garry <john.garry@huawei.com> +Date: Thu, 6 Dec 2018 21:34:40 +0800 +Subject: [PATCH 14/31] scsi: hisi_sas: Fix warnings detected by sparse +Origin: https://git.kernel.org/linus/735bcc77e6ba83e464665cea9041072190ede37e + +This patchset fixes some warnings detected by the sparse tool, like these: +drivers/scsi/hisi_sas/hisi_sas_main.c:1469:52: warning: incorrect type in assignment (different base types) +drivers/scsi/hisi_sas/hisi_sas_main.c:1469:52: expected unsigned short [unsigned] [assigned] [usertype] tag_of_task_to_be_managed +drivers/scsi/hisi_sas/hisi_sas_main.c:1469:52: got restricted __le16 [usertype] <noident> +drivers/scsi/hisi_sas/hisi_sas_main.c:1723:52: warning: incorrect type in assignment (different base types) +drivers/scsi/hisi_sas/hisi_sas_main.c:1723:52: expected unsigned short [unsigned] [assigned] [usertype] tag_of_task_to_be_managed +drivers/scsi/hisi_sas/hisi_sas_main.c:1723:52: got restricted __le16 [usertype] <noident> + +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas.h | 2 +- + drivers/scsi/hisi_sas/hisi_sas_main.c | 6 +-- + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 15 +++--- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 66 +++++++++++++++----------- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 37 +++++++++------ + 5 files changed, 71 insertions(+), 55 deletions(-) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas.h +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas.h ++++ linux/drivers/scsi/hisi_sas/hisi_sas.h +@@ -211,7 +211,7 @@ struct hisi_sas_slot { + /* Do not reorder/change members after here */ + void *buf; + dma_addr_t buf_dma; +- int idx; ++ u16 idx; + }; + + struct hisi_sas_hw { +Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -1463,12 +1463,12 @@ static int hisi_sas_abort_task(struct sa + if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { + struct scsi_cmnd *cmnd = task->uldd_task; + struct hisi_sas_slot *slot = task->lldd_task; +- u32 tag = slot->idx; ++ u16 tag = slot->idx; + int rc2; + + int_to_scsilun(cmnd->device->lun, &lun); + tmf_task.tmf = TMF_ABORT_TASK; +- tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag); ++ tmf_task.tag_of_task_to_be_managed = tag; + + rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun, + &tmf_task); +@@ -1722,7 +1722,7 @@ static int hisi_sas_query_task(struct sa + + int_to_scsilun(cmnd->device->lun, &lun); + tmf_task.tmf = TMF_QUERY_TASK; +- tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag); ++ tmf_task.tag_of_task_to_be_managed = tag; + + rc = hisi_sas_debug_issue_ssp_tmf(device, + lun.scsi_lun, +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -510,6 +510,7 @@ static void setup_itct_v1_hw(struct hisi + struct hisi_sas_itct *itct = &hisi_hba->itct[device_id]; + struct asd_sas_port *sas_port = device->port; + struct hisi_sas_port *port = to_hisi_sas_port(sas_port); ++ u64 sas_addr; + + memset(itct, 0, sizeof(*itct)); + +@@ -534,8 +535,8 @@ static void setup_itct_v1_hw(struct hisi + itct->qw0 = cpu_to_le64(qw0); + + /* qw1 */ +- memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); +- itct->sas_addr = __swab64(itct->sas_addr); ++ memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE); ++ itct->sas_addr = cpu_to_le64(__swab64(sas_addr)); + + /* qw2 */ + itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) | +@@ -561,7 +562,7 @@ static void clear_itct_v1_hw(struct hisi + reg_val &= ~CFG_AGING_TIME_ITCT_REL_MSK; + hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val); + +- qw0 = cpu_to_le64(itct->qw0); ++ qw0 = le64_to_cpu(itct->qw0); + qw0 &= ~ITCT_HDR_VALID_MSK; + itct->qw0 = cpu_to_le64(qw0); + } +@@ -1100,7 +1101,7 @@ static void slot_err_v1_hw(struct hisi_h + case SAS_PROTOCOL_SSP: + { + int error = -1; +- u32 dma_err_type = cpu_to_le32(err_record->dma_err_type); ++ u32 dma_err_type = le32_to_cpu(err_record->dma_err_type); + u32 dma_tx_err_type = ((dma_err_type & + ERR_HDR_DMA_TX_ERR_TYPE_MSK)) >> + ERR_HDR_DMA_TX_ERR_TYPE_OFF; +@@ -1108,9 +1109,9 @@ static void slot_err_v1_hw(struct hisi_h + ERR_HDR_DMA_RX_ERR_TYPE_MSK)) >> + ERR_HDR_DMA_RX_ERR_TYPE_OFF; + u32 trans_tx_fail_type = +- cpu_to_le32(err_record->trans_tx_fail_type); ++ le32_to_cpu(err_record->trans_tx_fail_type); + u32 trans_rx_fail_type = +- cpu_to_le32(err_record->trans_rx_fail_type); ++ le32_to_cpu(err_record->trans_rx_fail_type); + + if (dma_tx_err_type) { + /* dma tx err */ +@@ -1558,7 +1559,7 @@ static irqreturn_t cq_interrupt_v1_hw(in + u32 cmplt_hdr_data; + + complete_hdr = &complete_queue[rd_point]; +- cmplt_hdr_data = cpu_to_le32(complete_hdr->data); ++ cmplt_hdr_data = le32_to_cpu(complete_hdr->data); + idx = (cmplt_hdr_data & CMPLT_HDR_IPTT_MSK) >> + CMPLT_HDR_IPTT_OFF; + slot = &hisi_hba->slot_info[idx]; +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -934,6 +934,7 @@ static void setup_itct_v2_hw(struct hisi + struct domain_device *parent_dev = device->parent; + struct asd_sas_port *sas_port = device->port; + struct hisi_sas_port *port = to_hisi_sas_port(sas_port); ++ u64 sas_addr; + + memset(itct, 0, sizeof(*itct)); + +@@ -966,8 +967,8 @@ static void setup_itct_v2_hw(struct hisi + itct->qw0 = cpu_to_le64(qw0); + + /* qw1 */ +- memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); +- itct->sas_addr = __swab64(itct->sas_addr); ++ memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE); ++ itct->sas_addr = cpu_to_le64(__swab64(sas_addr)); + + /* qw2 */ + if (!dev_is_sata(device)) +@@ -2044,11 +2045,11 @@ static void slot_err_v2_hw(struct hisi_h + struct task_status_struct *ts = &task->task_status; + struct hisi_sas_err_record_v2 *err_record = + hisi_sas_status_buf_addr_mem(slot); +- u32 trans_tx_fail_type = cpu_to_le32(err_record->trans_tx_fail_type); +- u32 trans_rx_fail_type = cpu_to_le32(err_record->trans_rx_fail_type); +- u16 dma_tx_err_type = cpu_to_le16(err_record->dma_tx_err_type); +- u16 sipc_rx_err_type = cpu_to_le16(err_record->sipc_rx_err_type); +- u32 dma_rx_err_type = cpu_to_le32(err_record->dma_rx_err_type); ++ u32 trans_tx_fail_type = le32_to_cpu(err_record->trans_tx_fail_type); ++ u32 trans_rx_fail_type = le32_to_cpu(err_record->trans_rx_fail_type); ++ u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type); ++ u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type); ++ u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type); + int error = -1; + + if (err_phase == 1) { +@@ -2059,8 +2060,7 @@ static void slot_err_v2_hw(struct hisi_h + trans_tx_fail_type); + } else if (err_phase == 2) { + /* error in RX phase, the priority is: DW1 > DW3 > DW2 */ +- error = parse_trans_rx_err_code_v2_hw( +- trans_rx_fail_type); ++ error = parse_trans_rx_err_code_v2_hw(trans_rx_fail_type); + if (error == -1) { + error = parse_dma_rx_err_code_v2_hw( + dma_rx_err_type); +@@ -2358,6 +2358,7 @@ slot_complete_v2_hw(struct hisi_hba *his + &complete_queue[slot->cmplt_queue_slot]; + unsigned long flags; + bool is_internal = slot->is_internal; ++ u32 dw0; + + if (unlikely(!task || !task->lldd_task || !task->dev)) + return -EINVAL; +@@ -2382,8 +2383,9 @@ slot_complete_v2_hw(struct hisi_hba *his + } + + /* Use SAS+TMF status codes */ +- switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK) +- >> CMPLT_HDR_ABORT_STAT_OFF) { ++ dw0 = le32_to_cpu(complete_hdr->dw0); ++ switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >> ++ CMPLT_HDR_ABORT_STAT_OFF) { + case STAT_IO_ABORTED: + /* this io has been aborted by abort command */ + ts->stat = SAS_ABORTED_TASK; +@@ -2408,9 +2410,8 @@ slot_complete_v2_hw(struct hisi_hba *his + break; + } + +- if ((complete_hdr->dw0 & CMPLT_HDR_ERX_MSK) && +- (!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) { +- u32 err_phase = (complete_hdr->dw0 & CMPLT_HDR_ERR_PHASE_MSK) ++ if ((dw0 & CMPLT_HDR_ERX_MSK) && (!(dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) { ++ u32 err_phase = (dw0 & CMPLT_HDR_ERR_PHASE_MSK) + >> CMPLT_HDR_ERR_PHASE_OFF; + u32 *error_info = hisi_sas_status_buf_addr_mem(slot); + +@@ -2526,22 +2527,23 @@ static void prep_ata_v2_hw(struct hisi_h + struct hisi_sas_tmf_task *tmf = slot->tmf; + u8 *buf_cmd; + int has_data = 0, hdr_tag = 0; +- u32 dw1 = 0, dw2 = 0; ++ u32 dw0, dw1 = 0, dw2 = 0; + + /* create header */ + /* dw0 */ +- hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF); ++ dw0 = port->id << CMD_HDR_PORT_OFF; + if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) +- hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF); ++ dw0 |= 3 << CMD_HDR_CMD_OFF; + else +- hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF); ++ dw0 |= 4 << CMD_HDR_CMD_OFF; + + if (tmf && tmf->force_phy) { +- hdr->dw0 |= CMD_HDR_FORCE_PHY_MSK; +- hdr->dw0 |= cpu_to_le32((1 << tmf->phy_id) +- << CMD_HDR_PHY_ID_OFF); ++ dw0 |= CMD_HDR_FORCE_PHY_MSK; ++ dw0 |= (1 << tmf->phy_id) << CMD_HDR_PHY_ID_OFF; + } + ++ hdr->dw0 = cpu_to_le32(dw0); ++ + /* dw1 */ + switch (task->data_dir) { + case DMA_TO_DEVICE: +@@ -3152,20 +3154,24 @@ static void cq_tasklet_v2_hw(unsigned lo + + /* Check for NCQ completion */ + if (complete_hdr->act) { +- u32 act_tmp = complete_hdr->act; ++ u32 act_tmp = le32_to_cpu(complete_hdr->act); + int ncq_tag_count = ffs(act_tmp); ++ u32 dw1 = le32_to_cpu(complete_hdr->dw1); + +- dev_id = (complete_hdr->dw1 & CMPLT_HDR_DEV_ID_MSK) >> ++ dev_id = (dw1 & CMPLT_HDR_DEV_ID_MSK) >> + CMPLT_HDR_DEV_ID_OFF; + itct = &hisi_hba->itct[dev_id]; + + /* The NCQ tags are held in the itct header */ + while (ncq_tag_count) { +- __le64 *ncq_tag = &itct->qw4_15[0]; ++ __le64 *_ncq_tag = &itct->qw4_15[0], __ncq_tag; ++ u64 ncq_tag; + +- ncq_tag_count -= 1; +- iptt = (ncq_tag[ncq_tag_count / 5] +- >> (ncq_tag_count % 5) * 12) & 0xfff; ++ ncq_tag_count--; ++ __ncq_tag = _ncq_tag[ncq_tag_count / 5]; ++ ncq_tag = le64_to_cpu(__ncq_tag); ++ iptt = (ncq_tag >> (ncq_tag_count % 5) * 12) & ++ 0xfff; + + slot = &hisi_hba->slot_info[iptt]; + slot->cmplt_queue_slot = rd_point; +@@ -3176,7 +3182,9 @@ static void cq_tasklet_v2_hw(unsigned lo + ncq_tag_count = ffs(act_tmp); + } + } else { +- iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK; ++ u32 dw1 = le32_to_cpu(complete_hdr->dw1); ++ ++ iptt = dw1 & CMPLT_HDR_IPTT_MSK; + slot = &hisi_hba->slot_info[iptt]; + slot->cmplt_queue_slot = rd_point; + slot->cmplt_queue = queue; +@@ -3552,7 +3560,7 @@ static void wait_cmds_complete_timeout_v + dev_dbg(dev, "wait commands complete %dms\n", time); + } + +-struct device_attribute *host_attrs_v2_hw[] = { ++static struct device_attribute *host_attrs_v2_hw[] = { + &dev_attr_phy_event_threshold, + NULL + }; +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -628,6 +628,7 @@ static void setup_itct_v3_hw(struct hisi + struct domain_device *parent_dev = device->parent; + struct asd_sas_port *sas_port = device->port; + struct hisi_sas_port *port = to_hisi_sas_port(sas_port); ++ u64 sas_addr; + + memset(itct, 0, sizeof(*itct)); + +@@ -660,8 +661,8 @@ static void setup_itct_v3_hw(struct hisi + itct->qw0 = cpu_to_le64(qw0); + + /* qw1 */ +- memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); +- itct->sas_addr = __swab64(itct->sas_addr); ++ memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE); ++ itct->sas_addr = cpu_to_le64(__swab64(sas_addr)); + + /* qw2 */ + if (!dev_is_sata(device)) +@@ -1590,15 +1591,16 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba + &complete_queue[slot->cmplt_queue_slot]; + struct hisi_sas_err_record_v3 *record = + hisi_sas_status_buf_addr_mem(slot); +- u32 dma_rx_err_type = record->dma_rx_err_type; +- u32 trans_tx_fail_type = record->trans_tx_fail_type; ++ u32 dma_rx_err_type = le32_to_cpu(record->dma_rx_err_type); ++ u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type); ++ u32 dw3 = le32_to_cpu(complete_hdr->dw3); + + switch (task->task_proto) { + case SAS_PROTOCOL_SSP: + if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { + ts->residual = trans_tx_fail_type; + ts->stat = SAS_DATA_UNDERRUN; +- } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { ++ } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { + ts->stat = SAS_QUEUE_FULL; + slot->abort = 1; + } else { +@@ -1612,7 +1614,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba + if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { + ts->residual = trans_tx_fail_type; + ts->stat = SAS_DATA_UNDERRUN; +- } else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { ++ } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { + ts->stat = SAS_PHY_DOWN; + slot->abort = 1; + } else { +@@ -1645,6 +1647,7 @@ slot_complete_v3_hw(struct hisi_hba *his + &complete_queue[slot->cmplt_queue_slot]; + unsigned long flags; + bool is_internal = slot->is_internal; ++ u32 dw0, dw1, dw3; + + if (unlikely(!task || !task->lldd_task || !task->dev)) + return -EINVAL; +@@ -1668,11 +1671,14 @@ slot_complete_v3_hw(struct hisi_hba *his + goto out; + } + ++ dw0 = le32_to_cpu(complete_hdr->dw0); ++ dw1 = le32_to_cpu(complete_hdr->dw1); ++ dw3 = le32_to_cpu(complete_hdr->dw3); ++ + /* + * Use SAS+TMF status codes + */ +- switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK) +- >> CMPLT_HDR_ABORT_STAT_OFF) { ++ switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >> CMPLT_HDR_ABORT_STAT_OFF) { + case STAT_IO_ABORTED: + /* this IO has been aborted by abort command */ + ts->stat = SAS_ABORTED_TASK; +@@ -1695,7 +1701,7 @@ slot_complete_v3_hw(struct hisi_hba *his + } + + /* check for erroneous completion */ +- if ((complete_hdr->dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { ++ if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { + u32 *error_info = hisi_sas_status_buf_addr_mem(slot); + + slot_err_v3_hw(hisi_hba, task, slot); +@@ -1704,8 +1710,7 @@ slot_complete_v3_hw(struct hisi_hba *his + "CQ hdr: 0x%x 0x%x 0x%x 0x%x " + "Error info: 0x%x 0x%x 0x%x 0x%x\n", + slot->idx, task, sas_dev->device_id, +- complete_hdr->dw0, complete_hdr->dw1, +- complete_hdr->act, complete_hdr->dw3, ++ dw0, dw1, complete_hdr->act, dw3, + error_info[0], error_info[1], + error_info[2], error_info[3]); + if (unlikely(slot->abort)) +@@ -1803,11 +1808,13 @@ static void cq_tasklet_v3_hw(unsigned lo + while (rd_point != wr_point) { + struct hisi_sas_complete_v3_hdr *complete_hdr; + struct device *dev = hisi_hba->dev; ++ u32 dw1; + int iptt; + + complete_hdr = &complete_queue[rd_point]; ++ dw1 = le32_to_cpu(complete_hdr->dw1); + +- iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK; ++ iptt = dw1 & CMPLT_HDR_IPTT_MSK; + if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) { + slot = &hisi_hba->slot_info[iptt]; + slot->cmplt_queue_slot = rd_point; +@@ -2203,7 +2210,7 @@ static ssize_t intr_coal_count_v3_hw_sto + } + static DEVICE_ATTR_RW(intr_coal_count_v3_hw); + +-struct device_attribute *host_attrs_v3_hw[] = { ++static struct device_attribute *host_attrs_v3_hw[] = { + &dev_attr_phy_event_threshold, + &dev_attr_intr_conv_v3_hw, + &dev_attr_intr_coal_ticks_v3_hw, +@@ -2649,7 +2656,7 @@ static int hisi_sas_v3_suspend(struct pc + struct hisi_hba *hisi_hba = sha->lldd_ha; + struct device *dev = hisi_hba->dev; + struct Scsi_Host *shost = hisi_hba->shost; +- u32 device_state; ++ pci_power_t device_state; + int rc; + + if (!pdev->pm_cap) { +@@ -2695,7 +2702,7 @@ static int hisi_sas_v3_resume(struct pci + struct Scsi_Host *shost = hisi_hba->shost; + struct device *dev = hisi_hba->dev; + unsigned int rc; +- u32 device_state = pdev->current_state; ++ pci_power_t device_state = pdev->current_state; + + dev_warn(dev, "resuming from operating state [D%d]\n", + device_state); diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch b/debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch new file mode 100644 index 000000000..1e44aa3b8 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch @@ -0,0 +1,187 @@ +From 9e9903e8e143c32498565cb49a7aab6081734782 Mon Sep 17 00:00:00 2001 +From: Xiang Chen <chenxiang66@hisilicon.com> +Date: Thu, 6 Dec 2018 21:34:41 +0800 +Subject: [PATCH 15/31] scsi: hisi_sas: Relocate some code to reduce complexity +Origin: https://git.kernel.org/linus/6e1b731b535231e199c7810451c851398afccd33 + +Relocate the codes related to dma_map/unmap in hisi_sas_task_prep() to +reduce complexity, with a view to add DIF/DIX support. + +Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 146 ++++++++++++++++---------- + 1 file changed, 90 insertions(+), 56 deletions(-) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -297,6 +297,90 @@ static void hisi_sas_task_prep_abort(str + device_id, abort_flag, tag_to_abort); + } + ++static void hisi_sas_dma_unmap(struct hisi_hba *hisi_hba, ++ struct sas_task *task, int n_elem, ++ int n_elem_req, int n_elem_resp) ++{ ++ struct device *dev = hisi_hba->dev; ++ ++ if (!sas_protocol_ata(task->task_proto)) { ++ if (task->num_scatter) { ++ if (n_elem) ++ dma_unmap_sg(dev, task->scatter, ++ task->num_scatter, ++ task->data_dir); ++ } else if (task->task_proto & SAS_PROTOCOL_SMP) { ++ if (n_elem_req) ++ dma_unmap_sg(dev, &task->smp_task.smp_req, ++ 1, DMA_TO_DEVICE); ++ if (n_elem_resp) ++ dma_unmap_sg(dev, &task->smp_task.smp_resp, ++ 1, DMA_FROM_DEVICE); ++ } ++ } ++} ++ ++static int hisi_sas_dma_map(struct hisi_hba *hisi_hba, ++ struct sas_task *task, int *n_elem, ++ int *n_elem_req, int *n_elem_resp) ++{ ++ struct device *dev = hisi_hba->dev; ++ int rc; ++ ++ if (sas_protocol_ata(task->task_proto)) { ++ *n_elem = task->num_scatter; ++ } else { ++ unsigned int req_len, resp_len; ++ ++ if (task->num_scatter) { ++ *n_elem = dma_map_sg(dev, task->scatter, ++ task->num_scatter, task->data_dir); ++ if (!*n_elem) { ++ rc = -ENOMEM; ++ goto prep_out; ++ } ++ } else if (task->task_proto & SAS_PROTOCOL_SMP) { ++ *n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req, ++ 1, DMA_TO_DEVICE); ++ if (!*n_elem_req) { ++ rc = -ENOMEM; ++ goto prep_out; ++ } ++ req_len = sg_dma_len(&task->smp_task.smp_req); ++ if (req_len & 0x3) { ++ rc = -EINVAL; ++ goto err_out_dma_unmap; ++ } ++ *n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp, ++ 1, DMA_FROM_DEVICE); ++ if (!*n_elem_resp) { ++ rc = -ENOMEM; ++ goto err_out_dma_unmap; ++ } ++ resp_len = sg_dma_len(&task->smp_task.smp_resp); ++ if (resp_len & 0x3) { ++ rc = -EINVAL; ++ goto err_out_dma_unmap; ++ } ++ } ++ } ++ ++ if (*n_elem > HISI_SAS_SGE_PAGE_CNT) { ++ dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT", ++ *n_elem); ++ rc = -EINVAL; ++ goto err_out_dma_unmap; ++ } ++ return 0; ++ ++err_out_dma_unmap: ++ /* It would be better to call dma_unmap_sg() here, but it's messy */ ++ hisi_sas_dma_unmap(hisi_hba, task, *n_elem, ++ *n_elem_req, *n_elem_resp); ++prep_out: ++ return rc; ++} ++ + static int hisi_sas_task_prep(struct sas_task *task, + struct hisi_sas_dq **dq_pointer, + bool is_tmf, struct hisi_sas_tmf_task *tmf, +@@ -339,49 +423,10 @@ static int hisi_sas_task_prep(struct sas + return -ECOMM; + } + +- if (!sas_protocol_ata(task->task_proto)) { +- unsigned int req_len, resp_len; +- +- if (task->num_scatter) { +- n_elem = dma_map_sg(dev, task->scatter, +- task->num_scatter, task->data_dir); +- if (!n_elem) { +- rc = -ENOMEM; +- goto prep_out; +- } +- } else if (task->task_proto & SAS_PROTOCOL_SMP) { +- n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req, +- 1, DMA_TO_DEVICE); +- if (!n_elem_req) { +- rc = -ENOMEM; +- goto prep_out; +- } +- req_len = sg_dma_len(&task->smp_task.smp_req); +- if (req_len & 0x3) { +- rc = -EINVAL; +- goto err_out_dma_unmap; +- } +- n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp, +- 1, DMA_FROM_DEVICE); +- if (!n_elem_resp) { +- rc = -ENOMEM; +- goto err_out_dma_unmap; +- } +- resp_len = sg_dma_len(&task->smp_task.smp_resp); +- if (resp_len & 0x3) { +- rc = -EINVAL; +- goto err_out_dma_unmap; +- } +- } +- } else +- n_elem = task->num_scatter; +- +- if (n_elem > HISI_SAS_SGE_PAGE_CNT) { +- dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT", +- n_elem); +- rc = -EINVAL; +- goto err_out_dma_unmap; +- } ++ rc = hisi_sas_dma_map(hisi_hba, task, &n_elem, ++ &n_elem_req, &n_elem_resp); ++ if (rc < 0) ++ goto prep_out; + + if (hisi_hba->hw->slot_index_alloc) + rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device); +@@ -466,19 +511,8 @@ static int hisi_sas_task_prep(struct sas + err_out_tag: + hisi_sas_slot_index_free(hisi_hba, slot_idx); + err_out_dma_unmap: +- if (!sas_protocol_ata(task->task_proto)) { +- if (task->num_scatter) { +- dma_unmap_sg(dev, task->scatter, task->num_scatter, +- task->data_dir); +- } else if (task->task_proto & SAS_PROTOCOL_SMP) { +- if (n_elem_req) +- dma_unmap_sg(dev, &task->smp_task.smp_req, +- 1, DMA_TO_DEVICE); +- if (n_elem_resp) +- dma_unmap_sg(dev, &task->smp_task.smp_resp, +- 1, DMA_FROM_DEVICE); +- } +- } ++ hisi_sas_dma_unmap(hisi_hba, task, n_elem, ++ n_elem_req, n_elem_resp); + prep_out: + dev_err(dev, "task prep: failed[%d]!\n", rc); + return rc; diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch b/debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch new file mode 100644 index 000000000..e025687be --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch @@ -0,0 +1,82 @@ +From 8baf75dd36d8e311434162c6a2c74a45262dc0d4 Mon Sep 17 00:00:00 2001 +From: Xiang Chen <chenxiang66@hisilicon.com> +Date: Thu, 6 Dec 2018 21:34:42 +0800 +Subject: [PATCH 16/31] scsi: hisi_sas: Make sg_tablesize consistent value +Origin: https://git.kernel.org/linus/6db831f4ef764ca19d7300d56ab9455af3cb930d + +Sht->sg_tablesize is set in the driver, and it will be assigned to +shost->sg_tablesize in SCSI mid-layer. So it is not necessary to assign +shost->sg_table one more time in the driver. + +In addition to the change, change each scsi_host_template.sg_tablesize +to HISI_SAS_SGE_PAGE_CNT instead of SG_ALL. + +Signed-off-by: Xiang Chen <chenxiang66@hisilicon.com> +Signed-off-by: John Garry <john.garry@huawei.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 1 - + drivers/scsi/hisi_sas/hisi_sas_v1_hw.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v2_hw.c | 2 +- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 3 +-- + 4 files changed, 3 insertions(+), 5 deletions(-) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2426,7 +2426,6 @@ int hisi_sas_probe(struct platform_devic + shost->max_lun = ~0; + shost->max_channel = 1; + shost->max_cmd_len = 16; +- shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT); + if (hisi_hba->hw->slot_index_alloc) { + shost->can_queue = hisi_hba->hw->max_command_entries; + shost->cmd_per_lun = hisi_hba->hw->max_command_entries; +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +@@ -1814,7 +1814,7 @@ static struct scsi_host_template sht_v1_ + .change_queue_depth = sas_change_queue_depth, + .bios_param = sas_bios_param, + .this_id = -1, +- .sg_tablesize = SG_ALL, ++ .sg_tablesize = HISI_SAS_SGE_PAGE_CNT, + .max_sectors = SCSI_DEFAULT_MAX_SECTORS, + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = sas_eh_device_reset_handler, +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +@@ -3576,7 +3576,7 @@ static struct scsi_host_template sht_v2_ + .change_queue_depth = sas_change_queue_depth, + .bios_param = sas_bios_param, + .this_id = -1, +- .sg_tablesize = SG_ALL, ++ .sg_tablesize = HISI_SAS_SGE_PAGE_CNT, + .max_sectors = SCSI_DEFAULT_MAX_SECTORS, + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = sas_eh_device_reset_handler, +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2229,7 +2229,7 @@ static struct scsi_host_template sht_v3_ + .change_queue_depth = sas_change_queue_depth, + .bios_param = sas_bios_param, + .this_id = -1, +- .sg_tablesize = SG_ALL, ++ .sg_tablesize = HISI_SAS_SGE_PAGE_CNT, + .max_sectors = SCSI_DEFAULT_MAX_SECTORS, + .use_clustering = ENABLE_CLUSTERING, + .eh_device_reset_handler = sas_eh_device_reset_handler, +@@ -2371,7 +2371,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev, + shost->max_lun = ~0; + shost->max_channel = 1; + shost->max_cmd_len = 16; +- shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT); + shost->can_queue = hisi_hba->hw->max_command_entries - + HISI_SAS_RESERVED_IPTT_CNT; + shost->cmd_per_lun = hisi_hba->hw->max_command_entries - diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch b/debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch new file mode 100644 index 000000000..377ee58bd --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch @@ -0,0 +1,43 @@ +From 341487a9b370af5c2566fb0c3fe5384c96bdbda7 Mon Sep 17 00:00:00 2001 +From: Huazhong Tan <tanhuazhong@huawei.com> +Date: Tue, 18 Dec 2018 19:37:52 +0800 +Subject: [PATCH 17/31] net: hns3: remove unnecessary configuration recapture + while resetting +Origin: https://git.kernel.org/linus/b51c366df70da0100193d13975980f1990a2d47b + +When doing reset, it is unnecessary to get the hardware's default +configuration again, otherwise, the user's configuration will be +overwritten. + +Fixes: 4ed340ab8f49 ("net: hns3: Add reset process in hclge_main") +Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com> +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + .../net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 13 ------------- + 1 file changed, 13 deletions(-) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -5814,19 +5814,6 @@ static int hclge_reset_ae_dev(struct hna + return ret; + } + +- ret = hclge_get_cap(hdev); +- if (ret) { +- dev_err(&pdev->dev, "get hw capability error, ret = %d.\n", +- ret); +- return ret; +- } +- +- ret = hclge_configure(hdev); +- if (ret) { +- dev_err(&pdev->dev, "Configure dev error, ret = %d.\n", ret); +- return ret; +- } +- + ret = hclge_map_tqp(hdev); + if (ret) { + dev_err(&pdev->dev, "Map tqp error, ret = %d.\n", ret); diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch b/debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch new file mode 100644 index 000000000..e5141d719 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch @@ -0,0 +1,29 @@ +From 7740fe91e657e23f25e750d9e34da059a6f607ac Mon Sep 17 00:00:00 2001 +From: Fuyun Liang <liangfuyun1@huawei.com> +Date: Tue, 18 Dec 2018 19:37:55 +0800 +Subject: [PATCH 18/31] net: hns3: remove 1000M/half support of phy +Origin: https://git.kernel.org/linus/8362089d787724bb252f13f942921051943369c7 + +Our phy does not support 1000M/half, this patch removes 1000M/half from +PHY_SUPPORTED_FEATURES. + +Signed-off-by: Fuyun Liang <liangfuyun1@huawei.com> +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c +@@ -14,7 +14,7 @@ + SUPPORTED_Asym_Pause | \ + PHY_10BT_FEATURES | \ + PHY_100BT_FEATURES | \ +- PHY_1000BT_FEATURES) ++ SUPPORTED_1000baseT_Full) + + enum hclge_mdio_c22_op_seq { + HCLGE_MDIO_C22_WRITE = 1, diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch b/debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch new file mode 100644 index 000000000..6769afdcf --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch @@ -0,0 +1,32 @@ +From 4f28c6b52ffb62eb5a0a5a85af4fa10658fecee5 Mon Sep 17 00:00:00 2001 +From: Peng Li <lipeng321@huawei.com> +Date: Tue, 18 Dec 2018 19:37:56 +0800 +Subject: [PATCH 19/31] net: hns3: synchronize speed and duplex from phy when + phy link up +Origin: https://git.kernel.org/linus/0ad5ea5dbd6cb1e62bac547db5e61bab15af4f44 + +Driver calls phy_connect_direct and registers hclge_mac_adjust_link +to synchronize mac speed and duplex from phy. It is better to +synchronize mac speed and duplex from phy when phy link up. + +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c | 4 ++++ + 1 file changed, 4 insertions(+) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_mdio.c +@@ -181,6 +181,10 @@ static void hclge_mac_adjust_link(struct + int duplex, speed; + int ret; + ++ /* When phy link down, do nothing */ ++ if (netdev->phydev->link == 0) ++ return; ++ + speed = netdev->phydev->speed; + duplex = netdev->phydev->duplex; + diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch b/debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch new file mode 100644 index 000000000..de4795be4 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch @@ -0,0 +1,157 @@ +From caeef6247aa6f5250d14108b33cef5458ba6c58e Mon Sep 17 00:00:00 2001 +From: Yunsheng Lin <linyunsheng@huawei.com> +Date: Tue, 18 Dec 2018 19:37:57 +0800 +Subject: [PATCH 20/31] net: hns3: getting tx and dv buffer size through + firmware +Origin: https://git.kernel.org/linus/368686be234daf365ef184a6ee1c4a6c18ede3b1 + +This patch adds support of getting tx and dv buffer size through +firmware, because different version of hardware requires different +size of tx and dv buffer. + +This patch also add dv_buf_size to tc' private buffer size even if +pfc is not enable for the tc. + +Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + .../hisilicon/hns3/hns3pf/hclge_cmd.h | 5 ++- + .../hisilicon/hns3/hns3pf/hclge_main.c | 41 ++++++++++++++----- + .../hisilicon/hns3/hns3pf/hclge_main.h | 3 ++ + 3 files changed, 38 insertions(+), 11 deletions(-) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +@@ -365,7 +365,9 @@ struct hclge_pf_res_cmd { + #define HCLGE_PF_VEC_NUM_M GENMASK(7, 0) + __le16 pf_intr_vector_number; + __le16 pf_own_fun_number; +- __le32 rsv[3]; ++ __le16 tx_buf_size; ++ __le16 dv_buf_size; ++ __le32 rsv[2]; + }; + + #define HCLGE_CFG_OFFSET_S 0 +@@ -791,6 +793,7 @@ struct hclge_serdes_lb_cmd { + #define HCLGE_TOTAL_PKT_BUF 0x108000 /* 1.03125M bytes */ + #define HCLGE_DEFAULT_DV 0xA000 /* 40k byte */ + #define HCLGE_DEFAULT_NON_DCB_DV 0x7800 /* 30K byte */ ++#define HCLGE_NON_DCB_ADDITIONAL_BUF 0x200 /* 512 byte */ + + #define HCLGE_TYPE_CRQ 0 + #define HCLGE_TYPE_CSQ 1 +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -931,6 +931,18 @@ static int hclge_query_pf_resource(struc + hdev->num_tqps = __le16_to_cpu(req->tqp_num); + hdev->pkt_buf_size = __le16_to_cpu(req->buf_size) << HCLGE_BUF_UNIT_S; + ++ if (req->tx_buf_size) ++ hdev->tx_buf_size = ++ __le16_to_cpu(req->tx_buf_size) << HCLGE_BUF_UNIT_S; ++ else ++ hdev->tx_buf_size = HCLGE_DEFAULT_TX_BUF; ++ ++ if (req->dv_buf_size) ++ hdev->dv_buf_size = ++ __le16_to_cpu(req->dv_buf_size) << HCLGE_BUF_UNIT_S; ++ else ++ hdev->dv_buf_size = HCLGE_DEFAULT_DV; ++ + if (hnae3_dev_roce_supported(hdev)) { + hdev->roce_base_msix_offset = + hnae3_get_field(__le16_to_cpu(req->msixcap_localid_ba_rocee), +@@ -1591,9 +1603,10 @@ static bool hclge_is_rx_buf_ok(struct h + pfc_enable_num = hclge_get_pfc_enalbe_num(hdev); + + if (hnae3_dev_dcb_supported(hdev)) +- shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_DV; ++ shared_buf_min = 2 * hdev->mps + hdev->dv_buf_size; + else +- shared_buf_min = 2 * hdev->mps + HCLGE_DEFAULT_NON_DCB_DV; ++ shared_buf_min = hdev->mps + HCLGE_NON_DCB_ADDITIONAL_BUF ++ + hdev->dv_buf_size; + + shared_buf_tc = pfc_enable_num * hdev->mps + + (tc_num - pfc_enable_num) * hdev->mps / 2 + +@@ -1606,8 +1619,15 @@ static bool hclge_is_rx_buf_ok(struct h + + shared_buf = rx_all - rx_priv; + buf_alloc->s_buf.buf_size = shared_buf; +- buf_alloc->s_buf.self.high = shared_buf; +- buf_alloc->s_buf.self.low = 2 * hdev->mps; ++ if (hnae3_dev_dcb_supported(hdev)) { ++ buf_alloc->s_buf.self.high = shared_buf - hdev->dv_buf_size; ++ buf_alloc->s_buf.self.low = buf_alloc->s_buf.self.high ++ - hdev->mps / 2; ++ } else { ++ buf_alloc->s_buf.self.high = hdev->mps + ++ HCLGE_NON_DCB_ADDITIONAL_BUF; ++ buf_alloc->s_buf.self.low = hdev->mps / 2; ++ } + + for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { + if ((hdev->hw_tc_map & BIT(i)) && +@@ -1634,11 +1654,11 @@ static int hclge_tx_buffer_calc(struct h + for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { + struct hclge_priv_buf *priv = &buf_alloc->priv_buf[i]; + +- if (total_size < HCLGE_DEFAULT_TX_BUF) ++ if (total_size < hdev->tx_buf_size) + return -ENOMEM; + + if (hdev->hw_tc_map & BIT(i)) +- priv->tx_buf_size = HCLGE_DEFAULT_TX_BUF; ++ priv->tx_buf_size = hdev->tx_buf_size; + else + priv->tx_buf_size = 0; + +@@ -1684,11 +1704,12 @@ static int hclge_rx_buffer_calc(struct h + priv->wl.low = aligned_mps; + priv->wl.high = priv->wl.low + aligned_mps; + priv->buf_size = priv->wl.high + +- HCLGE_DEFAULT_DV; ++ hdev->dv_buf_size; + } else { + priv->wl.low = 0; + priv->wl.high = 2 * aligned_mps; +- priv->buf_size = priv->wl.high; ++ priv->buf_size = priv->wl.high + ++ hdev->dv_buf_size; + } + } else { + priv->enable = 0; +@@ -1720,11 +1741,11 @@ static int hclge_rx_buffer_calc(struct h + if (hdev->tm_info.hw_pfc_map & BIT(i)) { + priv->wl.low = 128; + priv->wl.high = priv->wl.low + aligned_mps; +- priv->buf_size = priv->wl.high + HCLGE_DEFAULT_DV; ++ priv->buf_size = priv->wl.high + hdev->dv_buf_size; + } else { + priv->wl.low = 0; + priv->wl.high = aligned_mps; +- priv->buf_size = priv->wl.high; ++ priv->buf_size = priv->wl.high + hdev->dv_buf_size; + } + } + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +@@ -545,6 +545,9 @@ struct hclge_dev { + u32 flag; + + u32 pkt_buf_size; /* Total pf buf size for tx/rx */ ++ u32 tx_buf_size; /* Tx buffer size for each TC */ ++ u32 dv_buf_size; /* Dv buffer size for each TC */ ++ + u32 mps; /* Max packet size */ + + enum hclge_mta_dmac_sel_type mta_mac_sel_type; diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch b/debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch new file mode 100644 index 000000000..e5c403de9 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch @@ -0,0 +1,144 @@ +From 234c314e892d40daa37e97e9057e04d3e3a0c285 Mon Sep 17 00:00:00 2001 +From: Yunsheng Lin <linyunsheng@huawei.com> +Date: Tue, 18 Dec 2018 19:37:58 +0800 +Subject: [PATCH 21/31] net: hns3: aligning buffer size in SSU to 256 bytes +Origin: https://git.kernel.org/linus/b9a400ac295728b2d47445e09814e1880409b311 + +The hardware expects the buffer size set to SSU is aligned to +256 bytes, this patch aligns the buffer size to 256 byte using +roundup or rounddown function. + +Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + .../hisilicon/hns3/hns3pf/hclge_main.c | 45 ++++++++++++------- + 1 file changed, 28 insertions(+), 17 deletions(-) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -31,6 +31,10 @@ static int hclge_set_mta_filter_mode(str + enum hclge_mta_dmac_sel_type mta_mac_sel, + bool enable); + static int hclge_set_mtu(struct hnae3_handle *handle, int new_mtu); ++ ++#define HCLGE_BUF_SIZE_UNIT 256 ++ ++static int hclge_set_mac_mtu(struct hclge_dev *hdev, int new_mps); + static int hclge_init_vlan_config(struct hclge_dev *hdev); + static int hclge_reset_ae_dev(struct hnae3_ae_dev *ae_dev); + +@@ -937,12 +941,16 @@ static int hclge_query_pf_resource(struc + else + hdev->tx_buf_size = HCLGE_DEFAULT_TX_BUF; + ++ hdev->tx_buf_size = roundup(hdev->tx_buf_size, HCLGE_BUF_SIZE_UNIT); ++ + if (req->dv_buf_size) + hdev->dv_buf_size = + __le16_to_cpu(req->dv_buf_size) << HCLGE_BUF_UNIT_S; + else + hdev->dv_buf_size = HCLGE_DEFAULT_DV; + ++ hdev->dv_buf_size = roundup(hdev->dv_buf_size, HCLGE_BUF_SIZE_UNIT); ++ + if (hnae3_dev_roce_supported(hdev)) { + hdev->roce_base_msix_offset = + hnae3_get_field(__le16_to_cpu(req->msixcap_localid_ba_rocee), +@@ -1595,48 +1603,50 @@ static bool hclge_is_rx_buf_ok(struct h + { + u32 shared_buf_min, shared_buf_tc, shared_std; + int tc_num, pfc_enable_num; +- u32 shared_buf; ++ u32 shared_buf, aligned_mps; + u32 rx_priv; + int i; + + tc_num = hclge_get_tc_num(hdev); + pfc_enable_num = hclge_get_pfc_enalbe_num(hdev); ++ aligned_mps = roundup(hdev->mps, HCLGE_BUF_SIZE_UNIT); + + if (hnae3_dev_dcb_supported(hdev)) +- shared_buf_min = 2 * hdev->mps + hdev->dv_buf_size; ++ shared_buf_min = 2 * aligned_mps + hdev->dv_buf_size; + else +- shared_buf_min = hdev->mps + HCLGE_NON_DCB_ADDITIONAL_BUF ++ shared_buf_min = aligned_mps + HCLGE_NON_DCB_ADDITIONAL_BUF + + hdev->dv_buf_size; + +- shared_buf_tc = pfc_enable_num * hdev->mps + +- (tc_num - pfc_enable_num) * hdev->mps / 2 + +- hdev->mps; ++ shared_buf_tc = pfc_enable_num * aligned_mps + ++ (tc_num - pfc_enable_num) * aligned_mps / 2 + ++ aligned_mps; + shared_std = max_t(u32, shared_buf_min, shared_buf_tc); + + rx_priv = hclge_get_rx_priv_buff_alloced(buf_alloc); + if (rx_all <= rx_priv + shared_std) + return false; + +- shared_buf = rx_all - rx_priv; ++ shared_buf = rounddown(rx_all - rx_priv, HCLGE_BUF_SIZE_UNIT); + buf_alloc->s_buf.buf_size = shared_buf; + if (hnae3_dev_dcb_supported(hdev)) { + buf_alloc->s_buf.self.high = shared_buf - hdev->dv_buf_size; + buf_alloc->s_buf.self.low = buf_alloc->s_buf.self.high +- - hdev->mps / 2; ++ - roundup(aligned_mps / 2, HCLGE_BUF_SIZE_UNIT); + } else { +- buf_alloc->s_buf.self.high = hdev->mps + ++ buf_alloc->s_buf.self.high = aligned_mps + + HCLGE_NON_DCB_ADDITIONAL_BUF; +- buf_alloc->s_buf.self.low = hdev->mps / 2; ++ buf_alloc->s_buf.self.low = ++ roundup(aligned_mps / 2, HCLGE_BUF_SIZE_UNIT); + } + + for (i = 0; i < HCLGE_MAX_TC_NUM; i++) { + if ((hdev->hw_tc_map & BIT(i)) && + (hdev->tm_info.hw_pfc_map & BIT(i))) { +- buf_alloc->s_buf.tc_thrd[i].low = hdev->mps; +- buf_alloc->s_buf.tc_thrd[i].high = 2 * hdev->mps; ++ buf_alloc->s_buf.tc_thrd[i].low = aligned_mps; ++ buf_alloc->s_buf.tc_thrd[i].high = 2 * aligned_mps; + } else { + buf_alloc->s_buf.tc_thrd[i].low = 0; +- buf_alloc->s_buf.tc_thrd[i].high = hdev->mps; ++ buf_alloc->s_buf.tc_thrd[i].high = aligned_mps; + } + } + +@@ -1676,7 +1686,6 @@ static int hclge_tx_buffer_calc(struct h + static int hclge_rx_buffer_calc(struct hclge_dev *hdev, + struct hclge_pkt_buf_alloc *buf_alloc) + { +-#define HCLGE_BUF_SIZE_UNIT 128 + u32 rx_all = hdev->pkt_buf_size, aligned_mps; + int no_pfc_priv_num, pfc_priv_num; + struct hclge_priv_buf *priv; +@@ -1702,9 +1711,11 @@ static int hclge_rx_buffer_calc(struct h + priv->enable = 1; + if (hdev->tm_info.hw_pfc_map & BIT(i)) { + priv->wl.low = aligned_mps; +- priv->wl.high = priv->wl.low + aligned_mps; ++ priv->wl.high = ++ roundup(priv->wl.low + aligned_mps, ++ HCLGE_BUF_SIZE_UNIT); + priv->buf_size = priv->wl.high + +- hdev->dv_buf_size; ++ hdev->dv_buf_size; + } else { + priv->wl.low = 0; + priv->wl.high = 2 * aligned_mps; +@@ -1739,7 +1750,7 @@ static int hclge_rx_buffer_calc(struct h + priv->enable = 1; + + if (hdev->tm_info.hw_pfc_map & BIT(i)) { +- priv->wl.low = 128; ++ priv->wl.low = 256; + priv->wl.high = priv->wl.low + aligned_mps; + priv->buf_size = priv->wl.high + hdev->dv_buf_size; + } else { diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch b/debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch new file mode 100644 index 000000000..26cee78ea --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch @@ -0,0 +1,45 @@ +From 4d887b7901d59b472df97bd8a2f8bdeb43be7ced Mon Sep 17 00:00:00 2001 +From: Yunsheng Lin <linyunsheng@huawei.com> +Date: Tue, 18 Dec 2018 19:37:59 +0800 +Subject: [PATCH 22/31] net: hns3: fix a SSU buffer checking bug +Origin: https://git.kernel.org/linus/af854724e51e4047f534ac6d19b3ef9fb3c35c49 + +When caculating the SSU buffer, it first allocate tx and +rx private buffer, then the remaining buffer is for rx +shared buffer. The remaining buffer size should be at +least bigger than or equal to the shared_std, which is the +minimum shared buffer size required by the driver, but +currently if the remaining buffer size is equal to the +shared_std, it returns failure, which causes SSU buffer +allocation failure problem. + +This patch fixes this problem by rounding up shared_std before +checking the the remaining buffer size bigger than or equal to +the shared_std. + +Fixes: 46a3df9f9718 ("net: hns3: Add HNS3 Acceleration Engine & Compatibility Layer Support") +Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -1620,10 +1620,11 @@ static bool hclge_is_rx_buf_ok(struct h + shared_buf_tc = pfc_enable_num * aligned_mps + + (tc_num - pfc_enable_num) * aligned_mps / 2 + + aligned_mps; +- shared_std = max_t(u32, shared_buf_min, shared_buf_tc); ++ shared_std = roundup(max_t(u32, shared_buf_min, shared_buf_tc), ++ HCLGE_BUF_SIZE_UNIT); + + rx_priv = hclge_get_rx_priv_buff_alloced(buf_alloc); +- if (rx_all <= rx_priv + shared_std) ++ if (rx_all < rx_priv + shared_std) + return false; + + shared_buf = rounddown(rx_all - rx_priv, HCLGE_BUF_SIZE_UNIT); diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch b/debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch new file mode 100644 index 000000000..ad8ccd77f --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch @@ -0,0 +1,30 @@ +From ea3eff7a2ef69730c8e48715fbf965cb9da8b0bc Mon Sep 17 00:00:00 2001 +From: Jian Shen <shenjian15@huawei.com> +Date: Thu, 20 Dec 2018 11:51:59 +0800 +Subject: [PATCH 23/31] net: hns3: change default tc state to close +Origin: https://git.kernel.org/linus/a298797532d9dc244abf349d7c2ed063732c6ba3 + +In original codes, default tc value is set to the max tc. It's more +reasonable to close tc by changing default tc value to 1. Users can +enable it with lldp tool when they want to use tc. + +Signed-off-by: Jian Shen <shenjian15@huawei.com> +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +@@ -1200,7 +1200,7 @@ static int hclge_configure(struct hclge_ + hdev->pfc_max = hdev->tc_max; + } + +- hdev->tm_info.num_tc = hdev->tc_max; ++ hdev->tm_info.num_tc = 1; + + /* Currently not support uncontiuous tc */ + for (i = 0; i < hdev->tm_info.num_tc; i++) diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch b/debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch new file mode 100644 index 000000000..b3c3464ca --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch @@ -0,0 +1,39 @@ +From 0f27af14383edac1efaf140d7cbe2d7dfdab7318 Mon Sep 17 00:00:00 2001 +From: Peng Li <lipeng321@huawei.com> +Date: Thu, 20 Dec 2018 11:52:00 +0800 +Subject: [PATCH 24/31] net: hns3: fix a bug caused by udelay +Origin: https://git.kernel.org/linus/1b7d7b0581173219b82abbd81c88cf8aa7d402c2 + +udelay() in driver may always occupancy processor. If there is only +one cpu in system, the VF driver may initialize fail when insmod +PF and VF driver in the same system. This patch use msleep() to free +cpu when VF wait PF message. + +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_mbx.c +@@ -26,7 +26,7 @@ static int hclgevf_get_mbx_resp(struct h + u8 *resp_data, u16 resp_len) + { + #define HCLGEVF_MAX_TRY_TIMES 500 +-#define HCLGEVF_SLEEP_USCOEND 1000 ++#define HCLGEVF_SLEEP_USECOND 1000 + struct hclgevf_mbx_resp_status *mbx_resp; + u16 r_code0, r_code1; + int i = 0; +@@ -40,7 +40,7 @@ static int hclgevf_get_mbx_resp(struct h + } + + while ((!hdev->mbx_resp.received_resp) && (i < HCLGEVF_MAX_TRY_TIMES)) { +- udelay(HCLGEVF_SLEEP_USCOEND); ++ usleep_range(HCLGEVF_SLEEP_USECOND, HCLGEVF_SLEEP_USECOND * 2); + i++; + } + diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch b/debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch new file mode 100644 index 000000000..2dcf9f2ef --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch @@ -0,0 +1,28 @@ +From 883a7a53d7f6a6494e3a0df73fb02f76ecc42bc1 Mon Sep 17 00:00:00 2001 +From: Peng Li <lipeng321@huawei.com> +Date: Thu, 20 Dec 2018 11:52:06 +0800 +Subject: [PATCH 25/31] net: hns3: remove redundant variable initialization +Origin: https://git.kernel.org/linus/1154bb26c879fea51c20aee167ddce4345caa255 + +This patch removes the redundant variable initialization, +as driver will devm_kzalloc to set value to hdev soon. + +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3vf/hclgevf_main.c +@@ -1360,7 +1360,7 @@ static int hclgevf_configure(struct hclg + static int hclgevf_alloc_hdev(struct hnae3_ae_dev *ae_dev) + { + struct pci_dev *pdev = ae_dev->pdev; +- struct hclgevf_dev *hdev = ae_dev->priv; ++ struct hclgevf_dev *hdev; + + hdev = devm_kzalloc(&pdev->dev, sizeof(*hdev), GFP_KERNEL); + if (!hdev) diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch b/debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch new file mode 100644 index 000000000..9eddea483 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch @@ -0,0 +1,46 @@ +From a4e5945057386872cb9add271aea76ca2413f481 Mon Sep 17 00:00:00 2001 +From: Huazhong Tan <tanhuazhong@huawei.com> +Date: Mon, 31 Dec 2018 10:58:29 +0800 +Subject: [PATCH 26/31] net: hns3: call hns3_nic_net_open() while doing + HNAE3_UP_CLIENT +Origin: https://git.kernel.org/linus/e888402789b9db5de4fcda361331d66dbf0cd9fd + +For HNAE3_DOWN_CLIENT calling hns3_nic_net_stop(), HNAE3_UP_CLIENT +should call hns3_nic_net_open(), since if the number of queue or +the map of TC has is changed before HHAE3_UP_CLIENT is called, +it will cause problem. + +Also the HNS3_NIC_STATE_RESETTING flag needs to be cleared before +hns3_nic_net_open() called, and set it back while hns3_nic_net_open() +failed. + +Fixes: bb6b94a896d4 ("net: hns3: Add reset interface implementation in client") +Signed-off-by: Huazhong Tan <tanhuazhong@huawei.com> +Signed-off-by: Yunsheng Lin <linyunsheng@huawei.com> +Signed-off-by: Peng Li <lipeng321@huawei.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +=================================================================== +--- linux.orig/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c ++++ linux/drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +@@ -3439,11 +3439,15 @@ static int hns3_reset_notify_down_enet(s + static int hns3_reset_notify_up_enet(struct hnae3_handle *handle) + { + struct hnae3_knic_private_info *kinfo = &handle->kinfo; ++ struct hns3_nic_priv *priv = netdev_priv(kinfo->netdev); + int ret = 0; + ++ clear_bit(HNS3_NIC_STATE_RESETTING, &priv->state); ++ + if (netif_running(kinfo->netdev)) { +- ret = hns3_nic_net_up(kinfo->netdev); ++ ret = hns3_nic_net_open(kinfo->netdev); + if (ret) { ++ set_bit(HNS3_NIC_STATE_RESETTING, &priv->state); + netdev_err(kinfo->netdev, + "hns net up fail, ret=%d!\n", ret); + return ret; diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch b/debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch new file mode 100644 index 000000000..48e2022bd --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch @@ -0,0 +1,43 @@ +From 84193e72c505286e4681b3c566c64eea3e25f7fd Mon Sep 17 00:00:00 2001 +From: Lijun Ou <oulijun@huawei.com> +Date: Wed, 12 Dec 2018 17:49:08 +0800 +Subject: [PATCH 29/31] RDMA/hns: Add constraint on the setting of local ACK + timeout +Origin: https://git.kernel.org/linus/44754b95dd35ee07c462b5425ae9c4cde8c7e7c8 + +According to IB protocol, local ACK timeout shall be a 5 bit +value. Currently, hip08 could not support the possible max value 31. Fail +the request in this case. + +Signed-off-by: Yixian Liu <liuyixian@huawei.com> +Signed-off-by: Lijun Ou <oulijun@huawei.com> +Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +Index: linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +=================================================================== +--- linux.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -3398,10 +3398,16 @@ static int modify_qp_rtr_to_rts(struct i + V2_QPC_BYTE_212_LSN_S, 0); + + if (attr_mask & IB_QP_TIMEOUT) { +- roce_set_field(context->byte_28_at_fl, V2_QPC_BYTE_28_AT_M, +- V2_QPC_BYTE_28_AT_S, attr->timeout); +- roce_set_field(qpc_mask->byte_28_at_fl, V2_QPC_BYTE_28_AT_M, +- V2_QPC_BYTE_28_AT_S, 0); ++ if (attr->timeout < 31) { ++ roce_set_field(context->byte_28_at_fl, ++ V2_QPC_BYTE_28_AT_M, V2_QPC_BYTE_28_AT_S, ++ attr->timeout); ++ roce_set_field(qpc_mask->byte_28_at_fl, ++ V2_QPC_BYTE_28_AT_M, V2_QPC_BYTE_28_AT_S, ++ 0); ++ } else { ++ dev_warn(dev, "Local ACK timeout shall be 0 to 30.\n"); ++ } + } + + roce_set_field(context->byte_172_sq_psn, V2_QPC_BYTE_172_SQ_CUR_PSN_M, diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch b/debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch new file mode 100644 index 000000000..612b481ff --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch @@ -0,0 +1,28 @@ +From 454bc02382f8ed2eb3ebc7db4867ed419e3f0241 Mon Sep 17 00:00:00 2001 +From: Lijun Ou <oulijun@huawei.com> +Date: Wed, 12 Dec 2018 17:49:09 +0800 +Subject: [PATCH 30/31] RDMA/hns: Modify the pbl ba page size for hip08 +Origin: https://git.kernel.org/linus/91fb4d83b88a7b544ce564c44167aad29d4154f0 + +Modify the pbl ba page size to 16K for in order to support 4G MR size. + +Signed-off-by: Wei Hu (Xavier) <xavier.huwei@huawei.com> +Signed-off-by: Lijun Ou <oulijun@huawei.com> +Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> +--- + drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +=================================================================== +--- linux.orig/drivers/infiniband/hw/hns/hns_roce_hw_v2.c ++++ linux/drivers/infiniband/hw/hns/hns_roce_hw_v2.c +@@ -1235,7 +1235,7 @@ static int hns_roce_v2_profile(struct hn + caps->mpt_ba_pg_sz = 0; + caps->mpt_buf_pg_sz = 0; + caps->mpt_hop_num = HNS_ROCE_CONTEXT_HOP_NUM; +- caps->pbl_ba_pg_sz = 0; ++ caps->pbl_ba_pg_sz = 2; + caps->pbl_buf_pg_sz = 0; + caps->pbl_hop_num = HNS_ROCE_PBL_HOP_NUM; + caps->mtt_ba_pg_sz = 0; diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch b/debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch new file mode 100644 index 000000000..4f9e5f6be --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch @@ -0,0 +1,63 @@ +From 07a7830061e657ce352e690dbe0a794ffb10d22e Mon Sep 17 00:00:00 2001 +From: Lijun Ou <oulijun@huawei.com> +Date: Sat, 12 Jan 2019 18:36:29 +0800 +Subject: [PATCH 31/31] RDMA/hns: RDMA/hns: Assign rq head pointer when enable + rq record db +Origin: https://git.kernel.org/linus/de77503a59403e7045c18c6bb0a10c245a99b648 + +When flush cqe, it needs to get the pointer of rq and sq from db address +space of user and update it into qp context by modified qp. if rq does not +exist, it will not get the value from db address space of user. + +Signed-off-by: Lijun Ou <oulijun@huawei.com> +Signed-off-by: Jason Gunthorpe <jgg@mellanox.com> +--- + drivers/infiniband/hw/hns/hns_roce_qp.c | 19 ++++++++++--------- + 1 file changed, 10 insertions(+), 9 deletions(-) + +Index: linux/drivers/infiniband/hw/hns/hns_roce_qp.c +=================================================================== +--- linux.orig/drivers/infiniband/hw/hns/hns_roce_qp.c ++++ linux/drivers/infiniband/hw/hns/hns_roce_qp.c +@@ -652,6 +652,10 @@ static int hns_roce_create_qp_common(str + dev_err(dev, "rq record doorbell map failed!\n"); + goto err_sq_dbmap; + } ++ ++ /* indicate kernel supports rq record db */ ++ resp.cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB; ++ hr_qp->rdb_en = 1; + } + } else { + if (init_attr->create_flags & +@@ -760,16 +764,11 @@ static int hns_roce_create_qp_common(str + else + hr_qp->doorbell_qpn = cpu_to_le64(hr_qp->qpn); + +- if (ib_pd->uobject && (udata->outlen >= sizeof(resp)) && +- (hr_dev->caps.flags & HNS_ROCE_CAP_FLAG_RECORD_DB)) { +- +- /* indicate kernel supports rq record db */ +- resp.cap_flags |= HNS_ROCE_SUPPORT_RQ_RECORD_DB; +- ret = ib_copy_to_udata(udata, &resp, sizeof(resp)); ++ if (udata) { ++ ret = ib_copy_to_udata(udata, &resp, ++ min(udata->outlen, sizeof(resp))); + if (ret) + goto err_qp; +- +- hr_qp->rdb_en = 1; + } + hr_qp->event = hns_roce_ib_qp_event; + +@@ -946,7 +945,9 @@ int hns_roce_modify_qp(struct ib_qp *ibq + (attr_mask & IB_QP_STATE) && new_state == IB_QPS_ERR) { + if (hr_qp->sdb_en == 1) { + hr_qp->sq.head = *(int *)(hr_qp->sdb.virt_addr); +- hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr); ++ ++ if (hr_qp->rdb_en == 1) ++ hr_qp->rq.head = *(int *)(hr_qp->rdb.virt_addr); + } else { + dev_warn(dev, "flush cqe is not supported in userspace!\n"); + goto out; diff --git a/debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch b/debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch new file mode 100644 index 000000000..68374aee8 --- /dev/null +++ b/debian/patches/bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch @@ -0,0 +1,70 @@ +From badecc38102204f5297ad6ce1d7c7875e514c6f7 Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke <hare@suse.de> +Date: Mon, 18 Feb 2019 08:34:25 +0100 +Subject: [PATCH] scsi: hisi_sas: fix calls to dma_set_mask_and_coherent() +Origin: https://git.kernel.org/linus/d9a00459effc30f6de2cdd887b64f15c6c54ae71 + +The change to use dma_set_mask_and_coherent() incorrectly made a second +call with the 32 bit DMA mask value when the call with the 64 bit DMA +mask value succeeded. + +[mkp: fixed commit message] + +Fixes: e4db40e7a1a2 ("scsi: hisi_sas: use dma_set_mask_and_coherent") +Cc: <stable@vger.kernel.org> +Suggested-by: Ewan D. Milne <emilne@redhat.com> +Signed-off-by: Hannes Reinecke <hare@suse.com> +Reviewed-by: Christoph Hellwig <hch@lst.de> +Signed-off-by: Hannes Reinecke <hare@suse.com> +Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com> +--- + drivers/scsi/hisi_sas/hisi_sas_main.c | 8 ++++++-- + drivers/scsi/hisi_sas/hisi_sas_v3_hw.c | 8 +++++--- + 2 files changed, 11 insertions(+), 5 deletions(-) + +Index: linux/drivers/scsi/hisi_sas/hisi_sas_main.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_main.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_main.c +@@ -2339,6 +2339,7 @@ static struct Scsi_Host *hisi_sas_shost_ + struct Scsi_Host *shost; + struct hisi_hba *hisi_hba; + struct device *dev = &pdev->dev; ++ int error; + + shost = scsi_host_alloc(hw->sht, sizeof(*hisi_hba)); + if (!shost) { +@@ -2359,8 +2360,11 @@ static struct Scsi_Host *hisi_sas_shost_ + if (hisi_sas_get_fw_info(hisi_hba) < 0) + goto err_out; + +- if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)) && +- dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32))) { ++ error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); ++ if (error) ++ error = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); ++ ++ if (error) { + dev_err(dev, "No usable DMA addressing method\n"); + goto err_out; + } +Index: linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +=================================================================== +--- linux.orig/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c ++++ linux/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +@@ -2328,10 +2328,12 @@ hisi_sas_v3_probe(struct pci_dev *pdev, + if (rc) + goto err_out_disable_device; + +- if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) || +- dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) { ++ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)); ++ if (rc) ++ rc = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); ++ if (rc) { + dev_err(dev, "No usable DMA addressing method\n"); +- rc = -EIO; ++ rc = -ENODEV; + goto err_out_regions; + } + diff --git a/debian/patches/bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch b/debian/patches/bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch new file mode 100644 index 000000000..b45fc948b --- /dev/null +++ b/debian/patches/bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch @@ -0,0 +1,387 @@ +From: Huacai Chen <chenhc@lemote.com> +Date: Tue, 15 Jan 2019 16:04:54 +0800 +Subject: MIPS: Loongson: Introduce and use loongson_llsc_mb() +Origin: https://git.kernel.org/linus/e02e07e3127d8aec1f4bcdfb2fc52a2d99b4859e + +On the Loongson-2G/2H/3A/3B there is a hardware flaw that ll/sc and +lld/scd is very weak ordering. We should add sync instructions "before +each ll/lld" and "at the branch-target between ll/sc" to workaround. +Otherwise, this flaw will cause deadlock occasionally (e.g. when doing +heavy load test with LTP). + +Below is the explaination of CPU designer: + +"For Loongson 3 family, when a memory access instruction (load, store, +or prefetch)'s executing occurs between the execution of LL and SC, the +success or failure of SC is not predictable. Although programmer would +not insert memory access instructions between LL and SC, the memory +instructions before LL in program-order, may dynamically executed +between the execution of LL/SC, so a memory fence (SYNC) is needed +before LL/LLD to avoid this situation. + +Since Loongson-3A R2 (3A2000), we have improved our hardware design to +handle this case. But we later deduce a rarely circumstance that some +speculatively executed memory instructions due to branch misprediction +between LL/SC still fall into the above case, so a memory fence (SYNC) +at branch-target (if its target is not between LL/SC) is needed for +Loongson 3A1000, 3B1500, 3A2000 and 3A3000. + +Our processor is continually evolving and we aim to to remove all these +workaround-SYNCs around LL/SC for new-come processor." + +Here is an example: + +Both cpu1 and cpu2 simutaneously run atomic_add by 1 on same atomic var, +this bug cause both 'sc' run by two cpus (in atomic_add) succeed at same +time('sc' return 1), and the variable is only *added by 1*, sometimes, +which is wrong and unacceptable(it should be added by 2). + +Why disable fix-loongson3-llsc in compiler? +Because compiler fix will cause problems in kernel's __ex_table section. + +This patch fix all the cases in kernel, but: + ++. the fix at the end of futex_atomic_cmpxchg_inatomic is for branch-target +of 'bne', there other cases which smp_mb__before_llsc() and smp_llsc_mb() fix +the ll and branch-target coincidently such as atomic_sub_if_positive/ +cmpxchg/xchg, just like this one. + ++. Loongson 3 does support CONFIG_EDAC_ATOMIC_SCRUB, so no need to touch +edac.h + ++. local_ops and cmpxchg_local should not be affected by this bug since +only the owner can write. + ++. mips_atomic_set for syscall.c is deprecated and rarely used, just let +it go + +Signed-off-by: Huacai Chen <chenhc@lemote.com> +Signed-off-by: Huang Pei <huangpei@loongson.cn> +[paul.burton@mips.com: + - Simplify the addition of -mno-fix-loongson3-llsc to cflags, and add + a comment describing why it's there. + - Make loongson_llsc_mb() a no-op when + CONFIG_CPU_LOONGSON3_WORKAROUNDS=n, rather than a compiler memory + barrier. + - Add a comment describing the bug & how loongson_llsc_mb() helps + in asm/barrier.h.] +Signed-off-by: Paul Burton <paul.burton@mips.com> +Cc: Ralf Baechle <ralf@linux-mips.org> +Cc: ambrosehua@gmail.com +Cc: Steven J . Hill <Steven.Hill@cavium.com> +Cc: linux-mips@linux-mips.org +Cc: Fuxin Zhang <zhangfx@lemote.com> +Cc: Zhangjin Wu <wuzhangjin@gmail.com> +Cc: Li Xuefeng <lixuefeng@loongson.cn> +Cc: Xu Chenghua <xuchenghua@loongson.cn> +--- + arch/mips/Kconfig | 15 +++++++++++++++ + arch/mips/include/asm/atomic.h | 6 ++++++ + arch/mips/include/asm/barrier.h | 36 ++++++++++++++++++++++++++++++++++++ + arch/mips/include/asm/bitops.h | 5 +++++ + arch/mips/include/asm/futex.h | 3 +++ + arch/mips/include/asm/pgtable.h | 2 ++ + arch/mips/loongson64/Platform | 23 +++++++++++++++++++++++ + arch/mips/mm/tlbex.c | 10 ++++++++++ + 8 files changed, 100 insertions(+) + +Index: linux/arch/mips/Kconfig +=================================================================== +--- linux.orig/arch/mips/Kconfig ++++ linux/arch/mips/Kconfig +@@ -1397,6 +1397,21 @@ config LOONGSON3_ENHANCEMENT + please say 'N' here. If you want a high-performance kernel to run on + new Loongson 3 machines only, please say 'Y' here. + ++config CPU_LOONGSON3_WORKAROUNDS ++ bool "Old Loongson 3 LLSC Workarounds" ++ default y if SMP ++ depends on CPU_LOONGSON3 ++ help ++ Loongson 3 processors have the llsc issues which require workarounds. ++ Without workarounds the system may hang unexpectedly. ++ ++ Newer Loongson 3 will fix these issues and no workarounds are needed. ++ The workarounds have no significant side effect on them but may ++ decrease the performance of the system so this option should be ++ disabled unless the kernel is intended to be run on old systems. ++ ++ If unsure, please say Y. ++ + config CPU_LOONGSON2E + bool "Loongson 2E" + depends on SYS_HAS_CPU_LOONGSON2E +Index: linux/arch/mips/include/asm/atomic.h +=================================================================== +--- linux.orig/arch/mips/include/asm/atomic.h ++++ linux/arch/mips/include/asm/atomic.h +@@ -58,6 +58,7 @@ static __inline__ void atomic_##op(int i + if (kernel_uses_llsc) { \ + int temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: ll %0, %1 # atomic_" #op " \n" \ +@@ -84,6 +85,7 @@ static __inline__ int atomic_##op##_retu + if (kernel_uses_llsc) { \ + int temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: ll %1, %2 # atomic_" #op "_return \n" \ +@@ -116,6 +118,7 @@ static __inline__ int atomic_fetch_##op# + if (kernel_uses_llsc) { \ + int temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: ll %1, %2 # atomic_fetch_" #op " \n" \ +@@ -251,6 +254,7 @@ static __inline__ void atomic64_##op(lon + if (kernel_uses_llsc) { \ + long temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: lld %0, %1 # atomic64_" #op " \n" \ +@@ -277,6 +281,7 @@ static __inline__ long atomic64_##op##_r + if (kernel_uses_llsc) { \ + long temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: lld %1, %2 # atomic64_" #op "_return\n" \ +@@ -309,6 +314,7 @@ static __inline__ long atomic64_fetch_## + if (kernel_uses_llsc) { \ + long temp; \ + \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set "MIPS_ISA_LEVEL" \n" \ + "1: lld %1, %2 # atomic64_fetch_" #op "\n" \ +Index: linux/arch/mips/include/asm/barrier.h +=================================================================== +--- linux.orig/arch/mips/include/asm/barrier.h ++++ linux/arch/mips/include/asm/barrier.h +@@ -222,6 +222,42 @@ + #define __smp_mb__before_atomic() __smp_mb__before_llsc() + #define __smp_mb__after_atomic() smp_llsc_mb() + ++/* ++ * Some Loongson 3 CPUs have a bug wherein execution of a memory access (load, ++ * store or pref) in between an ll & sc can cause the sc instruction to ++ * erroneously succeed, breaking atomicity. Whilst it's unusual to write code ++ * containing such sequences, this bug bites harder than we might otherwise ++ * expect due to reordering & speculation: ++ * ++ * 1) A memory access appearing prior to the ll in program order may actually ++ * be executed after the ll - this is the reordering case. ++ * ++ * In order to avoid this we need to place a memory barrier (ie. a sync ++ * instruction) prior to every ll instruction, in between it & any earlier ++ * memory access instructions. Many of these cases are already covered by ++ * smp_mb__before_llsc() but for the remaining cases, typically ones in ++ * which multiple CPUs may operate on a memory location but ordering is not ++ * usually guaranteed, we use loongson_llsc_mb() below. ++ * ++ * This reordering case is fixed by 3A R2 CPUs, ie. 3A2000 models and later. ++ * ++ * 2) If a conditional branch exists between an ll & sc with a target outside ++ * of the ll-sc loop, for example an exit upon value mismatch in cmpxchg() ++ * or similar, then misprediction of the branch may allow speculative ++ * execution of memory accesses from outside of the ll-sc loop. ++ * ++ * In order to avoid this we need a memory barrier (ie. a sync instruction) ++ * at each affected branch target, for which we also use loongson_llsc_mb() ++ * defined below. ++ * ++ * This case affects all current Loongson 3 CPUs. ++ */ ++#ifdef CONFIG_CPU_LOONGSON3_WORKAROUNDS /* Loongson-3's LLSC workaround */ ++#define loongson_llsc_mb() __asm__ __volatile__(__WEAK_LLSC_MB : : :"memory") ++#else ++#define loongson_llsc_mb() do { } while (0) ++#endif ++ + #include <asm-generic/barrier.h> + + #endif /* __ASM_BARRIER_H */ +Index: linux/arch/mips/include/asm/bitops.h +=================================================================== +--- linux.orig/arch/mips/include/asm/bitops.h ++++ linux/arch/mips/include/asm/bitops.h +@@ -68,6 +68,7 @@ static inline void set_bit(unsigned long + : "ir" (1UL << bit), GCC_OFF_SMALL_ASM() (*m)); + #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) + } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " " __LL "%0, %1 # set_bit \n" +@@ -78,6 +79,7 @@ static inline void set_bit(unsigned long + } while (unlikely(!temp)); + #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ + } else if (kernel_uses_llsc) { ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " .set "MIPS_ISA_ARCH_LEVEL" \n" +@@ -120,6 +122,7 @@ static inline void clear_bit(unsigned lo + : "ir" (~(1UL << bit))); + #if defined(CONFIG_CPU_MIPSR2) || defined(CONFIG_CPU_MIPSR6) + } else if (kernel_uses_llsc && __builtin_constant_p(bit)) { ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " " __LL "%0, %1 # clear_bit \n" +@@ -130,6 +133,7 @@ static inline void clear_bit(unsigned lo + } while (unlikely(!temp)); + #endif /* CONFIG_CPU_MIPSR2 || CONFIG_CPU_MIPSR6 */ + } else if (kernel_uses_llsc) { ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " .set "MIPS_ISA_ARCH_LEVEL" \n" +@@ -188,6 +192,7 @@ static inline void change_bit(unsigned l + unsigned long *m = ((unsigned long *) addr) + (nr >> SZLONG_LOG); + unsigned long temp; + ++ loongson_llsc_mb(); + do { + __asm__ __volatile__( + " .set "MIPS_ISA_ARCH_LEVEL" \n" +Index: linux/arch/mips/include/asm/futex.h +=================================================================== +--- linux.orig/arch/mips/include/asm/futex.h ++++ linux/arch/mips/include/asm/futex.h +@@ -50,6 +50,7 @@ + "i" (-EFAULT) \ + : "memory"); \ + } else if (cpu_has_llsc) { \ ++ loongson_llsc_mb(); \ + __asm__ __volatile__( \ + " .set push \n" \ + " .set noat \n" \ +@@ -162,6 +163,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, + "i" (-EFAULT) + : "memory"); + } else if (cpu_has_llsc) { ++ loongson_llsc_mb(); + __asm__ __volatile__( + "# futex_atomic_cmpxchg_inatomic \n" + " .set push \n" +@@ -190,6 +192,7 @@ futex_atomic_cmpxchg_inatomic(u32 *uval, + : GCC_OFF_SMALL_ASM() (*uaddr), "Jr" (oldval), "Jr" (newval), + "i" (-EFAULT) + : "memory"); ++ loongson_llsc_mb(); + } else + return -ENOSYS; + +Index: linux/arch/mips/include/asm/pgtable.h +=================================================================== +--- linux.orig/arch/mips/include/asm/pgtable.h ++++ linux/arch/mips/include/asm/pgtable.h +@@ -229,6 +229,7 @@ static inline void set_pte(pte_t *ptep, + : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) + : [global] "r" (page_global)); + } else if (kernel_uses_llsc) { ++ loongson_llsc_mb(); + __asm__ __volatile__ ( + " .set "MIPS_ISA_ARCH_LEVEL" \n" + " .set push \n" +@@ -244,6 +245,7 @@ static inline void set_pte(pte_t *ptep, + " .set mips0 \n" + : [buddy] "+m" (buddy->pte), [tmp] "=&r" (tmp) + : [global] "r" (page_global)); ++ loongson_llsc_mb(); + } + #else /* !CONFIG_SMP */ + if (pte_none(*buddy)) +Index: linux/arch/mips/loongson64/Platform +=================================================================== +--- linux.orig/arch/mips/loongson64/Platform ++++ linux/arch/mips/loongson64/Platform +@@ -23,6 +23,29 @@ ifdef CONFIG_CPU_LOONGSON2F_WORKAROUNDS + endif + + cflags-$(CONFIG_CPU_LOONGSON3) += -Wa,--trap ++ ++# ++# Some versions of binutils, not currently mainline as of 2019/02/04, support ++# an -mfix-loongson3-llsc flag which emits a sync prior to each ll instruction ++# to work around a CPU bug (see loongson_llsc_mb() in asm/barrier.h for a ++# description). ++# ++# We disable this in order to prevent the assembler meddling with the ++# instruction that labels refer to, ie. if we label an ll instruction: ++# ++# 1: ll v0, 0(a0) ++# ++# ...then with the assembler fix applied the label may actually point at a sync ++# instruction inserted by the assembler, and if we were using the label in an ++# exception table the table would no longer contain the address of the ll ++# instruction. ++# ++# Avoid this by explicitly disabling that assembler behaviour. If upstream ++# binutils does not merge support for the flag then we can revisit & remove ++# this later - for now it ensures vendor toolchains don't cause problems. ++# ++cflags-$(CONFIG_CPU_LOONGSON3) += $(call as-option,-Wa$(comma)-mno-fix-loongson3-llsc,) ++ + # + # binutils from v2.25 on and gcc starting from v4.9.0 treat -march=loongson3a + # as MIPS64 R2; older versions as just R1. This leaves the possibility open +Index: linux/arch/mips/mm/tlbex.c +=================================================================== +--- linux.orig/arch/mips/mm/tlbex.c ++++ linux/arch/mips/mm/tlbex.c +@@ -943,6 +943,8 @@ build_get_pgd_vmalloc64(u32 **p, struct + * to mimic that here by taking a load/istream page + * fault. + */ ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(p, 0); + UASM_i_LA(p, ptr, (unsigned long)tlb_do_page_fault_0); + uasm_i_jr(p, ptr); + +@@ -1663,6 +1665,8 @@ static void + iPTE_LW(u32 **p, unsigned int pte, unsigned int ptr) + { + #ifdef CONFIG_SMP ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(p, 0); + # ifdef CONFIG_PHYS_ADDR_T_64BIT + if (cpu_has_64bits) + uasm_i_lld(p, pte, 0, ptr); +@@ -2276,6 +2280,8 @@ static void build_r4000_tlb_load_handler + #endif + + uasm_l_nopage_tlbl(&l, p); ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(&p, 0); + build_restore_work_registers(&p); + #ifdef CONFIG_CPU_MICROMIPS + if ((unsigned long)tlb_do_page_fault_0 & 1) { +@@ -2330,6 +2336,8 @@ static void build_r4000_tlb_store_handle + #endif + + uasm_l_nopage_tlbs(&l, p); ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(&p, 0); + build_restore_work_registers(&p); + #ifdef CONFIG_CPU_MICROMIPS + if ((unsigned long)tlb_do_page_fault_1 & 1) { +@@ -2385,6 +2393,8 @@ static void build_r4000_tlb_modify_handl + #endif + + uasm_l_nopage_tlbm(&l, p); ++ if (IS_ENABLED(CONFIG_CPU_LOONGSON3_WORKAROUNDS)) ++ uasm_i_sync(&p, 0); + build_restore_work_registers(&p); + #ifdef CONFIG_CPU_MICROMIPS + if ((unsigned long)tlb_do_page_fault_1 & 1) { diff --git a/debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch b/debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch new file mode 100644 index 000000000..45e1252df --- /dev/null +++ b/debian/patches/bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch @@ -0,0 +1,39 @@ +From: Krzysztof Kozlowski <krzk@kernel.org> +Date: Wed, 29 Aug 2018 09:32:23 +0200 +Subject: powerpc/boot: Fix missing crc32poly.h when building with KERNEL_XZ +Origin: https://patchwork.ozlabs.org/patch/963258/ + +After commit faa16bc404d7 ("lib: Use existing define with +polynomial") the lib/xz/xz_crc32.c includes a header from include/linux +directory thus any other user of this code should define proper include +path. + +This fixes the build error on powerpc with CONFIG_KERNEL_XZ: + + In file included from ../arch/powerpc/boot/../../../lib/decompress_unxz.c:233:0, + from ../arch/powerpc/boot/decompress.c:42: + ../arch/powerpc/boot/../../../lib/xz/xz_crc32.c:18:29: fatal error: linux/crc32poly.h: No such file or directory + +Reported-by: Michal Kubecek <mkubecek@suse.cz> +Fixes: faa16bc404d7 ("lib: Use existing define with polynomial") +Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org> +Reported-by: kbuild test robot <lkp@intel.com> +Reported-by: Meelis Roos <mroos@linux.ee> +Tested-by: Michal Kubecek <mkubecek@suse.cz> +--- + arch/powerpc/boot/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/arch/powerpc/boot/Makefile +=================================================================== +--- linux.orig/arch/powerpc/boot/Makefile ++++ linux/arch/powerpc/boot/Makefile +@@ -68,7 +68,7 @@ ifeq ($(call cc-option-yn, -fstack-prote + BOOTCFLAGS += -fno-stack-protector + endif + +-BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj) ++BOOTCFLAGS += -I$(objtree)/$(obj) -I$(srctree)/$(obj) -I$(srctree)/include + + DTC_FLAGS ?= -p 1024 + diff --git a/debian/patches/bugfix/powerpc/powerpc-fix-mcpu-options-for-spe-only-compiler.patch b/debian/patches/bugfix/powerpc/powerpc-fix-mcpu-options-for-spe-only-compiler.patch new file mode 100644 index 000000000..833cf5a3c --- /dev/null +++ b/debian/patches/bugfix/powerpc/powerpc-fix-mcpu-options-for-spe-only-compiler.patch @@ -0,0 +1,42 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 26 Dec 2018 00:00:40 +0000 +Subject: powerpc: Fix -mcpu= options for SPE-only compiler +Forwarded: https://lists.debian.org/debian-kernel/2018/12/msg00295.html + +GCC for Debian's "powerpcspe" architecture only supports 32-bit +SPE targets, and using -mcpu=powerpc or -mcpu=powerpc64 is a fatal +error. + +* Change the test for a biarch compiler to pass both the -m32 and -m64 + options, so that it doesn't catch 32-bit-only compilers +* Add an ifdef CONFIG_PPC64 around the 64-bit CPU option definitions + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +--- a/arch/powerpc/Makefile ++++ b/arch/powerpc/Makefile +@@ -12,7 +12,7 @@ + # Rewritten by Cort Dougan and Paul Mackerras + # + +-HAS_BIARCH := $(call cc-option-yn, -m32) ++HAS_BIARCH := $(call cc-option-yn, -m32 -m64) + + # Set default 32 bits cross compilers for vdso and boot wrapper + CROSS32_COMPILE ?= +@@ -159,6 +159,7 @@ CFLAGS-$(CONFIG_PPC32) += $(call cc-opti + + CFLAGS-$(CONFIG_PPC32) += $(call cc-option,-mno-readonly-in-sdata) + ++ifdef CONFIG_PPC64 + ifdef CONFIG_PPC_BOOK3S_64 + ifdef CONFIG_CPU_LITTLE_ENDIAN + CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=power8 +@@ -170,6 +171,7 @@ endif + else ifdef CONFIG_PPC_BOOK3E_64 + CFLAGS-$(CONFIG_GENERIC_CPU) += -mcpu=powerpc64 + endif ++endif + + ifdef CONFIG_FUNCTION_TRACER + CC_FLAGS_FTRACE := -pg diff --git a/debian/patches/bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch b/debian/patches/bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch new file mode 100644 index 000000000..8fc19da9f --- /dev/null +++ b/debian/patches/bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch @@ -0,0 +1,30 @@ +From: James Clarke <jrtc27@jrtc27.com> +Date: Sun, 18 Feb 2018 15:54:44 +0000 +Subject: powerpc/lib/Makefile: Don't pull in quad.o for 32-bit kernels +Origin: https://people.debian.org/~jrtc27/linux-ppc32/0002-powerpc-lib-Makefile-Don-t-pull-in-quad.o-for-32-bit.patch + +The functions exported by quad.o are only used when guarded by +__powerpc64__ and so are unused on 32-bit kernels. Moreover, their +implementations make use of instructions which will cause an illegal +instruction error on 32-bit processors, and are not accepted by the +assembler for SPE processors. + +Fixes: 31bfdb036f12 ("powerpc: Use instruction emulation infrastructure to handle alignment faults") +Signed-off-by: James Clarke <jrtc27@jrtc27.com> +--- + arch/powerpc/lib/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/arch/powerpc/lib/Makefile +=================================================================== +--- linux.orig/arch/powerpc/lib/Makefile ++++ linux/arch/powerpc/lib/Makefile +@@ -35,7 +35,7 @@ obj64-$(CONFIG_KPROBES_SANITY_TEST) += t + obj-y += checksum_$(BITS).o checksum_wrappers.o \ + string_$(BITS).o memcmp_$(BITS).o + +-obj-y += sstep.o ldstfp.o quad.o ++obj-y += sstep.o ldstfp.o + obj64-y += quad.o + + obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o diff --git a/debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch b/debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch new file mode 100644 index 000000000..8e50801c9 --- /dev/null +++ b/debian/patches/bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch @@ -0,0 +1,132 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 19 Aug 2017 21:42:09 +0100 +Subject: sh: Do not use hyphen in exported variable names +Forwarded: https://marc.info/?l=linux-sh&m=150317827322995&w=2 + +arch/sh/Makefile defines and exports ld-bfd to be used by +arch/sh/boot/Makefile and arch/sh/boot/compressed/Makefile. Similarly +arch/sh/boot/Makefile defines and exports suffix-y to be used by +arch/sh/boot/compressed/Makefile. However some shells, including +dash, will not pass through environment variables whose name includes +a hyphen. Usually GNU make does not use a shell to recurse, but if +e.g. $(srctree) contains '~' it will use a shell here. + +Rename these variables to ld_bfd and suffix_y. + +References: https://buildd.debian.org/status/fetch.php?pkg=linux&arch=sh4&ver=4.13%7Erc5-1%7Eexp1&stamp=1502943967&raw=0 +Fixes: ef9b542fce00 ("sh: bzip2/lzma uImage support.") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + arch/sh/Makefile | 10 +++++----- + arch/sh/boot/Makefile | 16 ++++++++-------- + arch/sh/boot/compressed/Makefile | 6 +++--- + arch/sh/boot/romimage/Makefile | 4 ++-- + 4 files changed, 18 insertions(+), 18 deletions(-) + +Index: linux/arch/sh/Makefile +=================================================================== +--- linux.orig/arch/sh/Makefile ++++ linux/arch/sh/Makefile +@@ -119,16 +119,16 @@ LDFLAGS_vmlinux += --defsym phys_stext= + endif + + ifdef CONFIG_CPU_LITTLE_ENDIAN +-ld-bfd := elf32-$(UTS_MACHINE)-linux +-LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld-bfd) ++ld_bfd := elf32-$(UTS_MACHINE)-linux ++LDFLAGS_vmlinux += --defsym jiffies=jiffies_64 --oformat $(ld_bfd) + KBUILD_LDFLAGS += -EL + else +-ld-bfd := elf32-$(UTS_MACHINE)big-linux +-LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld-bfd) ++ld_bfd := elf32-$(UTS_MACHINE)big-linux ++LDFLAGS_vmlinux += --defsym jiffies=jiffies_64+4 --oformat $(ld_bfd) + KBUILD_LDFLAGS += -EB + endif + +-export ld-bfd BITS ++export ld_bfd BITS + + head-y := arch/sh/kernel/head_$(BITS).o + +Index: linux/arch/sh/boot/Makefile +=================================================================== +--- linux.orig/arch/sh/boot/Makefile ++++ linux/arch/sh/boot/Makefile +@@ -19,12 +19,12 @@ CONFIG_ZERO_PAGE_OFFSET ?= 0x00001000 + CONFIG_ENTRY_OFFSET ?= 0x00001000 + CONFIG_PHYSICAL_START ?= $(CONFIG_MEMORY_START) + +-suffix-y := bin +-suffix-$(CONFIG_KERNEL_GZIP) := gz +-suffix-$(CONFIG_KERNEL_BZIP2) := bz2 +-suffix-$(CONFIG_KERNEL_LZMA) := lzma +-suffix-$(CONFIG_KERNEL_XZ) := xz +-suffix-$(CONFIG_KERNEL_LZO) := lzo ++suffix_y := bin ++suffix_$(CONFIG_KERNEL_GZIP) := gz ++suffix_$(CONFIG_KERNEL_BZIP2) := bz2 ++suffix_$(CONFIG_KERNEL_LZMA) := lzma ++suffix_$(CONFIG_KERNEL_XZ) := xz ++suffix_$(CONFIG_KERNEL_LZO) := lzo + + targets := zImage vmlinux.srec romImage uImage uImage.srec uImage.gz \ + uImage.bz2 uImage.lzma uImage.xz uImage.lzo uImage.bin +@@ -106,10 +106,10 @@ OBJCOPYFLAGS_uImage.srec := -I binary -O + $(obj)/uImage.srec: $(obj)/uImage + $(call if_changed,objcopy) + +-$(obj)/uImage: $(obj)/uImage.$(suffix-y) ++$(obj)/uImage: $(obj)/uImage.$(suffix_y) + @ln -sf $(notdir $<) $@ + @echo ' Image $@ is ready' + + export CONFIG_PAGE_OFFSET CONFIG_MEMORY_START CONFIG_BOOT_LINK_OFFSET \ + CONFIG_PHYSICAL_START CONFIG_ZERO_PAGE_OFFSET CONFIG_ENTRY_OFFSET \ +- KERNEL_MEMORY suffix-y ++ KERNEL_MEMORY suffix_y +Index: linux/arch/sh/boot/compressed/Makefile +=================================================================== +--- linux.orig/arch/sh/boot/compressed/Makefile ++++ linux/arch/sh/boot/compressed/Makefile +@@ -33,7 +33,7 @@ ORIG_CFLAGS := $(KBUILD_CFLAGS) + KBUILD_CFLAGS = $(subst -pg, , $(ORIG_CFLAGS)) + endif + +-LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(IMAGE_OFFSET) -e startup \ ++LDFLAGS_vmlinux := --oformat $(ld_bfd) -Ttext $(IMAGE_OFFSET) -e startup \ + -T $(obj)/../../kernel/vmlinux.lds + + # +@@ -75,7 +75,7 @@ $(obj)/vmlinux.bin.lzo: $(vmlinux.bin.al + + OBJCOPYFLAGS += -R .empty_zero_page + +-LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T ++LDFLAGS_piggy.o := -r --format binary --oformat $(ld_bfd) -T + +-$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix-y) FORCE ++$(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/vmlinux.bin.$(suffix_y) FORCE + $(call if_changed,ld) +Index: linux/arch/sh/boot/romimage/Makefile +=================================================================== +--- linux.orig/arch/sh/boot/romimage/Makefile ++++ linux/arch/sh/boot/romimage/Makefile +@@ -13,7 +13,7 @@ mmcif-obj-$(CONFIG_CPU_SUBTYPE_SH7724) : + load-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-load-y) + obj-$(CONFIG_ROMIMAGE_MMCIF) := $(mmcif-obj-y) + +-LDFLAGS_vmlinux := --oformat $(ld-bfd) -Ttext $(load-y) -e romstart \ ++LDFLAGS_vmlinux := --oformat $(ld_bfd) -Ttext $(load-y) -e romstart \ + -T $(obj)/../../kernel/vmlinux.lds + + $(obj)/vmlinux: $(obj)/head.o $(obj-y) $(obj)/piggy.o FORCE +@@ -24,7 +24,7 @@ OBJCOPYFLAGS += -j .empty_zero_page + $(obj)/zeropage.bin: vmlinux FORCE + $(call if_changed,objcopy) + +-LDFLAGS_piggy.o := -r --format binary --oformat $(ld-bfd) -T ++LDFLAGS_piggy.o := -r --format binary --oformat $(ld_bfd) -T + + $(obj)/piggy.o: $(obj)/vmlinux.scr $(obj)/zeropage.bin arch/sh/boot/zImage FORCE + $(call if_changed,ld) diff --git a/debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch b/debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch new file mode 100644 index 000000000..e8727ef11 --- /dev/null +++ b/debian/patches/bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch @@ -0,0 +1,37 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 22 Jul 2017 17:37:33 +0100 +Subject: perf tools: Fix unwind build on i386 +Forwarded: no + +EINVAL may not be defined when building unwind-libunwind.c with +REMOTE_UNWIND_LIBUNWIND, resulting in a compiler error in +LIBUNWIND__ARCH_REG_ID(). Its only caller, access_reg(), only checks +for a negative return value and doesn't care what it is. So change +-EINVAL to -1. + +Fixes: 52ffe0ff02fc ("Support x86(32-bit) cross platform callchain unwind.") +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + +Index: linux/tools/perf/arch/x86/util/unwind-libunwind.c +=================================================================== +--- linux.orig/tools/perf/arch/x86/util/unwind-libunwind.c ++++ linux/tools/perf/arch/x86/util/unwind-libunwind.c +@@ -67,7 +67,7 @@ int LIBUNWIND__ARCH_REG_ID(int regnum) + break; + default: + pr_err("unwind: invalid reg id %d\n", regnum); +- return -EINVAL; ++ return -1; + } + + return id; +@@ -107,7 +107,7 @@ int LIBUNWIND__ARCH_REG_ID(int regnum) + break; + default: + pr_err("unwind: invalid reg id %d\n", regnum); +- return -EINVAL; ++ return -1; + } + + return id; diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-310-15ikb-to.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-310-15ikb-to.patch new file mode 100644 index 000000000..c9cd5cfc4 --- /dev/null +++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-310-15ikb-to.patch @@ -0,0 +1,37 @@ +From: Sven Rebhan <sven.rebhan@gmail.com> +Date: Tue, 21 Feb 2017 20:53:48 +0100 +Subject: platform/x86: ideapad-laptop: Add IdeaPad 310-15IKB to no_hw_rfkill +Origin: https://git.kernel.org/linus/1f3bc53d843f92d6e7e7cf56ee79acec918e6421 + +Like other Lenovo models the IdeaPad 310-15IKB does not have an hw rfkill +switch. This results in hard-blocked radios after boot, resulting in +always blocked radios rendering them unusable. + +Add the IdeaPad 310-15IKB to the no_hw_rfkill DMI list and allows using +the built-in radios. + +Signed-off-by: Sven Rebhan <Sven.Rebhan@googlemail.com> +[andy: massaged commit message] +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +--- + drivers/platform/x86/ideapad-laptop.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: linux/drivers/platform/x86/ideapad-laptop.c +=================================================================== +--- linux.orig/drivers/platform/x86/ideapad-laptop.c ++++ linux/drivers/platform/x86/ideapad-laptop.c +@@ -1098,6 +1098,13 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo ideapad 310-15IKB", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15IKB"), ++ }, ++ }, ++ { + .ident = "Lenovo ideapad Y700-15ACZ", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v310-15isk-t.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v310-15isk-t.patch new file mode 100644 index 000000000..43a075fea --- /dev/null +++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v310-15isk-t.patch @@ -0,0 +1,35 @@ +From: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Date: Tue, 21 Feb 2017 20:53:48 +0100 +Subject: platform/x86: ideapad-laptop: Add IdeaPad V310-15ISK to no_hw_rfkill +Origin: https://git.kernel.org/linus/ccc7179f4d9467947c94f4302d61cd5143842fcd + +Like other Lenovo models the IdeaPad V310-15ISK does not have an hw +rfkill switch. This results in hard-blocked radios after boot, resulting +in always blocked radios rendering them unusable. + +Add the IdeaPad V310-15ISK to the no_hw_rfkill DMI list and allows using +the built-in radios. + +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +--- + drivers/platform/x86/ideapad-laptop.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: linux/drivers/platform/x86/ideapad-laptop.c +=================================================================== +--- linux.orig/drivers/platform/x86/ideapad-laptop.c ++++ linux/drivers/platform/x86/ideapad-laptop.c +@@ -1098,6 +1098,13 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo V310-15ISK", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V310-15ISK"), ++ }, ++ }, ++ { + .ident = "Lenovo ideapad 310-15IKB", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v510-15ikb-t.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v510-15ikb-t.patch new file mode 100644 index 000000000..f64747726 --- /dev/null +++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v510-15ikb-t.patch @@ -0,0 +1,37 @@ +From: Sven Eckelmann <sven@narfation.org> +Date: Sat, 1 Jul 2017 08:20:18 +0200 +Subject: platform/x86: ideapad-laptop: Add IdeaPad V510-15IKB to no_hw_rfkill +Origin: https://git.kernel.org/linus/0df4b805cbccbe3f8378f49c415adb2fcffdd3dc +Bug-Debian: https://bugs.debian.org/866706 + +Like other Lenovo models the IdeaPad V510-15IKB does not have an hw +rfkill switch. This results in hard-blocked radios after boot, resulting +in always blocked radios rendering them unusable. + +Add the IdeaPad V510-15IKB to the no_hw_rfkill DMI list and allows using +the built-in radios. + +Signed-off-by: Sven Eckelmann <sven@narfation.org> +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +--- + drivers/platform/x86/ideapad-laptop.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: linux/drivers/platform/x86/ideapad-laptop.c +=================================================================== +--- linux.orig/drivers/platform/x86/ideapad-laptop.c ++++ linux/drivers/platform/x86/ideapad-laptop.c +@@ -1105,6 +1105,13 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo V510-15IKB", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V510-15IKB"), ++ }, ++ }, ++ { + .ident = "Lenovo ideapad 310-15IKB", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-several-models-to-no.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-several-models-to-no.patch new file mode 100644 index 000000000..4041cd9a3 --- /dev/null +++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-several-models-to-no.patch @@ -0,0 +1,112 @@ +From: Yang Jiaxun <yjx@flygoat.com> +Date: Tue, 4 Jul 2017 14:39:19 +0000 +Subject: platform/x86: ideapad-laptop: Add several models to no_hw_rfkill +Origin: https://git.kernel.org/linus/710c059c248a24609051f5a3dd1d8468cdc675b0 + +Some Lenovo ideapad models do not have hardware rfkill switches, but +trying to read the rfkill switches through the ideapad-laptop module. +It caused to always reported blocking breaking wifi. + +Fix it by adding those models to no_hw_rfkill_list. + +Signed-off-by: Yang Jiaxun <yjx@flygoat.com> +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +--- + drivers/platform/x86/ideapad-laptop.c | 70 +++++++++++++++++++++++++++++++++++ + 1 file changed, 70 insertions(+) + +Index: linux/drivers/platform/x86/ideapad-laptop.c +=================================================================== +--- linux.orig/drivers/platform/x86/ideapad-laptop.c ++++ linux/drivers/platform/x86/ideapad-laptop.c +@@ -1098,6 +1098,27 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo V310-14IKB", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V310-14IKB"), ++ }, ++ }, ++ { ++ .ident = "Lenovo V310-14ISK", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V310-14ISK"), ++ }, ++ }, ++ { ++ .ident = "Lenovo V310-15IKB", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo V310-15IKB"), ++ }, ++ }, ++ { + .ident = "Lenovo V310-15ISK", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +@@ -1112,6 +1133,41 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo ideapad 300-15IBR", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 300-15IBR"), ++ }, ++ }, ++ { ++ .ident = "Lenovo ideapad 300-15IKB", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 300-15IKB"), ++ }, ++ }, ++ { ++ .ident = "Lenovo ideapad 300S-11IBR", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 300S-11BR"), ++ }, ++ }, ++ { ++ .ident = "Lenovo ideapad 310-15ABR", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15ABR"), ++ }, ++ }, ++ { ++ .ident = "Lenovo ideapad 310-15IAP", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15IAP"), ++ }, ++ }, ++ { + .ident = "Lenovo ideapad 310-15IKB", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), +@@ -1119,6 +1175,20 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo ideapad 310-15ISK", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad 310-15ISK"), ++ }, ++ }, ++ { ++ .ident = "Lenovo ideapad Y700-14ISK", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad Y700-14ISK"), ++ }, ++ }, ++ { + .ident = "Lenovo ideapad Y700-15ACZ", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y520-15ikbn-to-no_hw.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y520-15ikbn-to-no_hw.patch new file mode 100644 index 000000000..0020839df --- /dev/null +++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y520-15ikbn-to-no_hw.patch @@ -0,0 +1,35 @@ +From: Olle Liljenzin <olle@liljenzin.se> +Date: Sun, 18 Jun 2017 13:09:31 +0200 +Subject: platform/x86: ideapad-laptop: Add Y520-15IKBN to no_hw_rfkill +Origin: https://git.kernel.org/linus/5d9f40b56630a8702b5f7a61a770f9b73aa07464 + +Lenovo Legion Y520-15IKBN is yet another Lenovo model that does not +have an hw rfkill switch, resulting in wifi always reported as hard +blocked. + +Add the model to the list of models without rfkill switch. + +Signed-off-by: Olle Liljenzin <olle@liljenzin.se> +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +--- + drivers/platform/x86/ideapad-laptop.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: linux/drivers/platform/x86/ideapad-laptop.c +=================================================================== +--- linux.orig/drivers/platform/x86/ideapad-laptop.c ++++ linux/drivers/platform/x86/ideapad-laptop.c +@@ -1182,6 +1182,13 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo Legion Y520-15IKBN", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y520-15IKBN"), ++ }, ++ }, ++ { + .ident = "Lenovo Yoga 2 11 / 13 / Pro", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y720-15ikbn-to-no_hw.patch b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y720-15ikbn-to-no_hw.patch new file mode 100644 index 000000000..59f3dc3f6 --- /dev/null +++ b/debian/patches/bugfix/x86/platform-x86-ideapad-laptop-add-y720-15ikbn-to-no_hw.patch @@ -0,0 +1,35 @@ +From: Olle Liljenzin <olle@liljenzin.se> +Date: Sun, 18 Jun 2017 14:37:58 +0200 +Subject: platform/x86: ideapad-laptop: Add Y720-15IKBN to no_hw_rfkill +Origin: https://git.kernel.org/linus/b2f2fe205c3b9b595dc50ee431230a45d03f9c2c + +Lenovo Legion Y720-15IKBN is yet another Lenovo model that does not +have an hw rfkill switch, resulting in wifi always reported as hard +blocked. + +Add the model to the list of models without rfkill switch. + +Signed-off-by: Olle Liljenzin <olle@liljenzin.se> +Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +--- + drivers/platform/x86/ideapad-laptop.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: linux/drivers/platform/x86/ideapad-laptop.c +=================================================================== +--- linux.orig/drivers/platform/x86/ideapad-laptop.c ++++ linux/drivers/platform/x86/ideapad-laptop.c +@@ -1189,6 +1189,13 @@ static const struct dmi_system_id no_hw_ + }, + }, + { ++ .ident = "Lenovo Legion Y720-15IKBN", ++ .matches = { ++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), ++ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo Y720-15IKBN"), ++ }, ++ }, ++ { + .ident = "Lenovo Yoga 2 11 / 13 / Pro", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), diff --git a/debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch b/debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch new file mode 100644 index 000000000..e571c91fe --- /dev/null +++ b/debian/patches/bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch @@ -0,0 +1,24 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 25 Sep 2015 22:50:50 +0100 +Subject: Revert "perf build: Fix libunwind feature detection on 32-bit x86" +Forwarded: no + +This reverts commit 05b41775e2edd69a83f592e3534930c934d4038e. +It broke feature detection that was working just fine for us. +--- + tools/perf/Makefile.config | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/tools/perf/Makefile.config +=================================================================== +--- linux.orig/tools/perf/Makefile.config ++++ linux/tools/perf/Makefile.config +@@ -42,7 +42,7 @@ ifeq ($(SRCARCH),x86) + LIBUNWIND_LIBS = -lunwind-x86_64 -lunwind -llzma + $(call detected,CONFIG_X86_64) + else +- LIBUNWIND_LIBS = -lunwind-x86 -llzma -lunwind ++ LIBUNWIND_LIBS = -lunwind -lunwind-x86 + endif + NO_PERF_REGS := 0 + endif diff --git a/debian/patches/bugfix/x86/tools-turbostat-Add-checks-for-failure-of-fgets-and-.patch b/debian/patches/bugfix/x86/tools-turbostat-Add-checks-for-failure-of-fgets-and-.patch new file mode 100644 index 000000000..77b56df47 --- /dev/null +++ b/debian/patches/bugfix/x86/tools-turbostat-Add-checks-for-failure-of-fgets-and-.patch @@ -0,0 +1,114 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 11 Sep 2018 03:07:28 +0100 +Subject: tools: turbostat: Add checks for failure of fgets() and fscanf() +Forwarded: https://marc.info/?l=linux-pm&m=153711036626779 + +Most calls to fgets() and fscanf() are followed by error checks. +Add an exit-on-error in the remaining cases. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + tools/power/x86/turbostat/turbostat.c | 28 +++++++++++++++++---------- + 1 file changed, 18 insertions(+), 10 deletions(-) + +Index: linux/tools/power/x86/turbostat/turbostat.c +=================================================================== +--- linux.orig/tools/power/x86/turbostat/turbostat.c ++++ linux/tools/power/x86/turbostat/turbostat.c +@@ -2554,7 +2554,8 @@ int get_thread_siblings(struct cpu_topol + filep = fopen_or_die(path, "r"); + do { + offset -= BITMASK_SIZE; +- fscanf(filep, "%lx%c", &map, &character); ++ if (fscanf(filep, "%lx%c", &map, &character) != 2) ++ err(1, "%s: failed to parse file", path); + for (shift = 0; shift < BITMASK_SIZE; shift++) { + if ((map >> shift) & 0x1) { + so = shift + offset; +@@ -3407,14 +3408,14 @@ dump_sysfs_cstate_config(void) + input = fopen(path, "r"); + if (input == NULL) + continue; +- fgets(name_buf, sizeof(name_buf), input); ++ if (!fgets(name_buf, sizeof(name_buf), input)) ++ err(1, "%s: failed to read file", path); + + /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ + sp = strchr(name_buf, '-'); + if (!sp) + sp = strchrnul(name_buf, '\n'); + *sp = '\0'; +- + fclose(input); + + sprintf(path, "/sys/devices/system/cpu/cpu%d/cpuidle/state%d/desc", +@@ -3422,7 +3423,8 @@ dump_sysfs_cstate_config(void) + input = fopen(path, "r"); + if (input == NULL) + continue; +- fgets(desc, sizeof(desc), input); ++ if (!fgets(desc, sizeof(desc), input)) ++ err(1, "%s: failed to read file", path); + + fprintf(outf, "cpu%d: %s: %s", base_cpu, name_buf, desc); + fclose(input); +@@ -3444,7 +3446,8 @@ dump_sysfs_pstate_config(void) + fprintf(stderr, "NSFOD %s\n", path); + return; + } +- fgets(driver_buf, sizeof(driver_buf), input); ++ if (!fgets(driver_buf, sizeof(driver_buf), input)) ++ err(1, "%s: failed to read file", path); + fclose(input); + + sprintf(path, "/sys/devices/system/cpu/cpu%d/cpufreq/scaling_governor", +@@ -3454,7 +3457,8 @@ dump_sysfs_pstate_config(void) + fprintf(stderr, "NSFOD %s\n", path); + return; + } +- fgets(governor_buf, sizeof(governor_buf), input); ++ if (!fgets(governor_buf, sizeof(governor_buf), input)) ++ err(1, "%s: failed to read file", path); + fclose(input); + + fprintf(outf, "cpu%d: cpufreq driver: %s", base_cpu, driver_buf); +@@ -3463,7 +3467,8 @@ dump_sysfs_pstate_config(void) + sprintf(path, "/sys/devices/system/cpu/cpufreq/boost"); + input = fopen(path, "r"); + if (input != NULL) { +- fscanf(input, "%d", &turbo); ++ if (fscanf(input, "%d", &turbo) != 1) ++ err(1, "%s: failed to parse number from file", path); + fprintf(outf, "cpufreq boost: %d\n", turbo); + fclose(input); + } +@@ -3471,7 +3476,8 @@ dump_sysfs_pstate_config(void) + sprintf(path, "/sys/devices/system/cpu/intel_pstate/no_turbo"); + input = fopen(path, "r"); + if (input != NULL) { +- fscanf(input, "%d", &turbo); ++ if (fscanf(input, "%d", &turbo) != 1) ++ err(1, "%s: failed to parse number from file", path); + fprintf(outf, "cpufreq intel_pstate no_turbo: %d\n", turbo); + fclose(input); + } +@@ -5296,7 +5302,8 @@ void probe_sysfs(void) + input = fopen(path, "r"); + if (input == NULL) + continue; +- fgets(name_buf, sizeof(name_buf), input); ++ if (!fgets(name_buf, sizeof(name_buf), input)) ++ err(1, "%s: failed to read file", path); + + /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ + sp = strchr(name_buf, '-'); +@@ -5323,7 +5330,8 @@ void probe_sysfs(void) + input = fopen(path, "r"); + if (input == NULL) + continue; +- fgets(name_buf, sizeof(name_buf), input); ++ if (!fgets(name_buf, sizeof(name_buf), input)) ++ err(1, "%s: failed to read file", path); + /* truncate "C1-HSW\n" to "C1", or truncate "C1\n" to "C1" */ + sp = strchr(name_buf, '-'); + if (!sp) diff --git a/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch b/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch new file mode 100644 index 000000000..14df64f35 --- /dev/null +++ b/debian/patches/bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch @@ -0,0 +1,36 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 20 Apr 2013 15:52:02 +0100 +Subject: viafb: Autoload on OLPC XO 1.5 only +Bug-Debian: https://bugs.debian.org/705788 +Forwarded: no + +It appears that viafb won't work automatically on all the boards for +which it has a PCI device ID match. Currently, it is blacklisted by +udev along with most other framebuffer drivers, so this doesn't matter +much. + +However, this driver is required for console support on the XO 1.5. +We need to allow it to be autoloaded on this model only, and then +un-blacklist it in udev. + +--- +Index: linux/drivers/video/fbdev/via/via-core.c +=================================================================== +--- linux.orig/drivers/video/fbdev/via/via-core.c ++++ linux/drivers/video/fbdev/via/via-core.c +@@ -752,7 +752,14 @@ static const struct pci_device_id via_pc + .driver_data = UNICHROME_VX900 }, + { } + }; +-MODULE_DEVICE_TABLE(pci, via_pci_table); ++ ++static const struct pci_device_id via_pci_autoload_table[] __initconst = { ++ /* OLPC XO 1.5 */ ++ { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), ++ .subvendor = 0x152d, .subdevice = 0x0833 }, ++ { } ++}; ++MODULE_DEVICE_TABLE(pci, via_pci_autoload_table); + + static struct pci_driver via_driver = { + .name = "viafb", diff --git a/debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch b/debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch new file mode 100644 index 000000000..2970dc8b4 --- /dev/null +++ b/debian/patches/bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch @@ -0,0 +1,31 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 25 Sep 2018 19:44:13 +0100 +Subject: x86-32: Disable 3D-Now in generic config + +We want the 686 flavour to run on Geode LX and similar AMD family 5 +CPUs as well as family 6 and higher CPUs. This used to work with +CONFIG_M686=y. However commit 25d76ac88821 "x86/Kconfig: Explicitly +enumerate i686-class CPUs in Kconfig" in Linux 4.16 has made the +kernel require family 6 or higher. + +It looks like a sensible choice would be to enable CONFIG_MGEODE_LX +and CONFIG_X86_GENERIC (for more generic optimisations), but this +currently enables CONFIG_X86_USE_3D_NOW which will cause the kernel to +crash on CPUs without the AMD-specific 3D-Now instructions. + +Make CONFIG_X86_USE_3DNOW depend on CONFIG_X86_GENERIC being disabled. + +--- +Index: linux/arch/x86/Kconfig.cpu +=================================================================== +--- linux.orig/arch/x86/Kconfig.cpu ++++ linux/arch/x86/Kconfig.cpu +@@ -337,7 +337,7 @@ config X86_USE_PPRO_CHECKSUM + + config X86_USE_3DNOW + def_bool y +- depends on (MCYRIXIII || MK7 || MGEODE_LX) && !UML ++ depends on (MCYRIXIII || MK7 || MGEODE_LX) && !X86_GENERIC && !UML + + # + # P6_NOPs are a relatively minor optimization that require a family >= diff --git a/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch b/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch new file mode 100644 index 000000000..3f6baa5dc --- /dev/null +++ b/debian/patches/debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch @@ -0,0 +1,99 @@ +From: Serge Hallyn <serge.hallyn@canonical.com> +Date: Fri, 31 May 2013 19:12:12 +0000 (+0100) +Subject: add sysctl to disallow unprivileged CLONE_NEWUSER by default +Origin: http://kernel.ubuntu.com/git?p=serge%2Fubuntu-saucy.git;a=commit;h=5c847404dcb2e3195ad0057877e1422ae90892b8 + +add sysctl to disallow unprivileged CLONE_NEWUSER by default + +This is a short-term patch. Unprivileged use of CLONE_NEWUSER +is certainly an intended feature of user namespaces. However +for at least saucy we want to make sure that, if any security +issues are found, we have a fail-safe. + +Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com> +[bwh: Remove unneeded binary sysctl bits] +--- +Index: linux/kernel/fork.c +=================================================================== +--- linux.orig/kernel/fork.c ++++ linux/kernel/fork.c +@@ -103,6 +103,11 @@ + + #define CREATE_TRACE_POINTS + #include <trace/events/task.h> ++#ifdef CONFIG_USER_NS ++extern int unprivileged_userns_clone; ++#else ++#define unprivileged_userns_clone 0 ++#endif + + /* + * Minimum number of threads to boot the kernel +@@ -1675,6 +1680,10 @@ static __latent_entropy struct task_stru + if ((clone_flags & (CLONE_NEWUSER|CLONE_FS)) == (CLONE_NEWUSER|CLONE_FS)) + return ERR_PTR(-EINVAL); + ++ if ((clone_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) ++ if (!capable(CAP_SYS_ADMIN)) ++ return ERR_PTR(-EPERM); ++ + /* + * Thread groups must share signals as well, and detached threads + * can only be started up within the thread group. +@@ -2504,6 +2513,12 @@ int ksys_unshare(unsigned long unshare_f + if (unshare_flags & CLONE_NEWNS) + unshare_flags |= CLONE_FS; + ++ if ((unshare_flags & CLONE_NEWUSER) && !unprivileged_userns_clone) { ++ err = -EPERM; ++ if (!capable(CAP_SYS_ADMIN)) ++ goto bad_unshare_out; ++ } ++ + err = check_unshare_flags(unshare_flags); + if (err) + goto bad_unshare_out; +Index: linux/kernel/sysctl.c +=================================================================== +--- linux.orig/kernel/sysctl.c ++++ linux/kernel/sysctl.c +@@ -105,6 +105,9 @@ extern int core_uses_pid; + extern char core_pattern[]; + extern unsigned int core_pipe_limit; + #endif ++#ifdef CONFIG_USER_NS ++extern int unprivileged_userns_clone; ++#endif + extern int pid_max; + extern int pid_max_min, pid_max_max; + extern int percpu_pagelist_fraction; +@@ -515,6 +518,15 @@ static struct ctl_table kern_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec, + }, ++#endif ++#ifdef CONFIG_USER_NS ++ { ++ .procname = "unprivileged_userns_clone", ++ .data = &unprivileged_userns_clone, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec, ++ }, + #endif + #ifdef CONFIG_PROC_SYSCTL + { +Index: linux/kernel/user_namespace.c +=================================================================== +--- linux.orig/kernel/user_namespace.c ++++ linux/kernel/user_namespace.c +@@ -26,6 +26,9 @@ + #include <linux/bsearch.h> + #include <linux/sort.h> + ++/* sysctl */ ++int unprivileged_userns_clone; ++ + static struct kmem_cache *user_ns_cachep __read_mostly; + static DEFINE_MUTEX(userns_state_mutex); + diff --git a/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch b/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch new file mode 100644 index 000000000..8726519ad --- /dev/null +++ b/debian/patches/debian/af_802154-Disable-auto-loading-as-mitigation-against.patch @@ -0,0 +1,31 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 19 Nov 2010 02:12:48 +0000 +Subject: [PATCH 2/3] af_802154: Disable auto-loading as mitigation against local exploits +Forwarded: not-needed + +Recent review has revealed several bugs in obscure protocol +implementations that can be exploited by local users for denial of +service or privilege escalation. We can mitigate the effect of any +remaining vulnerabilities in such protocols by preventing unprivileged +users from loading the modules, so that they are only exploitable on +systems where the administrator has chosen to load the protocol. + +The 'af_802154' (IEEE 802.15.4) protocol is not widely used, was +not present in the 'lenny' kernel, and seems to receive only sporadic +maintenance. Therefore disable auto-loading. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/ieee802154/socket.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: linux/net/ieee802154/socket.c +=================================================================== +--- linux.orig/net/ieee802154/socket.c ++++ linux/net/ieee802154/socket.c +@@ -1144,4 +1144,4 @@ module_init(af_ieee802154_init); + module_exit(af_ieee802154_remove); + + MODULE_LICENSE("GPL"); +-MODULE_ALIAS_NETPROTO(PF_IEEE802154); ++/* MODULE_ALIAS_NETPROTO(PF_IEEE802154); */ diff --git a/debian/patches/debian/android-enable-building-ashmem-and-binder-as-modules.patch b/debian/patches/debian/android-enable-building-ashmem-and-binder-as-modules.patch new file mode 100644 index 000000000..da02e00e0 --- /dev/null +++ b/debian/patches/debian/android-enable-building-ashmem-and-binder-as-modules.patch @@ -0,0 +1,97 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 22 Jun 2018 17:27:00 +0100 +Subject: android: Enable building ashmem and binder as modules +Bug-Debian: https://bugs.debian.org/901492 + +We want to enable use of the Android ashmem and binder drivers to +support Anbox, but they should not be built-in as that would waste +resources and increase security attack surface on systems that don't +need them. + +- Add a MODULE_LICENSE declaration to ashmem +- Change the Makefiles to build each driver as an object with the + "_linux" suffix (which is what Anbox expects) +- Change config symbol types to tristate + +--- +Index: linux/drivers/android/Kconfig +=================================================================== +--- linux.orig/drivers/android/Kconfig ++++ linux/drivers/android/Kconfig +@@ -9,7 +9,7 @@ config ANDROID + if ANDROID + + config ANDROID_BINDER_IPC +- bool "Android Binder IPC Driver" ++ tristate "Android Binder IPC Driver" + depends on MMU + default n + ---help--- +Index: linux/drivers/android/Makefile +=================================================================== +--- linux.orig/drivers/android/Makefile ++++ linux/drivers/android/Makefile +@@ -1,4 +1,5 @@ + ccflags-y += -I$(src) # needed for trace events + +-obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o +-obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o ++obj-$(CONFIG_ANDROID_BINDER_IPC) += binder_linux.o ++binder_linux-y := binder.o binder_alloc.o ++binder_linux-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o +Index: linux/drivers/staging/android/Kconfig +=================================================================== +--- linux.orig/drivers/staging/android/Kconfig ++++ linux/drivers/staging/android/Kconfig +@@ -3,7 +3,7 @@ menu "Android" + if ANDROID + + config ASHMEM +- bool "Enable the Anonymous Shared Memory Subsystem" ++ tristate "Enable the Anonymous Shared Memory Subsystem" + default n + depends on SHMEM + help +Index: linux/drivers/staging/android/Makefile +=================================================================== +--- linux.orig/drivers/staging/android/Makefile ++++ linux/drivers/staging/android/Makefile +@@ -2,5 +2,6 @@ ccflags-y += -I$(src) # needed for tra + + obj-y += ion/ + +-obj-$(CONFIG_ASHMEM) += ashmem.o ++obj-$(CONFIG_ASHMEM) += ashmem_linux.o ++ashmem_linux-y += ashmem.o + obj-$(CONFIG_ANDROID_VSOC) += vsoc.o +Index: linux/drivers/staging/android/ashmem.c +=================================================================== +--- linux.orig/drivers/staging/android/ashmem.c ++++ linux/drivers/staging/android/ashmem.c +@@ -24,6 +24,7 @@ + #include <linux/bitops.h> + #include <linux/mutex.h> + #include <linux/shmem_fs.h> ++#include <linux/module.h> + #include "ashmem.h" + + #define ASHMEM_NAME_PREFIX "dev/ashmem/" +@@ -924,3 +925,5 @@ out: + return ret; + } + device_initcall(ashmem_init); ++ ++MODULE_LICENSE("GPL v2"); +Index: linux/drivers/android/binder_alloc.c +=================================================================== +--- linux.orig/drivers/android/binder_alloc.c ++++ linux/drivers/android/binder_alloc.c +@@ -44,7 +44,7 @@ enum { + }; + static uint32_t binder_alloc_debug_mask = BINDER_DEBUG_USER_ERROR; + +-module_param_named(debug_mask, binder_alloc_debug_mask, ++module_param_named(alloc_debug_mask, binder_alloc_debug_mask, + uint, 0644); + + #define binder_alloc_debug(mask, x...) \ diff --git a/debian/patches/debian/arch-sh4-fix-uimage-build.patch b/debian/patches/debian/arch-sh4-fix-uimage-build.patch new file mode 100644 index 000000000..d9c651ccb --- /dev/null +++ b/debian/patches/debian/arch-sh4-fix-uimage-build.patch @@ -0,0 +1,20 @@ +From: Nobuhiro Iwamatsu <iwamatsu@nigauri.org> +Subject: [sh4] Fix uImage build +Bug-Debian: https://bugs.debian.org/569034 +Forwarded: not-needed + +[bwh: This was added without a description, but I think it is dealing +with a similar issue to powerpcspe-omit-uimage.patch] + +Index: linux/arch/sh/Makefile +=================================================================== +--- linux.orig/arch/sh/Makefile ++++ linux/arch/sh/Makefile +@@ -89,7 +89,6 @@ OBJCOPYFLAGS := -O binary -R .note -R .n + + # Give the various platforms the opportunity to set default image types + defaultimage-$(CONFIG_SUPERH32) := zImage +-defaultimage-$(CONFIG_SH_SH7785LCR) := uImage + defaultimage-$(CONFIG_SH_RSK) := uImage + defaultimage-$(CONFIG_SH_URQUELL) := uImage + defaultimage-$(CONFIG_SH_MIGOR) := uImage diff --git a/debian/patches/debian/btrfs-warn-about-raid5-6-being-experimental-at-mount.patch b/debian/patches/debian/btrfs-warn-about-raid5-6-being-experimental-at-mount.patch new file mode 100644 index 000000000..5be1b26a7 --- /dev/null +++ b/debian/patches/debian/btrfs-warn-about-raid5-6-being-experimental-at-mount.patch @@ -0,0 +1,37 @@ +From: Adam Borowski <kilobyte@angband.pl> +Date: Tue, 28 Mar 2017 16:55:05 +0200 +Subject: btrfs: warn about RAID5/6 being experimental at mount time +Bug-Debian: https://bugs.debian.org/863290 +Origin: https://bugs.debian.org/863290#5 + +Too many people come complaining about losing their data -- and indeed, +there's no warning outside a wiki and the mailing list tribal knowledge. +Message severity chosen for consistency with XFS -- "alert" makes dmesg +produce nice red background which should get the point across. + +Signed-off-by: Adam Borowski <kilobyte@angband.pl> +[bwh: Also add_taint() so this is flagged in bug reports] +--- + fs/btrfs/disk-io.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +Index: linux/fs/btrfs/disk-io.c +=================================================================== +--- linux.orig/fs/btrfs/disk-io.c ++++ linux/fs/btrfs/disk-io.c +@@ -3089,6 +3089,15 @@ retry_root_backup: + btrfs_set_and_info(fs_info, SSD, "enabling ssd optimizations"); + } + ++ if ((fs_info->avail_data_alloc_bits | ++ fs_info->avail_metadata_alloc_bits | ++ fs_info->avail_system_alloc_bits) & ++ BTRFS_BLOCK_GROUP_RAID56_MASK) { ++ btrfs_alert(fs_info, ++ "btrfs RAID5/6 is EXPERIMENTAL and has known data-loss bugs"); ++ add_taint(TAINT_USER, LOCKDEP_STILL_OK); ++ } ++ + /* + * Mount does not set all options immediately, we can do it now and do + * not have to wait for transaction commit diff --git a/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch b/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch new file mode 100644 index 000000000..57e118698 --- /dev/null +++ b/debian/patches/debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: cdc_ncm,cdc_mbim: Use NCM by default +Date: Sun, 31 Mar 2013 03:58:04 +0100 +Forwarded: not-needed + +Devices that support both NCM and MBIM modes should be kept in NCM +mode unless there is userland support for MBIM. + +Set the default value of cdc_ncm.prefer_mbim to false and leave it to +userland (modem-manager) to override this with a modprobe.conf file +once it's ready to speak MBIM. + +--- +Index: linux/drivers/net/usb/cdc_ncm.c +=================================================================== +--- linux.orig/drivers/net/usb/cdc_ncm.c ++++ linux/drivers/net/usb/cdc_ncm.c +@@ -53,11 +53,7 @@ + #include <linux/usb/cdc.h> + #include <linux/usb/cdc_ncm.h> + +-#if IS_ENABLED(CONFIG_USB_NET_CDC_MBIM) +-static bool prefer_mbim = true; +-#else + static bool prefer_mbim; +-#endif + module_param(prefer_mbim, bool, 0644); + MODULE_PARM_DESC(prefer_mbim, "Prefer MBIM setting on dual NCM/MBIM functions"); + diff --git a/debian/patches/debian/dccp-disable-auto-loading-as-mitigation-against-local-exploits.patch b/debian/patches/debian/dccp-disable-auto-loading-as-mitigation-against-local-exploits.patch new file mode 100644 index 000000000..9f0e897c7 --- /dev/null +++ b/debian/patches/debian/dccp-disable-auto-loading-as-mitigation-against-local-exploits.patch @@ -0,0 +1,45 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Thu, 16 Feb 2017 19:09:17 +0000 +Subject: dccp: Disable auto-loading as mitigation against local exploits +Forwarded: not-needed + +We can mitigate the effect of vulnerabilities in obscure protocols by +preventing unprivileged users from loading the modules, so that they +are only exploitable on systems where the administrator has chosen to +load the protocol. + +The 'dccp' protocol is not actively maintained or widely used. +Therefore disable auto-loading. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/net/dccp/ipv4.c +=================================================================== +--- linux.orig/net/dccp/ipv4.c ++++ linux/net/dccp/ipv4.c +@@ -1079,8 +1079,8 @@ module_exit(dccp_v4_exit); + * values directly, Also cover the case where the protocol is not specified, + * i.e. net-pf-PF_INET-proto-0-type-SOCK_DCCP + */ +-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 33, 6); +-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 0, 6); ++/* MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 33, 6); */ ++/* MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET, 0, 6); */ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>"); + MODULE_DESCRIPTION("DCCP - Datagram Congestion Controlled Protocol"); +Index: linux/net/dccp/ipv6.c +=================================================================== +--- linux.orig/net/dccp/ipv6.c ++++ linux/net/dccp/ipv6.c +@@ -1162,8 +1162,8 @@ module_exit(dccp_v6_exit); + * values directly, Also cover the case where the protocol is not specified, + * i.e. net-pf-PF_INET6-proto-0-type-SOCK_DCCP + */ +-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6); +-MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6); ++/* MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 33, 6); */ ++/* MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_INET6, 0, 6); */ + MODULE_LICENSE("GPL"); + MODULE_AUTHOR("Arnaldo Carvalho de Melo <acme@mandriva.com>"); + MODULE_DESCRIPTION("DCCPv6 - Datagram Congestion Controlled Protocol"); diff --git a/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch b/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch new file mode 100644 index 000000000..cb83e5ee8 --- /dev/null +++ b/debian/patches/debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch @@ -0,0 +1,34 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 20 Nov 2010 02:24:55 +0000 +Subject: [PATCH] decnet: Disable auto-loading as mitigation against local exploits +Forwarded: not-needed + +Recent review has revealed several bugs in obscure protocol +implementations that can be exploited by local users for denial of +service or privilege escalation. We can mitigate the effect of any +remaining vulnerabilities in such protocols by preventing unprivileged +users from loading the modules, so that they are only exploitable on +systems where the administrator has chosen to load the protocol. + +The 'decnet' protocol is unmaintained and of mostly historical +interest, and the user-space support package 'dnet-common' loads the +module explicitly. Therefore disable auto-loading. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/decnet/af_decnet.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: linux/net/decnet/af_decnet.c +=================================================================== +--- linux.orig/net/decnet/af_decnet.c ++++ linux/net/decnet/af_decnet.c +@@ -2346,7 +2346,7 @@ static const struct proto_ops dn_proto_o + MODULE_DESCRIPTION("The Linux DECnet Network Protocol"); + MODULE_AUTHOR("Linux DECnet Project Team"); + MODULE_LICENSE("GPL"); +-MODULE_ALIAS_NETPROTO(PF_DECnet); ++/* MODULE_ALIAS_NETPROTO(PF_DECnet); */ + + static const char banner[] __initconst = KERN_INFO + "NET4: DECnet for Linux: V.2.5.68s (C) 1995-2003 Linux DECnet Project Team\n"; diff --git a/debian/patches/debian/dfsg/arch-powerpc-platforms-8xx-ucode-disable.patch b/debian/patches/debian/dfsg/arch-powerpc-platforms-8xx-ucode-disable.patch new file mode 100644 index 000000000..97d8be0b2 --- /dev/null +++ b/debian/patches/debian/dfsg/arch-powerpc-platforms-8xx-ucode-disable.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 13 Apr 2009 17:34:00 +0100 +Subject: Remove microcode patches for mgsuvd (not enabled in Debian configs) +Forwarded: not-needed + +Index: linux/arch/powerpc/platforms/8xx/Kconfig +=================================================================== +--- linux.orig/arch/powerpc/platforms/8xx/Kconfig ++++ linux/arch/powerpc/platforms/8xx/Kconfig +@@ -144,16 +144,19 @@ config NO_UCODE_PATCH + + config USB_SOF_UCODE_PATCH + bool "USB SOF patch" ++ depends on BROKEN + help + Help not implemented yet, coming soon. + + config I2C_SPI_UCODE_PATCH + bool "I2C/SPI relocation patch" ++ depends on BROKEN + help + Help not implemented yet, coming soon. + + config I2C_SPI_SMC1_UCODE_PATCH + bool "I2C/SPI/SMC1 relocation patch" ++ depends on BROKEN + help + Help not implemented yet, coming soon. + diff --git a/debian/patches/debian/dfsg/drivers-media-dvb-dvb-usb-af9005-disable.patch b/debian/patches/debian/dfsg/drivers-media-dvb-dvb-usb-af9005-disable.patch new file mode 100644 index 000000000..47233b0ff --- /dev/null +++ b/debian/patches/debian/dfsg/drivers-media-dvb-dvb-usb-af9005-disable.patch @@ -0,0 +1,17 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 17 Aug 2009 02:45:41 +0100 +Subject: dvb-usb-af9005: mark as broken +Forwarded: not-needed + +Index: linux/drivers/media/usb/dvb-usb/Kconfig +=================================================================== +--- linux.orig/drivers/media/usb/dvb-usb/Kconfig ++++ linux/drivers/media/usb/dvb-usb/Kconfig +@@ -246,6 +246,7 @@ config DVB_USB_OPERA1 + + config DVB_USB_AF9005 + tristate "Afatech AF9005 DVB-T USB1.1 support" ++ depends on BROKEN + depends on DVB_USB + select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT diff --git a/debian/patches/debian/dfsg/drivers-net-appletalk-cops.patch b/debian/patches/debian/dfsg/drivers-net-appletalk-cops.patch new file mode 100644 index 000000000..d0d266861 --- /dev/null +++ b/debian/patches/debian/dfsg/drivers-net-appletalk-cops.patch @@ -0,0 +1,52 @@ +From: Frederik Schüler <fs@debian.org> +Date: Fri, 05 Jan 2007 15:55:24 +0000 +Subject: Add removal patches for: 3c359, smctr, keyspan, cops +Forwarded: not-needed + +Index: linux/drivers/net/appletalk/Kconfig +=================================================================== +--- linux.orig/drivers/net/appletalk/Kconfig ++++ linux/drivers/net/appletalk/Kconfig +@@ -49,32 +49,6 @@ config LTPC + This driver is experimental, which means that it may not work. + See the file <file:Documentation/networking/ltpc.txt>. + +-config COPS +- tristate "COPS LocalTalk PC support" +- depends on DEV_APPLETALK && (ISA || EISA) +- help +- This allows you to use COPS AppleTalk cards to connect to LocalTalk +- networks. You also need version 1.3.3 or later of the netatalk +- package. This driver is experimental, which means that it may not +- work. This driver will only work if you choose "AppleTalk DDP" +- networking support, above. +- Please read the file <file:Documentation/networking/cops.txt>. +- +-config COPS_DAYNA +- bool "Dayna firmware support" +- depends on COPS +- help +- Support COPS compatible cards with Dayna style firmware (Dayna +- DL2000/ Daynatalk/PC (half length), COPS LT-95, Farallon PhoneNET PC +- III, Farallon PhoneNET PC II). +- +-config COPS_TANGENT +- bool "Tangent firmware support" +- depends on COPS +- help +- Support COPS compatible cards with Tangent style firmware (Tangent +- ATB_II, Novell NL-1000, Daystar Digital LT-200. +- + config IPDDP + tristate "Appletalk-IP driver support" + depends on DEV_APPLETALK && ATALK +Index: linux/drivers/net/appletalk/Makefile +=================================================================== +--- linux.orig/drivers/net/appletalk/Makefile ++++ linux/drivers/net/appletalk/Makefile +@@ -3,5 +3,4 @@ + # + + obj-$(CONFIG_IPDDP) += ipddp.o +-obj-$(CONFIG_COPS) += cops.o + obj-$(CONFIG_LTPC) += ltpc.o diff --git a/debian/patches/debian/dfsg/video-remove-nvidiafb-and-rivafb.patch b/debian/patches/debian/dfsg/video-remove-nvidiafb-and-rivafb.patch new file mode 100644 index 000000000..24e209fd1 --- /dev/null +++ b/debian/patches/debian/dfsg/video-remove-nvidiafb-and-rivafb.patch @@ -0,0 +1,134 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 2 Jun 2012 19:53:38 +0100 +Subject: video: Remove nvidiafb and rivafb +Bug-Debian: https://bugs.debian.org/383481 +Forwarded: no + +These drivers contain register programming code provided by the +hardware vendor that appears to have been deliberately obfuscated. +This is arguably not the preferred form for modification. + +These drivers are also largely redundant with nouveau. The RIVA 128 +(NV3) is not supported by nouveau but is about 15 years old and +probably discontinued 10 years ago. + +--- +Index: linux/drivers/video/fbdev/Kconfig +=================================================================== +--- linux.orig/drivers/video/fbdev/Kconfig ++++ linux/drivers/video/fbdev/Kconfig +@@ -901,101 +901,6 @@ config FB_ATMEL + help + This enables support for the AT91/AT32 LCD Controller. + +-config FB_NVIDIA +- tristate "nVidia Framebuffer Support" +- depends on FB && PCI +- select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT +- select FB_MODE_HELPERS +- select FB_CFB_FILLRECT +- select FB_CFB_COPYAREA +- select FB_CFB_IMAGEBLIT +- select BITREVERSE +- select VGASTATE +- help +- This driver supports graphics boards with the nVidia chips, TNT +- and newer. For very old chipsets, such as the RIVA128, then use +- the rivafb. +- Say Y if you have such a graphics board. +- +- To compile this driver as a module, choose M here: the +- module will be called nvidiafb. +- +-config FB_NVIDIA_I2C +- bool "Enable DDC Support" +- depends on FB_NVIDIA +- select FB_DDC +- help +- This enables I2C support for nVidia Chipsets. This is used +- only for getting EDID information from the attached display +- allowing for robust video mode handling and switching. +- +- Because fbdev-2.6 requires that drivers must be able to +- independently validate video mode parameters, you should say Y +- here. +- +-config FB_NVIDIA_DEBUG +- bool "Lots of debug output" +- depends on FB_NVIDIA +- default n +- help +- Say Y here if you want the nVidia driver to output all sorts +- of debugging information to provide to the maintainer when +- something goes wrong. +- +-config FB_NVIDIA_BACKLIGHT +- bool "Support for backlight control" +- depends on FB_NVIDIA +- default y +- help +- Say Y here if you want to control the backlight of your display. +- +-config FB_RIVA +- tristate "nVidia Riva support" +- depends on FB && PCI +- select FB_BACKLIGHT if FB_RIVA_BACKLIGHT +- select FB_MODE_HELPERS +- select FB_CFB_FILLRECT +- select FB_CFB_COPYAREA +- select FB_CFB_IMAGEBLIT +- select BITREVERSE +- select VGASTATE +- help +- This driver supports graphics boards with the nVidia Riva/Geforce +- chips. +- Say Y if you have such a graphics board. +- +- To compile this driver as a module, choose M here: the +- module will be called rivafb. +- +-config FB_RIVA_I2C +- bool "Enable DDC Support" +- depends on FB_RIVA +- select FB_DDC +- help +- This enables I2C support for nVidia Chipsets. This is used +- only for getting EDID information from the attached display +- allowing for robust video mode handling and switching. +- +- Because fbdev-2.6 requires that drivers must be able to +- independently validate video mode parameters, you should say Y +- here. +- +-config FB_RIVA_DEBUG +- bool "Lots of debug output" +- depends on FB_RIVA +- default n +- help +- Say Y here if you want the Riva driver to output all sorts +- of debugging information to provide to the maintainer when +- something goes wrong. +- +-config FB_RIVA_BACKLIGHT +- bool "Support for backlight control" +- depends on FB_RIVA +- default y +- help +- Say Y here if you want to control the backlight of your display. +- + config FB_I740 + tristate "Intel740 support" + depends on FB && PCI +Index: linux/drivers/video/fbdev/Makefile +=================================================================== +--- linux.orig/drivers/video/fbdev/Makefile ++++ linux/drivers/video/fbdev/Makefile +@@ -22,8 +22,6 @@ obj-$(CONFIG_FB_PM3) += pm3fb.o + + obj-$(CONFIG_FB_I740) += i740fb.o + obj-$(CONFIG_FB_MATROX) += matrox/ +-obj-$(CONFIG_FB_RIVA) += riva/ +-obj-$(CONFIG_FB_NVIDIA) += nvidia/ + obj-$(CONFIG_FB_ATY) += aty/ macmodes.o + obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o + obj-$(CONFIG_FB_RADEON) += aty/ diff --git a/debian/patches/debian/dfsg/vs6624-disable.patch b/debian/patches/debian/dfsg/vs6624-disable.patch new file mode 100644 index 000000000..41219ffd5 --- /dev/null +++ b/debian/patches/debian/dfsg/vs6624-disable.patch @@ -0,0 +1,17 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 27 May 2012 01:56:58 +0100 +Subject: vs6624: mark as broken +Forwarded: not-needed + +Index: linux/drivers/media/i2c/Kconfig +=================================================================== +--- linux.orig/drivers/media/i2c/Kconfig ++++ linux/drivers/media/i2c/Kconfig +@@ -803,6 +803,7 @@ config VIDEO_OV13858 + OV13858 camera. + + config VIDEO_VS6624 ++ depends on BROKEN + tristate "ST VS6624 sensor support" + depends on VIDEO_V4L2 && I2C + depends on MEDIA_CAMERA_SUPPORT diff --git a/debian/patches/debian/export-symbols-needed-by-android-drivers.patch b/debian/patches/debian/export-symbols-needed-by-android-drivers.patch new file mode 100644 index 000000000..c2c8b5f23 --- /dev/null +++ b/debian/patches/debian/export-symbols-needed-by-android-drivers.patch @@ -0,0 +1,156 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 26 Jun 2018 16:59:01 +0100 +Subject: Export symbols needed by Android drivers +Bug-Debian: https://bugs.debian.org/901492 + +We want to enable use of the Android ashmem and binder drivers to +support Anbox, but they should not be built-in as that would waste +resources and increase security attack surface on systems that don't +need them. + +Export the currently un-exported symbols they depend on. + +--- +--- a/fs/file.c ++++ b/fs/file.c +@@ -409,6 +409,7 @@ struct files_struct *get_files_struct(st + + return files; + } ++EXPORT_SYMBOL_GPL(get_files_struct); + + void put_files_struct(struct files_struct *files) + { +@@ -421,6 +422,7 @@ void put_files_struct(struct files_struc + kmem_cache_free(files_cachep, files); + } + } ++EXPORT_SYMBOL_GPL(put_files_struct); + + void reset_files_struct(struct files_struct *files) + { +@@ -534,6 +536,7 @@ out: + spin_unlock(&files->file_lock); + return error; + } ++EXPORT_SYMBOL_GPL(__alloc_fd); + + static int alloc_fd(unsigned start, unsigned flags) + { +@@ -607,6 +610,7 @@ void __fd_install(struct files_struct *f + rcu_assign_pointer(fdt->fd[fd], file); + rcu_read_unlock_sched(); + } ++EXPORT_SYMBOL_GPL(__fd_install); + + void fd_install(unsigned int fd, struct file *file) + { +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -1054,6 +1054,7 @@ void mmput_async(struct mm_struct *mm) + schedule_work(&mm->async_put_work); + } + } ++EXPORT_SYMBOL_GPL(mmput_async); + #endif + + /** +--- a/kernel/signal.c ++++ b/kernel/signal.c +@@ -1368,6 +1368,7 @@ struct sighand_struct *__lock_task_sigha + + return sighand; + } ++EXPORT_SYMBOL_GPL(__lock_task_sighand); + + /* + * send signal info to all the members of a group +--- a/mm/memory.c ++++ b/mm/memory.c +@@ -1644,6 +1644,7 @@ void zap_page_range(struct vm_area_struc + mmu_notifier_invalidate_range_end(mm, start, end); + tlb_finish_mmu(&tlb, start, end); + } ++EXPORT_SYMBOL_GPL(zap_page_range); + + /** + * zap_page_range_single - remove user pages in a given range +--- a/mm/shmem.c ++++ b/mm/shmem.c +@@ -4053,6 +4053,7 @@ int shmem_zero_setup(struct vm_area_stru + + return 0; + } ++EXPORT_SYMBOL_GPL(shmem_zero_setup); + + /** + * shmem_read_mapping_page_gfp - read into page cache, using specified page allocation flags. +--- a/mm/vmalloc.c ++++ b/mm/vmalloc.c +@@ -1300,6 +1300,7 @@ int map_kernel_range_noflush(unsigned lo + { + return vmap_page_range_noflush(addr, addr + size, prot, pages); + } ++EXPORT_SYMBOL_GPL(map_kernel_range_noflush); + + /** + * unmap_kernel_range_noflush - unmap kernel VM area +@@ -1440,6 +1441,7 @@ struct vm_struct *get_vm_area(unsigned l + NUMA_NO_NODE, GFP_KERNEL, + __builtin_return_address(0)); + } ++EXPORT_SYMBOL_GPL(get_vm_area); + + struct vm_struct *get_vm_area_caller(unsigned long size, unsigned long flags, + const void *caller) +--- a/security/security.c ++++ b/security/security.c +@@ -236,24 +236,28 @@ int security_binder_set_context_mgr(cons + { + return call_int_hook(binder_set_context_mgr, 0, mgr); + } ++EXPORT_SYMBOL_GPL(security_binder_set_context_mgr); + + int security_binder_transaction(const struct cred *from, + const struct cred *to) + { + return call_int_hook(binder_transaction, 0, from, to); + } ++EXPORT_SYMBOL_GPL(security_binder_transaction); + + int security_binder_transfer_binder(const struct cred *from, + const struct cred *to) + { + return call_int_hook(binder_transfer_binder, 0, from, to); + } ++EXPORT_SYMBOL_GPL(security_binder_transfer_binder); + + int security_binder_transfer_file(const struct cred *from, + const struct cred *to, struct file *file) + { + return call_int_hook(binder_transfer_file, 0, from, to, file); + } ++EXPORT_SYMBOL_GPL(security_binder_transfer_file); + + int security_ptrace_access_check(struct task_struct *child, unsigned int mode) + { +--- a/kernel/sched/core.c ++++ b/kernel/sched/core.c +@@ -3979,6 +3979,7 @@ int can_nice(const struct task_struct *p + return (nice_rlim <= task_rlimit(p, RLIMIT_NICE) || + capable(CAP_SYS_NICE)); + } ++EXPORT_SYMBOL_GPL(can_nice); + + #ifdef __ARCH_WANT_SYS_NICE + +--- a/kernel/sched/wait.c ++++ b/kernel/sched/wait.c +@@ -215,6 +215,7 @@ void __wake_up_pollfree(struct wait_queu + /* POLLFREE must have cleared the queue. */ + WARN_ON_ONCE(waitqueue_active(wq_head)); + } ++EXPORT_SYMBOL_GPL(__wake_up_pollfree); + + /* + * Note: we use "set_current_state()" _after_ the wait-queue add, diff --git a/debian/patches/debian/fanotify-taint-on-use-of-fanotify_access_permissions.patch b/debian/patches/debian/fanotify-taint-on-use-of-fanotify_access_permissions.patch new file mode 100644 index 000000000..5149007a4 --- /dev/null +++ b/debian/patches/debian/fanotify-taint-on-use-of-fanotify_access_permissions.patch @@ -0,0 +1,31 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: fanotify: Taint on use of FANOTIFY_ACCESS_PERMISSIONS +Date: Wed, 13 Jul 2016 01:37:22 +0100 +Forwarded: not-needed + +Various free and proprietary AV products use this feature and users +apparently want it. But punting access checks to userland seems like +an easy way to deadlock the system, and there will be nothing we can +do about that. So warn and taint the kernel if this feature is +actually used. + +--- +Index: linux/fs/notify/fanotify/fanotify_user.c +=================================================================== +--- linux.orig/fs/notify/fanotify/fanotify_user.c ++++ linux/fs/notify/fanotify/fanotify_user.c +@@ -842,6 +842,14 @@ static int do_fanotify_mark(int fanotify + if (mask & ~valid_mask) + return -EINVAL; + ++#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS ++ if (mask & FAN_ALL_PERM_EVENTS) { ++ pr_warn_once("%s (%d): Using fanotify permission checks may lead to deadlock; tainting kernel\n", ++ current->comm, current->pid); ++ add_taint(TAINT_USER, LOCKDEP_STILL_OK); ++ } ++#endif ++ + f = fdget(fanotify_fd); + if (unlikely(!f.file)) + return -EBADF; diff --git a/debian/patches/debian/firmware_class-refer-to-debian-wiki-firmware-page.patch b/debian/patches/debian/firmware_class-refer-to-debian-wiki-firmware-page.patch new file mode 100644 index 000000000..da4942ee6 --- /dev/null +++ b/debian/patches/debian/firmware_class-refer-to-debian-wiki-firmware-page.patch @@ -0,0 +1,58 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 12 Mar 2018 01:14:03 +0000 +Subject: firmware_class: Refer to Debian wiki page when logging missing firmware +Bug-Debian: https://bugs.debian.org/888405 +Forwarded: not-needed + +If firmware loading fails due to a missing file, log a second error +message referring to our wiki page about firmware. This will explain +why some firmware is in non-free, or can't be packaged at all. Only +do this once per boot. + +Do something similar in the radeon and amdgpu drivers, where we have +an early check to avoid failing at a point where we cannot display +anything. + +--- +Index: linux/drivers/base/firmware_loader/main.c +=================================================================== +--- linux.orig/drivers/base/firmware_loader/main.c ++++ linux/drivers/base/firmware_loader/main.c +@@ -340,9 +340,12 @@ fw_get_filesystem_firmware(struct device + } + __putname(path); + +- if (rc) ++ if (rc) { + dev_err(device, "firmware: failed to load %s (%d)\n", + fw_priv->fw_name, rc); ++ if (rc == -ENOENT) ++ pr_err_once("See https://wiki.debian.org/Firmware for information about missing firmware\n"); ++ } + + return rc; + } +Index: linux/drivers/gpu/drm/radeon/radeon_drv.c +=================================================================== +--- linux.orig/drivers/gpu/drm/radeon/radeon_drv.c ++++ linux/drivers/gpu/drm/radeon/radeon_drv.c +@@ -403,6 +403,7 @@ static int radeon_pci_probe(struct pci_d + if ((ent->driver_data & RADEON_FAMILY_MASK) >= CHIP_R600 && + !radeon_firmware_installed()) { + DRM_ERROR("radeon kernel modesetting for R600 or later requires firmware installed\n"); ++ pr_err_once("See https://wiki.debian.org/Firmware for information about missing firmware\n"); + return -ENODEV; + } + +Index: linux/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +=================================================================== +--- linux.orig/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c ++++ linux/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +@@ -859,6 +859,7 @@ static int amdgpu_pci_probe(struct pci_d + + if (!amdgpu_firmware_installed()) { + DRM_ERROR("amdgpu requires firmware installed\n"); ++ pr_err_once("See https://wiki.debian.org/Firmware for information about missing firmware\n"); + return -ENODEV; + } + diff --git a/debian/patches/debian/fjes-disable-autoload.patch b/debian/patches/debian/fjes-disable-autoload.patch new file mode 100644 index 000000000..e1081d872 --- /dev/null +++ b/debian/patches/debian/fjes-disable-autoload.patch @@ -0,0 +1,26 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sat, 18 Mar 2017 20:47:58 +0000 +Subject: fjes: Disable auto-loading +Bug-Debian: https://bugs.debian.org/853976 +Forwarded: no + +fjes matches a generic ACPI device ID, and relies on its probe +function to distinguish whether that really corresponds to a supported +device. Very few system will need the driver and it wastes memory on +all the other systems where the same device ID appears, so disable +auto-loading. + +--- +Index: linux/drivers/net/fjes/fjes_main.c +=================================================================== +--- linux.orig/drivers/net/fjes/fjes_main.c ++++ linux/drivers/net/fjes/fjes_main.c +@@ -83,7 +83,7 @@ static const struct acpi_device_id fjes_ + {ACPI_MOTHERBOARD_RESOURCE_HID, 0}, + {"", 0}, + }; +-MODULE_DEVICE_TABLE(acpi, fjes_acpi_ids); ++/* MODULE_DEVICE_TABLE(acpi, fjes_acpi_ids); */ + + static struct acpi_driver fjes_acpi_driver = { + .name = DRV_NAME, diff --git a/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch b/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch new file mode 100644 index 000000000..50b32bc2d --- /dev/null +++ b/debian/patches/debian/fs-enable-link-security-restrictions-by-default.patch @@ -0,0 +1,24 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: fs: Enable link security restrictions by default +Date: Fri, 02 Nov 2012 05:32:06 +0000 +Bug-Debian: https://bugs.debian.org/609455 +Forwarded: not-needed + +This reverts commit 561ec64ae67ef25cac8d72bb9c4bfc955edfd415 +('VFS: don't do protected {sym,hard}links by default'). + +Index: linux/fs/namei.c +=================================================================== +--- linux.orig/fs/namei.c ++++ linux/fs/namei.c +@@ -885,8 +885,8 @@ static inline void put_link(struct namei + path_put(&last->link); + } + +-int sysctl_protected_symlinks __read_mostly = 0; +-int sysctl_protected_hardlinks __read_mostly = 0; ++int sysctl_protected_symlinks __read_mostly = 1; ++int sysctl_protected_hardlinks __read_mostly = 1; + int sysctl_protected_fifos __read_mostly; + int sysctl_protected_regular __read_mostly; + diff --git a/debian/patches/debian/gitignore.patch b/debian/patches/debian/gitignore.patch new file mode 100644 index 000000000..493e558b7 --- /dev/null +++ b/debian/patches/debian/gitignore.patch @@ -0,0 +1,49 @@ +From: Ian Campbell <ijc@hellion.org.uk> +Date: Thu, 17 Jan 2013 08:55:21 +0000 +Subject: Tweak gitignore for Debian pkg-kernel using git svn. +Forwarded: not-needed + +[bwh: Tweak further for pure git] + +Index: linux/.gitignore +=================================================================== +--- linux.orig/.gitignore ++++ linux/.gitignore +@@ -64,11 +64,6 @@ modules.builtin + /*.spec + + # +-# Debian directory (make deb-pkg) +-# +-/debian/ +- +-# + # Snap directory (make snap-pkg) + # + /snap/ +@@ -79,14 +74,6 @@ modules.builtin + /tar-install/ + + # +-# git files that we don't want to ignore even if they are dot-files +-# +-!.gitignore +-!.mailmap +-!.cocciconfig +-!.clang-format +- +-# + # Generated include files + # + include/config +@@ -132,3 +119,10 @@ all.config + + # Kdevelop4 + *.kdev4 ++ ++# ++# Debian packaging: ignore everything at the top level, since it isn't ++# included in our repository ++# ++/* ++!/debian/ diff --git a/debian/patches/debian/i386-686-pae-pci-set-pci-nobios-by-default.patch b/debian/patches/debian/i386-686-pae-pci-set-pci-nobios-by-default.patch new file mode 100644 index 000000000..d9dcef669 --- /dev/null +++ b/debian/patches/debian/i386-686-pae-pci-set-pci-nobios-by-default.patch @@ -0,0 +1,29 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Tue, 16 Feb 2016 02:45:42 +0000 +Subject: [i386/686-pae] PCI: Set pci=nobios by default +Forwarded: not-needed + +CONFIG_PCI_GOBIOS results in physical addresses 640KB-1MB being mapped +W+X, which is undesirable for security reasons and will result in a +warning at boot now that we enable CONFIG_DEBUG_WX. + +This can be overridden using the kernel parameter "pci=nobios", but we +want to disable W+X by default. Disable PCI BIOS probing by default; +it can still be enabled using "pci=bios". + +--- +Index: linux/arch/x86/pci/common.c +=================================================================== +--- linux.orig/arch/x86/pci/common.c ++++ linux/arch/x86/pci/common.c +@@ -19,8 +19,8 @@ + #include <asm/pci_x86.h> + #include <asm/setup.h> + +-unsigned int pci_probe = PCI_PROBE_BIOS | PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | +- PCI_PROBE_MMCONF; ++unsigned int pci_probe = PCI_PROBE_CONF1 | PCI_PROBE_CONF2 | PCI_PROBE_MMCONF | ++ (IS_ENABLED(CONFIG_X86_64) || IS_ENABLED(CONFIG_X86_PAE) ? 0 : PCI_PROBE_BIOS); + + static int pci_bf_sort; + int pci_routeirq; diff --git a/debian/patches/debian/ia64-hardcode-arch-script-output.patch b/debian/patches/debian/ia64-hardcode-arch-script-output.patch new file mode 100644 index 000000000..f4b320f15 --- /dev/null +++ b/debian/patches/debian/ia64-hardcode-arch-script-output.patch @@ -0,0 +1,72 @@ +From: dann frazier <dannf@debian.org> +Subject: Hardcode arch script output +Date: Mon, 26 Mar 2007 16:30:51 -0600 +Bug-Debian: https://bugs.debian.org/392592 +Forwarded: not-needed + +Here's a patch that simply uses hardcoded definitions instead of +doing the dynamic tests that require architecture-specific scripts. + +I don't particularly like this approach because it restricts +portability and diverts from upstream. But, it is simpler, and this +really needs to be fixed somehow before etch (along with a rebuild of +linux-modules-extra-2.6), so I'm willing to live with it if my other +patch is deemed unacceptable. + +My primary concern is that, in the future, the output of these scripts +will change and we (or our successors) will either not notice or +forget to update the hardcoded values. + +Including the scripts in linux-kbuild will avoid this manual step +altogether, and allow for the possibility of other archs to provide +their own scripts in the future. + +Index: linux/arch/ia64/Makefile +=================================================================== +--- linux.orig/arch/ia64/Makefile ++++ linux/arch/ia64/Makefile +@@ -30,16 +30,7 @@ cflags-y := -pipe $(EXTRA) -ffixed-r13 - + -falign-functions=32 -frename-registers -fno-optimize-sibling-calls + KBUILD_CFLAGS_KERNEL := -mconstant-gp + +-GAS_STATUS = $(shell $(srctree)/arch/ia64/scripts/check-gas "$(CC)" "$(OBJDUMP)") +-KBUILD_CPPFLAGS += $(shell $(srctree)/arch/ia64/scripts/toolchain-flags "$(CC)" "$(OBJDUMP)" "$(READELF)") +- +-ifeq ($(GAS_STATUS),buggy) +-$(error Sorry, you need a newer version of the assember, one that is built from \ +- a source-tree that post-dates 18-Dec-2002. You can find a pre-compiled \ +- static binary of such an assembler at: \ +- \ +- ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz) +-endif ++KBUILD_CPPFLAGS += -DHAVE_WORKING_TEXT_ALIGN -DHAVE_MODEL_SMALL_ATTRIBUTE -DHAVE_SERIALIZE_DIRECTIVE + + KBUILD_CFLAGS += $(cflags-y) + head-y := arch/ia64/kernel/head.o +@@ -65,7 +56,7 @@ boot := arch/ia64/hp/sim/boot + + PHONY += boot compressed check + +-all: compressed unwcheck ++all: compressed + + compressed: vmlinux.gz + +@@ -74,9 +65,6 @@ vmlinuz: vmlinux.gz + vmlinux.gz: vmlinux + $(Q)$(MAKE) $(build)=$(boot) $@ + +-unwcheck: vmlinux +- -$(Q)READELF=$(READELF) $(PYTHON) $(srctree)/arch/ia64/scripts/unwcheck.py $< +- + archclean: + $(Q)$(MAKE) $(clean)=$(boot) + +@@ -92,7 +80,6 @@ define archhelp + echo '* compressed - Build compressed kernel image' + echo ' install - Install compressed kernel image' + echo ' boot - Build vmlinux and bootloader for Ski simulator' +- echo '* unwcheck - Check vmlinux for invalid unwind info' + endef + + archprepare: make_nr_irqs_h diff --git a/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch b/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch new file mode 100644 index 000000000..37d84d005 --- /dev/null +++ b/debian/patches/debian/iwlwifi-do-not-request-unreleased-firmware.patch @@ -0,0 +1,28 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: iwlwifi: Do not request unreleased firmware for IWL6000 +Bug-Debian: https://bugs.debian.org/689416 +Forwarded: not-needed + +The iwlwifi driver currently supports firmware API versions 4-6 for +these devices. It will request the file for the latest supported +version and then fall back to earlier versions. However, the latest +version that has actually been released is 4, so we expect the +requests for versions 6 and then 5 to fail. + +The installer appears to report any failed request, and it is probably +not easy to detect that this particular failure is harmless. So stop +requesting the unreleased firmware. + +Index: linux/drivers/net/wireless/intel/iwlwifi/cfg/6000.c +=================================================================== +--- linux.orig/drivers/net/wireless/intel/iwlwifi/cfg/6000.c ++++ linux/drivers/net/wireless/intel/iwlwifi/cfg/6000.c +@@ -32,7 +32,7 @@ + #include "dvm/commands.h" /* needed for BT for now */ + + /* Highest firmware API version supported */ +-#define IWL6000_UCODE_API_MAX 6 ++#define IWL6000_UCODE_API_MAX 4 /* v5-6 are supported but not released */ + #define IWL6050_UCODE_API_MAX 5 + #define IWL6000G2_UCODE_API_MAX 6 + #define IWL6035_UCODE_API_MAX 6 diff --git a/debian/patches/debian/kernelvariables.patch b/debian/patches/debian/kernelvariables.patch new file mode 100644 index 000000000..d33dad595 --- /dev/null +++ b/debian/patches/debian/kernelvariables.patch @@ -0,0 +1,81 @@ +From: Bastian Blank <waldi@debian.org> +Subject: kbuild: Make the toolchain variables easily overwritable +Date: Sun, 22 Feb 2009 15:39:35 +0100 +Forwarded: not-needed + +Allow make variables to be overridden for each flavour by a file in +the build tree, .kernelvariables. + +We currently use this for ARCH, KERNELRELEASE, CC, and in some cases +also CROSS_COMPILE, CFLAGS_KERNEL and CFLAGS_MODULE. + +This file can only be read after we establish the build tree, and all +use of $(ARCH) needs to be moved after this. + +Index: linux/Makefile +=================================================================== +--- linux.orig/Makefile ++++ linux/Makefile +@@ -321,31 +321,6 @@ include scripts/subarch.include + # Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile + ARCH ?= $(SUBARCH) + +-# Architecture as present in compile.h +-UTS_MACHINE := $(ARCH) +-SRCARCH := $(ARCH) +- +-# Additional ARCH settings for x86 +-ifeq ($(ARCH),i386) +- SRCARCH := x86 +-endif +-ifeq ($(ARCH),x86_64) +- SRCARCH := x86 +-endif +- +-# Additional ARCH settings for sparc +-ifeq ($(ARCH),sparc32) +- SRCARCH := sparc +-endif +-ifeq ($(ARCH),sparc64) +- SRCARCH := sparc +-endif +- +-# Additional ARCH settings for sh +-ifeq ($(ARCH),sh64) +- SRCARCH := sh +-endif +- + KCONFIG_CONFIG ?= .config + export KCONFIG_CONFIG + +@@ -399,6 +374,30 @@ CFLAGS_KERNEL = + AFLAGS_KERNEL = + LDFLAGS_vmlinux = + ++-include $(obj)/.kernelvariables ++ ++# Architecture as present in compile.h ++UTS_MACHINE := $(ARCH) ++SRCARCH := $(ARCH) ++ ++# Additional ARCH settings for x86 ++ifeq ($(ARCH),i386) ++ SRCARCH := x86 ++endif ++ifeq ($(ARCH),x86_64) ++ SRCARCH := x86 ++endif ++ ++# Additional ARCH settings for sparc ++ifeq ($(ARCH),sparc64) ++ SRCARCH := sparc ++endif ++ ++# Additional ARCH settings for sh ++ifeq ($(ARCH),sh64) ++ SRCARCH := sh ++endif ++ + # Use USERINCLUDE when you must reference the UAPI directories only. + USERINCLUDE := \ + -I$(srctree)/arch/$(SRCARCH)/include/uapi \ diff --git a/debian/patches/debian/mips-boston-disable-its.patch b/debian/patches/debian/mips-boston-disable-its.patch new file mode 100644 index 000000000..ad93dfa8a --- /dev/null +++ b/debian/patches/debian/mips-boston-disable-its.patch @@ -0,0 +1,22 @@ +From: YunQiang Su <syq@debian.org> +Date: Mon, 14 May 2018 16:16:18 +0800 +Subject: Disable uImage generation for mips generic +Forwarded: not-needed + +MIPS generic trys to generate uImage when build, which then ask for +u-boot-tools. + +Index: linux/arch/mips/generic/Platform +=================================================================== +--- linux.orig/arch/mips/generic/Platform ++++ linux/arch/mips/generic/Platform +@@ -11,9 +11,7 @@ + platform-$(CONFIG_MIPS_GENERIC) += generic/ + cflags-$(CONFIG_MIPS_GENERIC) += -I$(srctree)/arch/mips/include/asm/mach-generic + load-$(CONFIG_MIPS_GENERIC) += 0xffffffff80100000 +-all-$(CONFIG_MIPS_GENERIC) := vmlinux.gz.itb + +-its-y := vmlinux.its.S + its-$(CONFIG_FIT_IMAGE_FDT_BOSTON) += board-boston.its.S + its-$(CONFIG_FIT_IMAGE_FDT_NI169445) += board-ni169445.its.S + its-$(CONFIG_FIT_IMAGE_FDT_OCELOT_PCB123) += board-ocelot_pcb123.its.S diff --git a/debian/patches/debian/mips-disable-werror.patch b/debian/patches/debian/mips-disable-werror.patch new file mode 100644 index 000000000..37da74ce3 --- /dev/null +++ b/debian/patches/debian/mips-disable-werror.patch @@ -0,0 +1,25 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 13 Sep 2010 02:16:18 +0100 +Subject: [PATCH] Partially revert "MIPS: Add -Werror to arch/mips/Kbuild" +Forwarded: not-needed + +This reverts commits 66f9ba101f54bda63ab1db97f9e9e94763d0651b and +5373633cc9253ba82547473e899cab141c54133e. + +We really don't want to add -Werror anywhere. +--- +Index: linux/arch/mips/Kbuild +=================================================================== +--- linux.orig/arch/mips/Kbuild ++++ linux/arch/mips/Kbuild +@@ -1,10 +1,3 @@ +-# Fail on warnings - also for files referenced in subdirs +-# -Werror can be disabled for specific files using: +-# CFLAGS_<file.o> := -Wno-error +-ifeq ($(W),) +-subdir-ccflags-y := -Werror +-endif +- + # platform specific definitions + include arch/mips/Kbuild.platforms + obj-y := $(platform-y) diff --git a/debian/patches/debian/ntfs-mark-it-as-broken.patch b/debian/patches/debian/ntfs-mark-it-as-broken.patch new file mode 100644 index 000000000..19892c9f0 --- /dev/null +++ b/debian/patches/debian/ntfs-mark-it-as-broken.patch @@ -0,0 +1,21 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Thu, 25 Apr 2019 15:31:33 +0100 +Subject: ntfs: mark it as broken + +NTFS has unfixed issues CVE-2018-12929, CVE-2018-12930, and +CVE-2018-12931. ntfs-3g is a better supported alternative. + +Make sure it can't be enabled even in custom kernels. + +--- +Index: linux/fs/ntfs/Kconfig +=================================================================== +--- linux.orig/fs/ntfs/Kconfig ++++ linux/fs/ntfs/Kconfig +@@ -1,5 +1,6 @@ + config NTFS_FS + tristate "NTFS file system support" ++ depends on BROKEN + select NLS + help + NTFS is the file system of Microsoft Windows NT, 2000, XP and 2003. diff --git a/debian/patches/debian/overlayfs-permit-mounts-in-userns.patch b/debian/patches/debian/overlayfs-permit-mounts-in-userns.patch new file mode 100644 index 000000000..b951744e5 --- /dev/null +++ b/debian/patches/debian/overlayfs-permit-mounts-in-userns.patch @@ -0,0 +1,59 @@ +From: Nicolas Schier <nicolas@fjasle.eu> +Subject: ovl: permit overlayfs mounts in user namespaces (taints kernel) +Date: Mon, 19 Nov 2018 20:36:14 +0100 + +Permit overlayfs mounts within user namespaces to allow utilisation of e.g. +unprivileged LXC overlay snapshots. + +Except by the Ubuntu community [1], overlayfs mounts in user namespaces are +expected to be a security risk [2] and thus are not enabled on upstream +Linux kernels. For the non-Ubuntu users that have to stick to unprivileged +overlay-based LXCs, this meant to patch and compile the kernel manually. +Instead, adding the kernel tainting 'permit_mounts_in_userns' module +parameter allows a kind of a user-friendly way to enable the feature. + +Testable with: + + sudo modprobe overlay permit_mounts_in_userns=1 + sudo sysctl -w kernel.unprivileged_userns_clone=1 + mkdir -p lower upper work mnt + unshare --map-root-user --mount \ + mount -t overlay none mnt \ + -o lowerdir=lower,upperdir=upper,workdir=work + +[1]: Ubuntu allows unprivileged mounting of overlay filesystem +https://lists.ubuntu.com/archives/kernel-team/2014-February/038091.html + +[2]: User namespaces + overlayfs = root privileges +https://lwn.net/Articles/671641/ + +Signed-off-by: Nicolas Schier <nicolas@fjasle.eu> + +Index: linux/fs/overlayfs/super.c +=================================================================== +--- linux.orig/fs/overlayfs/super.c ++++ linux/fs/overlayfs/super.c +@@ -56,6 +56,11 @@ module_param_named(xino_auto, ovl_xino_a + MODULE_PARM_DESC(ovl_xino_auto_def, + "Auto enable xino feature"); + ++static bool ovl_permit_mounts_in_userns; ++module_param_named_unsafe(permit_mounts_in_userns, ovl_permit_mounts_in_userns, ++ bool, 0444); ++MODULE_PARM_DESC(permit_mounts_in_userns, "Permit mounts in user namespaces"); ++ + static void ovl_entry_stack_free(struct ovl_entry *oe) + { + unsigned int i; +@@ -1715,6 +1720,11 @@ static int __init ovl_init(void) + if (ovl_inode_cachep == NULL) + return -ENOMEM; + ++ if (unlikely(ovl_permit_mounts_in_userns)) { ++ pr_warn("overlayfs: Allowing overlay mounts in user namespaces bears security risks\n"); ++ ovl_fs_type.fs_flags |= FS_USERNS_MOUNT; ++ } ++ + err = register_filesystem(&ovl_fs_type); + if (err) + kmem_cache_destroy(ovl_inode_cachep); diff --git a/debian/patches/debian/powerpcspe-omit-uimage.patch b/debian/patches/debian/powerpcspe-omit-uimage.patch new file mode 100644 index 000000000..48606a174 --- /dev/null +++ b/debian/patches/debian/powerpcspe-omit-uimage.patch @@ -0,0 +1,45 @@ +Description: Prevent building uImage with missing mkimage + On some powerpc platforms, CONFIG_DEFAULT_UIMAGE is selected automatically, + which leads to uImage being built automatically with mkimage. This tool is not + available in linux's build-dependencies, and the file is not strictly + necessary, so we are omitting this step in the build process, Debian-specific. +Author: Roland Stigge <stigge@antcom.de> +Bug-Debian: https://bugs.debian.org/708094 +Forwarded: not-needed + +Index: linux/arch/powerpc/boot/Makefile +=================================================================== +--- linux.orig/arch/powerpc/boot/Makefile ++++ linux/arch/powerpc/boot/Makefile +@@ -268,7 +268,6 @@ image-$(CONFIG_PPC_CHRP) += zImage.chrp + image-$(CONFIG_PPC_EFIKA) += zImage.chrp + image-$(CONFIG_PPC_PMAC) += zImage.pmac + image-$(CONFIG_PPC_HOLLY) += dtbImage.holly +-image-$(CONFIG_DEFAULT_UIMAGE) += uImage + image-$(CONFIG_EPAPR_BOOT) += zImage.epapr + + # +@@ -327,23 +326,6 @@ image-$(CONFIG_MPC834x_MDS) += cuImage. + image-$(CONFIG_MPC836x_MDS) += cuImage.mpc836x_mds + image-$(CONFIG_ASP834x) += dtbImage.asp834x-redboot + +-# Board ports in arch/powerpc/platform/85xx/Kconfig +-image-$(CONFIG_MPC8540_ADS) += cuImage.mpc8540ads +-image-$(CONFIG_MPC8560_ADS) += cuImage.mpc8560ads +-image-$(CONFIG_MPC85xx_CDS) += cuImage.mpc8541cds \ +- cuImage.mpc8548cds_32b \ +- cuImage.mpc8555cds +-image-$(CONFIG_MPC85xx_MDS) += cuImage.mpc8568mds +-image-$(CONFIG_MPC85xx_DS) += cuImage.mpc8544ds \ +- cuImage.mpc8572ds +-image-$(CONFIG_TQM8540) += cuImage.tqm8540 +-image-$(CONFIG_TQM8541) += cuImage.tqm8541 +-image-$(CONFIG_TQM8548) += cuImage.tqm8548 +-image-$(CONFIG_TQM8555) += cuImage.tqm8555 +-image-$(CONFIG_TQM8560) += cuImage.tqm8560 +-image-$(CONFIG_SBC8548) += cuImage.sbc8548 +-image-$(CONFIG_KSI8560) += cuImage.ksi8560 +- + # Board ports in arch/powerpc/platform/86xx/Kconfig + image-$(CONFIG_MVME7100) += dtbImage.mvme7100 + diff --git a/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch b/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch new file mode 100644 index 000000000..451c2923e --- /dev/null +++ b/debian/patches/debian/rds-Disable-auto-loading-as-mitigation-against-local.patch @@ -0,0 +1,31 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 19 Nov 2010 02:12:48 +0000 +Subject: [PATCH 1/3] rds: Disable auto-loading as mitigation against local exploits +Forwarded: not-needed + +Recent review has revealed several bugs in obscure protocol +implementations that can be exploited by local users for denial of +service or privilege escalation. We can mitigate the effect of any +remaining vulnerabilities in such protocols by preventing unprivileged +users from loading the modules, so that they are only exploitable on +systems where the administrator has chosen to load the protocol. + +The 'rds' protocol is one such protocol that has been found to be +vulnerable, and which was not present in the 'lenny' kernel. +Therefore disable auto-loading. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + net/rds/af_rds.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: linux/net/rds/af_rds.c +=================================================================== +--- linux.orig/net/rds/af_rds.c ++++ linux/net/rds/af_rds.c +@@ -836,4 +836,4 @@ MODULE_DESCRIPTION("RDS: Reliable Datagr + " v" DRV_VERSION " (" DRV_RELDATE ")"); + MODULE_VERSION(DRV_VERSION); + MODULE_LICENSE("Dual BSD/GPL"); +-MODULE_ALIAS_NETPROTO(PF_RDS); ++/* MODULE_ALIAS_NETPROTO(PF_RDS); */ diff --git a/debian/patches/debian/revert-objtool-fix-config_stack_validation-y-warning.patch b/debian/patches/debian/revert-objtool-fix-config_stack_validation-y-warning.patch new file mode 100644 index 000000000..6abe64a8f --- /dev/null +++ b/debian/patches/debian/revert-objtool-fix-config_stack_validation-y-warning.patch @@ -0,0 +1,50 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 14 Jan 2018 19:27:18 +0000 +Subject: Revert "objtool: Fix CONFIG_STACK_VALIDATION=y warning for + out-of-tree modules" + +This reverts commit 9f0c18aec620bc9d82268b3cb937568dd07b43ff. This +check doesn't make sense for OOT modules as they should always use +a pre-built objtool. +--- + Makefile | 22 +++++++++++----------- + 1 file changed, 11 insertions(+), 11 deletions(-) + +--- a/Makefile ++++ b/Makefile +@@ -971,17 +971,6 @@ export mod_sign_cmd + + HOST_LIBELF_LIBS = $(shell pkg-config libelf --libs 2>/dev/null || echo -lelf) + +-ifdef CONFIG_STACK_VALIDATION +- has_libelf := $(call try-run,\ +- echo "int main() {}" | $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0) +- ifeq ($(has_libelf),1) +- objtool_target := tools/objtool FORCE +- else +- SKIP_STACK_VALIDATION := 1 +- export SKIP_STACK_VALIDATION +- endif +-endif +- + PHONY += prepare0 + + ifeq ($(KBUILD_EXTMOD),) +@@ -1132,6 +1121,17 @@ uapi-asm-generic: + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.asm-generic \ + src=uapi/asm obj=arch/$(SRCARCH)/include/generated/uapi/asm + ++ifdef CONFIG_STACK_VALIDATION ++ has_libelf := $(call try-run,\ ++ echo "int main() {}" | $(HOSTCC) $(KBUILD_HOSTLDFLAGS) -xc -o /dev/null $(HOST_LIBELF_LIBS) -,1,0) ++ ifeq ($(has_libelf),1) ++ objtool_target := tools/objtool FORCE ++ else ++ SKIP_STACK_VALIDATION := 1 ++ export SKIP_STACK_VALIDATION ++ endif ++endif ++ + PHONY += prepare-objtool + prepare-objtool: $(objtool_target) + ifeq ($(SKIP_STACK_VALIDATION),1) diff --git a/debian/patches/debian/sched-autogroup-disabled.patch b/debian/patches/debian/sched-autogroup-disabled.patch new file mode 100644 index 000000000..20e57105c --- /dev/null +++ b/debian/patches/debian/sched-autogroup-disabled.patch @@ -0,0 +1,21 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: sched: Do not enable autogrouping by default +Date: Wed, 16 Mar 2011 03:17:06 +0000 +Forwarded: not-needed + +We want to provide the option of autogrouping but without enabling +it by default yet. + +Index: linux/kernel/sched/autogroup.c +=================================================================== +--- linux.orig/kernel/sched/autogroup.c ++++ linux/kernel/sched/autogroup.c +@@ -5,7 +5,7 @@ + #include <linux/nospec.h> + #include "sched.h" + +-unsigned int __read_mostly sysctl_sched_autogroup_enabled = 1; ++unsigned int __read_mostly sysctl_sched_autogroup_enabled = 0; + static struct autogroup autogroup_default; + static atomic_t autogroup_seq_nr; + diff --git a/debian/patches/debian/snd-pcsp-disable-autoload.patch b/debian/patches/debian/snd-pcsp-disable-autoload.patch new file mode 100644 index 000000000..2681d4275 --- /dev/null +++ b/debian/patches/debian/snd-pcsp-disable-autoload.patch @@ -0,0 +1,32 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Wed, 05 Feb 2014 23:01:30 +0000 +Subject: snd-pcsp: Disable autoload +Forwarded: not-needed +Bug-Debian: https://bugs.debian.org/697709 + +There are two drivers claiming the platform:pcspkr device: +- pcspkr creates an input(!) device that can only beep +- snd-pcsp creates an equivalent input device plus a PCM device that can + play barely recognisable renditions of sampled sound + +snd-pcsp is blacklisted by the alsa-base package, but not everyone +installs that. On PCs where no sound is wanted at all, both drivers +will still be loaded and one or other will complain that it couldn't +claim the relevant I/O range. + +In case anyone finds snd-pcsp useful, we continue to build it. But +remove the alias, to ensure it's not loaded where it's not wanted. + +Index: linux/sound/drivers/pcsp/pcsp.c +=================================================================== +--- linux.orig/sound/drivers/pcsp/pcsp.c ++++ linux/sound/drivers/pcsp/pcsp.c +@@ -22,7 +22,7 @@ MODULE_AUTHOR("Stas Sergeev <stsp@users. + MODULE_DESCRIPTION("PC-Speaker driver"); + MODULE_LICENSE("GPL"); + MODULE_SUPPORTED_DEVICE("{{PC-Speaker, pcsp}}"); +-MODULE_ALIAS("platform:pcspkr"); ++/*MODULE_ALIAS("platform:pcspkr");*/ + + static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ + static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ diff --git a/debian/patches/debian/tools-perf-install.patch b/debian/patches/debian/tools-perf-install.patch new file mode 100644 index 000000000..8cfd02afd --- /dev/null +++ b/debian/patches/debian/tools-perf-install.patch @@ -0,0 +1,58 @@ +From: Bastian Blank <waldi@debian.org> +Date: Fri, 07 Oct 2011 21:37:52 +0100 +Subject: Install perf scripts non-executable +Forwarded: no + +[bwh: Forward-ported to 4.13] + +Index: linux/tools/perf/Makefile.perf +=================================================================== +--- linux.orig/tools/perf/Makefile.perf ++++ linux/tools/perf/Makefile.perf +@@ -796,8 +796,8 @@ endif + ifndef NO_LIBPERL + $(call QUIET_INSTALL, perl-scripts) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \ +- $(INSTALL) scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \ +- $(INSTALL) scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \ ++ $(INSTALL) -m 644 scripts/perl/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/Perf-Trace-Util/lib/Perf/Trace'; \ ++ $(INSTALL) -m 644 scripts/perl/*.pl -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl'; \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin'; \ + $(INSTALL) scripts/perl/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/perl/bin' + endif +@@ -805,27 +805,27 @@ ifndef NO_LIBPYTHON + $(call QUIET_INSTALL, python-scripts) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin'; \ +- $(INSTALL) scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \ +- $(INSTALL) scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'; \ ++ $(INSTALL) -m 644 scripts/python/Perf-Trace-Util/lib/Perf/Trace/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/Perf-Trace-Util/lib/Perf/Trace'; \ ++ $(INSTALL) -m 644 scripts/python/*.py -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python'; \ + $(INSTALL) scripts/python/bin/* -t '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/scripts/python/bin' + endif + $(call QUIET_INSTALL, perf_completion-script) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \ +- $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf_$(VERSION)' ++ $(INSTALL) -m 644 perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf_$(VERSION)' + $(call QUIET_INSTALL, perf-tip) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(tip_instdir_SQ)'; \ +- $(INSTALL) Documentation/tips.txt -t '$(DESTDIR_SQ)$(tip_instdir_SQ)' ++ $(INSTALL) -m 644 Documentation/tips.txt -t '$(DESTDIR_SQ)$(tip_instdir_SQ)' + + install-tests: all install-gtk + $(call QUIET_INSTALL, tests) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ +- $(INSTALL) tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ ++ $(INSTALL) -m 644 tests/attr.py '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests'; \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ +- $(INSTALL) tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ ++ $(INSTALL) -m 644 tests/attr/* '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/attr'; \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ +- $(INSTALL) tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ ++ $(INSTALL) -m 644 tests/shell/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell'; \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib'; \ +- $(INSTALL) tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib' ++ $(INSTALL) -m 644 tests/shell/lib/*.sh '$(DESTDIR_SQ)$(perfexec_instdir_SQ)/tests/shell/lib' + + install-bin: install-tools install-tests install-traceevent-plugins + diff --git a/debian/patches/debian/tools-perf-version.patch b/debian/patches/debian/tools-perf-version.patch new file mode 100644 index 000000000..6833bb7a7 --- /dev/null +++ b/debian/patches/debian/tools-perf-version.patch @@ -0,0 +1,119 @@ +From: Bastian Blank <waldi@debian.org> +Date: Mon, 26 Sep 2011 13:53:12 +0100 +Subject: Create manpages and binaries including the version +Forwarded: no + +[bwh: Fix version insertion in perf man page cross-references and perf +man page title. Install bash_completion script for perf with a +version-dependent name. And do the same for trace.] + +Index: linux/tools/perf/Makefile.perf +=================================================================== +--- linux.orig/tools/perf/Makefile.perf ++++ linux/tools/perf/Makefile.perf +@@ -759,23 +759,23 @@ endif + install-tools: all install-gtk + $(call QUIET_INSTALL, binaries) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(bindir_SQ)'; \ +- $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)'; \ +- $(LN) '$(DESTDIR_SQ)$(bindir_SQ)/perf' '$(DESTDIR_SQ)$(bindir_SQ)/trace' ++ $(INSTALL) $(OUTPUT)perf '$(DESTDIR_SQ)$(bindir_SQ)/perf_$(VERSION)'; \ ++ $(LN) '$(DESTDIR_SQ)$(bindir_SQ)/perf_$(VERSION)' '$(DESTDIR_SQ)$(bindir_SQ)/trace_$(VERSION)' ++ $(call QUIET_INSTALL, libexec) \ ++ $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' + ifndef NO_PERF_READ_VDSO32 + $(call QUIET_INSTALL, perf-read-vdso32) \ +- $(INSTALL) $(OUTPUT)perf-read-vdso32 '$(DESTDIR_SQ)$(bindir_SQ)'; ++ $(INSTALL) $(OUTPUT)perf-read-vdso32 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'; + endif + ifndef NO_PERF_READ_VDSOX32 + $(call QUIET_INSTALL, perf-read-vdsox32) \ +- $(INSTALL) $(OUTPUT)perf-read-vdsox32 '$(DESTDIR_SQ)$(bindir_SQ)'; ++ $(INSTALL) $(OUTPUT)perf-read-vdsox32 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)'; + endif + ifndef NO_JVMTI + $(call QUIET_INSTALL, $(LIBJVMTI)) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(libdir_SQ)'; \ + $(INSTALL) $(OUTPUT)$(LIBJVMTI) '$(DESTDIR_SQ)$(libdir_SQ)'; + endif +- $(call QUIET_INSTALL, libexec) \ +- $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perfexec_instdir_SQ)' + ifndef NO_LIBBPF + $(call QUIET_INSTALL, bpf-headers) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(perf_include_instdir_SQ)/bpf'; \ +@@ -811,7 +811,7 @@ ifndef NO_LIBPYTHON + endif + $(call QUIET_INSTALL, perf_completion-script) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d'; \ +- $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf' ++ $(INSTALL) perf-completion.sh '$(DESTDIR_SQ)$(sysconfdir_SQ)/bash_completion.d/perf_$(VERSION)' + $(call QUIET_INSTALL, perf-tip) \ + $(INSTALL) -d -m 755 '$(DESTDIR_SQ)$(tip_instdir_SQ)'; \ + $(INSTALL) Documentation/tips.txt -t '$(DESTDIR_SQ)$(tip_instdir_SQ)' +@@ -836,7 +836,7 @@ install-python_ext: + + # 'make install-doc' should call 'make -C Documentation install' + $(INSTALL_DOC_TARGETS): +- $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=) ++ $(QUIET_SUBDIR0)Documentation $(QUIET_SUBDIR1) $(@:-doc=) VERSION=$(VERSION) + + ### Cleaning rules + +Index: linux/tools/perf/Documentation/Makefile +=================================================================== +--- linux.orig/tools/perf/Documentation/Makefile ++++ linux/tools/perf/Documentation/Makefile +@@ -194,14 +194,16 @@ ifdef missing_tools + $(error "You need to install $(missing_tools) for man pages") + endif + +-do-install-man: man ++do-install-man: $(addprefix install-man-,$(_DOC_MAN1)) ++ ++install-man-perf.1: $(OUTPUT)perf.1 ++ $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir) ++ sed -e 's/"PERF"/"PERF_$(VERSION)"/' -e 's/fBperf-/fBperf_$(VERSION)-/g' $^ > $(DESTDIR)$(man1dir)/perf_$(VERSION).1 ++ ++install-man-perf%.1: $(OUTPUT)perf%.1 + $(call QUIET_INSTALL, Documentation-man) \ + $(INSTALL) -d -m 755 $(DESTDIR)$(man1dir); \ +-# $(INSTALL) -d -m 755 $(DESTDIR)$(man5dir); \ +-# $(INSTALL) -d -m 755 $(DESTDIR)$(man7dir); \ +- $(INSTALL) -m 644 $(DOC_MAN1) $(DESTDIR)$(man1dir); \ +-# $(INSTALL) -m 644 $(DOC_MAN5) $(DESTDIR)$(man5dir); \ +-# $(INSTALL) -m 644 $(DOC_MAN7) $(DESTDIR)$(man7dir) ++ sed -e 's/"PERF\\-/"PERF_$(VERSION)\\-/' -e 's/fBperf-/fBperf_$(VERSION)-/g' $^ > $(DESTDIR)$(man1dir)/perf_$(VERSION)$*.1 + + install-man: check-man-tools man do-install-man + +Index: linux/tools/perf/util/Build +=================================================================== +--- linux.orig/tools/perf/util/Build ++++ linux/tools/perf/util/Build +@@ -193,6 +193,7 @@ CFLAGS_libstring.o += -Wno-unused-pa + CFLAGS_hweight.o += -Wno-unused-parameter -DETC_PERFCONFIG="BUILD_STR($(ETC_PERFCONFIG_SQ))" + CFLAGS_parse-events.o += -Wno-redundant-decls + CFLAGS_header.o += -include $(OUTPUT)PERF-VERSION-FILE ++CFLAGS_vdso.o += -DPERFEXECDIR='"$(perfexec_instdir_SQ)"' + + $(OUTPUT)util/kallsyms.o: ../lib/symbol/kallsyms.c FORCE + $(call rule_mkdir) +Index: linux/tools/perf/util/vdso.c +=================================================================== +--- linux.orig/tools/perf/util/vdso.c ++++ linux/tools/perf/util/vdso.c +@@ -52,12 +52,12 @@ static struct vdso_info *vdso_info__new( + .vdso32 = { + .temp_file_name = VDSO__TEMP_FILE_NAME, + .dso_name = DSO__NAME_VDSO32, +- .read_prog = "perf-read-vdso32", ++ .read_prog = PERFEXECDIR "/perf-read-vdso32", + }, + .vdsox32 = { + .temp_file_name = VDSO__TEMP_FILE_NAME, + .dso_name = DSO__NAME_VDSOX32, +- .read_prog = "perf-read-vdsox32", ++ .read_prog = PERFEXECDIR "/perf-read-vdsox32", + }, + #endif + }; diff --git a/debian/patches/debian/uname-version-timestamp.patch b/debian/patches/debian/uname-version-timestamp.patch new file mode 100644 index 000000000..74cbebbde --- /dev/null +++ b/debian/patches/debian/uname-version-timestamp.patch @@ -0,0 +1,35 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: Make mkcompile_h accept an alternate timestamp string +Date: Tue, 12 May 2015 19:29:22 +0100 +Forwarded: not-needed + +We want to include the Debian version in the utsname::version string +instead of a full timestamp string. However, we still need to provide +a standard timestamp string for gen_initramfs_list.sh to make the +kernel image reproducible. + +Make mkcompile_h use $KBUILD_BUILD_VERSION_TIMESTAMP in preference to +$KBUILD_BUILD_TIMESTAMP. + +Index: linux/scripts/mkcompile_h +=================================================================== +--- linux.orig/scripts/mkcompile_h ++++ linux/scripts/mkcompile_h +@@ -33,10 +33,14 @@ else + VERSION=$KBUILD_BUILD_VERSION + fi + +-if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then +- TIMESTAMP=`date` ++if [ -z "$KBUILD_BUILD_VERSION_TIMESTAMP" ]; then ++ if [ -z "$KBUILD_BUILD_TIMESTAMP" ]; then ++ TIMESTAMP=`date` ++ else ++ TIMESTAMP=$KBUILD_BUILD_TIMESTAMP ++ fi + else +- TIMESTAMP=$KBUILD_BUILD_TIMESTAMP ++ TIMESTAMP=$KBUILD_BUILD_VERSION_TIMESTAMP + fi + if test -z "$KBUILD_BUILD_USER"; then + LINUX_COMPILE_BY=$(whoami | sed 's/\\/\\\\/') diff --git a/debian/patches/debian/version.patch b/debian/patches/debian/version.patch new file mode 100644 index 000000000..4447df7bb --- /dev/null +++ b/debian/patches/debian/version.patch @@ -0,0 +1,177 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: Include package version along with kernel release in stack traces +Date: Tue, 24 Jul 2012 03:13:10 +0100 +Forwarded: not-needed + +For distribution binary packages we assume +$DISTRIBUTION_OFFICIAL_BUILD, $DISTRIBUTOR and $DISTRIBUTION_VERSION +are set. + +Index: linux/Makefile +=================================================================== +--- linux.orig/Makefile ++++ linux/Makefile +@@ -1087,7 +1087,8 @@ endif + # that need to depend on updated CONFIG_* values can be checked here. + prepare2: prepare3 outputmakefile asm-generic + +-prepare1: prepare2 $(version_h) $(autoksyms_h) include/generated/utsrelease.h ++prepare1: prepare2 $(version_h) $(autoksyms_h) include/generated/utsrelease.h \ ++ include/generated/package.h + $(cmd_crmodverdir) + + archprepare: archheaders archscripts prepare1 scripts_basic +@@ -1139,6 +1140,16 @@ define filechk_version.h + echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))';) + endef + ++ifneq ($(DISTRIBUTION_OFFICIAL_BUILD),) ++define filechk_package.h ++ echo \#define LINUX_PACKAGE_ID \" $(DISTRIBUTOR) $(DISTRIBUTION_VERSION)\" ++endef ++else ++define filechk_package.h ++ echo \#define LINUX_PACKAGE_ID \"\" ++endef ++endif ++ + $(version_h): FORCE + $(call filechk,version.h) + $(Q)rm -f $(old_version_h) +@@ -1146,6 +1157,9 @@ $(version_h): FORCE + include/generated/utsrelease.h: include/config/kernel.release FORCE + $(call filechk,utsrelease.h) + ++include/generated/package.h: $(srctree)/Makefile FORCE ++ $(call filechk,package.h) ++ + PHONY += headerdep + headerdep: + $(Q)find $(srctree)/include/ -name '*.h' | xargs --max-args 1 \ +Index: linux/arch/x86/um/sysrq_64.c +=================================================================== +--- linux.orig/arch/x86/um/sysrq_64.c ++++ linux/arch/x86/um/sysrq_64.c +@@ -9,6 +9,7 @@ + #include <linux/sched.h> + #include <linux/sched/debug.h> + #include <linux/utsname.h> ++#include <generated/package.h> + #include <asm/current.h> + #include <asm/ptrace.h> + #include <asm/sysrq.h> +@@ -17,8 +18,9 @@ void show_regs(struct pt_regs *regs) + { + printk("\n"); + print_modules(); +- printk(KERN_INFO "Pid: %d, comm: %.20s %s %s\n", task_pid_nr(current), +- current->comm, print_tainted(), init_utsname()->release); ++ printk(KERN_INFO "Pid: %d, comm: %.20s %s %s%s\n", task_pid_nr(current), ++ current->comm, print_tainted(), init_utsname()->release, ++ LINUX_PACKAGE_ID); + printk(KERN_INFO "RIP: %04lx:[<%016lx>]\n", PT_REGS_CS(regs) & 0xffff, + PT_REGS_IP(regs)); + printk(KERN_INFO "RSP: %016lx EFLAGS: %08lx\n", PT_REGS_SP(regs), +Index: linux/arch/ia64/kernel/process.c +=================================================================== +--- linux.orig/arch/ia64/kernel/process.c ++++ linux/arch/ia64/kernel/process.c +@@ -34,6 +34,7 @@ + #include <linux/utsname.h> + #include <linux/tracehook.h> + #include <linux/rcupdate.h> ++#include <generated/package.h> + + #include <asm/cpu.h> + #include <asm/delay.h> +@@ -104,9 +105,9 @@ show_regs (struct pt_regs *regs) + print_modules(); + printk("\n"); + show_regs_print_info(KERN_DEFAULT); +- printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s)\n", ++ printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s (%s%s)\n", + regs->cr_ipsr, regs->cr_ifs, ip, print_tainted(), +- init_utsname()->release); ++ init_utsname()->release, LINUX_PACKAGE_ID); + printk("ip is at %pS\n", (void *)ip); + printk("unat: %016lx pfs : %016lx rsc : %016lx\n", + regs->ar_unat, regs->ar_pfs, regs->ar_rsc); +Index: linux/arch/powerpc/kernel/process.c +=================================================================== +--- linux.orig/arch/powerpc/kernel/process.c ++++ linux/arch/powerpc/kernel/process.c +@@ -43,6 +43,7 @@ + #include <linux/uaccess.h> + #include <linux/elf-randomize.h> + #include <linux/pkeys.h> ++#include <generated/package.h> + + #include <asm/pgtable.h> + #include <asm/io.h> +@@ -1424,8 +1425,9 @@ void show_regs(struct pt_regs * regs) + + printk("NIP: "REG" LR: "REG" CTR: "REG"\n", + regs->nip, regs->link, regs->ctr); +- printk("REGS: %px TRAP: %04lx %s (%s)\n", +- regs, regs->trap, print_tainted(), init_utsname()->release); ++ printk("REGS: %px TRAP: %04lx %s (%s%s)\n", ++ regs, regs->trap, print_tainted(), init_utsname()->release, ++ LINUX_PACKAGE_ID); + printk("MSR: "REG" ", regs->msr); + print_msr_bits(regs->msr); + pr_cont(" CR: %08lx XER: %08lx\n", regs->ccr, regs->xer); +Index: linux/kernel/hung_task.c +=================================================================== +--- linux.orig/kernel/hung_task.c ++++ linux/kernel/hung_task.c +@@ -21,6 +21,7 @@ + #include <linux/sched/debug.h> + + #include <trace/events/sched.h> ++#include <generated/package.h> + + /* + * The number of tasks checked: +@@ -127,10 +128,11 @@ static void check_hung_task(struct task_ + sysctl_hung_task_warnings--; + pr_err("INFO: task %s:%d blocked for more than %ld seconds.\n", + t->comm, t->pid, timeout); +- pr_err(" %s %s %.*s\n", ++ pr_err(" %s %s %.*s%s\n", + print_tainted(), init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), +- init_utsname()->version); ++ init_utsname()->version, ++ LINUX_PACKAGE_ID); + pr_err("\"echo 0 > /proc/sys/kernel/hung_task_timeout_secs\"" + " disables this message.\n"); + sched_show_task(t); +Index: linux/lib/dump_stack.c +=================================================================== +--- linux.orig/lib/dump_stack.c ++++ linux/lib/dump_stack.c +@@ -12,6 +12,7 @@ + #include <linux/atomic.h> + #include <linux/kexec.h> + #include <linux/utsname.h> ++#include <generated/package.h> + + static char dump_stack_arch_desc_str[128]; + +@@ -44,13 +45,14 @@ void __init dump_stack_set_arch_desc(con + */ + void dump_stack_print_info(const char *log_lvl) + { +- printk("%sCPU: %d PID: %d Comm: %.20s %s%s %s %.*s\n", ++ printk("%sCPU: %d PID: %d Comm: %.20s %s%s %s %.*s%s\n", + log_lvl, raw_smp_processor_id(), current->pid, current->comm, + kexec_crash_loaded() ? "Kdump: loaded " : "", + print_tainted(), + init_utsname()->release, + (int)strcspn(init_utsname()->version, " "), +- init_utsname()->version); ++ init_utsname()->version, ++ LINUX_PACKAGE_ID); + + if (dump_stack_arch_desc_str[0] != '\0') + printk("%sHardware name: %s\n", diff --git a/debian/patches/debian/wireless-add-debian-wireless-regdb-certificates.patch b/debian/patches/debian/wireless-add-debian-wireless-regdb-certificates.patch new file mode 100644 index 000000000..112683839 --- /dev/null +++ b/debian/patches/debian/wireless-add-debian-wireless-regdb-certificates.patch @@ -0,0 +1,963 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 13 Apr 2018 20:10:28 +0100 +Subject: wireless: Add Debian wireless-regdb certificates +Forwarded: not-needed + +This hex dump is generated using: + +{ + for cert in debian/certs/wireless-regdb-*.pem; do + openssl x509 -in $cert -outform der; + done +} | hexdump -v -e '1/1 "0x%.2x," "\n"' > net/wireless/certs/debian.hex + +--- +Index: linux/net/wireless/certs/debian.hex +=================================================================== +--- /dev/null ++++ linux/net/wireless/certs/debian.hex +@@ -0,0 +1,944 @@ ++0x30, ++0x82, ++0x03, ++0xac, ++0x30, ++0x82, ++0x02, ++0x94, ++0xa0, ++0x03, ++0x02, ++0x01, ++0x02, ++0x02, ++0x09, ++0x00, ++0xd9, ++0xb1, ++0xe4, ++0x6f, ++0x28, ++0xf3, ++0xd4, ++0x97, ++0x30, ++0x0d, ++0x06, ++0x09, ++0x2a, ++0x86, ++0x48, ++0x86, ++0xf7, ++0x0d, ++0x01, ++0x01, ++0x0b, ++0x05, ++0x00, ++0x30, ++0x6b, ++0x31, ++0x0b, ++0x30, ++0x09, ++0x06, ++0x03, ++0x55, ++0x04, ++0x06, ++0x13, ++0x02, ++0x47, ++0x42, ++0x31, ++0x13, ++0x30, ++0x11, ++0x06, ++0x03, ++0x55, ++0x04, ++0x07, ++0x0c, ++0x0a, ++0x4d, ++0x61, ++0x6e, ++0x63, ++0x68, ++0x65, ++0x73, ++0x74, ++0x65, ++0x72, ++0x31, ++0x0f, ++0x30, ++0x0d, ++0x06, ++0x03, ++0x55, ++0x04, ++0x0a, ++0x0c, ++0x06, ++0x44, ++0x65, ++0x62, ++0x69, ++0x61, ++0x6e, ++0x31, ++0x16, ++0x30, ++0x14, ++0x06, ++0x03, ++0x55, ++0x04, ++0x03, ++0x0c, ++0x0d, ++0x42, ++0x65, ++0x6e, ++0x20, ++0x48, ++0x75, ++0x74, ++0x63, ++0x68, ++0x69, ++0x6e, ++0x67, ++0x73, ++0x31, ++0x1e, ++0x30, ++0x1c, ++0x06, ++0x09, ++0x2a, ++0x86, ++0x48, ++0x86, ++0xf7, ++0x0d, ++0x01, ++0x09, ++0x01, ++0x16, ++0x0f, ++0x62, ++0x65, ++0x6e, ++0x68, ++0x40, ++0x64, ++0x65, ++0x62, ++0x69, ++0x61, ++0x6e, ++0x2e, ++0x6f, ++0x72, ++0x67, ++0x30, ++0x1e, ++0x17, ++0x0d, ++0x31, ++0x38, ++0x30, ++0x34, ++0x31, ++0x33, ++0x31, ++0x38, ++0x32, ++0x31, ++0x34, ++0x36, ++0x5a, ++0x17, ++0x0d, ++0x31, ++0x38, ++0x30, ++0x35, ++0x31, ++0x33, ++0x31, ++0x38, ++0x32, ++0x31, ++0x34, ++0x36, ++0x5a, ++0x30, ++0x6b, ++0x31, ++0x0b, ++0x30, ++0x09, ++0x06, ++0x03, ++0x55, ++0x04, ++0x06, ++0x13, ++0x02, ++0x47, ++0x42, ++0x31, ++0x13, ++0x30, ++0x11, ++0x06, ++0x03, ++0x55, ++0x04, ++0x07, ++0x0c, ++0x0a, ++0x4d, ++0x61, ++0x6e, ++0x63, ++0x68, ++0x65, ++0x73, ++0x74, ++0x65, ++0x72, ++0x31, ++0x0f, ++0x30, ++0x0d, ++0x06, ++0x03, ++0x55, ++0x04, ++0x0a, ++0x0c, ++0x06, ++0x44, ++0x65, ++0x62, ++0x69, ++0x61, ++0x6e, ++0x31, ++0x16, ++0x30, ++0x14, ++0x06, ++0x03, ++0x55, ++0x04, ++0x03, ++0x0c, ++0x0d, ++0x42, ++0x65, ++0x6e, ++0x20, ++0x48, ++0x75, ++0x74, ++0x63, ++0x68, ++0x69, ++0x6e, ++0x67, ++0x73, ++0x31, ++0x1e, ++0x30, ++0x1c, ++0x06, ++0x09, ++0x2a, ++0x86, ++0x48, ++0x86, ++0xf7, ++0x0d, ++0x01, ++0x09, ++0x01, ++0x16, ++0x0f, ++0x62, ++0x65, ++0x6e, ++0x68, ++0x40, ++0x64, ++0x65, ++0x62, ++0x69, ++0x61, ++0x6e, ++0x2e, ++0x6f, ++0x72, ++0x67, ++0x30, ++0x82, ++0x01, ++0x22, ++0x30, ++0x0d, ++0x06, ++0x09, ++0x2a, ++0x86, ++0x48, ++0x86, ++0xf7, ++0x0d, ++0x01, ++0x01, ++0x01, ++0x05, ++0x00, ++0x03, ++0x82, ++0x01, ++0x0f, ++0x00, ++0x30, ++0x82, ++0x01, ++0x0a, ++0x02, ++0x82, ++0x01, ++0x01, ++0x00, ++0x9d, ++0xe1, ++0x77, ++0xa0, ++0x24, ++0xa0, ++0xd5, ++0x79, ++0x65, ++0x3a, ++0x07, ++0x90, ++0xc9, ++0xf6, ++0xa5, ++0xa6, ++0x1f, ++0x84, ++0x1c, ++0x23, ++0x07, ++0x4b, ++0x4f, ++0xa5, ++0x03, ++0xc6, ++0x0f, ++0xf7, ++0x54, ++0xd5, ++0x8b, ++0x7e, ++0x79, ++0x81, ++0x00, ++0xd2, ++0xe9, ++0x3d, ++0xf4, ++0x97, ++0xfe, ++0x84, ++0xcd, ++0x55, ++0xbd, ++0xc9, ++0x8f, ++0x21, ++0x57, ++0x88, ++0x06, ++0x39, ++0x90, ++0x66, ++0x41, ++0x26, ++0x79, ++0x2c, ++0xca, ++0x3f, ++0x95, ++0x87, ++0x01, ++0x11, ++0x2f, ++0x2f, ++0xb0, ++0xe1, ++0x0b, ++0x43, ++0xfc, ++0x5f, ++0x2f, ++0x4f, ++0x67, ++0x04, ++0xdb, ++0x4d, ++0xb7, ++0x72, ++0x4d, ++0xd1, ++0xc5, ++0x76, ++0x73, ++0x4d, ++0x91, ++0x69, ++0xb0, ++0x71, ++0x17, ++0x36, ++0xea, ++0xab, ++0x0a, ++0x3a, ++0xcd, ++0x95, ++0x9b, ++0x76, ++0x1b, ++0x8e, ++0x21, ++0x17, ++0x8f, ++0xc5, ++0x02, ++0xbf, ++0x24, ++0xc7, ++0xc0, ++0x40, ++0xb1, ++0x3b, ++0xc4, ++0x80, ++0x7c, ++0x71, ++0xa5, ++0x51, ++0xdc, ++0xf7, ++0x3a, ++0x58, ++0x7f, ++0xb1, ++0x07, ++0x81, ++0x8a, ++0x10, ++0xd1, ++0xf6, ++0x93, ++0x17, ++0x71, ++0xe0, ++0xfa, ++0x51, ++0x79, ++0x15, ++0xd4, ++0xd7, ++0x8f, ++0xad, ++0xbd, ++0x6f, ++0x38, ++0xe1, ++0x26, ++0x7d, ++0xbc, ++0xf0, ++0x3e, ++0x80, ++0x89, ++0xb4, ++0xec, ++0x8e, ++0x69, ++0x90, ++0xdb, ++0x97, ++0x8a, ++0xf0, ++0x23, ++0x23, ++0x83, ++0x82, ++0x3b, ++0x6a, ++0xb1, ++0xac, ++0xeb, ++0xe7, ++0x99, ++0x74, ++0x2a, ++0x35, ++0x8e, ++0xa9, ++0x64, ++0xfd, ++0x46, ++0x9e, ++0xe8, ++0xe5, ++0x48, ++0x61, ++0x31, ++0x6e, ++0xe6, ++0xfc, ++0x19, ++0x18, ++0x54, ++0xc3, ++0x1b, ++0x4f, ++0xd6, ++0x00, ++0x44, ++0x87, ++0x1c, ++0x37, ++0x45, ++0xea, ++0xf5, ++0xc9, ++0xcb, ++0x0f, ++0x0c, ++0x55, ++0xec, ++0xcf, ++0x6a, ++0xc2, ++0x45, ++0x26, ++0x23, ++0xa2, ++0x31, ++0x52, ++0x4d, ++0xee, ++0x21, ++0x7d, ++0xfd, ++0x58, ++0x72, ++0xc2, ++0x28, ++0xc5, ++0x8e, ++0xa9, ++0xd0, ++0xee, ++0x01, ++0x77, ++0x08, ++0xa5, ++0xf0, ++0x22, ++0x2b, ++0x47, ++0x79, ++0x2b, ++0xcf, ++0x9a, ++0x46, ++0xb5, ++0x8f, ++0xfd, ++0x64, ++0xa2, ++0xb5, ++0xed, ++0x02, ++0x03, ++0x01, ++0x00, ++0x01, ++0xa3, ++0x53, ++0x30, ++0x51, ++0x30, ++0x1d, ++0x06, ++0x03, ++0x55, ++0x1d, ++0x0e, ++0x04, ++0x16, ++0x04, ++0x14, ++0xd3, ++0xfb, ++0x2d, ++0xdb, ++0xf0, ++0x8e, ++0xfa, ++0x67, ++0x6d, ++0x2f, ++0x21, ++0x99, ++0x4c, ++0xeb, ++0x41, ++0x59, ++0xe6, ++0x9d, ++0xd8, ++0xd5, ++0x30, ++0x1f, ++0x06, ++0x03, ++0x55, ++0x1d, ++0x23, ++0x04, ++0x18, ++0x30, ++0x16, ++0x80, ++0x14, ++0xd3, ++0xfb, ++0x2d, ++0xdb, ++0xf0, ++0x8e, ++0xfa, ++0x67, ++0x6d, ++0x2f, ++0x21, ++0x99, ++0x4c, ++0xeb, ++0x41, ++0x59, ++0xe6, ++0x9d, ++0xd8, ++0xd5, ++0x30, ++0x0f, ++0x06, ++0x03, ++0x55, ++0x1d, ++0x13, ++0x01, ++0x01, ++0xff, ++0x04, ++0x05, ++0x30, ++0x03, ++0x01, ++0x01, ++0xff, ++0x30, ++0x0d, ++0x06, ++0x09, ++0x2a, ++0x86, ++0x48, ++0x86, ++0xf7, ++0x0d, ++0x01, ++0x01, ++0x0b, ++0x05, ++0x00, ++0x03, ++0x82, ++0x01, ++0x01, ++0x00, ++0x71, ++0x71, ++0xe4, ++0xcd, ++0x40, ++0x84, ++0xf3, ++0x60, ++0x34, ++0x6a, ++0x78, ++0xdc, ++0xe7, ++0x81, ++0x20, ++0x8f, ++0x1e, ++0x7f, ++0x54, ++0x31, ++0x8e, ++0x4a, ++0xe5, ++0x69, ++0x91, ++0x1c, ++0x4c, ++0x77, ++0x00, ++0x47, ++0x09, ++0x98, ++0x91, ++0xf4, ++0x27, ++0x52, ++0x9a, ++0x2d, ++0x30, ++0x87, ++0x4c, ++0x51, ++0x51, ++0x1f, ++0xae, ++0xd8, ++0x8c, ++0xdb, ++0x3c, ++0x73, ++0x06, ++0x43, ++0xc6, ++0x1f, ++0x3a, ++0xba, ++0xaf, ++0x9e, ++0xd2, ++0xeb, ++0x3e, ++0x9f, ++0xd1, ++0xb2, ++0x8a, ++0xa2, ++0x16, ++0x08, ++0x26, ++0xa1, ++0x39, ++0x0c, ++0x63, ++0xe7, ++0x2d, ++0x78, ++0x9c, ++0xac, ++0x2c, ++0x4e, ++0x69, ++0xd5, ++0xa0, ++0xfd, ++0xbd, ++0xea, ++0x95, ++0xfe, ++0xe2, ++0x69, ++0x06, ++0xe1, ++0xb2, ++0x27, ++0x90, ++0x68, ++0xd8, ++0x3a, ++0xac, ++0xd6, ++0xa0, ++0x4e, ++0xe2, ++0x8a, ++0xfa, ++0xff, ++0x9c, ++0x98, ++0x6b, ++0x60, ++0x83, ++0xea, ++0xe7, ++0x46, ++0x24, ++0x09, ++0x21, ++0x12, ++0xa8, ++0xfe, ++0xaa, ++0x46, ++0x0d, ++0x24, ++0xa5, ++0xcf, ++0x52, ++0x37, ++0x48, ++0xb9, ++0xe2, ++0xb1, ++0xd6, ++0xb0, ++0xe4, ++0xbf, ++0x6f, ++0x59, ++0x7b, ++0x17, ++0x9e, ++0xdd, ++0x24, ++0x00, ++0xee, ++0xc6, ++0x89, ++0x76, ++0xe9, ++0x35, ++0x40, ++0x1f, ++0xeb, ++0x7d, ++0x23, ++0x8c, ++0xed, ++0x13, ++0x6c, ++0x66, ++0xbc, ++0xc4, ++0x88, ++0xb5, ++0x55, ++0x9a, ++0xec, ++0xbd, ++0x52, ++0x0d, ++0x0b, ++0xc5, ++0x40, ++0xe1, ++0xfe, ++0xb7, ++0x20, ++0xb1, ++0x22, ++0x16, ++0x32, ++0xed, ++0x28, ++0x3e, ++0x1f, ++0xbf, ++0xf2, ++0x00, ++0x12, ++0x75, ++0x92, ++0xd7, ++0x99, ++0x2e, ++0x25, ++0xfb, ++0xf2, ++0xe6, ++0xfd, ++0x2a, ++0x10, ++0xd1, ++0x75, ++0x89, ++0x31, ++0x52, ++0xe4, ++0xb2, ++0xc2, ++0xee, ++0xcd, ++0x41, ++0xa3, ++0x08, ++0x48, ++0x18, ++0x5e, ++0x66, ++0x42, ++0x67, ++0xcf, ++0x0b, ++0x2a, ++0x26, ++0x6b, ++0x65, ++0x87, ++0x4d, ++0xfa, ++0x04, ++0x51, ++0xec, ++0xed, ++0x03, ++0x8b, ++0x38, ++0x52, ++0x93, ++0x6d, ++0xc4, ++0x30, ++0x41, ++0x9a, ++0x6c, ++0x28, ++0x35, ++0xf0, ++0x87, ++0x15, ++0xce, ++0x78, ++0x4f, ++0x32, ++0xca, ++0x52, ++0xed, diff --git a/debian/patches/debian/wireless-disable-regulatory.db-direct-loading.patch b/debian/patches/debian/wireless-disable-regulatory.db-direct-loading.patch new file mode 100644 index 000000000..6815dc947 --- /dev/null +++ b/debian/patches/debian/wireless-disable-regulatory.db-direct-loading.patch @@ -0,0 +1,75 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Thu, 05 Apr 2018 18:13:52 +0200 +Subject: wireless: Disable regulatory.db direct loading +Forwarded: not-needed +Bug-Debian: https://bugs.debian.org/892229 + +Don't complain about being unable to load regulatory.db directly. +This is expected until we generate a signing key and update +wireless-regdb to be signed with it. + +Index: linux/net/wireless/reg.c +=================================================================== +--- linux.orig/net/wireless/reg.c ++++ linux/net/wireless/reg.c +@@ -476,6 +476,7 @@ static void reg_regdb_apply(struct work_ + + static DECLARE_WORK(reg_regdb_work, reg_regdb_apply); + ++#if 0 + static int reg_schedule_apply(const struct ieee80211_regdomain *regdom) + { + struct reg_regdb_apply_request *request; +@@ -495,6 +496,7 @@ static int reg_schedule_apply(const stru + schedule_work(®_regdb_work); + return 0; + } ++#endif + + #ifdef CONFIG_CFG80211_CRDA_SUPPORT + /* Max number of consecutive attempts to communicate with CRDA */ +@@ -574,6 +576,35 @@ static inline int call_crda(const char * + /* code to directly load a firmware database through request_firmware */ + static const struct fwdb_header *regdb; + ++#if 1 ++ ++static int load_builtin_regdb_keys(void) ++{ ++ return 0; ++} ++ ++static void free_regdb_keyring(void) ++{ ++} ++ ++static int query_regdb_file(const char *alpha2) ++{ ++ return -ENOENT; ++} ++ ++int reg_reload_regdb(void) ++{ ++ return -ENOENT; ++} ++ ++int reg_query_regdb_wmm(char *alpha2, int freq, struct ieee80211_reg_rule *rule) ++{ ++ return -ENODATA; ++} ++EXPORT_SYMBOL(reg_query_regdb_wmm); ++ ++#else /* disabled until we update wireless-regdb */ ++ + struct fwdb_country { + u8 alpha2[2]; + __be16 coll_ptr; +@@ -1090,6 +1121,8 @@ int reg_reload_regdb(void) + return err; + } + ++#endif ++ + static bool reg_query_database(struct regulatory_request *request) + { + if (query_regdb_file(request->alpha2) == 0) diff --git a/debian/patches/debian/yama-disable-by-default.patch b/debian/patches/debian/yama-disable-by-default.patch new file mode 100644 index 000000000..f35a598ae --- /dev/null +++ b/debian/patches/debian/yama-disable-by-default.patch @@ -0,0 +1,28 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Subject: yama: Disable by default +Date: Wed, 19 Jun 2013 04:35:28 +0100 +Bug-Debian: https://bugs.debian.org/712740 +Forwarded: not-needed + +Index: linux/security/yama/yama_lsm.c +=================================================================== +--- linux.orig/security/yama/yama_lsm.c ++++ linux/security/yama/yama_lsm.c +@@ -28,7 +28,7 @@ + #define YAMA_SCOPE_CAPABILITY 2 + #define YAMA_SCOPE_NO_ATTACH 3 + +-static int ptrace_scope = YAMA_SCOPE_RELATIONAL; ++static int ptrace_scope = YAMA_SCOPE_DISABLED; + + /* describe a ptrace relationship for potential exception */ + struct ptrace_relation { +@@ -481,7 +481,7 @@ static inline void yama_init_sysctl(void + + void __init yama_add_hooks(void) + { +- pr_info("Yama: becoming mindful.\n"); ++ pr_info("Yama: disabled by default; enable with sysctl kernel.yama.*\n"); + security_add_hooks(yama_hooks, ARRAY_SIZE(yama_hooks), "yama"); + yama_init_sysctl(); + } diff --git a/debian/patches/features/all/aufs4/aufs4-base.patch b/debian/patches/features/all/aufs4/aufs4-base.patch new file mode 100644 index 000000000..c0e036a73 --- /dev/null +++ b/debian/patches/features/all/aufs4/aufs4-base.patch @@ -0,0 +1,328 @@ +From: J. R. Okajima <hooanon05@yahoo.co.jp> +Date: Tue Sep 3 14:14:09 2019 +0900 +Subject: aufs4.19.63+ base patch +Origin: https://github.com/sfjro/aufs4-standalone/tree/6c582cc629cbfb4fac5bfc7d20db128c7d201da6 +Bug-Debian: https://bugs.debian.org/541828 + +Patch headers added by debian/bin/genpatch-aufs + +SPDX-License-Identifier: GPL-2.0 +aufs4.19.63+ base patch + +diff --git a/MAINTAINERS b/MAINTAINERS +index 11a59e82d92e..573d5b42b28b 100644 +--- a/MAINTAINERS ++++ b/MAINTAINERS +@@ -2605,6 +2605,19 @@ F: include/linux/audit.h + F: include/uapi/linux/audit.h + F: kernel/audit* + ++AUFS (advanced multi layered unification filesystem) FILESYSTEM ++M: "J. R. Okajima" <hooanon05g@gmail.com> ++L: aufs-users@lists.sourceforge.net (members only) ++L: linux-unionfs@vger.kernel.org ++W: http://aufs.sourceforge.net ++T: git://github.com/sfjro/aufs4-linux.git ++S: Supported ++F: Documentation/filesystems/aufs/ ++F: Documentation/ABI/testing/debugfs-aufs ++F: Documentation/ABI/testing/sysfs-aufs ++F: fs/aufs/ ++F: include/uapi/linux/aufs_type.h ++ + AUXILIARY DISPLAY DRIVERS + M: Miguel Ojeda Sandonis <miguel.ojeda.sandonis@gmail.com> + S: Maintained +diff --git a/drivers/block/loop.c b/drivers/block/loop.c +index f1e63eb7cbca..b732df5f14f3 100644 +--- a/drivers/block/loop.c ++++ b/drivers/block/loop.c +@@ -739,6 +739,24 @@ static int loop_change_fd(struct loop_device *lo, struct block_device *bdev, + return error; + } + ++/* ++ * for AUFS ++ * no get/put for file. ++ */ ++struct file *loop_backing_file(struct super_block *sb) ++{ ++ struct file *ret; ++ struct loop_device *l; ++ ++ ret = NULL; ++ if (MAJOR(sb->s_dev) == LOOP_MAJOR) { ++ l = sb->s_bdev->bd_disk->private_data; ++ ret = l->lo_backing_file; ++ } ++ return ret; ++} ++EXPORT_SYMBOL_GPL(loop_backing_file); ++ + /* loop sysfs attributes */ + + static ssize_t loop_attr_show(struct device *dev, char *page, +diff --git a/fs/dcache.c b/fs/dcache.c +index 6e0022326afe..3bd53094ac3d 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1234,7 +1234,7 @@ enum d_walk_ret { + * + * The @enter() callbacks are called with d_lock held. + */ +-static void d_walk(struct dentry *parent, void *data, ++void d_walk(struct dentry *parent, void *data, + enum d_walk_ret (*enter)(void *, struct dentry *)) + { + struct dentry *this_parent; +diff --git a/fs/fcntl.c b/fs/fcntl.c +index 4137d96534a6..c91b3e3c4580 100644 +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -32,7 +32,7 @@ + + #define SETFL_MASK (O_APPEND | O_NONBLOCK | O_NDELAY | O_DIRECT | O_NOATIME) + +-static int setfl(int fd, struct file * filp, unsigned long arg) ++int setfl(int fd, struct file * filp, unsigned long arg) + { + struct inode * inode = file_inode(filp); + int error = 0; +@@ -63,6 +63,8 @@ static int setfl(int fd, struct file * filp, unsigned long arg) + + if (filp->f_op->check_flags) + error = filp->f_op->check_flags(arg); ++ if (!error && filp->f_op->setfl) ++ error = filp->f_op->setfl(filp, arg); + if (error) + return error; + +diff --git a/fs/inode.c b/fs/inode.c +index 5c63693326bb..43046d7223e4 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1657,7 +1657,7 @@ EXPORT_SYMBOL(generic_update_time); + * This does the actual work of updating an inodes time or version. Must have + * had called mnt_want_write() before calling this. + */ +-static int update_time(struct inode *inode, struct timespec64 *time, int flags) ++int update_time(struct inode *inode, struct timespec64 *time, int flags) + { + int (*update_time)(struct inode *, struct timespec64 *, int); + +diff --git a/fs/namespace.c b/fs/namespace.c +index 1fce41ba3535..fbd7edd49a2f 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -770,6 +770,12 @@ static inline int check_mnt(struct mount *mnt) + return mnt->mnt_ns == current->nsproxy->mnt_ns; + } + ++/* for aufs, CONFIG_AUFS_BR_FUSE */ ++int is_current_mnt_ns(struct vfsmount *mnt) ++{ ++ return check_mnt(real_mount(mnt)); ++} ++ + /* + * vfsmount lock must be held for write + */ +diff --git a/fs/read_write.c b/fs/read_write.c +index 85fd7a8ee29e..c1335b4f19c0 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -489,6 +489,28 @@ ssize_t __vfs_write(struct file *file, const char __user *p, size_t count, + return -EINVAL; + } + ++vfs_readf_t vfs_readf(struct file *file) ++{ ++ const struct file_operations *fop = file->f_op; ++ ++ if (fop->read) ++ return fop->read; ++ if (fop->read_iter) ++ return new_sync_read; ++ return ERR_PTR(-ENOSYS); ++} ++ ++vfs_writef_t vfs_writef(struct file *file) ++{ ++ const struct file_operations *fop = file->f_op; ++ ++ if (fop->write) ++ return fop->write; ++ if (fop->write_iter) ++ return new_sync_write; ++ return ERR_PTR(-ENOSYS); ++} ++ + ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) + { + mm_segment_t old_fs; +diff --git a/fs/splice.c b/fs/splice.c +index 485e409ef841..b2c2d320565b 100644 +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -838,8 +838,8 @@ EXPORT_SYMBOL(generic_splice_sendpage); + /* + * Attempt to initiate a splice from pipe to file. + */ +-static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +- loff_t *ppos, size_t len, unsigned int flags) ++long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags) + { + ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, + loff_t *, size_t, unsigned int); +@@ -855,9 +855,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + /* + * Attempt to initiate a splice from a file to a pipe. + */ +-static long do_splice_to(struct file *in, loff_t *ppos, +- struct pipe_inode_info *pipe, size_t len, +- unsigned int flags) ++long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags) + { + ssize_t (*splice_read)(struct file *, loff_t *, + struct pipe_inode_info *, size_t, unsigned int); +diff --git a/fs/sync.c b/fs/sync.c +index b54e0541ad89..28607828e96f 100644 +--- a/fs/sync.c ++++ b/fs/sync.c +@@ -28,7 +28,7 @@ + * wait == 1 case since in that case write_inode() functions do + * sync_dirty_buffer() and thus effectively write one block at a time. + */ +-static int __sync_filesystem(struct super_block *sb, int wait) ++int __sync_filesystem(struct super_block *sb, int wait) + { + if (wait) + sync_inodes_sb(sb); +diff --git a/include/linux/fs.h b/include/linux/fs.h +index 92420009b9bc..ecad33c40cae 100644 +--- a/include/linux/fs.h ++++ b/include/linux/fs.h +@@ -1295,6 +1295,7 @@ extern void fasync_free(struct fasync_struct *); + /* can be called from interrupts */ + extern void kill_fasync(struct fasync_struct **, int, int); + ++extern int setfl(int fd, struct file * filp, unsigned long arg); + extern void __f_setown(struct file *filp, struct pid *, enum pid_type, int force); + extern int f_setown(struct file *filp, unsigned long arg, int force); + extern void f_delown(struct file *filp); +@@ -1759,6 +1760,7 @@ struct file_operations { + ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int); + unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); + int (*check_flags)(int); ++ int (*setfl)(struct file *, unsigned long); + int (*flock) (struct file *, int, struct file_lock *); + ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); + ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); +@@ -1830,6 +1832,12 @@ ssize_t rw_copy_check_uvector(int type, const struct iovec __user * uvector, + struct iovec *fast_pointer, + struct iovec **ret_pointer); + ++typedef ssize_t (*vfs_readf_t)(struct file *, char __user *, size_t, loff_t *); ++typedef ssize_t (*vfs_writef_t)(struct file *, const char __user *, size_t, ++ loff_t *); ++vfs_readf_t vfs_readf(struct file *file); ++vfs_writef_t vfs_writef(struct file *file); ++ + extern ssize_t __vfs_read(struct file *, char __user *, size_t, loff_t *); + extern ssize_t vfs_read(struct file *, char __user *, size_t, loff_t *); + extern ssize_t vfs_write(struct file *, const char __user *, size_t, loff_t *); +@@ -2255,6 +2263,7 @@ extern int current_umask(void); + extern void ihold(struct inode * inode); + extern void iput(struct inode *); + extern int generic_update_time(struct inode *, struct timespec64 *, int); ++extern int update_time(struct inode *, struct timespec64 *, int); + + /* /sys/fs */ + extern struct kobject *fs_kobj; +@@ -2542,6 +2551,7 @@ static inline bool sb_is_blkdev_sb(struct super_block *sb) + return false; + } + #endif ++extern int __sync_filesystem(struct super_block *, int); + extern int sync_filesystem(struct super_block *); + extern const struct file_operations def_blk_fops; + extern const struct file_operations def_chr_fops; +diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h +index b0d0b51c4d85..f73ffaa0199e 100644 +--- a/include/linux/lockdep.h ++++ b/include/linux/lockdep.h +@@ -313,6 +313,8 @@ static inline int lockdep_match_key(struct lockdep_map *lock, + return lock->key == key; + } + ++struct lock_class *lockdep_hlock_class(struct held_lock *hlock); ++ + /* + * Acquire a lock. + * +@@ -439,6 +441,7 @@ struct lockdep_map { }; + + #define lockdep_depth(tsk) (0) + ++#define lockdep_is_held(lock) (1) + #define lockdep_is_held_type(l, r) (1) + + #define lockdep_assert_held(l) do { (void)(l); } while (0) +diff --git a/include/linux/mnt_namespace.h b/include/linux/mnt_namespace.h +index 35942084cd40..24f5fd1a789d 100644 +--- a/include/linux/mnt_namespace.h ++++ b/include/linux/mnt_namespace.h +@@ -6,11 +6,14 @@ + struct mnt_namespace; + struct fs_struct; + struct user_namespace; ++struct vfsmount; + + extern struct mnt_namespace *copy_mnt_ns(unsigned long, struct mnt_namespace *, + struct user_namespace *, struct fs_struct *); + extern void put_mnt_ns(struct mnt_namespace *ns); + ++extern int is_current_mnt_ns(struct vfsmount *mnt); ++ + extern const struct file_operations proc_mounts_operations; + extern const struct file_operations proc_mountinfo_operations; + extern const struct file_operations proc_mountstats_operations; +diff --git a/include/linux/splice.h b/include/linux/splice.h +index 74b4911ac16d..19789fbea567 100644 +--- a/include/linux/splice.h ++++ b/include/linux/splice.h +@@ -87,4 +87,10 @@ extern void splice_shrink_spd(struct splice_pipe_desc *); + + extern const struct pipe_buf_operations page_cache_pipe_buf_ops; + extern const struct pipe_buf_operations default_pipe_buf_ops; ++ ++extern long do_splice_from(struct pipe_inode_info *pipe, struct file *out, ++ loff_t *ppos, size_t len, unsigned int flags); ++extern long do_splice_to(struct file *in, loff_t *ppos, ++ struct pipe_inode_info *pipe, size_t len, ++ unsigned int flags); + #endif +diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c +index e810e8cb17e1..d0c9931e6531 100644 +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -140,7 +140,7 @@ static struct lock_list list_entries[MAX_LOCKDEP_ENTRIES]; + unsigned long nr_lock_classes; + static struct lock_class lock_classes[MAX_LOCKDEP_KEYS]; + +-static inline struct lock_class *hlock_class(struct held_lock *hlock) ++inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) + { + if (!hlock->class_idx) { + /* +@@ -151,6 +151,7 @@ static inline struct lock_class *hlock_class(struct held_lock *hlock) + } + return lock_classes + hlock->class_idx - 1; + } ++#define hlock_class(hlock) lockdep_hlock_class(hlock) + + #ifdef CONFIG_LOCK_STAT + static DEFINE_PER_CPU(struct lock_class_stats[MAX_LOCKDEP_KEYS], cpu_lock_stats); diff --git a/debian/patches/features/all/aufs4/aufs4-mmap.patch b/debian/patches/features/all/aufs4/aufs4-mmap.patch new file mode 100644 index 000000000..98fe007a8 --- /dev/null +++ b/debian/patches/features/all/aufs4/aufs4-mmap.patch @@ -0,0 +1,406 @@ +From: J. R. Okajima <hooanon05@yahoo.co.jp> +Date: Tue Sep 3 14:14:09 2019 +0900 +Subject: aufs4.19.63+ mmap patch +Origin: https://github.com/sfjro/aufs4-standalone/tree/6c582cc629cbfb4fac5bfc7d20db128c7d201da6 +Bug-Debian: https://bugs.debian.org/541828 + +Patch headers added by debian/bin/genpatch-aufs + +SPDX-License-Identifier: GPL-2.0 +aufs4.19.63+ mmap patch + +diff --git a/fs/proc/base.c b/fs/proc/base.c +index a7fbda72afeb..9c8439a01c5b 100644 +--- a/fs/proc/base.c ++++ b/fs/proc/base.c +@@ -2018,7 +2018,7 @@ static int map_files_get_link(struct dentry *dentry, struct path *path) + rc = -ENOENT; + vma = find_exact_vma(mm, vm_start, vm_end); + if (vma && vma->vm_file) { +- *path = vma->vm_file->f_path; ++ *path = vma_pr_or_file(vma)->f_path; + path_get(path); + rc = 0; + } +diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c +index 3b63be64e436..fb9913bf3d10 100644 +--- a/fs/proc/nommu.c ++++ b/fs/proc/nommu.c +@@ -45,7 +45,10 @@ static int nommu_region_show(struct seq_file *m, struct vm_region *region) + file = region->vm_file; + + if (file) { +- struct inode *inode = file_inode(region->vm_file); ++ struct inode *inode; ++ ++ file = vmr_pr_or_file(region); ++ inode = file_inode(file); + dev = inode->i_sb->s_dev; + ino = inode->i_ino; + } +diff --git a/fs/proc/task_mmu.c b/fs/proc/task_mmu.c +index 71aba44c4fa6..87cdce66a3f4 100644 +--- a/fs/proc/task_mmu.c ++++ b/fs/proc/task_mmu.c +@@ -309,7 +309,10 @@ show_map_vma(struct seq_file *m, struct vm_area_struct *vma) + const char *name = NULL; + + if (file) { +- struct inode *inode = file_inode(vma->vm_file); ++ struct inode *inode; ++ ++ file = vma_pr_or_file(vma); ++ inode = file_inode(file); + dev = inode->i_sb->s_dev; + ino = inode->i_ino; + pgoff = ((loff_t)vma->vm_pgoff) << PAGE_SHIFT; +@@ -1766,7 +1769,7 @@ static int show_numa_map(struct seq_file *m, void *v) + struct proc_maps_private *proc_priv = &numa_priv->proc_maps; + struct vm_area_struct *vma = v; + struct numa_maps *md = &numa_priv->md; +- struct file *file = vma->vm_file; ++ struct file *file = vma_pr_or_file(vma); + struct mm_struct *mm = vma->vm_mm; + struct mm_walk walk = { + .hugetlb_entry = gather_hugetlb_stats, +diff --git a/fs/proc/task_nommu.c b/fs/proc/task_nommu.c +index 5161894a6d62..b6d13cce45f3 100644 +--- a/fs/proc/task_nommu.c ++++ b/fs/proc/task_nommu.c +@@ -155,7 +155,10 @@ static int nommu_vma_show(struct seq_file *m, struct vm_area_struct *vma) + file = vma->vm_file; + + if (file) { +- struct inode *inode = file_inode(vma->vm_file); ++ struct inode *inode; ++ ++ file = vma_pr_or_file(vma); ++ inode = file_inode(file); + dev = inode->i_sb->s_dev; + ino = inode->i_ino; + pgoff = (loff_t)vma->vm_pgoff << PAGE_SHIFT; +diff --git a/include/linux/mm.h b/include/linux/mm.h +index bdec425c8e14..88cb95dc57dd 100644 +--- a/include/linux/mm.h ++++ b/include/linux/mm.h +@@ -1453,6 +1453,28 @@ static inline void unmap_shared_mapping_range(struct address_space *mapping, + unmap_mapping_range(mapping, holebegin, holelen, 0); + } + ++extern void vma_do_file_update_time(struct vm_area_struct *, const char[], int); ++extern struct file *vma_do_pr_or_file(struct vm_area_struct *, const char[], ++ int); ++extern void vma_do_get_file(struct vm_area_struct *, const char[], int); ++extern void vma_do_fput(struct vm_area_struct *, const char[], int); ++ ++#define vma_file_update_time(vma) vma_do_file_update_time(vma, __func__, \ ++ __LINE__) ++#define vma_pr_or_file(vma) vma_do_pr_or_file(vma, __func__, \ ++ __LINE__) ++#define vma_get_file(vma) vma_do_get_file(vma, __func__, __LINE__) ++#define vma_fput(vma) vma_do_fput(vma, __func__, __LINE__) ++ ++#ifndef CONFIG_MMU ++extern struct file *vmr_do_pr_or_file(struct vm_region *, const char[], int); ++extern void vmr_do_fput(struct vm_region *, const char[], int); ++ ++#define vmr_pr_or_file(region) vmr_do_pr_or_file(region, __func__, \ ++ __LINE__) ++#define vmr_fput(region) vmr_do_fput(region, __func__, __LINE__) ++#endif /* !CONFIG_MMU */ ++ + extern int access_process_vm(struct task_struct *tsk, unsigned long addr, + void *buf, int len, unsigned int gup_flags); + extern int access_remote_vm(struct mm_struct *mm, unsigned long addr, +diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h +index 5ed8f6292a53..01229754077f 100644 +--- a/include/linux/mm_types.h ++++ b/include/linux/mm_types.h +@@ -239,6 +239,7 @@ struct vm_region { + unsigned long vm_top; /* region allocated to here */ + unsigned long vm_pgoff; /* the offset in vm_file corresponding to vm_start */ + struct file *vm_file; /* the backing file or NULL */ ++ struct file *vm_prfile; /* the virtual backing file or NULL */ + + int vm_usage; /* region usage count (access under nommu_region_sem) */ + bool vm_icache_flushed : 1; /* true if the icache has been flushed for +@@ -313,6 +314,7 @@ struct vm_area_struct { + unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE + units */ + struct file * vm_file; /* File we map to (can be NULL). */ ++ struct file *vm_prfile; /* shadow of vm_file */ + void * vm_private_data; /* was vm_pte (shared mem) */ + + atomic_long_t swap_readahead_info; +diff --git a/kernel/fork.c b/kernel/fork.c +index 69874db3fba8..757620e64e7b 100644 +--- a/kernel/fork.c ++++ b/kernel/fork.c +@@ -505,7 +505,7 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, + struct inode *inode = file_inode(file); + struct address_space *mapping = file->f_mapping; + +- get_file(file); ++ vma_get_file(tmp); + if (tmp->vm_flags & VM_DENYWRITE) + atomic_dec(&inode->i_writecount); + i_mmap_lock_write(mapping); +diff --git a/mm/Makefile b/mm/Makefile +index 26ef77a3883b..b2869af1ef08 100644 +--- a/mm/Makefile ++++ b/mm/Makefile +@@ -39,7 +39,7 @@ obj-y := filemap.o mempool.o oom_kill.o fadvise.o \ + mm_init.o mmu_context.o percpu.o slab_common.o \ + compaction.o vmacache.o \ + interval_tree.o list_lru.o workingset.o \ +- debug.o $(mmu-y) ++ prfile.o debug.o $(mmu-y) + + obj-y += init-mm.o + +diff --git a/mm/filemap.c b/mm/filemap.c +index 287f3fa02e5e..f96b6dd07b0b 100644 +--- a/mm/filemap.c ++++ b/mm/filemap.c +@@ -2722,7 +2722,7 @@ vm_fault_t filemap_page_mkwrite(struct vm_fault *vmf) + vm_fault_t ret = VM_FAULT_LOCKED; + + sb_start_pagefault(inode->i_sb); +- file_update_time(vmf->vma->vm_file); ++ vma_file_update_time(vmf->vma); + lock_page(page); + if (page->mapping != inode->i_mapping) { + unlock_page(page); +diff --git a/mm/mmap.c b/mm/mmap.c +index 1480880ff814..03ae15dfe614 100644 +--- a/mm/mmap.c ++++ b/mm/mmap.c +@@ -181,7 +181,7 @@ static struct vm_area_struct *remove_vma(struct vm_area_struct *vma) + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + mpol_put(vma_policy(vma)); + vm_area_free(vma); + return next; +@@ -906,7 +906,7 @@ int __vma_adjust(struct vm_area_struct *vma, unsigned long start, + if (remove_next) { + if (file) { + uprobe_munmap(next, next->vm_start, next->vm_end); +- fput(file); ++ vma_fput(vma); + } + if (next->anon_vma) + anon_vma_merge(vma, next); +@@ -1822,8 +1822,8 @@ unsigned long mmap_region(struct file *file, unsigned long addr, + return addr; + + unmap_and_free_vma: ++ vma_fput(vma); + vma->vm_file = NULL; +- fput(file); + + /* Undo any partial mapping done by a device driver. */ + unmap_region(mm, vma, prev, vma->vm_start, vma->vm_end); +@@ -2645,7 +2645,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, + goto out_free_mpol; + + if (new->vm_file) +- get_file(new->vm_file); ++ vma_get_file(new); + + if (new->vm_ops && new->vm_ops->open) + new->vm_ops->open(new); +@@ -2664,7 +2664,7 @@ int __split_vma(struct mm_struct *mm, struct vm_area_struct *vma, + if (new->vm_ops && new->vm_ops->close) + new->vm_ops->close(new); + if (new->vm_file) +- fput(new->vm_file); ++ vma_fput(new); + unlink_anon_vmas(new); + out_free_mpol: + mpol_put(vma_policy(new)); +@@ -2826,7 +2826,7 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, + struct vm_area_struct *vma; + unsigned long populate = 0; + unsigned long ret = -EINVAL; +- struct file *file; ++ struct file *file, *prfile; + + pr_warn_once("%s (%d) uses deprecated remap_file_pages() syscall. See Documentation/vm/remap_file_pages.rst.\n", + current->comm, current->pid); +@@ -2901,10 +2901,27 @@ SYSCALL_DEFINE5(remap_file_pages, unsigned long, start, unsigned long, size, + } + } + +- file = get_file(vma->vm_file); ++ vma_get_file(vma); ++ file = vma->vm_file; ++ prfile = vma->vm_prfile; + ret = do_mmap_pgoff(vma->vm_file, start, size, + prot, flags, pgoff, &populate, NULL); ++ if (!IS_ERR_VALUE(ret) && file && prfile) { ++ struct vm_area_struct *new_vma; ++ ++ new_vma = find_vma(mm, ret); ++ if (!new_vma->vm_prfile) ++ new_vma->vm_prfile = prfile; ++ if (new_vma != vma) ++ get_file(prfile); ++ } ++ /* ++ * two fput()s instead of vma_fput(vma), ++ * coz vma may not be available anymore. ++ */ + fput(file); ++ if (prfile) ++ fput(prfile); + out: + up_write(&mm->mmap_sem); + if (populate) +@@ -3210,7 +3227,7 @@ struct vm_area_struct *copy_vma(struct vm_area_struct **vmap, + if (anon_vma_clone(new_vma, vma)) + goto out_free_mempol; + if (new_vma->vm_file) +- get_file(new_vma->vm_file); ++ vma_get_file(new_vma); + if (new_vma->vm_ops && new_vma->vm_ops->open) + new_vma->vm_ops->open(new_vma); + vma_link(mm, new_vma, prev, rb_link, rb_parent); +diff --git a/mm/nommu.c b/mm/nommu.c +index 1d63ecfc98c5..15eafddeb944 100644 +--- a/mm/nommu.c ++++ b/mm/nommu.c +@@ -625,7 +625,7 @@ static void __put_nommu_region(struct vm_region *region) + up_write(&nommu_region_sem); + + if (region->vm_file) +- fput(region->vm_file); ++ vmr_fput(region); + + /* IO memory and memory shared directly out of the pagecache + * from ramfs/tmpfs mustn't be released here */ +@@ -763,7 +763,7 @@ static void delete_vma(struct mm_struct *mm, struct vm_area_struct *vma) + if (vma->vm_ops && vma->vm_ops->close) + vma->vm_ops->close(vma); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + put_nommu_region(vma->vm_region); + vm_area_free(vma); + } +@@ -1286,7 +1286,7 @@ unsigned long do_mmap(struct file *file, + goto error_just_free; + } + } +- fput(region->vm_file); ++ vmr_fput(region); + kmem_cache_free(vm_region_jar, region); + region = pregion; + result = start; +@@ -1361,10 +1361,10 @@ unsigned long do_mmap(struct file *file, + up_write(&nommu_region_sem); + error: + if (region->vm_file) +- fput(region->vm_file); ++ vmr_fput(region); + kmem_cache_free(vm_region_jar, region); + if (vma->vm_file) +- fput(vma->vm_file); ++ vma_fput(vma); + vm_area_free(vma); + return ret; + +diff --git a/mm/prfile.c b/mm/prfile.c +new file mode 100644 +index 000000000000..024cdcfae1b1 +--- /dev/null ++++ b/mm/prfile.c +@@ -0,0 +1,86 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/* ++ * Mainly for aufs which mmap(2) different file and wants to print different ++ * path in /proc/PID/maps. ++ * Call these functions via macros defined in linux/mm.h. ++ * ++ * See Documentation/filesystems/aufs/design/06mmap.txt ++ * ++ * Copyright (c) 2014-2019 Junjro R. Okajima ++ * Copyright (c) 2014 Ian Campbell ++ */ ++ ++#include <linux/mm.h> ++#include <linux/file.h> ++#include <linux/fs.h> ++ ++/* #define PRFILE_TRACE */ ++static inline void prfile_trace(struct file *f, struct file *pr, ++ const char func[], int line, const char func2[]) ++{ ++#ifdef PRFILE_TRACE ++ if (pr) ++ pr_info("%s:%d: %s, %pD2\n", func, line, func2, f); ++#endif ++} ++ ++void vma_do_file_update_time(struct vm_area_struct *vma, const char func[], ++ int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ file_update_time(f); ++ if (f && pr) ++ file_update_time(pr); ++} ++ ++struct file *vma_do_pr_or_file(struct vm_area_struct *vma, const char func[], ++ int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ return (f && pr) ? pr : f; ++} ++ ++void vma_do_get_file(struct vm_area_struct *vma, const char func[], int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ get_file(f); ++ if (f && pr) ++ get_file(pr); ++} ++ ++void vma_do_fput(struct vm_area_struct *vma, const char func[], int line) ++{ ++ struct file *f = vma->vm_file, *pr = vma->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ fput(f); ++ if (f && pr) ++ fput(pr); ++} ++ ++#ifndef CONFIG_MMU ++struct file *vmr_do_pr_or_file(struct vm_region *region, const char func[], ++ int line) ++{ ++ struct file *f = region->vm_file, *pr = region->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ return (f && pr) ? pr : f; ++} ++ ++void vmr_do_fput(struct vm_region *region, const char func[], int line) ++{ ++ struct file *f = region->vm_file, *pr = region->vm_prfile; ++ ++ prfile_trace(f, pr, func, line, __func__); ++ fput(f); ++ if (f && pr) ++ fput(pr); ++} ++#endif /* !CONFIG_MMU */ diff --git a/debian/patches/features/all/aufs4/aufs4-standalone.patch b/debian/patches/features/all/aufs4/aufs4-standalone.patch new file mode 100644 index 000000000..0a682c2f5 --- /dev/null +++ b/debian/patches/features/all/aufs4/aufs4-standalone.patch @@ -0,0 +1,385 @@ +From: J. R. Okajima <hooanon05@yahoo.co.jp> +Date: Tue Sep 3 14:14:09 2019 +0900 +Subject: aufs4.19.63+ standalone patch +Origin: https://github.com/sfjro/aufs4-standalone/tree/6c582cc629cbfb4fac5bfc7d20db128c7d201da6 +Bug-Debian: https://bugs.debian.org/541828 + +Patch headers added by debian/bin/genpatch-aufs + +SPDX-License-Identifier: GPL-2.0 +aufs4.19.63+ standalone patch + +diff --git a/fs/dcache.c b/fs/dcache.c +index 3bd53094ac3d..d6b2f7a994f4 100644 +--- a/fs/dcache.c ++++ b/fs/dcache.c +@@ -1339,6 +1339,7 @@ void d_walk(struct dentry *parent, void *data, + seq = 1; + goto again; + } ++EXPORT_SYMBOL_GPL(d_walk); + + struct check_mount { + struct vfsmount *mnt; +@@ -2835,6 +2836,7 @@ void d_exchange(struct dentry *dentry1, struct dentry *dentry2) + + write_sequnlock(&rename_lock); + } ++EXPORT_SYMBOL_GPL(d_exchange); + + /** + * d_ancestor - search for an ancestor +diff --git a/fs/exec.c b/fs/exec.c +index 433b1257694a..504c56308700 100644 +--- a/fs/exec.c ++++ b/fs/exec.c +@@ -109,6 +109,7 @@ bool path_noexec(const struct path *path) + return (path->mnt->mnt_flags & MNT_NOEXEC) || + (path->mnt->mnt_sb->s_iflags & SB_I_NOEXEC); + } ++EXPORT_SYMBOL_GPL(path_noexec); + + #ifdef CONFIG_USELIB + /* +diff --git a/fs/fcntl.c b/fs/fcntl.c +index c91b3e3c4580..77513097f04c 100644 +--- a/fs/fcntl.c ++++ b/fs/fcntl.c +@@ -85,6 +85,7 @@ int setfl(int fd, struct file * filp, unsigned long arg) + out: + return error; + } ++EXPORT_SYMBOL_GPL(setfl); + + static void f_modown(struct file *filp, struct pid *pid, enum pid_type type, + int force) +diff --git a/fs/file_table.c b/fs/file_table.c +index e49af4caf15d..569020fd1fb3 100644 +--- a/fs/file_table.c ++++ b/fs/file_table.c +@@ -161,6 +161,7 @@ struct file *alloc_empty_file(int flags, const struct cred *cred) + } + return ERR_PTR(-ENFILE); + } ++EXPORT_SYMBOL_GPL(alloc_empty_file); + + /* + * Variant of alloc_empty_file() that doesn't check and modify nr_files. +@@ -323,6 +324,7 @@ void flush_delayed_fput(void) + { + delayed_fput(NULL); + } ++EXPORT_SYMBOL_GPL(flush_delayed_fput); + + static DECLARE_DELAYED_WORK(delayed_fput_work, delayed_fput); + +@@ -365,6 +367,7 @@ void __fput_sync(struct file *file) + } + + EXPORT_SYMBOL(fput); ++EXPORT_SYMBOL_GPL(__fput_sync); + + void __init files_init(void) + { +diff --git a/fs/inode.c b/fs/inode.c +index 43046d7223e4..36146c757aa2 100644 +--- a/fs/inode.c ++++ b/fs/inode.c +@@ -1666,6 +1666,7 @@ int update_time(struct inode *inode, struct timespec64 *time, int flags) + + return update_time(inode, time, flags); + } ++EXPORT_SYMBOL_GPL(update_time); + + /** + * touch_atime - update the access time +diff --git a/fs/namespace.c b/fs/namespace.c +index fbd7edd49a2f..d6eca814d9fc 100644 +--- a/fs/namespace.c ++++ b/fs/namespace.c +@@ -437,6 +437,7 @@ void __mnt_drop_write(struct vfsmount *mnt) + mnt_dec_writers(real_mount(mnt)); + preempt_enable(); + } ++EXPORT_SYMBOL_GPL(__mnt_drop_write); + + /** + * mnt_drop_write - give up write access to a mount +@@ -775,6 +776,7 @@ int is_current_mnt_ns(struct vfsmount *mnt) + { + return check_mnt(real_mount(mnt)); + } ++EXPORT_SYMBOL_GPL(is_current_mnt_ns); + + /* + * vfsmount lock must be held for write +@@ -1844,6 +1846,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, + } + return 0; + } ++EXPORT_SYMBOL_GPL(iterate_mounts); + + static void cleanup_group_ids(struct mount *mnt, struct mount *end) + { +diff --git a/fs/notify/group.c b/fs/notify/group.c +index c03b83662876..94d210ca384a 100644 +--- a/fs/notify/group.c ++++ b/fs/notify/group.c +@@ -112,6 +112,7 @@ void fsnotify_get_group(struct fsnotify_group *group) + { + refcount_inc(&group->refcnt); + } ++EXPORT_SYMBOL_GPL(fsnotify_get_group); + + /* + * Drop a reference to a group. Free it if it's through. +@@ -121,6 +122,7 @@ void fsnotify_put_group(struct fsnotify_group *group) + if (refcount_dec_and_test(&group->refcnt)) + fsnotify_final_destroy_group(group); + } ++EXPORT_SYMBOL_GPL(fsnotify_put_group); + + /* + * Create a new fsnotify_group and hold a reference for the group returned. +@@ -150,6 +152,7 @@ struct fsnotify_group *fsnotify_alloc_group(const struct fsnotify_ops *ops) + + return group; + } ++EXPORT_SYMBOL_GPL(fsnotify_alloc_group); + + int fsnotify_fasync(int fd, struct file *file, int on) + { +diff --git a/fs/notify/mark.c b/fs/notify/mark.c +index 09535f6423fc..e9401ec71fc7 100644 +--- a/fs/notify/mark.c ++++ b/fs/notify/mark.c +@@ -285,6 +285,7 @@ void fsnotify_put_mark(struct fsnotify_mark *mark) + queue_delayed_work(system_unbound_wq, &reaper_work, + FSNOTIFY_REAPER_DELAY); + } ++EXPORT_SYMBOL_GPL(fsnotify_put_mark); + + /* + * Get mark reference when we found the mark via lockless traversal of object +@@ -439,6 +440,7 @@ void fsnotify_destroy_mark(struct fsnotify_mark *mark, + mutex_unlock(&group->mark_mutex); + fsnotify_free_mark(mark); + } ++EXPORT_SYMBOL_GPL(fsnotify_destroy_mark); + + /* + * Sorting function for lists of fsnotify marks. +@@ -654,6 +656,7 @@ int fsnotify_add_mark(struct fsnotify_mark *mark, fsnotify_connp_t *connp, + mutex_unlock(&group->mark_mutex); + return ret; + } ++EXPORT_SYMBOL_GPL(fsnotify_add_mark); + + /* + * Given a list of marks, find the mark associated with given group. If found +@@ -777,6 +780,7 @@ void fsnotify_init_mark(struct fsnotify_mark *mark, + fsnotify_get_group(group); + mark->group = group; + } ++EXPORT_SYMBOL_GPL(fsnotify_init_mark); + + /* + * Destroy all marks in destroy_list, waits for SRCU period to finish before +diff --git a/fs/open.c b/fs/open.c +index 878478745924..ab755f585f29 100644 +--- a/fs/open.c ++++ b/fs/open.c +@@ -64,6 +64,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, + inode_unlock(dentry->d_inode); + return ret; + } ++EXPORT_SYMBOL_GPL(do_truncate); + + long vfs_truncate(const struct path *path, loff_t length) + { +diff --git a/fs/read_write.c b/fs/read_write.c +index c1335b4f19c0..6ed1f2ddcb03 100644 +--- a/fs/read_write.c ++++ b/fs/read_write.c +@@ -459,6 +459,7 @@ ssize_t vfs_read(struct file *file, char __user *buf, size_t count, loff_t *pos) + + return ret; + } ++EXPORT_SYMBOL_GPL(vfs_read); + + static ssize_t new_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos) + { +@@ -499,6 +500,7 @@ vfs_readf_t vfs_readf(struct file *file) + return new_sync_read; + return ERR_PTR(-ENOSYS); + } ++EXPORT_SYMBOL_GPL(vfs_readf); + + vfs_writef_t vfs_writef(struct file *file) + { +@@ -510,6 +512,7 @@ vfs_writef_t vfs_writef(struct file *file) + return new_sync_write; + return ERR_PTR(-ENOSYS); + } ++EXPORT_SYMBOL_GPL(vfs_writef); + + ssize_t __kernel_write(struct file *file, const void *buf, size_t count, loff_t *pos) + { +@@ -579,6 +582,7 @@ ssize_t vfs_write(struct file *file, const char __user *buf, size_t count, loff_ + + return ret; + } ++EXPORT_SYMBOL_GPL(vfs_write); + + static inline loff_t file_pos_read(struct file *file) + { +diff --git a/fs/splice.c b/fs/splice.c +index b2c2d320565b..8250f2366329 100644 +--- a/fs/splice.c ++++ b/fs/splice.c +@@ -851,6 +851,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, + + return splice_write(pipe, out, ppos, len, flags); + } ++EXPORT_SYMBOL_GPL(do_splice_from); + + /* + * Attempt to initiate a splice from a file to a pipe. +@@ -880,6 +881,7 @@ long do_splice_to(struct file *in, loff_t *ppos, + + return splice_read(in, ppos, pipe, len, flags); + } ++EXPORT_SYMBOL_GPL(do_splice_to); + + /** + * splice_direct_to_actor - splices data directly between two non-pipes +diff --git a/fs/sync.c b/fs/sync.c +index 28607828e96f..ffd7ea43831e 100644 +--- a/fs/sync.c ++++ b/fs/sync.c +@@ -39,6 +39,7 @@ int __sync_filesystem(struct super_block *sb, int wait) + sb->s_op->sync_fs(sb, wait); + return __sync_blockdev(sb->s_bdev, wait); + } ++EXPORT_SYMBOL_GPL(__sync_filesystem); + + /* + * Write out and wait upon all dirty data associated with this +diff --git a/fs/xattr.c b/fs/xattr.c +index 0d6a6a4af861..7ce4701b7289 100644 +--- a/fs/xattr.c ++++ b/fs/xattr.c +@@ -295,6 +295,7 @@ vfs_getxattr_alloc(struct dentry *dentry, const char *name, char **xattr_value, + *xattr_value = value; + return error; + } ++EXPORT_SYMBOL_GPL(vfs_getxattr_alloc); + + ssize_t + __vfs_getxattr(struct dentry *dentry, struct inode *inode, const char *name, +diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c +index d0c9931e6531..0e5d9706723c 100644 +--- a/kernel/locking/lockdep.c ++++ b/kernel/locking/lockdep.c +@@ -151,6 +151,7 @@ inline struct lock_class *lockdep_hlock_class(struct held_lock *hlock) + } + return lock_classes + hlock->class_idx - 1; + } ++EXPORT_SYMBOL_GPL(lockdep_hlock_class); + #define hlock_class(hlock) lockdep_hlock_class(hlock) + + #ifdef CONFIG_LOCK_STAT +diff --git a/kernel/task_work.c b/kernel/task_work.c +index 0fef395662a6..83fb1ecfc33d 100644 +--- a/kernel/task_work.c ++++ b/kernel/task_work.c +@@ -116,3 +116,4 @@ void task_work_run(void) + } while (work); + } + } ++EXPORT_SYMBOL_GPL(task_work_run); +diff --git a/security/device_cgroup.c b/security/device_cgroup.c +index dc28914fa72e..c2ddfea2b280 100644 +--- a/security/device_cgroup.c ++++ b/security/device_cgroup.c +@@ -824,3 +824,4 @@ int __devcgroup_check_permission(short type, u32 major, u32 minor, + + return 0; + } ++EXPORT_SYMBOL_GPL(__devcgroup_check_permission); +diff --git a/security/security.c b/security/security.c +index 5ce2448f3a45..3997af3462bc 100644 +--- a/security/security.c ++++ b/security/security.c +@@ -542,6 +542,7 @@ int security_path_rmdir(const struct path *dir, struct dentry *dentry) + return 0; + return call_int_hook(path_rmdir, 0, dir, dentry); + } ++EXPORT_SYMBOL_GPL(security_path_rmdir); + + int security_path_unlink(const struct path *dir, struct dentry *dentry) + { +@@ -558,6 +559,7 @@ int security_path_symlink(const struct path *dir, struct dentry *dentry, + return 0; + return call_int_hook(path_symlink, 0, dir, dentry, old_name); + } ++EXPORT_SYMBOL_GPL(security_path_symlink); + + int security_path_link(struct dentry *old_dentry, const struct path *new_dir, + struct dentry *new_dentry) +@@ -566,6 +568,7 @@ int security_path_link(struct dentry *old_dentry, const struct path *new_dir, + return 0; + return call_int_hook(path_link, 0, old_dentry, new_dir, new_dentry); + } ++EXPORT_SYMBOL_GPL(security_path_link); + + int security_path_rename(const struct path *old_dir, struct dentry *old_dentry, + const struct path *new_dir, struct dentry *new_dentry, +@@ -593,6 +596,7 @@ int security_path_truncate(const struct path *path) + return 0; + return call_int_hook(path_truncate, 0, path); + } ++EXPORT_SYMBOL_GPL(security_path_truncate); + + int security_path_chmod(const struct path *path, umode_t mode) + { +@@ -600,6 +604,7 @@ int security_path_chmod(const struct path *path, umode_t mode) + return 0; + return call_int_hook(path_chmod, 0, path, mode); + } ++EXPORT_SYMBOL_GPL(security_path_chmod); + + int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) + { +@@ -607,6 +612,7 @@ int security_path_chown(const struct path *path, kuid_t uid, kgid_t gid) + return 0; + return call_int_hook(path_chown, 0, path, uid, gid); + } ++EXPORT_SYMBOL_GPL(security_path_chown); + + int security_path_chroot(const struct path *path) + { +@@ -707,6 +713,7 @@ int security_inode_permission(struct inode *inode, int mask) + return 0; + return call_int_hook(inode_permission, 0, inode, mask); + } ++EXPORT_SYMBOL_GPL(security_inode_permission); + + int security_inode_setattr(struct dentry *dentry, struct iattr *attr) + { +@@ -878,6 +885,7 @@ int security_file_permission(struct file *file, int mask) + + return fsnotify_perm(file, mask); + } ++EXPORT_SYMBOL_GPL(security_file_permission); + + int security_file_alloc(struct file *file) + { +@@ -937,6 +945,7 @@ int security_mmap_file(struct file *file, unsigned long prot, + return ret; + return ima_file_mmap(file, prot); + } ++EXPORT_SYMBOL_GPL(security_mmap_file); + + int security_mmap_addr(unsigned long addr) + { diff --git a/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch b/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch new file mode 100644 index 000000000..a67217c02 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch @@ -0,0 +1,91 @@ +From: David Howells <dhowells@redhat.com> +Date: Fri, 5 May 2017 08:21:56 +0100 +Subject: [PATCH 1/7] KEYS: Allow unrestricted boot-time addition of keys to + secondary keyring +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=40db8fc497d010ae6cee6297c3882d3dc3d76d48 + +Allow keys to be added to the system secondary certificates keyring during +kernel initialisation in an unrestricted fashion. Such keys are implicitly +trusted and don't have their trust chains checked on link. + +This allows keys in the UEFI database to be added in secure boot mode for +the purposes of module signing. + +Signed-off-by: David Howells <dhowells@redhat.com> +--- + certs/internal.h | 18 ++++++++++++++++++ + certs/system_keyring.c | 33 +++++++++++++++++++++++++++++++++ + 2 files changed, 51 insertions(+) + create mode 100644 certs/internal.h + +Index: linux/certs/internal.h +=================================================================== +--- /dev/null ++++ linux/certs/internal.h +@@ -0,0 +1,18 @@ ++/* Internal definitions ++ * ++ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++/* ++ * system_keyring.c ++ */ ++#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING ++extern void __init add_trusted_secondary_key(const char *source, ++ const void *data, size_t len); ++#endif +Index: linux/certs/system_keyring.c +=================================================================== +--- linux.orig/certs/system_keyring.c ++++ linux/certs/system_keyring.c +@@ -19,6 +19,7 @@ + #include <keys/asymmetric-type.h> + #include <keys/system_keyring.h> + #include <crypto/pkcs7.h> ++#include "internal.h" + + static struct key *builtin_trusted_keys; + #ifdef CONFIG_SECONDARY_TRUSTED_KEYRING +@@ -266,3 +267,35 @@ error: + EXPORT_SYMBOL_GPL(verify_pkcs7_signature); + + #endif /* CONFIG_SYSTEM_DATA_VERIFICATION */ ++ ++#ifdef CONFIG_SECONDARY_TRUSTED_KEYRING ++/** ++ * add_trusted_secondary_key - Add to secondary keyring with no validation ++ * @source: Source of key ++ * @data: The blob holding the key ++ * @len: The length of the data blob ++ * ++ * Add a key to the secondary keyring without checking its trust chain. This ++ * is available only during kernel initialisation. ++ */ ++void __init add_trusted_secondary_key(const char *source, ++ const void *data, size_t len) ++{ ++ key_ref_t key; ++ ++ key = key_create_or_update(make_key_ref(secondary_trusted_keys, 1), ++ "asymmetric", ++ NULL, data, len, ++ (KEY_POS_ALL & ~KEY_POS_SETATTR) | ++ KEY_USR_VIEW, ++ KEY_ALLOC_NOT_IN_QUOTA | ++ KEY_ALLOC_BYPASS_RESTRICTION); ++ ++ if (IS_ERR(key)) ++ pr_err("Problem loading %s X.509 certificate (%ld)\n", ++ source, PTR_ERR(key)); ++ else ++ pr_notice("Loaded %s cert '%s' linked to secondary sys keyring\n", ++ source, key_ref_to_ptr(key)->description); ++} ++#endif /* CONFIG_SECONDARY_TRUSTED_KEYRING */ diff --git a/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch new file mode 100644 index 000000000..d36028413 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch @@ -0,0 +1,64 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:37:59 +0800 +Subject: [PATCH 1/5] MODSIGN: do not load mok when secure boot disabled +Origin: https://lore.kernel.org/patchwork/patch/933173/ + +The mok can not be trusted when the secure boot is disabled. Which +means that the kernel embedded certificate is the only trusted key. + +Due to db/dbx are authenticated variables, they needs manufacturer's +KEK for update. So db/dbx are secure when secureboot disabled. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +--- + certs/load_uefi.c | 26 +++++++++++++++----------- + 1 file changed, 15 insertions(+), 11 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -171,17 +171,6 @@ static int __init load_uefi_certs(void) + } + } + +- rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok); +- if (rc < 0) { +- pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); +- } else if (moksize != 0) { +- rc = parse_efi_signature_list("UEFI:MokListRT", +- mok, moksize, get_handler_for_db); +- if (rc) +- pr_err("Couldn't parse MokListRT signatures: %d\n", rc); +- kfree(mok); +- } +- + rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx); + if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); +@@ -194,6 +183,21 @@ static int __init load_uefi_certs(void) + kfree(dbx); + } + ++ /* the MOK can not be trusted when secure boot is disabled */ ++ if (!efi_enabled(EFI_SECURE_BOOT)) ++ return 0; ++ ++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok); ++ if (rc < 0) { ++ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); ++ } else if (moksize != 0) { ++ rc = parse_efi_signature_list("UEFI:MokListRT", ++ mok, moksize, get_handler_for_db); ++ if (rc) ++ pr_err("Couldn't parse MokListRT signatures: %d\n", rc); ++ kfree(mok); ++ } ++ + return rc; + } + late_initcall(load_uefi_certs); diff --git a/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch b/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch new file mode 100644 index 000000000..d23b7ac98 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch @@ -0,0 +1,60 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:38:01 +0800 +Subject: [PATCH 2/4] MODSIGN: load blacklist from MOKx +Origin: https://lore.kernel.org/patchwork/patch/933177/ + +This patch adds the logic to load the blacklisted hash and +certificates from MOKx which is maintained by shim bootloader. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +--- + certs/load_uefi.c | 16 +++++++++++++--- + 1 file changed, 13 insertions(+), 3 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -148,8 +148,8 @@ static int __init load_uefi_certs(void) + { + efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; + efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; +- void *db = NULL, *dbx = NULL, *mok = NULL; +- unsigned long dbsize = 0, dbxsize = 0, moksize = 0; ++ void *db = NULL, *dbx = NULL, *mok = NULL, *mokx = NULL; ++ unsigned long dbsize = 0, dbxsize = 0, moksize = 0, mokxsize = 0; + int rc = 0; + + if (!efi.get_variable) +@@ -183,7 +183,7 @@ static int __init load_uefi_certs(void) + kfree(dbx); + } + +- /* the MOK can not be trusted when secure boot is disabled */ ++ /* the MOK and MOKx can not be trusted when secure boot is disabled */ + if (!efi_enabled(EFI_SECURE_BOOT)) + return 0; + +@@ -198,6 +198,18 @@ static int __init load_uefi_certs(void) + kfree(mok); + } + ++ rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx); ++ if (rc < 0) { ++ pr_info("MODSIGN: Couldn't get UEFI MokListXRT\n"); ++ } else if (mokxsize != 0) { ++ rc = parse_efi_signature_list("UEFI:mokx", ++ mokx, mokxsize, ++ get_handler_for_dbx); ++ if (rc) ++ pr_err("Couldn't parse MokListXRT signatures: %d\n", rc); ++ kfree(mokx); ++ } ++ + return rc; + } + late_initcall(load_uefi_certs); diff --git a/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch b/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch new file mode 100644 index 000000000..bf8d40768 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch @@ -0,0 +1,57 @@ +From: Dave Howells <dhowells@redhat.com> +Date: Fri, 5 May 2017 08:21:58 +0100 +Subject: [PATCH 2/7] efi: Add EFI signature data types +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=446e0e29d7d53fe7786d33603df5a6682dd00c12 + +Add the data types that are used for containing hashes, keys and +certificates for cryptographic verification along with their corresponding +type GUIDs. + +Signed-off-by: David Howells <dhowells@redhat.com> +--- + include/linux/efi.h | 25 +++++++++++++++++++++++++ + 1 file changed, 25 insertions(+) + +Index: linux/include/linux/efi.h +=================================================================== +--- linux.orig/include/linux/efi.h ++++ linux/include/linux/efi.h +@@ -663,6 +663,10 @@ void efi_native_runtime_setup(void); + #define EFI_IMAGE_SECURITY_DATABASE_GUID EFI_GUID(0xd719b2cb, 0x3d3a, 0x4596, 0xa3, 0xbc, 0xda, 0xd0, 0x0e, 0x67, 0x65, 0x6f) + #define EFI_SHIM_LOCK_GUID EFI_GUID(0x605dab50, 0xe046, 0x4300, 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23) + ++#define EFI_CERT_SHA256_GUID EFI_GUID(0xc1c41626, 0x504c, 0x4092, 0xac, 0xa9, 0x41, 0xf9, 0x36, 0x93, 0x43, 0x28) ++#define EFI_CERT_X509_GUID EFI_GUID(0xa5c059a1, 0x94e4, 0x4aa7, 0x87, 0xb5, 0xab, 0x15, 0x5c, 0x2b, 0xf0, 0x72) ++#define EFI_CERT_X509_SHA256_GUID EFI_GUID(0x3bd2a492, 0x96c0, 0x4079, 0xb4, 0x20, 0xfc, 0xf9, 0x8e, 0xf1, 0x03, 0xed) ++ + /* + * This GUID is used to pass to the kernel proper the struct screen_info + * structure that was populated by the stub based on the GOP protocol instance +@@ -934,6 +938,27 @@ typedef struct { + efi_memory_desc_t entry[0]; + } efi_memory_attributes_table_t; + ++typedef struct { ++ efi_guid_t signature_owner; ++ u8 signature_data[]; ++} efi_signature_data_t; ++ ++typedef struct { ++ efi_guid_t signature_type; ++ u32 signature_list_size; ++ u32 signature_header_size; ++ u32 signature_size; ++ u8 signature_header[]; ++ /* efi_signature_data_t signatures[][] */ ++} efi_signature_list_t; ++ ++typedef u8 efi_sha256_hash_t[32]; ++ ++typedef struct { ++ efi_sha256_hash_t to_be_signed_hash; ++ efi_time_t time_of_revocation; ++} efi_cert_x509_sha256_t; ++ + /* + * All runtime access to EFI goes through this structure: + */ diff --git a/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch new file mode 100644 index 000000000..1a43ca553 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch @@ -0,0 +1,129 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:38:02 +0800 +Subject: [PATCH 3/4] MODSIGN: checking the blacklisted hash before loading a + kernel module +Origin: https://lore.kernel.org/patchwork/patch/933175/ + +This patch adds the logic for checking the kernel module's hash +base on blacklist. The hash must be generated by sha256 and enrolled +to dbx/mokx. + +For example: + sha256sum sample.ko + mokutil --mokx --import-hash $HASH_RESULT + +Whether the signature on ko file is stripped or not, the hash can be +compared by kernel. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +--- + kernel/module_signing.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 60 insertions(+), 2 deletions(-) + +Index: linux/kernel/module_signing.c +=================================================================== +--- linux.orig/kernel/module_signing.c ++++ linux/kernel/module_signing.c +@@ -11,9 +11,12 @@ + + #include <linux/kernel.h> + #include <linux/errno.h> ++#include <linux/module.h> + #include <linux/string.h> + #include <linux/verification.h> + #include <crypto/public_key.h> ++#include <crypto/hash.h> ++#include <keys/system_keyring.h> + #include "module-internal.h" + + enum pkey_id_type { +@@ -42,19 +45,67 @@ struct module_signature { + __be32 sig_len; /* Length of signature data */ + }; + ++static int mod_is_hash_blacklisted(const void *mod, size_t verifylen) ++{ ++ struct crypto_shash *tfm; ++ struct shash_desc *desc; ++ size_t digest_size, desc_size; ++ u8 *digest; ++ int ret = 0; ++ ++ tfm = crypto_alloc_shash("sha256", 0, 0); ++ if (IS_ERR(tfm)) ++ goto error_return; ++ ++ desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); ++ digest_size = crypto_shash_digestsize(tfm); ++ digest = kzalloc(digest_size + desc_size, GFP_KERNEL); ++ if (!digest) { ++ pr_err("digest memory buffer allocate fail\n"); ++ ret = -ENOMEM; ++ goto error_digest; ++ } ++ desc = (void *)digest + digest_size; ++ desc->tfm = tfm; ++ desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP; ++ ret = crypto_shash_init(desc); ++ if (ret < 0) ++ goto error_shash; ++ ++ ret = crypto_shash_finup(desc, mod, verifylen, digest); ++ if (ret < 0) ++ goto error_shash; ++ ++ pr_debug("%ld digest: %*phN\n", verifylen, (int) digest_size, digest); ++ ++ ret = is_hash_blacklisted(digest, digest_size, "bin"); ++ if (ret == -EKEYREJECTED) ++ pr_err("Module hash %*phN is blacklisted\n", ++ (int) digest_size, digest); ++ ++error_shash: ++ kfree(digest); ++error_digest: ++ crypto_free_shash(tfm); ++error_return: ++ return ret; ++} ++ + /* + * Verify the signature on a module. + */ + int mod_verify_sig(const void *mod, struct load_info *info) + { + struct module_signature ms; +- size_t sig_len, modlen = info->len; ++ size_t sig_len, modlen = info->len, wholelen; ++ int ret;; + + pr_devel("==>%s(,%zu)\n", __func__, modlen); + + if (modlen <= sizeof(ms)) + return -EBADMSG; + ++ wholelen = modlen + sizeof(MODULE_SIG_STRING) - 1; + memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms)); + modlen -= sizeof(ms); + +@@ -82,8 +133,15 @@ int mod_verify_sig(const void *mod, stru + return -EBADMSG; + } + +- return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, ++ ret = verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, + VERIFY_USE_SECONDARY_KEYRING, + VERIFYING_MODULE_SIGNATURE, + NULL, NULL); ++ pr_devel("verify_pkcs7_signature() = %d\n", ret); ++ ++ /* checking hash of module is in blacklist */ ++ if (!ret) ++ ret = mod_is_hash_blacklisted(mod, wholelen); ++ ++ return ret; + } diff --git a/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch b/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch new file mode 100644 index 000000000..e82287cff --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch @@ -0,0 +1,193 @@ +From: Dave Howells <dhowells@redhat.com> +Date: Fri, 5 May 2017 08:21:58 +0100 +Subject: [PATCH 3/7] efi: Add an EFI signature blob parser +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=41a595bb0dc097c19ad377a0c32c993234aa2525 + +Add a function to parse an EFI signature blob looking for elements of +interest. A list is made up of a series of sublists, where all the +elements in a sublist are of the same type, but sublists can be of +different types. + +For each sublist encountered, the function pointed to by the +get_handler_for_guid argument is called with the type specifier GUID and +returns either a pointer to a function to handle elements of that type or +NULL if the type is not of interest. + +If the sublist is of interest, each element is passed to the handler +function in turn. + +Signed-off-by: David Howells <dhowells@redhat.com> +--- + certs/Kconfig | 8 ++++ + certs/Makefile | 1 + + certs/efi_parser.c | 112 ++++++++++++++++++++++++++++++++++++++++++++ + include/linux/efi.h | 9 ++++ + 4 files changed, 130 insertions(+) + create mode 100644 certs/efi_parser.c + +Index: linux/certs/Kconfig +=================================================================== +--- linux.orig/certs/Kconfig ++++ linux/certs/Kconfig +@@ -83,4 +83,12 @@ config SYSTEM_BLACKLIST_HASH_LIST + wrapper to incorporate the list into the kernel. Each <hash> should + be a string of hex digits. + ++config EFI_SIGNATURE_LIST_PARSER ++ bool "EFI signature list parser" ++ depends on EFI ++ select X509_CERTIFICATE_PARSER ++ help ++ This option provides support for parsing EFI signature lists for ++ X.509 certificates and turning them into keys. ++ + endmenu +Index: linux/certs/Makefile +=================================================================== +--- linux.orig/certs/Makefile ++++ linux/certs/Makefile +@@ -10,6 +10,7 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) + + else + obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) += blacklist_nohashes.o + endif ++obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o + + ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) + +Index: linux/certs/efi_parser.c +=================================================================== +--- /dev/null ++++ linux/certs/efi_parser.c +@@ -0,0 +1,112 @@ ++/* EFI signature/key/certificate list parser ++ * ++ * Copyright (C) 2012, 2016 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++#define pr_fmt(fmt) "EFI: "fmt ++#include <linux/module.h> ++#include <linux/printk.h> ++#include <linux/err.h> ++#include <linux/efi.h> ++ ++/** ++ * parse_efi_signature_list - Parse an EFI signature list for certificates ++ * @source: The source of the key ++ * @data: The data blob to parse ++ * @size: The size of the data blob ++ * @get_handler_for_guid: Get the handler func for the sig type (or NULL) ++ * ++ * Parse an EFI signature list looking for elements of interest. A list is ++ * made up of a series of sublists, where all the elements in a sublist are of ++ * the same type, but sublists can be of different types. ++ * ++ * For each sublist encountered, the @get_handler_for_guid function is called ++ * with the type specifier GUID and returns either a pointer to a function to ++ * handle elements of that type or NULL if the type is not of interest. ++ * ++ * If the sublist is of interest, each element is passed to the handler ++ * function in turn. ++ * ++ * Error EBADMSG is returned if the list doesn't parse correctly and 0 is ++ * returned if the list was parsed correctly. No error can be returned from ++ * the @get_handler_for_guid function or the element handler function it ++ * returns. ++ */ ++int __init parse_efi_signature_list( ++ const char *source, ++ const void *data, size_t size, ++ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)) ++{ ++ efi_element_handler_t handler; ++ unsigned offs = 0; ++ ++ pr_devel("-->%s(,%zu)\n", __func__, size); ++ ++ while (size > 0) { ++ const efi_signature_data_t *elem; ++ efi_signature_list_t list; ++ size_t lsize, esize, hsize, elsize; ++ ++ if (size < sizeof(list)) ++ return -EBADMSG; ++ ++ memcpy(&list, data, sizeof(list)); ++ pr_devel("LIST[%04x] guid=%pUl ls=%x hs=%x ss=%x\n", ++ offs, ++ list.signature_type.b, list.signature_list_size, ++ list.signature_header_size, list.signature_size); ++ ++ lsize = list.signature_list_size; ++ hsize = list.signature_header_size; ++ esize = list.signature_size; ++ elsize = lsize - sizeof(list) - hsize; ++ ++ if (lsize > size) { ++ pr_devel("<--%s() = -EBADMSG [overrun @%x]\n", ++ __func__, offs); ++ return -EBADMSG; ++ } ++ ++ if (lsize < sizeof(list) || ++ lsize - sizeof(list) < hsize || ++ esize < sizeof(*elem) || ++ elsize < esize || ++ elsize % esize != 0) { ++ pr_devel("- bad size combo @%x\n", offs); ++ return -EBADMSG; ++ } ++ ++ handler = get_handler_for_guid(&list.signature_type); ++ if (!handler) { ++ data += lsize; ++ size -= lsize; ++ offs += lsize; ++ continue; ++ } ++ ++ data += sizeof(list) + hsize; ++ size -= sizeof(list) + hsize; ++ offs += sizeof(list) + hsize; ++ ++ for (; elsize > 0; elsize -= esize) { ++ elem = data; ++ ++ pr_devel("ELEM[%04x]\n", offs); ++ handler(source, ++ &elem->signature_data, ++ esize - sizeof(*elem)); ++ ++ data += esize; ++ size -= esize; ++ offs += esize; ++ } ++ } ++ ++ return 0; ++} +Index: linux/include/linux/efi.h +=================================================================== +--- linux.orig/include/linux/efi.h ++++ linux/include/linux/efi.h +@@ -1139,6 +1139,15 @@ extern int efi_memattr_apply_permissions + char * __init efi_md_typeattr_format(char *buf, size_t size, + const efi_memory_desc_t *md); + ++ ++typedef void (*efi_element_handler_t)(const char *source, ++ const void *element_data, ++ size_t element_size); ++extern int __init parse_efi_signature_list( ++ const char *source, ++ const void *data, size_t size, ++ efi_element_handler_t (*get_handler_for_guid)(const efi_guid_t *)); ++ + /** + * efi_range_is_wc - check the WC bit on an address range + * @start: starting kvirt address diff --git a/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch new file mode 100644 index 000000000..cdb3b7a22 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch @@ -0,0 +1,242 @@ +From: Josh Boyer <jwboyer@fedoraproject.org> +Date: Fri, 5 May 2017 08:21:59 +0100 +Subject: [PATCH 4/7] MODSIGN: Import certificates from UEFI Secure Boot +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=7b7aae2efea13b5a7b80305856c28f235ea8b2fa + +Secure Boot stores a list of allowed certificates in the 'db' variable. +This imports those certificates into the system trusted keyring. This +allows for a third party signing certificate to be used in conjunction +with signed modules. By importing the public certificate into the 'db' +variable, a user can allow a module signed with that certificate to +load. The shim UEFI bootloader has a similar certificate list stored +in the 'MokListRT' variable. We import those as well. + +Secure Boot also maintains a list of disallowed certificates in the 'dbx' +variable. We load those certificates into the newly introduced system +blacklist keyring and forbid any module signed with those from loading and +forbid the use within the kernel of any key with a matching hash. + +This facility is enabled by setting CONFIG_LOAD_UEFI_KEYS. + +Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> +Signed-off-by: David Howells <dhowells@redhat.com> +--- + certs/Kconfig | 16 +++++ + certs/Makefile | 4 ++ + certs/load_uefi.c | 168 ++++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 188 insertions(+) + create mode 100644 certs/load_uefi.c + +Index: linux/certs/Kconfig +=================================================================== +--- linux.orig/certs/Kconfig ++++ linux/certs/Kconfig +@@ -91,4 +91,20 @@ config EFI_SIGNATURE_LIST_PARSER + This option provides support for parsing EFI signature lists for + X.509 certificates and turning them into keys. + ++config LOAD_UEFI_KEYS ++ bool "Load certs and blacklist from UEFI db for module checking" ++ depends on SYSTEM_BLACKLIST_KEYRING ++ depends on SECONDARY_TRUSTED_KEYRING ++ depends on EFI ++ depends on EFI_SIGNATURE_LIST_PARSER ++ help ++ If the kernel is booted in secure boot mode, this option will cause ++ the kernel to load the certificates from the UEFI db and MokListRT ++ into the secondary trusted keyring. It will also load any X.509 ++ SHA256 hashes in the dbx list into the blacklist. ++ ++ The effect of this is that, if the kernel is booted in secure boot ++ mode, modules signed with UEFI-stored keys will be permitted to be ++ loaded and keys that match the blacklist will be rejected. ++ + endmenu +Index: linux/certs/Makefile +=================================================================== +--- linux.orig/certs/Makefile ++++ linux/certs/Makefile +@@ -12,6 +12,10 @@ obj-$(CONFIG_SYSTEM_BLACKLIST_KEYRING) + + endif + obj-$(CONFIG_EFI_SIGNATURE_LIST_PARSER) += efi_parser.o + ++obj-$(CONFIG_LOAD_UEFI_KEYS) += load_uefi.o ++$(obj)/load_uefi.o: KBUILD_CFLAGS += -fshort-wchar ++ ++ + ifeq ($(CONFIG_SYSTEM_TRUSTED_KEYRING),y) + + $(eval $(call config_filename,SYSTEM_TRUSTED_KEYS)) +Index: linux/certs/load_uefi.c +=================================================================== +--- /dev/null ++++ linux/certs/load_uefi.c +@@ -0,0 +1,168 @@ ++#include <linux/kernel.h> ++#include <linux/sched.h> ++#include <linux/cred.h> ++#include <linux/err.h> ++#include <linux/efi.h> ++#include <linux/slab.h> ++#include <keys/asymmetric-type.h> ++#include <keys/system_keyring.h> ++#include "internal.h" ++ ++static __initdata efi_guid_t efi_cert_x509_guid = EFI_CERT_X509_GUID; ++static __initdata efi_guid_t efi_cert_x509_sha256_guid = EFI_CERT_X509_SHA256_GUID; ++static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID; ++ ++/* ++ * Get a certificate list blob from the named EFI variable. ++ */ ++static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, ++ unsigned long *size) ++{ ++ efi_status_t status; ++ unsigned long lsize = 4; ++ unsigned long tmpdb[4]; ++ void *db; ++ ++ status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); ++ if (status != EFI_BUFFER_TOO_SMALL) { ++ pr_err("Couldn't get size: 0x%lx\n", status); ++ return NULL; ++ } ++ ++ db = kmalloc(lsize, GFP_KERNEL); ++ if (!db) { ++ pr_err("Couldn't allocate memory for uefi cert list\n"); ++ return NULL; ++ } ++ ++ status = efi.get_variable(name, guid, NULL, &lsize, db); ++ if (status != EFI_SUCCESS) { ++ kfree(db); ++ pr_err("Error reading db var: 0x%lx\n", status); ++ return NULL; ++ } ++ ++ *size = lsize; ++ return db; ++} ++ ++/* ++ * Blacklist an X509 TBS hash. ++ */ ++static __init void uefi_blacklist_x509_tbs(const char *source, ++ const void *data, size_t len) ++{ ++ char *hash, *p; ++ ++ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL); ++ if (!hash) ++ return; ++ p = memcpy(hash, "tbs:", 4); ++ p += 4; ++ bin2hex(p, data, len); ++ p += len * 2; ++ *p = 0; ++ ++ mark_hash_blacklisted(hash); ++ kfree(hash); ++} ++ ++/* ++ * Blacklist the hash of an executable. ++ */ ++static __init void uefi_blacklist_binary(const char *source, ++ const void *data, size_t len) ++{ ++ char *hash, *p; ++ ++ hash = kmalloc(4 + len * 2 + 1, GFP_KERNEL); ++ if (!hash) ++ return; ++ p = memcpy(hash, "bin:", 4); ++ p += 4; ++ bin2hex(p, data, len); ++ p += len * 2; ++ *p = 0; ++ ++ mark_hash_blacklisted(hash); ++ kfree(hash); ++} ++ ++/* ++ * Return the appropriate handler for particular signature list types found in ++ * the UEFI db and MokListRT tables. ++ */ ++static __init efi_element_handler_t get_handler_for_db(const efi_guid_t *sig_type) ++{ ++ if (efi_guidcmp(*sig_type, efi_cert_x509_guid) == 0) ++ return add_trusted_secondary_key; ++ return 0; ++} ++ ++/* ++ * Return the appropriate handler for particular signature list types found in ++ * the UEFI dbx and MokListXRT tables. ++ */ ++static __init efi_element_handler_t get_handler_for_dbx(const efi_guid_t *sig_type) ++{ ++ if (efi_guidcmp(*sig_type, efi_cert_x509_sha256_guid) == 0) ++ return uefi_blacklist_x509_tbs; ++ if (efi_guidcmp(*sig_type, efi_cert_sha256_guid) == 0) ++ return uefi_blacklist_binary; ++ return 0; ++} ++ ++/* ++ * Load the certs contained in the UEFI databases ++ */ ++static int __init load_uefi_certs(void) ++{ ++ efi_guid_t secure_var = EFI_IMAGE_SECURITY_DATABASE_GUID; ++ efi_guid_t mok_var = EFI_SHIM_LOCK_GUID; ++ void *db = NULL, *dbx = NULL, *mok = NULL; ++ unsigned long dbsize = 0, dbxsize = 0, moksize = 0; ++ int rc = 0; ++ ++ if (!efi.get_variable) ++ return false; ++ ++ /* Get db, MokListRT, and dbx. They might not exist, so it isn't ++ * an error if we can't get them. ++ */ ++ db = get_cert_list(L"db", &secure_var, &dbsize); ++ if (!db) { ++ pr_err("MODSIGN: Couldn't get UEFI db list\n"); ++ } else { ++ rc = parse_efi_signature_list("UEFI:db", ++ db, dbsize, get_handler_for_db); ++ if (rc) ++ pr_err("Couldn't parse db signatures: %d\n", rc); ++ kfree(db); ++ } ++ ++ mok = get_cert_list(L"MokListRT", &mok_var, &moksize); ++ if (!mok) { ++ pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); ++ } else { ++ rc = parse_efi_signature_list("UEFI:MokListRT", ++ mok, moksize, get_handler_for_db); ++ if (rc) ++ pr_err("Couldn't parse MokListRT signatures: %d\n", rc); ++ kfree(mok); ++ } ++ ++ dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); ++ if (!dbx) { ++ pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); ++ } else { ++ rc = parse_efi_signature_list("UEFI:dbx", ++ dbx, dbxsize, ++ get_handler_for_dbx); ++ if (rc) ++ pr_err("Couldn't parse dbx signatures: %d\n", rc); ++ kfree(dbx); ++ } ++ ++ return rc; ++} ++late_initcall(load_uefi_certs); diff --git a/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch new file mode 100644 index 000000000..57b6e61ff --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch @@ -0,0 +1,108 @@ +From: "Lee, Chun-Yi" <joeyli.kernel@gmail.com> +Date: Tue, 13 Mar 2018 18:38:03 +0800 +Subject: [PATCH 4/4] MODSIGN: check the attributes of db and mok +Origin: https://lore.kernel.org/patchwork/patch/933176/ + +That's better for checking the attributes of db and mok variables +before loading certificates to kernel keyring. + +For db and dbx, both of them are authenticated variables. Which +means that they can only be modified by manufacturer's key. So +the kernel should checks EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS +attribute before we trust it. + +For mok-rt and mokx-rt, both of them are created by shim boot loader +to forward the mok/mokx content to runtime. They must be runtime-volatile +variables. So kernel should checks that the attributes map did not set +EFI_VARIABLE_NON_VOLATILE bit before we trust it. + +Cc: David Howells <dhowells@redhat.com> +Cc: Josh Boyer <jwboyer@fedoraproject.org> +Cc: James Bottomley <James.Bottomley@HansenPartnership.com> +Signed-off-by: "Lee, Chun-Yi" <jlee@suse.com> +[Rebased by Luca Boccassi] +--- + certs/load_uefi.c | 35 +++++++++++++++++++++++------------ + 1 file changed, 23 insertions(+), 12 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -36,12 +36,14 @@ static __init bool uefi_check_ignore_db( + * Get a certificate list blob from the named EFI variable. + */ + static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid, +- unsigned long *size, void **cert_list) ++ unsigned long *size, void **cert_list, ++ u32 pos_attr, u32 neg_attr) + { + efi_status_t status; + unsigned long lsize = 4; + unsigned long tmpdb[4]; + void *db; ++ u32 attr = 0; + + status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); + if (status == EFI_NOT_FOUND) { +@@ -61,12 +63,19 @@ static __init int get_cert_list(efi_char + return -ENOMEM; + } + +- status = efi.get_variable(name, guid, NULL, &lsize, db); ++ status = efi.get_variable(name, guid, &attr, &lsize, db); + if (status != EFI_SUCCESS) { + kfree(db); + pr_err("Error reading db var: 0x%lx\n", status); + return efi_status_to_err(status); + } ++ /* must have positive attributes and no negative attributes */ ++ if ((pos_attr && !(attr & pos_attr)) || ++ (neg_attr && (attr & neg_attr))) { ++ kfree(db); ++ pr_err("Error reading db var attributes: 0x%016x\n", attr); ++ return -1; ++ } + + *size = lsize; + *cert_list = db; +@@ -159,7 +168,8 @@ static int __init load_uefi_certs(void) + * an error if we can't get them. + */ + if (!uefi_check_ignore_db()) { +- rc = get_cert_list(L"db", &secure_var, &dbsize, &db); ++ rc = get_cert_list(L"db", &secure_var, &dbsize, &db, ++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0); + if (rc < 0) { + pr_err("MODSIGN: Couldn't get UEFI db list\n"); + } else if (dbsize != 0) { +@@ -171,7 +181,8 @@ static int __init load_uefi_certs(void) + } + } + +- rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx); ++ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx, ++ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS, 0); + if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); + } else if (dbxsize != 0) { +@@ -187,7 +198,8 @@ static int __init load_uefi_certs(void) + if (!efi_enabled(EFI_SECURE_BOOT)) + return 0; + +- rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok); ++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok, ++ 0, EFI_VARIABLE_NON_VOLATILE); + if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); + } else if (moksize != 0) { +@@ -198,7 +210,8 @@ static int __init load_uefi_certs(void) + kfree(mok); + } + +- rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx); ++ rc = get_cert_list(L"MokListXRT", &mok_var, &mokxsize, &mokx, ++ 0, EFI_VARIABLE_NON_VOLATILE); + if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI MokListXRT\n"); + } else if (mokxsize != 0) { diff --git a/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch b/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch new file mode 100644 index 000000000..b5e2e843c --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch @@ -0,0 +1,85 @@ +From: Josh Boyer <jwboyer@fedoraproject.org> +Date: Fri, 5 May 2017 08:21:59 +0100 +Subject: [PATCH 5/7] MODSIGN: Allow the "db" UEFI variable to be suppressed +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=b51ca4e4d6c0c8000789de31a1184a41ac611d33 + +If a user tells shim to not use the certs/hashes in the UEFI db variable +for verification purposes, shim will set a UEFI variable called +MokIgnoreDB. Have the uefi import code look for this and ignore the db +variable if it is found. + +Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> +Signed-off-by: David Howells <dhowells@redhat.com> +--- + certs/load_uefi.c | 44 ++++++++++++++++++++++++++++++++++---------- + 1 file changed, 34 insertions(+), 10 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -13,6 +13,26 @@ static __initdata efi_guid_t efi_cert_x5 + static __initdata efi_guid_t efi_cert_sha256_guid = EFI_CERT_SHA256_GUID; + + /* ++ * Look to see if a UEFI variable called MokIgnoreDB exists and return true if ++ * it does. ++ * ++ * This UEFI variable is set by the shim if a user tells the shim to not use ++ * the certs/hashes in the UEFI db variable for verification purposes. If it ++ * is set, we should ignore the db variable also and the true return indicates ++ * this. ++ */ ++static __init bool uefi_check_ignore_db(void) ++{ ++ efi_status_t status; ++ unsigned int db = 0; ++ unsigned long size = sizeof(db); ++ efi_guid_t guid = EFI_SHIM_LOCK_GUID; ++ ++ status = efi.get_variable(L"MokIgnoreDB", &guid, NULL, &size, &db); ++ return status == EFI_SUCCESS; ++} ++ ++/* + * Get a certificate list blob from the named EFI variable. + */ + static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, +@@ -113,7 +133,9 @@ static __init efi_element_handler_t get_ + } + + /* +- * Load the certs contained in the UEFI databases ++ * Load the certs contained in the UEFI databases into the secondary trusted ++ * keyring and the UEFI blacklisted X.509 cert SHA256 hashes into the blacklist ++ * keyring. + */ + static int __init load_uefi_certs(void) + { +@@ -129,15 +151,17 @@ static int __init load_uefi_certs(void) + /* Get db, MokListRT, and dbx. They might not exist, so it isn't + * an error if we can't get them. + */ +- db = get_cert_list(L"db", &secure_var, &dbsize); +- if (!db) { +- pr_err("MODSIGN: Couldn't get UEFI db list\n"); +- } else { +- rc = parse_efi_signature_list("UEFI:db", +- db, dbsize, get_handler_for_db); +- if (rc) +- pr_err("Couldn't parse db signatures: %d\n", rc); +- kfree(db); ++ if (!uefi_check_ignore_db()) { ++ db = get_cert_list(L"db", &secure_var, &dbsize); ++ if (!db) { ++ pr_err("MODSIGN: Couldn't get UEFI db list\n"); ++ } else { ++ rc = parse_efi_signature_list("UEFI:db", ++ db, dbsize, get_handler_for_db); ++ if (rc) ++ pr_err("Couldn't parse db signatures: %d\n", rc); ++ kfree(db); ++ } + } + + mok = get_cert_list(L"MokListRT", &mok_var, &moksize); diff --git a/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch b/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch new file mode 100644 index 000000000..c348e2f04 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch @@ -0,0 +1,106 @@ +From: Peter Jones <pjones@redhat.com> +Date: Mon, 2 Oct 2017 18:25:29 -0400 +Subject: [PATCH 6/7] Make get_cert_list() not complain about cert lists that + aren't present. +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/jforbes/linux.git/commit/?id=0f4d5c7b49b45e7cf038bb769e33451b78a6445d + +Signed-off-by: Peter Jones <pjones@redhat.com> +--- + certs/load_uefi.c | 37 ++++++++++++++++++++++--------------- + 1 file changed, 22 insertions(+), 15 deletions(-) + +Index: linux/certs/load_uefi.c +=================================================================== +--- linux.orig/certs/load_uefi.c ++++ linux/certs/load_uefi.c +@@ -35,8 +35,8 @@ static __init bool uefi_check_ignore_db( + /* + * Get a certificate list blob from the named EFI variable. + */ +-static __init void *get_cert_list(efi_char16_t *name, efi_guid_t *guid, +- unsigned long *size) ++static __init int get_cert_list(efi_char16_t *name, efi_guid_t *guid, ++ unsigned long *size, void **cert_list) + { + efi_status_t status; + unsigned long lsize = 4; +@@ -44,26 +44,33 @@ static __init void *get_cert_list(efi_ch + void *db; + + status = efi.get_variable(name, guid, NULL, &lsize, &tmpdb); ++ if (status == EFI_NOT_FOUND) { ++ *size = 0; ++ *cert_list = NULL; ++ return 0; ++ } ++ + if (status != EFI_BUFFER_TOO_SMALL) { + pr_err("Couldn't get size: 0x%lx\n", status); +- return NULL; ++ return efi_status_to_err(status); + } + + db = kmalloc(lsize, GFP_KERNEL); + if (!db) { + pr_err("Couldn't allocate memory for uefi cert list\n"); +- return NULL; ++ return -ENOMEM; + } + + status = efi.get_variable(name, guid, NULL, &lsize, db); + if (status != EFI_SUCCESS) { + kfree(db); + pr_err("Error reading db var: 0x%lx\n", status); +- return NULL; ++ return efi_status_to_err(status); + } + + *size = lsize; +- return db; ++ *cert_list = db; ++ return 0; + } + + /* +@@ -152,10 +159,10 @@ static int __init load_uefi_certs(void) + * an error if we can't get them. + */ + if (!uefi_check_ignore_db()) { +- db = get_cert_list(L"db", &secure_var, &dbsize); +- if (!db) { ++ rc = get_cert_list(L"db", &secure_var, &dbsize, &db); ++ if (rc < 0) { + pr_err("MODSIGN: Couldn't get UEFI db list\n"); +- } else { ++ } else if (dbsize != 0) { + rc = parse_efi_signature_list("UEFI:db", + db, dbsize, get_handler_for_db); + if (rc) +@@ -164,10 +171,10 @@ static int __init load_uefi_certs(void) + } + } + +- mok = get_cert_list(L"MokListRT", &mok_var, &moksize); +- if (!mok) { ++ rc = get_cert_list(L"MokListRT", &mok_var, &moksize, &mok); ++ if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI MokListRT\n"); +- } else { ++ } else if (moksize != 0) { + rc = parse_efi_signature_list("UEFI:MokListRT", + mok, moksize, get_handler_for_db); + if (rc) +@@ -175,10 +182,10 @@ static int __init load_uefi_certs(void) + kfree(mok); + } + +- dbx = get_cert_list(L"dbx", &secure_var, &dbxsize); +- if (!dbx) { ++ rc = get_cert_list(L"dbx", &secure_var, &dbxsize, &dbx); ++ if (rc < 0) { + pr_info("MODSIGN: Couldn't get UEFI dbx list\n"); +- } else { ++ } else if (dbxsize != 0) { + rc = parse_efi_signature_list("UEFI:dbx", + dbx, dbxsize, + get_handler_for_dbx); diff --git a/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch b/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch new file mode 100644 index 000000000..b831869e4 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch @@ -0,0 +1,28 @@ +From: Ke Wu <mikewu@google.com> +Date: Tue, 6 Nov 2018 15:21:30 -0800 +Subject: modsign: use all trusted keys to verify module signature +Origin: https://git.kernel.org/linus/e84cd7ee630e44a2cc8ae49e85920a271b214cb3 + +Make mod_verify_sig to use all trusted keys. This allows keys in +secondary_trusted_keys to be used to verify PKCS#7 signature on a +kernel module. + +Signed-off-by: Ke Wu <mikewu@google.com> +Signed-off-by: Jessica Yu <jeyu@kernel.org> +--- + kernel/module_signing.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +Index: linux/kernel/module_signing.c +=================================================================== +--- linux.orig/kernel/module_signing.c ++++ linux/kernel/module_signing.c +@@ -83,6 +83,7 @@ int mod_verify_sig(const void *mod, stru + } + + return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len, +- NULL, VERIFYING_MODULE_SIGNATURE, ++ VERIFY_USE_SECONDARY_KEYRING, ++ VERIFYING_MODULE_SIGNATURE, + NULL, NULL); + } diff --git a/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch new file mode 100644 index 000000000..a0aea95a2 --- /dev/null +++ b/debian/patches/features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch @@ -0,0 +1,30 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 05 May 2019 13:45:06 +0100 +Subject: MODSIGN: Make shash allocation failure fatal + +mod_is_hash_blacklisted() currently returns 0 (suceess) if +crypto_alloc_shash() fails. This should instead be a fatal error, +so unwrap and pass up the error code. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/kernel/module_signing.c +=================================================================== +--- linux.orig/kernel/module_signing.c ++++ linux/kernel/module_signing.c +@@ -51,11 +51,13 @@ static int mod_is_hash_blacklisted(const + struct shash_desc *desc; + size_t digest_size, desc_size; + u8 *digest; +- int ret = 0; ++ int ret; + + tfm = crypto_alloc_shash("sha256", 0, 0); +- if (IS_ERR(tfm)) ++ if (IS_ERR(tfm)) { ++ ret = PTR_ERR(tfm); + goto error_return; ++ } + + desc_size = crypto_shash_descsize(tfm) + sizeof(*desc); + digest_size = crypto_shash_digestsize(tfm); diff --git a/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch b/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch new file mode 100644 index 000000000..2d3b1a5da --- /dev/null +++ b/debian/patches/features/all/drivers-media-dvb-usb-af9005-request_firmware.patch @@ -0,0 +1,149 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 24 Aug 2009 23:19:58 +0100 +Subject: af9005: Use request_firmware() to load register init script +Forwarded: no + +Read the register init script from the Windows driver. This is sick +but should avoid the potential copyright infringement in distributing +a version of the script which is directly derived from the driver. +--- + drivers/media/dvb/dvb-usb/Kconfig | 2 +- + drivers/media/dvb/dvb-usb/af9005-fe.c | 66 ++++++++++++++++++++++++++------ + 2 files changed, 54 insertions(+), 14 deletions(-) + +Index: linux/drivers/media/usb/dvb-usb/Kconfig +=================================================================== +--- linux.orig/drivers/media/usb/dvb-usb/Kconfig ++++ linux/drivers/media/usb/dvb-usb/Kconfig +@@ -246,10 +246,10 @@ config DVB_USB_OPERA1 + + config DVB_USB_AF9005 + tristate "Afatech AF9005 DVB-T USB1.1 support" +- depends on BROKEN + depends on DVB_USB + select MEDIA_TUNER_MT2060 if MEDIA_SUBDRV_AUTOSELECT + select MEDIA_TUNER_QT1010 if MEDIA_SUBDRV_AUTOSELECT ++ select FW_LOADER + help + Say Y here to support the Afatech AF9005 based DVB-T USB1.1 receiver + and the TerraTec Cinergy T USB XE (Rev.1) +Index: linux/drivers/media/usb/dvb-usb/af9005-fe.c +=================================================================== +--- linux.orig/drivers/media/usb/dvb-usb/af9005-fe.c ++++ linux/drivers/media/usb/dvb-usb/af9005-fe.c +@@ -18,10 +18,26 @@ + * see Documentation/media/dvb-drivers/dvb-usb.rst for more information + */ + #include "af9005.h" +-#include "af9005-script.h" + #include "mt2060.h" + #include "qt1010.h" + #include <asm/div64.h> ++#include <linux/firmware.h> ++ ++/* Register initialisation script to be extracted from the Windows driver */ ++ ++typedef struct { ++ __le16 reg; ++ u8 pos; ++ u8 len; ++ u8 val; ++ u8 pad; ++} __packed RegDesc; ++ ++#define WIN_DRV_NAME "AF05BDA.sys" ++#define WIN_DRV_VERSION "6.3.2.1" ++#define WIN_DRV_SIZE 133504 ++#define WIN_DRV_SCRIPT_OFFSET 88316 ++#define WIN_DRV_SCRIPT_SIZE 1110 + + struct af9005_fe_state { + struct dvb_usb_device *d; +@@ -813,6 +829,8 @@ static int af9005_fe_init(struct dvb_fro + { + struct af9005_fe_state *state = fe->demodulator_priv; + struct dvb_usb_adapter *adap = fe->dvb->priv; ++ const struct firmware *fw; ++ const RegDesc *script; + int ret, i, scriptlen; + u8 temp, temp0 = 0, temp1 = 0, temp2 = 0; + u8 buf[2]; +@@ -965,37 +983,55 @@ static int af9005_fe_init(struct dvb_fro + if ((ret = af9005_write_ofdm_register(state->d, 0xaefb, 0x01))) + return ret; + +- /* load init script */ +- deb_info("load init script\n"); +- scriptlen = sizeof(script) / sizeof(RegDesc); ++ /* load and validate init script */ ++ deb_info("load init script from Windows driver\n"); ++ ret = request_firmware(&fw, WIN_DRV_NAME, &state->d->udev->dev); ++ if (ret) ++ return ret; ++ BUILD_BUG_ON(sizeof(RegDesc) != 6); ++ if (fw->size != WIN_DRV_SIZE || ++ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET, ++ "\x80\xa1\x00\x08\x0a\x00", 6) || ++ memcmp(fw->data + WIN_DRV_SCRIPT_OFFSET + WIN_DRV_SCRIPT_SIZE - 6, ++ "\x49\xa3\x00\x06\x02\x00", 6)) { ++ err("%s is invalid - should be version %s, size %u bytes\n", ++ WIN_DRV_NAME, WIN_DRV_VERSION, WIN_DRV_SIZE); ++ ret = -EINVAL; ++ goto fail_release; ++ } ++ ++ script = (const RegDesc *)(fw->data + WIN_DRV_SCRIPT_OFFSET); ++ scriptlen = WIN_DRV_SCRIPT_SIZE / sizeof(RegDesc); + for (i = 0; i < scriptlen; i++) { ++ u16 reg = le16_to_cpu(script[i].reg); + if ((ret = +- af9005_write_register_bits(state->d, script[i].reg, ++ af9005_write_register_bits(state->d, reg, + script[i].pos, + script[i].len, script[i].val))) +- return ret; ++ goto fail_release; + /* save 3 bytes of original fcw */ +- if (script[i].reg == 0xae18) ++ if (reg == 0xae18) + temp2 = script[i].val; +- if (script[i].reg == 0xae19) ++ if (reg == 0xae19) + temp1 = script[i].val; +- if (script[i].reg == 0xae1a) ++ if (reg == 0xae1a) + temp0 = script[i].val; + + /* save original unplug threshold */ +- if (script[i].reg == xd_p_reg_unplug_th) ++ if (reg == xd_p_reg_unplug_th) + state->original_if_unplug_th = script[i].val; +- if (script[i].reg == xd_p_reg_unplug_rf_gain_th) ++ if (reg == xd_p_reg_unplug_rf_gain_th) + state->original_rf_unplug_th = script[i].val; +- if (script[i].reg == xd_p_reg_unplug_dtop_if_gain_th) ++ if (reg == xd_p_reg_unplug_dtop_if_gain_th) + state->original_dtop_if_unplug_th = script[i].val; +- if (script[i].reg == xd_p_reg_unplug_dtop_rf_gain_th) ++ if (reg == xd_p_reg_unplug_dtop_rf_gain_th) + state->original_dtop_rf_unplug_th = script[i].val; + + } + state->original_fcw = + ((u32) temp2 << 16) + ((u32) temp1 << 8) + (u32) temp0; + ++ release_firmware(fw); + + /* save original TOPs */ + deb_info("save original TOPs\n"); +@@ -1075,6 +1111,10 @@ static int af9005_fe_init(struct dvb_fro + + deb_info("profit!\n"); + return 0; ++ ++fail_release: ++ release_firmware(fw); ++ return ret; + } + + static int af9005_fe_sleep(struct dvb_frontend *fe) diff --git a/debian/patches/features/all/e1000e-Add-support-for-Comet-Lake.patch b/debian/patches/features/all/e1000e-Add-support-for-Comet-Lake.patch new file mode 100644 index 000000000..2cb42334d --- /dev/null +++ b/debian/patches/features/all/e1000e-Add-support-for-Comet-Lake.patch @@ -0,0 +1,54 @@ +From: Sasha Neftin <sasha.neftin@intel.com> +Date: Thu, 10 Oct 2019 13:15:39 +0300 +Subject: e1000e: Add support for Comet Lake +Origin: https://git.kernel.org/linus/914ee9c436cbe90c8ca8a46ec8433cb614a2ada5 + +Add devices ID's for the next LOM generations that will be +available on the next Intel Client platform (Comet Lake) +This patch provides the initial support for these devices + +Signed-off-by: Sasha Neftin <sasha.neftin@intel.com> +Tested-by: Aaron Brown <aaron.f.brown@intel.com> +Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com> +--- + drivers/net/ethernet/intel/e1000e/hw.h | 6 ++++++ + drivers/net/ethernet/intel/e1000e/netdev.c | 6 ++++++ + 2 files changed, 12 insertions(+) + +diff --git a/drivers/net/ethernet/intel/e1000e/hw.h b/drivers/net/ethernet/intel/e1000e/hw.h +index eff75bd8a8f0..11fdc27faa82 100644 +--- a/drivers/net/ethernet/intel/e1000e/hw.h ++++ b/drivers/net/ethernet/intel/e1000e/hw.h +@@ -86,6 +86,12 @@ struct e1000_hw; + #define E1000_DEV_ID_PCH_ICP_I219_V8 0x15E0 + #define E1000_DEV_ID_PCH_ICP_I219_LM9 0x15E1 + #define E1000_DEV_ID_PCH_ICP_I219_V9 0x15E2 ++#define E1000_DEV_ID_PCH_CMP_I219_LM10 0x0D4E ++#define E1000_DEV_ID_PCH_CMP_I219_V10 0x0D4F ++#define E1000_DEV_ID_PCH_CMP_I219_LM11 0x0D4C ++#define E1000_DEV_ID_PCH_CMP_I219_V11 0x0D4D ++#define E1000_DEV_ID_PCH_CMP_I219_LM12 0x0D53 ++#define E1000_DEV_ID_PCH_CMP_I219_V12 0x0D55 + + #define E1000_REVISION_4 4 + +diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c +index 42f57ab8fb8e..731e1b3e103a 100644 +--- a/drivers/net/ethernet/intel/e1000e/netdev.c ++++ b/drivers/net/ethernet/intel/e1000e/netdev.c +@@ -7749,6 +7749,12 @@ static const struct pci_device_id e1000_pci_tbl[] = { + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ICP_I219_V8), board_pch_cnp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ICP_I219_LM9), board_pch_cnp }, + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ICP_I219_V9), board_pch_cnp }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_LM10), board_pch_cnp }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_V10), board_pch_cnp }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_LM11), board_pch_cnp }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_V11), board_pch_cnp }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_LM12), board_pch_spt }, ++ { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_CMP_I219_V12), board_pch_spt }, + + { 0, 0, 0, 0, 0, 0, 0 } /* terminate list */ + }; +-- +2.27.0 + diff --git a/debian/patches/features/all/ena/0001-net-ethernet-remove-redundant-include.patch b/debian/patches/features/all/ena/0001-net-ethernet-remove-redundant-include.patch new file mode 100644 index 000000000..0c681dd2a --- /dev/null +++ b/debian/patches/features/all/ena/0001-net-ethernet-remove-redundant-include.patch @@ -0,0 +1,34 @@ +From: zhong jiang <zhongjiang@huawei.com> +Date: Wed, 28 Nov 2018 23:04:48 -0800 +Subject: [PATCH 01/19] net: ethernet: remove redundant include +Origin: https://git.kernel.org/linus/e641e99f261f5203a911a9e0db54a214460d2cc4 + +Manual cherry-pick from e641e99f261f5203a911a9e0db54a214460d2cc4: + + module.h already contained moduleparam.h, so it is safe to remove + the redundant include. + + The issue is detected with the help of Coccinelle. + + Signed-off-by: zhong jiang <zhongjiang@huawei.com> + Signed-off-by: David S. Miller <davem@davemloft.net> + +limited only to the amazon/ena driver + +Signed-off-by: Noah Meyerhans <noahm@debian.org> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 1 - + 1 file changed, 1 deletion(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -39,7 +39,6 @@ + #include <linux/if_vlan.h> + #include <linux/kernel.h> + #include <linux/module.h> +-#include <linux/moduleparam.h> + #include <linux/numa.h> + #include <linux/pci.h> + #include <linux/utsname.h> diff --git a/debian/patches/features/all/ena/0002-net-ena-minor-performance-improvement.patch b/debian/patches/features/all/ena/0002-net-ena-minor-performance-improvement.patch new file mode 100644 index 000000000..f4f95e9fa --- /dev/null +++ b/debian/patches/features/all/ena/0002-net-ena-minor-performance-improvement.patch @@ -0,0 +1,139 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:16 +0300 +Subject: [PATCH 02/19] net: ena: minor performance improvement +Origin: https://git.kernel.org/linus/0e575f8542d1f4d74df30b5a9ba419c5373d01a1 + +Reduce fastpath overhead by making ena_com_tx_comp_req_id_get() inline. +Also move it to ena_eth_com.h file with its dependency function +ena_com_cq_inc_head(). + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_eth_com.c | 43 ----------------- + drivers/net/ethernet/amazon/ena/ena_eth_com.h | 46 ++++++++++++++++++- + 2 files changed, 44 insertions(+), 45 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +@@ -59,15 +59,6 @@ static inline struct ena_eth_io_rx_cdesc + return cdesc; + } + +-static inline void ena_com_cq_inc_head(struct ena_com_io_cq *io_cq) +-{ +- io_cq->head++; +- +- /* Switch phase bit in case of wrap around */ +- if (unlikely((io_cq->head & (io_cq->q_depth - 1)) == 0)) +- io_cq->phase ^= 1; +-} +- + static inline void *get_sq_desc(struct ena_com_io_sq *io_sq) + { + u16 tail_masked; +@@ -476,40 +467,6 @@ int ena_com_add_single_rx_desc(struct en + + return 0; + } +- +-int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id) +-{ +- u8 expected_phase, cdesc_phase; +- struct ena_eth_io_tx_cdesc *cdesc; +- u16 masked_head; +- +- masked_head = io_cq->head & (io_cq->q_depth - 1); +- expected_phase = io_cq->phase; +- +- cdesc = (struct ena_eth_io_tx_cdesc *) +- ((uintptr_t)io_cq->cdesc_addr.virt_addr + +- (masked_head * io_cq->cdesc_entry_size_in_bytes)); +- +- /* When the current completion descriptor phase isn't the same as the +- * expected, it mean that the device still didn't update +- * this completion. +- */ +- cdesc_phase = READ_ONCE(cdesc->flags) & ENA_ETH_IO_TX_CDESC_PHASE_MASK; +- if (cdesc_phase != expected_phase) +- return -EAGAIN; +- +- dma_rmb(); +- if (unlikely(cdesc->req_id >= io_cq->q_depth)) { +- pr_err("Invalid req id %d\n", cdesc->req_id); +- return -EINVAL; +- } +- +- ena_com_cq_inc_head(io_cq); +- +- *req_id = READ_ONCE(cdesc->req_id); +- +- return 0; +-} + + bool ena_com_cq_empty(struct ena_com_io_cq *io_cq) + { +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h +@@ -86,8 +86,6 @@ int ena_com_add_single_rx_desc(struct en + struct ena_com_buf *ena_buf, + u16 req_id); + +-int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, u16 *req_id); +- + bool ena_com_cq_empty(struct ena_com_io_cq *io_cq); + + static inline void ena_com_unmask_intr(struct ena_com_io_cq *io_cq, +@@ -159,4 +157,48 @@ static inline void ena_com_comp_ack(stru + io_sq->next_to_comp += elem; + } + ++static inline void ena_com_cq_inc_head(struct ena_com_io_cq *io_cq) ++{ ++ io_cq->head++; ++ ++ /* Switch phase bit in case of wrap around */ ++ if (unlikely((io_cq->head & (io_cq->q_depth - 1)) == 0)) ++ io_cq->phase ^= 1; ++} ++ ++static inline int ena_com_tx_comp_req_id_get(struct ena_com_io_cq *io_cq, ++ u16 *req_id) ++{ ++ u8 expected_phase, cdesc_phase; ++ struct ena_eth_io_tx_cdesc *cdesc; ++ u16 masked_head; ++ ++ masked_head = io_cq->head & (io_cq->q_depth - 1); ++ expected_phase = io_cq->phase; ++ ++ cdesc = (struct ena_eth_io_tx_cdesc *) ++ ((uintptr_t)io_cq->cdesc_addr.virt_addr + ++ (masked_head * io_cq->cdesc_entry_size_in_bytes)); ++ ++ /* When the current completion descriptor phase isn't the same as the ++ * expected, it mean that the device still didn't update ++ * this completion. ++ */ ++ cdesc_phase = READ_ONCE(cdesc->flags) & ENA_ETH_IO_TX_CDESC_PHASE_MASK; ++ if (cdesc_phase != expected_phase) ++ return -EAGAIN; ++ ++ dma_rmb(); ++ ++ *req_id = READ_ONCE(cdesc->req_id); ++ if (unlikely(*req_id >= io_cq->q_depth)) { ++ pr_err("Invalid req id %d\n", cdesc->req_id); ++ return -EINVAL; ++ } ++ ++ ena_com_cq_inc_head(io_cq); ++ ++ return 0; ++} ++ + #endif /* ENA_ETH_COM_H_ */ diff --git a/debian/patches/features/all/ena/0003-net-ena-complete-host-info-to-match-latest-ENA-spec.patch b/debian/patches/features/all/ena/0003-net-ena-complete-host-info-to-match-latest-ENA-spec.patch new file mode 100644 index 000000000..a7e02fd9e --- /dev/null +++ b/debian/patches/features/all/ena/0003-net-ena-complete-host-info-to-match-latest-ENA-spec.patch @@ -0,0 +1,178 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:17 +0300 +Subject: [PATCH 03/19] net: ena: complete host info to match latest ENA spec +Origin: https://git.kernel.org/linus/095f2f1facba0c78f23750dba65c78cef722c1ea + +Add new fields and definitions to host info and fill them +according to the latest ENA spec version. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + .../net/ethernet/amazon/ena/ena_admin_defs.h | 31 ++++++++++++++++++- + drivers/net/ethernet/amazon/ena/ena_com.c | 12 +++---- + .../net/ethernet/amazon/ena/ena_common_defs.h | 4 +-- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 10 ++++-- + 4 files changed, 43 insertions(+), 14 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +@@ -63,6 +63,8 @@ enum ena_admin_aq_completion_status { + ENA_ADMIN_ILLEGAL_PARAMETER = 5, + + ENA_ADMIN_UNKNOWN_ERROR = 6, ++ ++ ENA_ADMIN_RESOURCE_BUSY = 7, + }; + + enum ena_admin_aq_feature_id { +@@ -702,6 +704,10 @@ enum ena_admin_os_type { + ENA_ADMIN_OS_FREEBSD = 4, + + ENA_ADMIN_OS_IPXE = 5, ++ ++ ENA_ADMIN_OS_ESXI = 6, ++ ++ ENA_ADMIN_OS_GROUPS_NUM = 6, + }; + + struct ena_admin_host_info { +@@ -723,11 +729,27 @@ struct ena_admin_host_info { + /* 7:0 : major + * 15:8 : minor + * 23:16 : sub_minor ++ * 31:24 : module_type + */ + u32 driver_version; + + /* features bitmap */ +- u32 supported_network_features[4]; ++ u32 supported_network_features[2]; ++ ++ /* ENA spec version of driver */ ++ u16 ena_spec_version; ++ ++ /* ENA device's Bus, Device and Function ++ * 2:0 : function ++ * 7:3 : device ++ * 15:8 : bus ++ */ ++ u16 bdf; ++ ++ /* Number of CPUs */ ++ u16 num_cpus; ++ ++ u16 reserved; + }; + + struct ena_admin_rss_ind_table_entry { +@@ -1008,6 +1030,13 @@ struct ena_admin_ena_mmio_req_read_less_ + #define ENA_ADMIN_HOST_INFO_MINOR_MASK GENMASK(15, 8) + #define ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT 16 + #define ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK GENMASK(23, 16) ++#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT 24 ++#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_MASK GENMASK(31, 24) ++#define ENA_ADMIN_HOST_INFO_FUNCTION_MASK GENMASK(2, 0) ++#define ENA_ADMIN_HOST_INFO_DEVICE_SHIFT 3 ++#define ENA_ADMIN_HOST_INFO_DEVICE_MASK GENMASK(7, 3) ++#define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8 ++#define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 8) + + /* aenq_common_desc */ + #define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0) +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -41,9 +41,6 @@ + #define ENA_ASYNC_QUEUE_DEPTH 16 + #define ENA_ADMIN_QUEUE_DEPTH 32 + +-#define MIN_ENA_VER (((ENA_COMMON_SPEC_VERSION_MAJOR) << \ +- ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) \ +- | (ENA_COMMON_SPEC_VERSION_MINOR)) + + #define ENA_CTRL_MAJOR 0 + #define ENA_CTRL_MINOR 0 +@@ -1400,11 +1397,6 @@ int ena_com_validate_version(struct ena_ + ENA_REGS_VERSION_MAJOR_VERSION_SHIFT, + ver & ENA_REGS_VERSION_MINOR_VERSION_MASK); + +- if (ver < MIN_ENA_VER) { +- pr_err("ENA version is lower than the minimal version the driver supports\n"); +- return -1; +- } +- + pr_info("ena controller version: %d.%d.%d implementation version %d\n", + (ctrl_ver & ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK) >> + ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT, +@@ -2441,6 +2433,10 @@ int ena_com_allocate_host_info(struct en + if (unlikely(!host_attr->host_info)) + return -ENOMEM; + ++ host_attr->host_info->ena_spec_version = ++ ((ENA_COMMON_SPEC_VERSION_MAJOR << ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) | ++ (ENA_COMMON_SPEC_VERSION_MINOR)); ++ + return 0; + } + +Index: linux/drivers/net/ethernet/amazon/ena/ena_common_defs.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_common_defs.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_common_defs.h +@@ -32,8 +32,8 @@ + #ifndef _ENA_COMMON_H_ + #define _ENA_COMMON_H_ + +-#define ENA_COMMON_SPEC_VERSION_MAJOR 0 /* */ +-#define ENA_COMMON_SPEC_VERSION_MINOR 10 /* */ ++#define ENA_COMMON_SPEC_VERSION_MAJOR 2 ++#define ENA_COMMON_SPEC_VERSION_MINOR 0 + + /* ENA operates with 48-bit memory addresses. ena_mem_addr_t */ + struct ena_common_mem_addr { +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -2206,7 +2206,8 @@ static u16 ena_select_queue(struct net_d + return qid; + } + +-static void ena_config_host_info(struct ena_com_dev *ena_dev) ++static void ena_config_host_info(struct ena_com_dev *ena_dev, ++ struct pci_dev *pdev) + { + struct ena_admin_host_info *host_info; + int rc; +@@ -2220,6 +2221,7 @@ static void ena_config_host_info(struct + + host_info = ena_dev->host_attr.host_info; + ++ host_info->bdf = (pdev->bus->number << 8) | pdev->devfn; + host_info->os_type = ENA_ADMIN_OS_LINUX; + host_info->kernel_ver = LINUX_VERSION_CODE; + strlcpy(host_info->kernel_ver_str, utsname()->version, +@@ -2230,7 +2232,9 @@ static void ena_config_host_info(struct + host_info->driver_version = + (DRV_MODULE_VER_MAJOR) | + (DRV_MODULE_VER_MINOR << ENA_ADMIN_HOST_INFO_MINOR_SHIFT) | +- (DRV_MODULE_VER_SUBMINOR << ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT); ++ (DRV_MODULE_VER_SUBMINOR << ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT) | ++ ("K"[0] << ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT); ++ host_info->num_cpus = num_online_cpus(); + + rc = ena_com_set_host_attributes(ena_dev); + if (rc) { +@@ -2454,7 +2458,7 @@ static int ena_device_init(struct ena_co + */ + ena_com_set_admin_polling_mode(ena_dev, true); + +- ena_config_host_info(ena_dev); ++ ena_config_host_info(ena_dev, pdev); + + /* Get Device Attributes*/ + rc = ena_com_get_dev_attr_feat(ena_dev, get_feat_ctx); diff --git a/debian/patches/features/all/ena/0004-net-ena-introduce-Low-Latency-Queues-data-structures.patch b/debian/patches/features/all/ena/0004-net-ena-introduce-Low-Latency-Queues-data-structures.patch new file mode 100644 index 000000000..51e655bab --- /dev/null +++ b/debian/patches/features/all/ena/0004-net-ena-introduce-Low-Latency-Queues-data-structures.patch @@ -0,0 +1,271 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:18 +0300 +Subject: [PATCH 04/19] net: ena: introduce Low Latency Queues data structures + according to ENA spec +Origin: https://git.kernel.org/linus/a7982b8ec947052df6d4467b3a81571f02f528e0 + +Low Latency Queues(LLQ) allow usage of device's memory for descriptors +and headers. Such queues decrease processing time since data is already +located on the device when driver rings the doorbell. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + .../net/ethernet/amazon/ena/ena_admin_defs.h | 90 ++++++++++++++++++- + drivers/net/ethernet/amazon/ena/ena_com.h | 38 ++++++++ + drivers/net/ethernet/amazon/ena/ena_netdev.c | 6 +- + 3 files changed, 128 insertions(+), 6 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +@@ -74,6 +74,8 @@ enum ena_admin_aq_feature_id { + + ENA_ADMIN_HW_HINTS = 3, + ++ ENA_ADMIN_LLQ = 4, ++ + ENA_ADMIN_RSS_HASH_FUNCTION = 10, + + ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11, +@@ -485,8 +487,85 @@ struct ena_admin_device_attr_feature_des + u32 max_mtu; + }; + ++enum ena_admin_llq_header_location { ++ /* header is in descriptor list */ ++ ENA_ADMIN_INLINE_HEADER = 1, ++ /* header in a separate ring, implies 16B descriptor list entry */ ++ ENA_ADMIN_HEADER_RING = 2, ++}; ++ ++enum ena_admin_llq_ring_entry_size { ++ ENA_ADMIN_LIST_ENTRY_SIZE_128B = 1, ++ ENA_ADMIN_LIST_ENTRY_SIZE_192B = 2, ++ ENA_ADMIN_LIST_ENTRY_SIZE_256B = 4, ++}; ++ ++enum ena_admin_llq_num_descs_before_header { ++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_0 = 0, ++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_1 = 1, ++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2 = 2, ++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_4 = 4, ++ ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_8 = 8, ++}; ++ ++/* packet descriptor list entry always starts with one or more descriptors, ++ * followed by a header. The rest of the descriptors are located in the ++ * beginning of the subsequent entry. Stride refers to how the rest of the ++ * descriptors are placed. This field is relevant only for inline header ++ * mode ++ */ ++enum ena_admin_llq_stride_ctrl { ++ ENA_ADMIN_SINGLE_DESC_PER_ENTRY = 1, ++ ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY = 2, ++}; ++ ++struct ena_admin_feature_llq_desc { ++ u32 max_llq_num; ++ ++ u32 max_llq_depth; ++ ++ /* specify the header locations the device supports. bitfield of ++ * enum ena_admin_llq_header_location. ++ */ ++ u16 header_location_ctrl_supported; ++ ++ /* the header location the driver selected to use. */ ++ u16 header_location_ctrl_enabled; ++ ++ /* if inline header is specified - this is the size of descriptor ++ * list entry. If header in a separate ring is specified - this is ++ * the size of header ring entry. bitfield of enum ++ * ena_admin_llq_ring_entry_size. specify the entry sizes the device ++ * supports ++ */ ++ u16 entry_size_ctrl_supported; ++ ++ /* the entry size the driver selected to use. */ ++ u16 entry_size_ctrl_enabled; ++ ++ /* valid only if inline header is specified. First entry associated ++ * with the packet includes descriptors and header. Rest of the ++ * entries occupied by descriptors. This parameter defines the max ++ * number of descriptors precedding the header in the first entry. ++ * The field is bitfield of enum ++ * ena_admin_llq_num_descs_before_header and specify the values the ++ * device supports ++ */ ++ u16 desc_num_before_header_supported; ++ ++ /* the desire field the driver selected to use */ ++ u16 desc_num_before_header_enabled; ++ ++ /* valid only if inline was chosen. bitfield of enum ++ * ena_admin_llq_stride_ctrl ++ */ ++ u16 descriptors_stride_ctrl_supported; ++ ++ /* the stride control the driver selected to use */ ++ u16 descriptors_stride_ctrl_enabled; ++}; ++ + struct ena_admin_queue_feature_desc { +- /* including LLQs */ + u32 max_sq_num; + + u32 max_sq_depth; +@@ -495,9 +574,9 @@ struct ena_admin_queue_feature_desc { + + u32 max_cq_depth; + +- u32 max_llq_num; ++ u32 max_legacy_llq_num; + +- u32 max_llq_depth; ++ u32 max_legacy_llq_depth; + + u32 max_header_size; + +@@ -822,6 +901,8 @@ struct ena_admin_get_feat_resp { + + struct ena_admin_device_attr_feature_desc dev_attr; + ++ struct ena_admin_feature_llq_desc llq; ++ + struct ena_admin_queue_feature_desc max_queue; + + struct ena_admin_feature_aenq_desc aenq; +@@ -869,6 +950,9 @@ struct ena_admin_set_feat_cmd { + + /* rss indirection table */ + struct ena_admin_feature_rss_ind_table ind_table; ++ ++ /* LLQ configuration */ ++ struct ena_admin_feature_llq_desc llq; + } u; + }; + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -108,6 +108,14 @@ enum ena_intr_moder_level { + ENA_INTR_MAX_NUM_OF_LEVELS, + }; + ++struct ena_llq_configurations { ++ enum ena_admin_llq_header_location llq_header_location; ++ enum ena_admin_llq_ring_entry_size llq_ring_entry_size; ++ enum ena_admin_llq_stride_ctrl llq_stride_ctrl; ++ enum ena_admin_llq_num_descs_before_header llq_num_decs_before_header; ++ u16 llq_ring_entry_size_value; ++}; ++ + struct ena_intr_moder_entry { + unsigned int intr_moder_interval; + unsigned int pkts_per_interval; +@@ -142,6 +150,15 @@ struct ena_com_tx_meta { + u16 l4_hdr_len; /* In words */ + }; + ++struct ena_com_llq_info { ++ u16 header_location_ctrl; ++ u16 desc_stride_ctrl; ++ u16 desc_list_entry_size_ctrl; ++ u16 desc_list_entry_size; ++ u16 descs_num_before_header; ++ u16 descs_per_entry; ++}; ++ + struct ena_com_io_cq { + struct ena_com_io_desc_addr cdesc_addr; + +@@ -179,6 +196,20 @@ struct ena_com_io_cq { + + } ____cacheline_aligned; + ++struct ena_com_io_bounce_buffer_control { ++ u8 *base_buffer; ++ u16 next_to_use; ++ u16 buffer_size; ++ u16 buffers_num; /* Must be a power of 2 */ ++}; ++ ++/* This struct is to keep tracking the current location of the next llq entry */ ++struct ena_com_llq_pkt_ctrl { ++ u8 *curr_bounce_buf; ++ u16 idx; ++ u16 descs_left_in_line; ++}; ++ + struct ena_com_io_sq { + struct ena_com_io_desc_addr desc_addr; + +@@ -190,6 +221,9 @@ struct ena_com_io_sq { + + u32 msix_vector; + struct ena_com_tx_meta cached_tx_meta; ++ struct ena_com_llq_info llq_info; ++ struct ena_com_llq_pkt_ctrl llq_buf_ctrl; ++ struct ena_com_io_bounce_buffer_control bounce_buf_ctrl; + + u16 q_depth; + u16 qid; +@@ -197,6 +231,7 @@ struct ena_com_io_sq { + u16 idx; + u16 tail; + u16 next_to_comp; ++ u16 llq_last_copy_tail; + u32 tx_max_header_size; + u8 phase; + u8 desc_entry_size; +@@ -334,6 +369,8 @@ struct ena_com_dev { + u16 intr_delay_resolution; + u32 intr_moder_tx_interval; + struct ena_intr_moder_entry *intr_moder_tbl; ++ ++ struct ena_com_llq_info llq_info; + }; + + struct ena_com_dev_get_features_ctx { +@@ -342,6 +379,7 @@ struct ena_com_dev_get_features_ctx { + struct ena_admin_feature_aenq_desc aenq; + struct ena_admin_feature_offload_desc offload; + struct ena_admin_ena_hw_hints hw_hints; ++ struct ena_admin_feature_llq_desc llq; + }; + + struct ena_com_create_io_ctx { +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -2959,7 +2959,7 @@ static int ena_calc_io_queue_num(struct + + /* In case of LLQ use the llq number in the get feature cmd */ + if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { +- io_sq_num = get_feat_ctx->max_queues.max_llq_num; ++ io_sq_num = get_feat_ctx->max_queues.max_legacy_llq_num; + + if (io_sq_num == 0) { + dev_err(&pdev->dev, +@@ -2995,7 +2995,7 @@ static void ena_set_push_mode(struct pci + has_mem_bar = pci_select_bars(pdev, IORESOURCE_MEM) & BIT(ENA_MEM_BAR); + + /* Enable push mode if device supports LLQ */ +- if (has_mem_bar && (get_feat_ctx->max_queues.max_llq_num > 0)) ++ if (has_mem_bar && get_feat_ctx->max_queues.max_legacy_llq_num > 0) + ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_DEV; + else + ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; +@@ -3131,7 +3131,7 @@ static int ena_calc_queue_size(struct pc + + if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) + queue_size = min_t(u32, queue_size, +- get_feat_ctx->max_queues.max_llq_depth); ++ get_feat_ctx->max_queues.max_legacy_llq_depth); + + queue_size = rounddown_pow_of_two(queue_size); + diff --git a/debian/patches/features/all/ena/0005-net-ena-add-functions-for-handling-Low-Latency-Queue.patch b/debian/patches/features/all/ena/0005-net-ena-add-functions-for-handling-Low-Latency-Queue.patch new file mode 100644 index 000000000..375541b10 --- /dev/null +++ b/debian/patches/features/all/ena/0005-net-ena-add-functions-for-handling-Low-Latency-Queue.patch @@ -0,0 +1,832 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:19 +0300 +Subject: [PATCH 05/19] net: ena: add functions for handling Low Latency Queues + in ena_com +Origin: https://git.kernel.org/linus/689b2bdaaa1480ad2c14bdc4c6eaf38284549022 + +This patch introduces APIs for detection, initialization, configuration +and actual usage of low latency queues(LLQ). It extends transmit API with +creation of LLQ descriptors in device memory (which include host buffers +descriptors as well as packet header) + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 249 +++++++++++++++++- + drivers/net/ethernet/amazon/ena/ena_com.h | 28 ++ + drivers/net/ethernet/amazon/ena/ena_eth_com.c | 231 ++++++++++++---- + drivers/net/ethernet/amazon/ena/ena_eth_com.h | 25 +- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 21 +- + 5 files changed, 474 insertions(+), 80 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -58,6 +58,8 @@ + + #define ENA_MMIO_READ_TIMEOUT 0xFFFFFFFF + ++#define ENA_COM_BOUNCE_BUFFER_CNTRL_CNT 4 ++ + #define ENA_REGS_ADMIN_INTR_MASK 1 + + #define ENA_POLL_MS 5 +@@ -352,21 +354,48 @@ static int ena_com_init_io_sq(struct ena + &io_sq->desc_addr.phys_addr, + GFP_KERNEL); + } +- } else { ++ ++ if (!io_sq->desc_addr.virt_addr) { ++ pr_err("memory allocation failed"); ++ return -ENOMEM; ++ } ++ } ++ ++ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { ++ /* Allocate bounce buffers */ ++ io_sq->bounce_buf_ctrl.buffer_size = ++ ena_dev->llq_info.desc_list_entry_size; ++ io_sq->bounce_buf_ctrl.buffers_num = ++ ENA_COM_BOUNCE_BUFFER_CNTRL_CNT; ++ io_sq->bounce_buf_ctrl.next_to_use = 0; ++ ++ size = io_sq->bounce_buf_ctrl.buffer_size * ++ io_sq->bounce_buf_ctrl.buffers_num; ++ + dev_node = dev_to_node(ena_dev->dmadev); + set_dev_node(ena_dev->dmadev, ctx->numa_node); +- io_sq->desc_addr.virt_addr = ++ io_sq->bounce_buf_ctrl.base_buffer = + devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL); + set_dev_node(ena_dev->dmadev, dev_node); +- if (!io_sq->desc_addr.virt_addr) { +- io_sq->desc_addr.virt_addr = ++ if (!io_sq->bounce_buf_ctrl.base_buffer) ++ io_sq->bounce_buf_ctrl.base_buffer = + devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL); ++ ++ if (!io_sq->bounce_buf_ctrl.base_buffer) { ++ pr_err("bounce buffer memory allocation failed"); ++ return -ENOMEM; + } +- } + +- if (!io_sq->desc_addr.virt_addr) { +- pr_err("memory allocation failed"); +- return -ENOMEM; ++ memcpy(&io_sq->llq_info, &ena_dev->llq_info, ++ sizeof(io_sq->llq_info)); ++ ++ /* Initiate the first bounce buffer */ ++ io_sq->llq_buf_ctrl.curr_bounce_buf = ++ ena_com_get_next_bounce_buffer(&io_sq->bounce_buf_ctrl); ++ memset(io_sq->llq_buf_ctrl.curr_bounce_buf, ++ 0x0, io_sq->llq_info.desc_list_entry_size); ++ io_sq->llq_buf_ctrl.descs_left_in_line = ++ io_sq->llq_info.descs_num_before_header; + } + + io_sq->tail = 0; +@@ -554,6 +583,156 @@ err: + return ret; + } + ++/** ++ * Set the LLQ configurations of the firmware ++ * ++ * The driver provides only the enabled feature values to the device, ++ * which in turn, checks if they are supported. ++ */ ++static int ena_com_set_llq(struct ena_com_dev *ena_dev) ++{ ++ struct ena_com_admin_queue *admin_queue; ++ struct ena_admin_set_feat_cmd cmd; ++ struct ena_admin_set_feat_resp resp; ++ struct ena_com_llq_info *llq_info = &ena_dev->llq_info; ++ int ret; ++ ++ memset(&cmd, 0x0, sizeof(cmd)); ++ admin_queue = &ena_dev->admin_queue; ++ ++ cmd.aq_common_descriptor.opcode = ENA_ADMIN_SET_FEATURE; ++ cmd.feat_common.feature_id = ENA_ADMIN_LLQ; ++ ++ cmd.u.llq.header_location_ctrl_enabled = llq_info->header_location_ctrl; ++ cmd.u.llq.entry_size_ctrl_enabled = llq_info->desc_list_entry_size_ctrl; ++ cmd.u.llq.desc_num_before_header_enabled = llq_info->descs_num_before_header; ++ cmd.u.llq.descriptors_stride_ctrl_enabled = llq_info->desc_stride_ctrl; ++ ++ ret = ena_com_execute_admin_command(admin_queue, ++ (struct ena_admin_aq_entry *)&cmd, ++ sizeof(cmd), ++ (struct ena_admin_acq_entry *)&resp, ++ sizeof(resp)); ++ ++ if (unlikely(ret)) ++ pr_err("Failed to set LLQ configurations: %d\n", ret); ++ ++ return ret; ++} ++ ++static int ena_com_config_llq_info(struct ena_com_dev *ena_dev, ++ struct ena_admin_feature_llq_desc *llq_features, ++ struct ena_llq_configurations *llq_default_cfg) ++{ ++ struct ena_com_llq_info *llq_info = &ena_dev->llq_info; ++ u16 supported_feat; ++ int rc; ++ ++ memset(llq_info, 0, sizeof(*llq_info)); ++ ++ supported_feat = llq_features->header_location_ctrl_supported; ++ ++ if (likely(supported_feat & llq_default_cfg->llq_header_location)) { ++ llq_info->header_location_ctrl = ++ llq_default_cfg->llq_header_location; ++ } else { ++ pr_err("Invalid header location control, supported: 0x%x\n", ++ supported_feat); ++ return -EINVAL; ++ } ++ ++ if (likely(llq_info->header_location_ctrl == ENA_ADMIN_INLINE_HEADER)) { ++ supported_feat = llq_features->descriptors_stride_ctrl_supported; ++ if (likely(supported_feat & llq_default_cfg->llq_stride_ctrl)) { ++ llq_info->desc_stride_ctrl = llq_default_cfg->llq_stride_ctrl; ++ } else { ++ if (supported_feat & ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY) { ++ llq_info->desc_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY; ++ } else if (supported_feat & ENA_ADMIN_SINGLE_DESC_PER_ENTRY) { ++ llq_info->desc_stride_ctrl = ENA_ADMIN_SINGLE_DESC_PER_ENTRY; ++ } else { ++ pr_err("Invalid desc_stride_ctrl, supported: 0x%x\n", ++ supported_feat); ++ return -EINVAL; ++ } ++ ++ pr_err("Default llq stride ctrl is not supported, performing fallback, default: 0x%x, supported: 0x%x, used: 0x%x\n", ++ llq_default_cfg->llq_stride_ctrl, supported_feat, ++ llq_info->desc_stride_ctrl); ++ } ++ } else { ++ llq_info->desc_stride_ctrl = 0; ++ } ++ ++ supported_feat = llq_features->entry_size_ctrl_supported; ++ if (likely(supported_feat & llq_default_cfg->llq_ring_entry_size)) { ++ llq_info->desc_list_entry_size_ctrl = llq_default_cfg->llq_ring_entry_size; ++ llq_info->desc_list_entry_size = llq_default_cfg->llq_ring_entry_size_value; ++ } else { ++ if (supported_feat & ENA_ADMIN_LIST_ENTRY_SIZE_128B) { ++ llq_info->desc_list_entry_size_ctrl = ENA_ADMIN_LIST_ENTRY_SIZE_128B; ++ llq_info->desc_list_entry_size = 128; ++ } else if (supported_feat & ENA_ADMIN_LIST_ENTRY_SIZE_192B) { ++ llq_info->desc_list_entry_size_ctrl = ENA_ADMIN_LIST_ENTRY_SIZE_192B; ++ llq_info->desc_list_entry_size = 192; ++ } else if (supported_feat & ENA_ADMIN_LIST_ENTRY_SIZE_256B) { ++ llq_info->desc_list_entry_size_ctrl = ENA_ADMIN_LIST_ENTRY_SIZE_256B; ++ llq_info->desc_list_entry_size = 256; ++ } else { ++ pr_err("Invalid entry_size_ctrl, supported: 0x%x\n", ++ supported_feat); ++ return -EINVAL; ++ } ++ ++ pr_err("Default llq ring entry size is not supported, performing fallback, default: 0x%x, supported: 0x%x, used: 0x%x\n", ++ llq_default_cfg->llq_ring_entry_size, supported_feat, ++ llq_info->desc_list_entry_size); ++ } ++ if (unlikely(llq_info->desc_list_entry_size & 0x7)) { ++ /* The desc list entry size should be whole multiply of 8 ++ * This requirement comes from __iowrite64_copy() ++ */ ++ pr_err("illegal entry size %d\n", ++ llq_info->desc_list_entry_size); ++ return -EINVAL; ++ } ++ ++ if (llq_info->desc_stride_ctrl == ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY) ++ llq_info->descs_per_entry = llq_info->desc_list_entry_size / ++ sizeof(struct ena_eth_io_tx_desc); ++ else ++ llq_info->descs_per_entry = 1; ++ ++ supported_feat = llq_features->desc_num_before_header_supported; ++ if (likely(supported_feat & llq_default_cfg->llq_num_decs_before_header)) { ++ llq_info->descs_num_before_header = llq_default_cfg->llq_num_decs_before_header; ++ } else { ++ if (supported_feat & ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2) { ++ llq_info->descs_num_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2; ++ } else if (supported_feat & ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_1) { ++ llq_info->descs_num_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_1; ++ } else if (supported_feat & ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_4) { ++ llq_info->descs_num_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_4; ++ } else if (supported_feat & ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_8) { ++ llq_info->descs_num_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_8; ++ } else { ++ pr_err("Invalid descs_num_before_header, supported: 0x%x\n", ++ supported_feat); ++ return -EINVAL; ++ } ++ ++ pr_err("Default llq num descs before header is not supported, performing fallback, default: 0x%x, supported: 0x%x, used: 0x%x\n", ++ llq_default_cfg->llq_num_decs_before_header, ++ supported_feat, llq_info->descs_num_before_header); ++ } ++ ++ rc = ena_com_set_llq(ena_dev); ++ if (rc) ++ pr_err("Cannot set LLQ configuration: %d\n", rc); ++ ++ return 0; ++} ++ + static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *comp_ctx, + struct ena_com_admin_queue *admin_queue) + { +@@ -725,15 +904,17 @@ static void ena_com_io_queue_free(struct + if (io_sq->desc_addr.virt_addr) { + size = io_sq->desc_entry_size * io_sq->q_depth; + +- if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) +- dma_free_coherent(ena_dev->dmadev, size, +- io_sq->desc_addr.virt_addr, +- io_sq->desc_addr.phys_addr); +- else +- devm_kfree(ena_dev->dmadev, io_sq->desc_addr.virt_addr); ++ dma_free_coherent(ena_dev->dmadev, size, ++ io_sq->desc_addr.virt_addr, ++ io_sq->desc_addr.phys_addr); + + io_sq->desc_addr.virt_addr = NULL; + } ++ ++ if (io_sq->bounce_buf_ctrl.base_buffer) { ++ devm_kfree(ena_dev->dmadev, io_sq->bounce_buf_ctrl.base_buffer); ++ io_sq->bounce_buf_ctrl.base_buffer = NULL; ++ } + } + + static int wait_for_reset_state(struct ena_com_dev *ena_dev, u32 timeout, +@@ -1740,6 +1921,15 @@ int ena_com_get_dev_attr_feat(struct ena + else + return rc; + ++ rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_LLQ); ++ if (!rc) ++ memcpy(&get_feat_ctx->llq, &get_resp.u.llq, ++ sizeof(get_resp.u.llq)); ++ else if (rc == -EOPNOTSUPP) ++ memset(&get_feat_ctx->llq, 0x0, sizeof(get_feat_ctx->llq)); ++ else ++ return rc; ++ + return 0; + } + +@@ -2708,3 +2898,34 @@ void ena_com_get_intr_moderation_entry(s + intr_moder_tbl[level].pkts_per_interval; + entry->bytes_per_interval = intr_moder_tbl[level].bytes_per_interval; + } ++ ++int ena_com_config_dev_mode(struct ena_com_dev *ena_dev, ++ struct ena_admin_feature_llq_desc *llq_features, ++ struct ena_llq_configurations *llq_default_cfg) ++{ ++ int rc; ++ int size; ++ ++ if (!llq_features->max_llq_num) { ++ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; ++ return 0; ++ } ++ ++ rc = ena_com_config_llq_info(ena_dev, llq_features, llq_default_cfg); ++ if (rc) ++ return rc; ++ ++ /* Validate the descriptor is not too big */ ++ size = ena_dev->tx_max_header_size; ++ size += ena_dev->llq_info.descs_num_before_header * ++ sizeof(struct ena_eth_io_tx_desc); ++ ++ if (unlikely(ena_dev->llq_info.desc_list_entry_size < size)) { ++ pr_err("the size of the LLQ entry is smaller than needed\n"); ++ return -EINVAL; ++ } ++ ++ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_DEV; ++ ++ return 0; ++} +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -37,6 +37,7 @@ + #include <linux/delay.h> + #include <linux/dma-mapping.h> + #include <linux/gfp.h> ++#include <linux/io.h> + #include <linux/sched.h> + #include <linux/sizes.h> + #include <linux/spinlock.h> +@@ -973,6 +974,16 @@ void ena_com_get_intr_moderation_entry(s + enum ena_intr_moder_level level, + struct ena_intr_moder_entry *entry); + ++/* ena_com_config_dev_mode - Configure the placement policy of the device. ++ * @ena_dev: ENA communication layer struct ++ * @llq_features: LLQ feature descriptor, retrieve via ++ * ena_com_get_dev_attr_feat. ++ * @ena_llq_config: The default driver LLQ parameters configurations ++ */ ++int ena_com_config_dev_mode(struct ena_com_dev *ena_dev, ++ struct ena_admin_feature_llq_desc *llq_features, ++ struct ena_llq_configurations *llq_default_config); ++ + static inline bool ena_com_get_adaptive_moderation_enabled(struct ena_com_dev *ena_dev) + { + return ena_dev->adaptive_coalescing; +@@ -1082,4 +1093,21 @@ static inline void ena_com_update_intr_r + intr_reg->intr_control |= ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK; + } + ++static inline u8 *ena_com_get_next_bounce_buffer(struct ena_com_io_bounce_buffer_control *bounce_buf_ctrl) ++{ ++ u16 size, buffers_num; ++ u8 *buf; ++ ++ size = bounce_buf_ctrl->buffer_size; ++ buffers_num = bounce_buf_ctrl->buffers_num; ++ ++ buf = bounce_buf_ctrl->base_buffer + ++ (bounce_buf_ctrl->next_to_use++ & (buffers_num - 1)) * size; ++ ++ prefetchw(bounce_buf_ctrl->base_buffer + ++ (bounce_buf_ctrl->next_to_use & (buffers_num - 1)) * size); ++ ++ return buf; ++} ++ + #endif /* !(ENA_COM) */ +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +@@ -59,7 +59,7 @@ static inline struct ena_eth_io_rx_cdesc + return cdesc; + } + +-static inline void *get_sq_desc(struct ena_com_io_sq *io_sq) ++static inline void *get_sq_desc_regular_queue(struct ena_com_io_sq *io_sq) + { + u16 tail_masked; + u32 offset; +@@ -71,45 +71,159 @@ static inline void *get_sq_desc(struct e + return (void *)((uintptr_t)io_sq->desc_addr.virt_addr + offset); + } + +-static inline void ena_com_copy_curr_sq_desc_to_dev(struct ena_com_io_sq *io_sq) ++static inline int ena_com_write_bounce_buffer_to_dev(struct ena_com_io_sq *io_sq, ++ u8 *bounce_buffer) + { +- u16 tail_masked = io_sq->tail & (io_sq->q_depth - 1); +- u32 offset = tail_masked * io_sq->desc_entry_size; ++ struct ena_com_llq_info *llq_info = &io_sq->llq_info; + +- /* In case this queue isn't a LLQ */ +- if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) +- return; ++ u16 dst_tail_mask; ++ u32 dst_offset; + +- memcpy_toio(io_sq->desc_addr.pbuf_dev_addr + offset, +- io_sq->desc_addr.virt_addr + offset, +- io_sq->desc_entry_size); +-} ++ dst_tail_mask = io_sq->tail & (io_sq->q_depth - 1); ++ dst_offset = dst_tail_mask * llq_info->desc_list_entry_size; ++ ++ /* Make sure everything was written into the bounce buffer before ++ * writing the bounce buffer to the device ++ */ ++ wmb(); ++ ++ /* The line is completed. Copy it to dev */ ++ __iowrite64_copy(io_sq->desc_addr.pbuf_dev_addr + dst_offset, ++ bounce_buffer, (llq_info->desc_list_entry_size) / 8); + +-static inline void ena_com_sq_update_tail(struct ena_com_io_sq *io_sq) +-{ + io_sq->tail++; + + /* Switch phase bit in case of wrap around */ + if (unlikely((io_sq->tail & (io_sq->q_depth - 1)) == 0)) + io_sq->phase ^= 1; ++ ++ return 0; + } + +-static inline int ena_com_write_header(struct ena_com_io_sq *io_sq, +- u8 *head_src, u16 header_len) ++static inline int ena_com_write_header_to_bounce(struct ena_com_io_sq *io_sq, ++ u8 *header_src, ++ u16 header_len) ++{ ++ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; ++ struct ena_com_llq_info *llq_info = &io_sq->llq_info; ++ u8 *bounce_buffer = pkt_ctrl->curr_bounce_buf; ++ u16 header_offset; ++ ++ if (unlikely(io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)) ++ return 0; ++ ++ header_offset = ++ llq_info->descs_num_before_header * io_sq->desc_entry_size; ++ ++ if (unlikely((header_offset + header_len) > ++ llq_info->desc_list_entry_size)) { ++ pr_err("trying to write header larger than llq entry can accommodate\n"); ++ return -EFAULT; ++ } ++ ++ if (unlikely(!bounce_buffer)) { ++ pr_err("bounce buffer is NULL\n"); ++ return -EFAULT; ++ } ++ ++ memcpy(bounce_buffer + header_offset, header_src, header_len); ++ ++ return 0; ++} ++ ++static inline void *get_sq_desc_llq(struct ena_com_io_sq *io_sq) ++{ ++ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; ++ u8 *bounce_buffer; ++ void *sq_desc; ++ ++ bounce_buffer = pkt_ctrl->curr_bounce_buf; ++ ++ if (unlikely(!bounce_buffer)) { ++ pr_err("bounce buffer is NULL\n"); ++ return NULL; ++ } ++ ++ sq_desc = bounce_buffer + pkt_ctrl->idx * io_sq->desc_entry_size; ++ pkt_ctrl->idx++; ++ pkt_ctrl->descs_left_in_line--; ++ ++ return sq_desc; ++} ++ ++static inline int ena_com_close_bounce_buffer(struct ena_com_io_sq *io_sq) + { +- u16 tail_masked = io_sq->tail & (io_sq->q_depth - 1); +- u8 __iomem *dev_head_addr = +- io_sq->header_addr + (tail_masked * io_sq->tx_max_header_size); ++ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; ++ struct ena_com_llq_info *llq_info = &io_sq->llq_info; ++ int rc; + +- if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) ++ if (unlikely(io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST)) + return 0; + +- if (unlikely(!io_sq->header_addr)) { +- pr_err("Push buffer header ptr is NULL\n"); +- return -EINVAL; ++ /* bounce buffer was used, so write it and get a new one */ ++ if (pkt_ctrl->idx) { ++ rc = ena_com_write_bounce_buffer_to_dev(io_sq, ++ pkt_ctrl->curr_bounce_buf); ++ if (unlikely(rc)) ++ return rc; ++ ++ pkt_ctrl->curr_bounce_buf = ++ ena_com_get_next_bounce_buffer(&io_sq->bounce_buf_ctrl); ++ memset(io_sq->llq_buf_ctrl.curr_bounce_buf, ++ 0x0, llq_info->desc_list_entry_size); + } + +- memcpy_toio(dev_head_addr, head_src, header_len); ++ pkt_ctrl->idx = 0; ++ pkt_ctrl->descs_left_in_line = llq_info->descs_num_before_header; ++ return 0; ++} ++ ++static inline void *get_sq_desc(struct ena_com_io_sq *io_sq) ++{ ++ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ++ return get_sq_desc_llq(io_sq); ++ ++ return get_sq_desc_regular_queue(io_sq); ++} ++ ++static inline int ena_com_sq_update_llq_tail(struct ena_com_io_sq *io_sq) ++{ ++ struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; ++ struct ena_com_llq_info *llq_info = &io_sq->llq_info; ++ int rc; ++ ++ if (!pkt_ctrl->descs_left_in_line) { ++ rc = ena_com_write_bounce_buffer_to_dev(io_sq, ++ pkt_ctrl->curr_bounce_buf); ++ if (unlikely(rc)) ++ return rc; ++ ++ pkt_ctrl->curr_bounce_buf = ++ ena_com_get_next_bounce_buffer(&io_sq->bounce_buf_ctrl); ++ memset(io_sq->llq_buf_ctrl.curr_bounce_buf, ++ 0x0, llq_info->desc_list_entry_size); ++ ++ pkt_ctrl->idx = 0; ++ if (unlikely(llq_info->desc_stride_ctrl == ENA_ADMIN_SINGLE_DESC_PER_ENTRY)) ++ pkt_ctrl->descs_left_in_line = 1; ++ else ++ pkt_ctrl->descs_left_in_line = ++ llq_info->desc_list_entry_size / io_sq->desc_entry_size; ++ } ++ ++ return 0; ++} ++ ++static inline int ena_com_sq_update_tail(struct ena_com_io_sq *io_sq) ++{ ++ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ++ return ena_com_sq_update_llq_tail(io_sq); ++ ++ io_sq->tail++; ++ ++ /* Switch phase bit in case of wrap around */ ++ if (unlikely((io_sq->tail & (io_sq->q_depth - 1)) == 0)) ++ io_sq->phase ^= 1; + + return 0; + } +@@ -177,8 +291,8 @@ static inline bool ena_com_meta_desc_cha + return false; + } + +-static inline void ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, +- struct ena_com_tx_ctx *ena_tx_ctx) ++static inline int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, ++ struct ena_com_tx_ctx *ena_tx_ctx) + { + struct ena_eth_io_tx_meta_desc *meta_desc = NULL; + struct ena_com_tx_meta *ena_meta = &ena_tx_ctx->ena_meta; +@@ -223,8 +337,7 @@ static inline void ena_com_create_and_st + memcpy(&io_sq->cached_tx_meta, ena_meta, + sizeof(struct ena_com_tx_meta)); + +- ena_com_copy_curr_sq_desc_to_dev(io_sq); +- ena_com_sq_update_tail(io_sq); ++ return ena_com_sq_update_tail(io_sq); + } + + static inline void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx, +@@ -262,18 +375,19 @@ int ena_com_prepare_tx(struct ena_com_io + { + struct ena_eth_io_tx_desc *desc = NULL; + struct ena_com_buf *ena_bufs = ena_tx_ctx->ena_bufs; +- void *push_header = ena_tx_ctx->push_header; ++ void *buffer_to_push = ena_tx_ctx->push_header; + u16 header_len = ena_tx_ctx->header_len; + u16 num_bufs = ena_tx_ctx->num_bufs; +- int total_desc, i, rc; ++ u16 start_tail = io_sq->tail; ++ int i, rc; + bool have_meta; + u64 addr_hi; + + WARN(io_sq->direction != ENA_COM_IO_QUEUE_DIRECTION_TX, "wrong Q type"); + + /* num_bufs +1 for potential meta desc */ +- if (ena_com_sq_empty_space(io_sq) < (num_bufs + 1)) { +- pr_err("Not enough space in the tx queue\n"); ++ if (unlikely(!ena_com_sq_have_enough_space(io_sq, num_bufs + 1))) { ++ pr_debug("Not enough space in the tx queue\n"); + return -ENOMEM; + } + +@@ -283,23 +397,32 @@ int ena_com_prepare_tx(struct ena_com_io + return -EINVAL; + } + +- /* start with pushing the header (if needed) */ +- rc = ena_com_write_header(io_sq, push_header, header_len); ++ if (unlikely(io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV && ++ !buffer_to_push)) ++ return -EINVAL; ++ ++ rc = ena_com_write_header_to_bounce(io_sq, buffer_to_push, header_len); + if (unlikely(rc)) + return rc; + + have_meta = ena_tx_ctx->meta_valid && ena_com_meta_desc_changed(io_sq, + ena_tx_ctx); +- if (have_meta) +- ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx); ++ if (have_meta) { ++ rc = ena_com_create_and_store_tx_meta_desc(io_sq, ena_tx_ctx); ++ if (unlikely(rc)) ++ return rc; ++ } + +- /* If the caller doesn't want send packets */ ++ /* If the caller doesn't want to send packets */ + if (unlikely(!num_bufs && !header_len)) { +- *nb_hw_desc = have_meta ? 0 : 1; +- return 0; ++ rc = ena_com_close_bounce_buffer(io_sq); ++ *nb_hw_desc = io_sq->tail - start_tail; ++ return rc; + } + + desc = get_sq_desc(io_sq); ++ if (unlikely(!desc)) ++ return -EFAULT; + memset(desc, 0x0, sizeof(struct ena_eth_io_tx_desc)); + + /* Set first desc when we don't have meta descriptor */ +@@ -351,10 +474,14 @@ int ena_com_prepare_tx(struct ena_com_io + for (i = 0; i < num_bufs; i++) { + /* The first desc share the same desc as the header */ + if (likely(i != 0)) { +- ena_com_copy_curr_sq_desc_to_dev(io_sq); +- ena_com_sq_update_tail(io_sq); ++ rc = ena_com_sq_update_tail(io_sq); ++ if (unlikely(rc)) ++ return rc; + + desc = get_sq_desc(io_sq); ++ if (unlikely(!desc)) ++ return -EFAULT; ++ + memset(desc, 0x0, sizeof(struct ena_eth_io_tx_desc)); + + desc->len_ctrl |= (io_sq->phase << +@@ -377,15 +504,14 @@ int ena_com_prepare_tx(struct ena_com_io + /* set the last desc indicator */ + desc->len_ctrl |= ENA_ETH_IO_TX_DESC_LAST_MASK; + +- ena_com_copy_curr_sq_desc_to_dev(io_sq); +- +- ena_com_sq_update_tail(io_sq); ++ rc = ena_com_sq_update_tail(io_sq); ++ if (unlikely(rc)) ++ return rc; + +- total_desc = max_t(u16, num_bufs, 1); +- total_desc += have_meta ? 1 : 0; ++ rc = ena_com_close_bounce_buffer(io_sq); + +- *nb_hw_desc = total_desc; +- return 0; ++ *nb_hw_desc = io_sq->tail - start_tail; ++ return rc; + } + + int ena_com_rx_pkt(struct ena_com_io_cq *io_cq, +@@ -444,15 +570,18 @@ int ena_com_add_single_rx_desc(struct en + + WARN(io_sq->direction != ENA_COM_IO_QUEUE_DIRECTION_RX, "wrong Q type"); + +- if (unlikely(ena_com_sq_empty_space(io_sq) == 0)) ++ if (unlikely(!ena_com_sq_have_enough_space(io_sq, 1))) + return -ENOSPC; + + desc = get_sq_desc(io_sq); ++ if (unlikely(!desc)) ++ return -EFAULT; ++ + memset(desc, 0x0, sizeof(struct ena_eth_io_rx_desc)); + + desc->length = ena_buf->len; + +- desc->ctrl |= ENA_ETH_IO_RX_DESC_FIRST_MASK; ++ desc->ctrl = ENA_ETH_IO_RX_DESC_FIRST_MASK; + desc->ctrl |= ENA_ETH_IO_RX_DESC_LAST_MASK; + desc->ctrl |= io_sq->phase & ENA_ETH_IO_RX_DESC_PHASE_MASK; + desc->ctrl |= ENA_ETH_IO_RX_DESC_COMP_REQ_MASK; +@@ -463,9 +592,7 @@ int ena_com_add_single_rx_desc(struct en + desc->buff_addr_hi = + ((ena_buf->paddr & GENMASK_ULL(io_sq->dma_addr_bits - 1, 32)) >> 32); + +- ena_com_sq_update_tail(io_sq); +- +- return 0; ++ return ena_com_sq_update_tail(io_sq); + } + + bool ena_com_cq_empty(struct ena_com_io_cq *io_cq) +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h +@@ -94,7 +94,7 @@ static inline void ena_com_unmask_intr(s + writel(intr_reg->intr_control, io_cq->unmask_reg); + } + +-static inline int ena_com_sq_empty_space(struct ena_com_io_sq *io_sq) ++static inline int ena_com_free_desc(struct ena_com_io_sq *io_sq) + { + u16 tail, next_to_comp, cnt; + +@@ -105,11 +105,28 @@ static inline int ena_com_sq_empty_space + return io_sq->q_depth - 1 - cnt; + } + +-static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq) ++/* Check if the submission queue has enough space to hold required_buffers */ ++static inline bool ena_com_sq_have_enough_space(struct ena_com_io_sq *io_sq, ++ u16 required_buffers) + { +- u16 tail; ++ int temp; + +- tail = io_sq->tail; ++ if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) ++ return ena_com_free_desc(io_sq) >= required_buffers; ++ ++ /* This calculation doesn't need to be 100% accurate. So to reduce ++ * the calculation overhead just Subtract 2 lines from the free descs ++ * (one for the header line and one to compensate the devision ++ * down calculation. ++ */ ++ temp = required_buffers / io_sq->llq_info.descs_per_entry + 2; ++ ++ return ena_com_free_desc(io_sq) > temp; ++} ++ ++static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq) ++{ ++ u16 tail = io_sq->tail; + + pr_debug("write submission queue doorbell for queue: %d tail: %d\n", + io_sq->qid, tail); +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -804,12 +804,13 @@ static int ena_clean_tx_irq(struct ena_r + */ + smp_mb(); + +- above_thresh = ena_com_sq_empty_space(tx_ring->ena_com_io_sq) > +- ENA_TX_WAKEUP_THRESH; ++ above_thresh = ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq, ++ ENA_TX_WAKEUP_THRESH); + if (unlikely(netif_tx_queue_stopped(txq) && above_thresh)) { + __netif_tx_lock(txq, smp_processor_id()); +- above_thresh = ena_com_sq_empty_space(tx_ring->ena_com_io_sq) > +- ENA_TX_WAKEUP_THRESH; ++ above_thresh = ++ ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq, ++ ENA_TX_WAKEUP_THRESH); + if (netif_tx_queue_stopped(txq) && above_thresh) { + netif_tx_wake_queue(txq); + u64_stats_update_begin(&tx_ring->syncp); +@@ -1101,7 +1102,7 @@ static int ena_clean_rx_irq(struct ena_r + + rx_ring->next_to_clean = next_to_clean; + +- refill_required = ena_com_sq_empty_space(rx_ring->ena_com_io_sq); ++ refill_required = ena_com_free_desc(rx_ring->ena_com_io_sq); + refill_threshold = rx_ring->ring_size / ENA_RX_REFILL_THRESH_DIVIDER; + + /* Optimization, try to batch new rx buffers */ +@@ -2115,8 +2116,8 @@ static netdev_tx_t ena_start_xmit(struct + * to sgl_size + 2. one for the meta descriptor and one for header + * (if the header is larger than tx_max_header_size). + */ +- if (unlikely(ena_com_sq_empty_space(tx_ring->ena_com_io_sq) < +- (tx_ring->sgl_size + 2))) { ++ if (unlikely(!ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq, ++ tx_ring->sgl_size + 2))) { + netif_dbg(adapter, tx_queued, dev, "%s stop queue %d\n", + __func__, qid); + +@@ -2135,8 +2136,8 @@ static netdev_tx_t ena_start_xmit(struct + */ + smp_mb(); + +- if (ena_com_sq_empty_space(tx_ring->ena_com_io_sq) +- > ENA_TX_WAKEUP_THRESH) { ++ if (ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq, ++ ENA_TX_WAKEUP_THRESH)) { + netif_tx_wake_queue(txq); + u64_stats_update_begin(&tx_ring->syncp); + tx_ring->tx_stats.queue_wakeup++; +@@ -2813,7 +2814,7 @@ static void check_for_empty_rx_ring(stru + rx_ring = &adapter->rx_ring[i]; + + refill_required = +- ena_com_sq_empty_space(rx_ring->ena_com_io_sq); ++ ena_com_free_desc(rx_ring->ena_com_io_sq); + if (unlikely(refill_required == (rx_ring->ring_size - 1))) { + rx_ring->empty_rx_queue++; + diff --git a/debian/patches/features/all/ena/0006-net-ena-add-functions-for-handling-Low-Latency-Queue.patch b/debian/patches/features/all/ena/0006-net-ena-add-functions-for-handling-Low-Latency-Queue.patch new file mode 100644 index 000000000..8f288529e --- /dev/null +++ b/debian/patches/features/all/ena/0006-net-ena-add-functions-for-handling-Low-Latency-Queue.patch @@ -0,0 +1,655 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:20 +0300 +Subject: [PATCH 06/19] net: ena: add functions for handling Low Latency Queues + in ena_netdev +Origin: https://git.kernel.org/linus/38005ca816a7ef5516dc8e59ae95716739aa75b0 + +This patch includes all code changes necessary in ena_netdev to enable +packet sending via the LLQ placemnt mode. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 1 + + drivers/net/ethernet/amazon/ena/ena_netdev.c | 387 +++++++++++------- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 6 + + 3 files changed, 251 insertions(+), 143 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -81,6 +81,7 @@ static const struct ena_stats ena_stats_ + ENA_STAT_TX_ENTRY(doorbells), + ENA_STAT_TX_ENTRY(prepare_ctx_err), + ENA_STAT_TX_ENTRY(bad_req_id), ++ ENA_STAT_TX_ENTRY(llq_buffer_copy), + ENA_STAT_TX_ENTRY(missed_tx), + }; + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -237,6 +237,17 @@ static int ena_setup_tx_resources(struct + } + } + ++ size = tx_ring->tx_max_header_size; ++ tx_ring->push_buf_intermediate_buf = vzalloc_node(size, node); ++ if (!tx_ring->push_buf_intermediate_buf) { ++ tx_ring->push_buf_intermediate_buf = vzalloc(size); ++ if (!tx_ring->push_buf_intermediate_buf) { ++ vfree(tx_ring->tx_buffer_info); ++ vfree(tx_ring->free_tx_ids); ++ return -ENOMEM; ++ } ++ } ++ + /* Req id ring for TX out of order completions */ + for (i = 0; i < tx_ring->ring_size; i++) + tx_ring->free_tx_ids[i] = i; +@@ -265,6 +276,9 @@ static void ena_free_tx_resources(struct + + vfree(tx_ring->free_tx_ids); + tx_ring->free_tx_ids = NULL; ++ ++ vfree(tx_ring->push_buf_intermediate_buf); ++ tx_ring->push_buf_intermediate_buf = NULL; + } + + /* ena_setup_all_tx_resources - allocate I/O Tx queues resources for All queues +@@ -602,6 +616,36 @@ static void ena_free_all_rx_bufs(struct + ena_free_rx_bufs(adapter, i); + } + ++static inline void ena_unmap_tx_skb(struct ena_ring *tx_ring, ++ struct ena_tx_buffer *tx_info) ++{ ++ struct ena_com_buf *ena_buf; ++ u32 cnt; ++ int i; ++ ++ ena_buf = tx_info->bufs; ++ cnt = tx_info->num_of_bufs; ++ ++ if (unlikely(!cnt)) ++ return; ++ ++ if (tx_info->map_linear_data) { ++ dma_unmap_single(tx_ring->dev, ++ dma_unmap_addr(ena_buf, paddr), ++ dma_unmap_len(ena_buf, len), ++ DMA_TO_DEVICE); ++ ena_buf++; ++ cnt--; ++ } ++ ++ /* unmap remaining mapped pages */ ++ for (i = 0; i < cnt; i++) { ++ dma_unmap_page(tx_ring->dev, dma_unmap_addr(ena_buf, paddr), ++ dma_unmap_len(ena_buf, len), DMA_TO_DEVICE); ++ ena_buf++; ++ } ++} ++ + /* ena_free_tx_bufs - Free Tx Buffers per Queue + * @tx_ring: TX ring for which buffers be freed + */ +@@ -612,9 +656,6 @@ static void ena_free_tx_bufs(struct ena_ + + for (i = 0; i < tx_ring->ring_size; i++) { + struct ena_tx_buffer *tx_info = &tx_ring->tx_buffer_info[i]; +- struct ena_com_buf *ena_buf; +- int nr_frags; +- int j; + + if (!tx_info->skb) + continue; +@@ -630,21 +671,7 @@ static void ena_free_tx_bufs(struct ena_ + tx_ring->qid, i); + } + +- ena_buf = tx_info->bufs; +- dma_unmap_single(tx_ring->dev, +- ena_buf->paddr, +- ena_buf->len, +- DMA_TO_DEVICE); +- +- /* unmap remaining mapped pages */ +- nr_frags = tx_info->num_of_bufs - 1; +- for (j = 0; j < nr_frags; j++) { +- ena_buf++; +- dma_unmap_page(tx_ring->dev, +- ena_buf->paddr, +- ena_buf->len, +- DMA_TO_DEVICE); +- } ++ ena_unmap_tx_skb(tx_ring, tx_info); + + dev_kfree_skb_any(tx_info->skb); + } +@@ -735,8 +762,6 @@ static int ena_clean_tx_irq(struct ena_r + while (tx_pkts < budget) { + struct ena_tx_buffer *tx_info; + struct sk_buff *skb; +- struct ena_com_buf *ena_buf; +- int i, nr_frags; + + rc = ena_com_tx_comp_req_id_get(tx_ring->ena_com_io_cq, + &req_id); +@@ -756,24 +781,7 @@ static int ena_clean_tx_irq(struct ena_r + tx_info->skb = NULL; + tx_info->last_jiffies = 0; + +- if (likely(tx_info->num_of_bufs != 0)) { +- ena_buf = tx_info->bufs; +- +- dma_unmap_single(tx_ring->dev, +- dma_unmap_addr(ena_buf, paddr), +- dma_unmap_len(ena_buf, len), +- DMA_TO_DEVICE); +- +- /* unmap remaining mapped pages */ +- nr_frags = tx_info->num_of_bufs - 1; +- for (i = 0; i < nr_frags; i++) { +- ena_buf++; +- dma_unmap_page(tx_ring->dev, +- dma_unmap_addr(ena_buf, paddr), +- dma_unmap_len(ena_buf, len), +- DMA_TO_DEVICE); +- } +- } ++ ena_unmap_tx_skb(tx_ring, tx_info); + + netif_dbg(tx_ring->adapter, tx_done, tx_ring->netdev, + "tx_poll: q %d skb %p completed\n", tx_ring->qid, +@@ -1300,7 +1308,6 @@ static int ena_enable_msix(struct ena_ad + + /* Reserved the max msix vectors we might need */ + msix_vecs = ENA_MAX_MSIX_VEC(num_queues); +- + netif_dbg(adapter, probe, adapter->netdev, + "trying to enable MSI-X, vectors %d\n", msix_vecs); + +@@ -1591,7 +1598,7 @@ static int ena_up_complete(struct ena_ad + + static int ena_create_io_tx_queue(struct ena_adapter *adapter, int qid) + { +- struct ena_com_create_io_ctx ctx = { 0 }; ++ struct ena_com_create_io_ctx ctx; + struct ena_com_dev *ena_dev; + struct ena_ring *tx_ring; + u32 msix_vector; +@@ -1604,6 +1611,8 @@ static int ena_create_io_tx_queue(struct + msix_vector = ENA_IO_IRQ_IDX(qid); + ena_qid = ENA_IO_TXQ_IDX(qid); + ++ memset(&ctx, 0x0, sizeof(ctx)); ++ + ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_TX; + ctx.qid = ena_qid; + ctx.mem_queue_type = ena_dev->tx_mem_queue_type; +@@ -1657,7 +1666,7 @@ create_err: + static int ena_create_io_rx_queue(struct ena_adapter *adapter, int qid) + { + struct ena_com_dev *ena_dev; +- struct ena_com_create_io_ctx ctx = { 0 }; ++ struct ena_com_create_io_ctx ctx; + struct ena_ring *rx_ring; + u32 msix_vector; + u16 ena_qid; +@@ -1669,6 +1678,8 @@ static int ena_create_io_rx_queue(struct + msix_vector = ENA_IO_IRQ_IDX(qid); + ena_qid = ENA_IO_RXQ_IDX(qid); + ++ memset(&ctx, 0x0, sizeof(ctx)); ++ + ctx.qid = ena_qid; + ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_RX; + ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; +@@ -1986,73 +1997,70 @@ static int ena_check_and_linearize_skb(s + return rc; + } + +-/* Called with netif_tx_lock. */ +-static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev) ++static int ena_tx_map_skb(struct ena_ring *tx_ring, ++ struct ena_tx_buffer *tx_info, ++ struct sk_buff *skb, ++ void **push_hdr, ++ u16 *header_len) + { +- struct ena_adapter *adapter = netdev_priv(dev); +- struct ena_tx_buffer *tx_info; +- struct ena_com_tx_ctx ena_tx_ctx; +- struct ena_ring *tx_ring; +- struct netdev_queue *txq; ++ struct ena_adapter *adapter = tx_ring->adapter; + struct ena_com_buf *ena_buf; +- void *push_hdr; +- u32 len, last_frag; +- u16 next_to_use; +- u16 req_id; +- u16 push_len; +- u16 header_len; + dma_addr_t dma; +- int qid, rc, nb_hw_desc; +- int i = -1; +- +- netif_dbg(adapter, tx_queued, dev, "%s skb %p\n", __func__, skb); +- /* Determine which tx ring we will be placed on */ +- qid = skb_get_queue_mapping(skb); +- tx_ring = &adapter->tx_ring[qid]; +- txq = netdev_get_tx_queue(dev, qid); +- +- rc = ena_check_and_linearize_skb(tx_ring, skb); +- if (unlikely(rc)) +- goto error_drop_packet; +- +- skb_tx_timestamp(skb); +- len = skb_headlen(skb); ++ u32 skb_head_len, frag_len, last_frag; ++ u16 push_len = 0; ++ u16 delta = 0; ++ int i = 0; + +- next_to_use = tx_ring->next_to_use; +- req_id = tx_ring->free_tx_ids[next_to_use]; +- tx_info = &tx_ring->tx_buffer_info[req_id]; +- tx_info->num_of_bufs = 0; +- +- WARN(tx_info->skb, "SKB isn't NULL req_id %d\n", req_id); +- ena_buf = tx_info->bufs; ++ skb_head_len = skb_headlen(skb); + tx_info->skb = skb; ++ ena_buf = tx_info->bufs; + + if (tx_ring->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { +- /* prepared the push buffer */ +- push_len = min_t(u32, len, tx_ring->tx_max_header_size); +- header_len = push_len; +- push_hdr = skb->data; ++ /* When the device is LLQ mode, the driver will copy ++ * the header into the device memory space. ++ * the ena_com layer assume the header is in a linear ++ * memory space. ++ * This assumption might be wrong since part of the header ++ * can be in the fragmented buffers. ++ * Use skb_header_pointer to make sure the header is in a ++ * linear memory space. ++ */ ++ ++ push_len = min_t(u32, skb->len, tx_ring->tx_max_header_size); ++ *push_hdr = skb_header_pointer(skb, 0, push_len, ++ tx_ring->push_buf_intermediate_buf); ++ *header_len = push_len; ++ if (unlikely(skb->data != *push_hdr)) { ++ u64_stats_update_begin(&tx_ring->syncp); ++ tx_ring->tx_stats.llq_buffer_copy++; ++ u64_stats_update_end(&tx_ring->syncp); ++ ++ delta = push_len - skb_head_len; ++ } + } else { +- push_len = 0; +- header_len = min_t(u32, len, tx_ring->tx_max_header_size); +- push_hdr = NULL; ++ *push_hdr = NULL; ++ *header_len = min_t(u32, skb_head_len, ++ tx_ring->tx_max_header_size); + } + +- netif_dbg(adapter, tx_queued, dev, ++ netif_dbg(adapter, tx_queued, adapter->netdev, + "skb: %p header_buf->vaddr: %p push_len: %d\n", skb, +- push_hdr, push_len); ++ *push_hdr, push_len); + +- if (len > push_len) { ++ if (skb_head_len > push_len) { + dma = dma_map_single(tx_ring->dev, skb->data + push_len, +- len - push_len, DMA_TO_DEVICE); +- if (dma_mapping_error(tx_ring->dev, dma)) ++ skb_head_len - push_len, DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(tx_ring->dev, dma))) + goto error_report_dma_error; + + ena_buf->paddr = dma; +- ena_buf->len = len - push_len; ++ ena_buf->len = skb_head_len - push_len; + + ena_buf++; + tx_info->num_of_bufs++; ++ tx_info->map_linear_data = 1; ++ } else { ++ tx_info->map_linear_data = 0; + } + + last_frag = skb_shinfo(skb)->nr_frags; +@@ -2060,18 +2068,75 @@ static netdev_tx_t ena_start_xmit(struct + for (i = 0; i < last_frag; i++) { + const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; + +- len = skb_frag_size(frag); +- dma = skb_frag_dma_map(tx_ring->dev, frag, 0, len, +- DMA_TO_DEVICE); +- if (dma_mapping_error(tx_ring->dev, dma)) ++ frag_len = skb_frag_size(frag); ++ ++ if (unlikely(delta >= frag_len)) { ++ delta -= frag_len; ++ continue; ++ } ++ ++ dma = skb_frag_dma_map(tx_ring->dev, frag, delta, ++ frag_len - delta, DMA_TO_DEVICE); ++ if (unlikely(dma_mapping_error(tx_ring->dev, dma))) + goto error_report_dma_error; + + ena_buf->paddr = dma; +- ena_buf->len = len; ++ ena_buf->len = frag_len - delta; + ena_buf++; ++ tx_info->num_of_bufs++; ++ delta = 0; + } + +- tx_info->num_of_bufs += last_frag; ++ return 0; ++ ++error_report_dma_error: ++ u64_stats_update_begin(&tx_ring->syncp); ++ tx_ring->tx_stats.dma_mapping_err++; ++ u64_stats_update_end(&tx_ring->syncp); ++ netdev_warn(adapter->netdev, "failed to map skb\n"); ++ ++ tx_info->skb = NULL; ++ ++ tx_info->num_of_bufs += i; ++ ena_unmap_tx_skb(tx_ring, tx_info); ++ ++ return -EINVAL; ++} ++ ++/* Called with netif_tx_lock. */ ++static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev) ++{ ++ struct ena_adapter *adapter = netdev_priv(dev); ++ struct ena_tx_buffer *tx_info; ++ struct ena_com_tx_ctx ena_tx_ctx; ++ struct ena_ring *tx_ring; ++ struct netdev_queue *txq; ++ void *push_hdr; ++ u16 next_to_use, req_id, header_len; ++ int qid, rc, nb_hw_desc; ++ ++ netif_dbg(adapter, tx_queued, dev, "%s skb %p\n", __func__, skb); ++ /* Determine which tx ring we will be placed on */ ++ qid = skb_get_queue_mapping(skb); ++ tx_ring = &adapter->tx_ring[qid]; ++ txq = netdev_get_tx_queue(dev, qid); ++ ++ rc = ena_check_and_linearize_skb(tx_ring, skb); ++ if (unlikely(rc)) ++ goto error_drop_packet; ++ ++ skb_tx_timestamp(skb); ++ ++ next_to_use = tx_ring->next_to_use; ++ req_id = tx_ring->free_tx_ids[next_to_use]; ++ tx_info = &tx_ring->tx_buffer_info[req_id]; ++ tx_info->num_of_bufs = 0; ++ ++ WARN(tx_info->skb, "SKB isn't NULL req_id %d\n", req_id); ++ ++ rc = ena_tx_map_skb(tx_ring, tx_info, skb, &push_hdr, &header_len); ++ if (unlikely(rc)) ++ goto error_drop_packet; + + memset(&ena_tx_ctx, 0x0, sizeof(struct ena_com_tx_ctx)); + ena_tx_ctx.ena_bufs = tx_info->bufs; +@@ -2087,14 +2152,22 @@ static netdev_tx_t ena_start_xmit(struct + rc = ena_com_prepare_tx(tx_ring->ena_com_io_sq, &ena_tx_ctx, + &nb_hw_desc); + ++ /* ena_com_prepare_tx() can't fail due to overflow of tx queue, ++ * since the number of free descriptors in the queue is checked ++ * after sending the previous packet. In case there isn't enough ++ * space in the queue for the next packet, it is stopped ++ * until there is again enough available space in the queue. ++ * All other failure reasons of ena_com_prepare_tx() are fatal ++ * and therefore require a device reset. ++ */ + if (unlikely(rc)) { + netif_err(adapter, tx_queued, dev, + "failed to prepare tx bufs\n"); + u64_stats_update_begin(&tx_ring->syncp); +- tx_ring->tx_stats.queue_stop++; + tx_ring->tx_stats.prepare_ctx_err++; + u64_stats_update_end(&tx_ring->syncp); +- netif_tx_stop_queue(txq); ++ adapter->reset_reason = ENA_REGS_RESET_DRIVER_INVALID_STATE; ++ set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); + goto error_unmap_dma; + } + +@@ -2157,35 +2230,11 @@ static netdev_tx_t ena_start_xmit(struct + + return NETDEV_TX_OK; + +-error_report_dma_error: +- u64_stats_update_begin(&tx_ring->syncp); +- tx_ring->tx_stats.dma_mapping_err++; +- u64_stats_update_end(&tx_ring->syncp); +- netdev_warn(adapter->netdev, "failed to map skb\n"); +- +- tx_info->skb = NULL; +- + error_unmap_dma: +- if (i >= 0) { +- /* save value of frag that failed */ +- last_frag = i; +- +- /* start back at beginning and unmap skb */ +- tx_info->skb = NULL; +- ena_buf = tx_info->bufs; +- dma_unmap_single(tx_ring->dev, dma_unmap_addr(ena_buf, paddr), +- dma_unmap_len(ena_buf, len), DMA_TO_DEVICE); +- +- /* unmap remaining mapped pages */ +- for (i = 0; i < last_frag; i++) { +- ena_buf++; +- dma_unmap_page(tx_ring->dev, dma_unmap_addr(ena_buf, paddr), +- dma_unmap_len(ena_buf, len), DMA_TO_DEVICE); +- } +- } ++ ena_unmap_tx_skb(tx_ring, tx_info); ++ tx_info->skb = NULL; + + error_drop_packet: +- + dev_kfree_skb(skb); + return NETDEV_TX_OK; + } +@@ -2621,7 +2670,9 @@ static int ena_restore_device(struct ena + netif_carrier_on(adapter->netdev); + + mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); +- dev_err(&pdev->dev, "Device reset completed successfully\n"); ++ dev_err(&pdev->dev, ++ "Device reset completed successfully, Driver info: %s\n", ++ version); + + return rc; + err_disable_msix: +@@ -2988,18 +3039,52 @@ static int ena_calc_io_queue_num(struct + return io_queue_num; + } + +-static void ena_set_push_mode(struct pci_dev *pdev, struct ena_com_dev *ena_dev, +- struct ena_com_dev_get_features_ctx *get_feat_ctx) ++static int ena_set_queues_placement_policy(struct pci_dev *pdev, ++ struct ena_com_dev *ena_dev, ++ struct ena_admin_feature_llq_desc *llq, ++ struct ena_llq_configurations *llq_default_configurations) + { + bool has_mem_bar; ++ int rc; ++ u32 llq_feature_mask; ++ ++ llq_feature_mask = 1 << ENA_ADMIN_LLQ; ++ if (!(ena_dev->supported_features & llq_feature_mask)) { ++ dev_err(&pdev->dev, ++ "LLQ is not supported Fallback to host mode policy.\n"); ++ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; ++ return 0; ++ } + + has_mem_bar = pci_select_bars(pdev, IORESOURCE_MEM) & BIT(ENA_MEM_BAR); + +- /* Enable push mode if device supports LLQ */ +- if (has_mem_bar && get_feat_ctx->max_queues.max_legacy_llq_num > 0) +- ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_DEV; +- else ++ rc = ena_com_config_dev_mode(ena_dev, llq, llq_default_configurations); ++ if (unlikely(rc)) { ++ dev_err(&pdev->dev, ++ "Failed to configure the device mode. Fallback to host mode policy.\n"); ++ ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; ++ return 0; ++ } ++ ++ /* Nothing to config, exit */ ++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) ++ return 0; ++ ++ if (!has_mem_bar) { ++ dev_err(&pdev->dev, ++ "ENA device does not expose LLQ bar. Fallback to host mode policy.\n"); + ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; ++ return 0; ++ } ++ ++ ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev, ++ pci_resource_start(pdev, ENA_MEM_BAR), ++ pci_resource_len(pdev, ENA_MEM_BAR)); ++ ++ if (!ena_dev->mem_bar) ++ return -EFAULT; ++ ++ return 0; + } + + static void ena_set_dev_offloads(struct ena_com_dev_get_features_ctx *feat, +@@ -3117,6 +3202,15 @@ static void ena_release_bars(struct ena_ + pci_release_selected_regions(pdev, release_bars); + } + ++static inline void set_default_llq_configurations(struct ena_llq_configurations *llq_config) ++{ ++ llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER; ++ llq_config->llq_ring_entry_size = ENA_ADMIN_LIST_ENTRY_SIZE_128B; ++ llq_config->llq_stride_ctrl = ENA_ADMIN_MULTIPLE_DESCS_PER_ENTRY; ++ llq_config->llq_num_decs_before_header = ENA_ADMIN_LLQ_NUM_DESCS_BEFORE_HEADER_2; ++ llq_config->llq_ring_entry_size_value = 128; ++} ++ + static int ena_calc_queue_size(struct pci_dev *pdev, + struct ena_com_dev *ena_dev, + u16 *max_tx_sgl_size, +@@ -3165,7 +3259,9 @@ static int ena_probe(struct pci_dev *pde + static int version_printed; + struct net_device *netdev; + struct ena_adapter *adapter; ++ struct ena_llq_configurations llq_config; + struct ena_com_dev *ena_dev = NULL; ++ char *queue_type_str; + static int adapters_found; + int io_queue_num, bars, rc; + int queue_size; +@@ -3219,16 +3315,13 @@ static int ena_probe(struct pci_dev *pde + goto err_free_region; + } + +- ena_set_push_mode(pdev, ena_dev, &get_feat_ctx); ++ set_default_llq_configurations(&llq_config); + +- if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { +- ena_dev->mem_bar = devm_ioremap_wc(&pdev->dev, +- pci_resource_start(pdev, ENA_MEM_BAR), +- pci_resource_len(pdev, ENA_MEM_BAR)); +- if (!ena_dev->mem_bar) { +- rc = -EFAULT; +- goto err_device_destroy; +- } ++ rc = ena_set_queues_placement_policy(pdev, ena_dev, &get_feat_ctx.llq, ++ &llq_config); ++ if (rc) { ++ dev_err(&pdev->dev, "ena device init failed\n"); ++ goto err_device_destroy; + } + + /* initial Tx interrupt delay, Assumes 1 usec granularity. +@@ -3243,8 +3336,10 @@ static int ena_probe(struct pci_dev *pde + goto err_device_destroy; + } + +- dev_info(&pdev->dev, "creating %d io queues. queue size: %d\n", +- io_queue_num, queue_size); ++ dev_info(&pdev->dev, "creating %d io queues. queue size: %d. LLQ is %s\n", ++ io_queue_num, queue_size, ++ (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ? ++ "ENABLED" : "DISABLED"); + + /* dev zeroed in init_etherdev */ + netdev = alloc_etherdev_mq(sizeof(struct ena_adapter), io_queue_num); +@@ -3334,9 +3429,15 @@ static int ena_probe(struct pci_dev *pde + timer_setup(&adapter->timer_service, ena_timer_service, 0); + mod_timer(&adapter->timer_service, round_jiffies(jiffies + HZ)); + +- dev_info(&pdev->dev, "%s found at mem %lx, mac addr %pM Queues %d\n", ++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_HOST) ++ queue_type_str = "Regular"; ++ else ++ queue_type_str = "Low Latency"; ++ ++ dev_info(&pdev->dev, ++ "%s found at mem %lx, mac addr %pM Queues %d, Placement policy: %s\n", + DEVICE_NAME, (long)pci_resource_start(pdev, 0), +- netdev->dev_addr, io_queue_num); ++ netdev->dev_addr, io_queue_num, queue_type_str); + + set_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags); + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -151,6 +151,9 @@ struct ena_tx_buffer { + /* num of buffers used by this skb */ + u32 num_of_bufs; + ++ /* Indicate if bufs[0] map the linear data of the skb. */ ++ u8 map_linear_data; ++ + /* Used for detect missing tx packets to limit the number of prints */ + u32 print_once; + /* Save the last jiffies to detect missing tx packets +@@ -186,6 +189,7 @@ struct ena_stats_tx { + u64 tx_poll; + u64 doorbells; + u64 bad_req_id; ++ u64 llq_buffer_copy; + u64 missed_tx; + }; + +@@ -257,6 +261,8 @@ struct ena_ring { + struct ena_stats_tx tx_stats; + struct ena_stats_rx rx_stats; + }; ++ ++ u8 *push_buf_intermediate_buf; + int empty_rx_queue; + } ____cacheline_aligned; + diff --git a/debian/patches/features/all/ena/0007-net-ena-use-CSUM_CHECKED-device-indication-to-report.patch b/debian/patches/features/all/ena/0007-net-ena-use-CSUM_CHECKED-device-indication-to-report.patch new file mode 100644 index 000000000..cc25333b8 --- /dev/null +++ b/debian/patches/features/all/ena/0007-net-ena-use-CSUM_CHECKED-device-indication-to-report.patch @@ -0,0 +1,125 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:21 +0300 +Subject: [PATCH 07/19] net: ena: use CSUM_CHECKED device indication to report + skb's checksum status +Origin: https://git.kernel.org/linus/cb36bb36e1f17d2a7b9a9751e5cfec4235b46c93 + +Set skb->ip_summed to the correct value as reported by the device. +Add counter for the case where rx csum offload is enabled but +device didn't check it. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_eth_com.c | 7 +++++-- + drivers/net/ethernet/amazon/ena/ena_eth_com.h | 1 + + drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h | 10 ++++++++-- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 1 + + drivers/net/ethernet/amazon/ena/ena_netdev.c | 13 ++++++++++++- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 1 + + 6 files changed, 28 insertions(+), 5 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +@@ -354,6 +354,9 @@ static inline void ena_com_rx_set_flags( + ena_rx_ctx->l4_csum_err = + !!((cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK) >> + ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT); ++ ena_rx_ctx->l4_csum_checked = ++ !!((cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_MASK) >> ++ ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_SHIFT); + ena_rx_ctx->hash = cdesc->hash; + ena_rx_ctx->frag = + (cdesc->status & ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK) >> +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h +@@ -67,6 +67,7 @@ struct ena_com_rx_ctx { + enum ena_eth_io_l4_proto_index l4_proto; + bool l3_csum_err; + bool l4_csum_err; ++ u8 l4_csum_checked; + /* fragmented packet */ + bool frag; + u32 hash; +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h +@@ -242,9 +242,13 @@ struct ena_eth_io_rx_cdesc_base { + * checksum error detected, or, the controller didn't + * validate the checksum. This bit is valid only when + * l4_proto_idx indicates TCP/UDP packet, and, +- * ipv4_frag is not set ++ * ipv4_frag is not set. This bit is valid only when ++ * l4_csum_checked below is set. + * 15 : ipv4_frag - Indicates IPv4 fragmented packet +- * 23:16 : reserved16 ++ * 16 : l4_csum_checked - L4 checksum was verified ++ * (could be OK or error), when cleared the status of ++ * checksum is unknown ++ * 23:17 : reserved17 - MBZ + * 24 : phase + * 25 : l3_csum2 - second checksum engine result + * 26 : first - Indicates first descriptor in +@@ -390,6 +394,8 @@ struct ena_eth_io_numa_node_cfg_reg { + #define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK BIT(14) + #define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT 15 + #define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK BIT(15) ++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_SHIFT 16 ++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_MASK BIT(16) + #define ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT 24 + #define ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK BIT(24) + #define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT 25 +Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -97,6 +97,7 @@ static const struct ena_stats ena_stats_ + ENA_STAT_RX_ENTRY(rx_copybreak_pkt), + ENA_STAT_RX_ENTRY(bad_req_id), + ENA_STAT_RX_ENTRY(empty_rx_ring), ++ ENA_STAT_RX_ENTRY(csum_unchecked), + }; + + static const struct ena_stats ena_stats_ena_com_strings[] = { +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -994,8 +994,19 @@ static inline void ena_rx_checksum(struc + return; + } + +- skb->ip_summed = CHECKSUM_UNNECESSARY; ++ if (likely(ena_rx_ctx->l4_csum_checked)) { ++ skb->ip_summed = CHECKSUM_UNNECESSARY; ++ } else { ++ u64_stats_update_begin(&rx_ring->syncp); ++ rx_ring->rx_stats.csum_unchecked++; ++ u64_stats_update_end(&rx_ring->syncp); ++ skb->ip_summed = CHECKSUM_NONE; ++ } ++ } else { ++ skb->ip_summed = CHECKSUM_NONE; ++ return; + } ++ + } + + static void ena_set_rx_hash(struct ena_ring *rx_ring, +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -205,6 +205,7 @@ struct ena_stats_rx { + u64 rx_copybreak_pkt; + u64 bad_req_id; + u64 empty_rx_ring; ++ u64 csum_unchecked; + }; + + struct ena_ring { diff --git a/debian/patches/features/all/ena/0008-net-ena-explicit-casting-and-initialization-and-clea.patch b/debian/patches/features/all/ena/0008-net-ena-explicit-casting-and-initialization-and-clea.patch new file mode 100644 index 000000000..59ea0566a --- /dev/null +++ b/debian/patches/features/all/ena/0008-net-ena-explicit-casting-and-initialization-and-clea.patch @@ -0,0 +1,223 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:22 +0300 +Subject: [PATCH 08/19] net: ena: explicit casting and initialization, and + clearer error handling +Origin: https://git.kernel.org/linus/bd791175a6432d24fc5d7b348304276027372545 + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 39 ++++++++++++-------- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 5 +-- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 22 +++++------ + 3 files changed, 36 insertions(+), 30 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -235,7 +235,7 @@ static struct ena_comp_ctx *__ena_com_su + tail_masked = admin_queue->sq.tail & queue_size_mask; + + /* In case of queue FULL */ +- cnt = atomic_read(&admin_queue->outstanding_cmds); ++ cnt = (u16)atomic_read(&admin_queue->outstanding_cmds); + if (cnt >= admin_queue->q_depth) { + pr_debug("admin queue is full.\n"); + admin_queue->stats.out_of_space++; +@@ -304,7 +304,7 @@ static struct ena_comp_ctx *ena_com_subm + struct ena_admin_acq_entry *comp, + size_t comp_size_in_bytes) + { +- unsigned long flags; ++ unsigned long flags = 0; + struct ena_comp_ctx *comp_ctx; + + spin_lock_irqsave(&admin_queue->q_lock, flags); +@@ -332,7 +332,7 @@ static int ena_com_init_io_sq(struct ena + + memset(&io_sq->desc_addr, 0x0, sizeof(io_sq->desc_addr)); + +- io_sq->dma_addr_bits = ena_dev->dma_addr_bits; ++ io_sq->dma_addr_bits = (u8)ena_dev->dma_addr_bits; + io_sq->desc_entry_size = + (io_sq->direction == ENA_COM_IO_QUEUE_DIRECTION_TX) ? + sizeof(struct ena_eth_io_tx_desc) : +@@ -486,7 +486,7 @@ static void ena_com_handle_admin_complet + + /* Go over all the completions */ + while ((READ_ONCE(cqe->acq_common_descriptor.flags) & +- ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK) == phase) { ++ ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK) == phase) { + /* Do not read the rest of the completion entry before the + * phase bit was validated + */ +@@ -537,7 +537,8 @@ static int ena_com_comp_status_to_errno( + static int ena_com_wait_and_process_admin_cq_polling(struct ena_comp_ctx *comp_ctx, + struct ena_com_admin_queue *admin_queue) + { +- unsigned long flags, timeout; ++ unsigned long flags = 0; ++ unsigned long timeout; + int ret; + + timeout = jiffies + usecs_to_jiffies(admin_queue->completion_timeout); +@@ -736,7 +737,7 @@ static int ena_com_config_llq_info(struc + static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *comp_ctx, + struct ena_com_admin_queue *admin_queue) + { +- unsigned long flags; ++ unsigned long flags = 0; + int ret; + + wait_for_completion_timeout(&comp_ctx->wait_event, +@@ -782,7 +783,7 @@ static u32 ena_com_reg_bar_read32(struct + volatile struct ena_admin_ena_mmio_req_read_less_resp *read_resp = + mmio_read->read_resp; + u32 mmio_read_reg, ret, i; +- unsigned long flags; ++ unsigned long flags = 0; + u32 timeout = mmio_read->reg_read_to; + + might_sleep(); +@@ -1426,7 +1427,7 @@ void ena_com_abort_admin_commands(struct + void ena_com_wait_for_abort_completion(struct ena_com_dev *ena_dev) + { + struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue; +- unsigned long flags; ++ unsigned long flags = 0; + + spin_lock_irqsave(&admin_queue->q_lock, flags); + while (atomic_read(&admin_queue->outstanding_cmds) != 0) { +@@ -1470,7 +1471,7 @@ bool ena_com_get_admin_running_state(str + void ena_com_set_admin_running_state(struct ena_com_dev *ena_dev, bool state) + { + struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue; +- unsigned long flags; ++ unsigned long flags = 0; + + spin_lock_irqsave(&admin_queue->q_lock, flags); + ena_dev->admin_queue.running_state = state; +@@ -1504,7 +1505,7 @@ int ena_com_set_aenq_config(struct ena_c + } + + if ((get_resp.u.aenq.supported_groups & groups_flag) != groups_flag) { +- pr_warn("Trying to set unsupported aenq events. supported flag: %x asked flag: %x\n", ++ pr_warn("Trying to set unsupported aenq events. supported flag: 0x%x asked flag: 0x%x\n", + get_resp.u.aenq.supported_groups, groups_flag); + return -EOPNOTSUPP; + } +@@ -1652,7 +1653,7 @@ int ena_com_mmio_reg_read_request_init(s + sizeof(*mmio_read->read_resp), + &mmio_read->read_resp_dma_addr, GFP_KERNEL); + if (unlikely(!mmio_read->read_resp)) +- return -ENOMEM; ++ goto err; + + ena_com_mmio_reg_read_request_write_dev_addr(ena_dev); + +@@ -1661,6 +1662,10 @@ int ena_com_mmio_reg_read_request_init(s + mmio_read->readless_supported = true; + + return 0; ++ ++err: ++ ++ return -ENOMEM; + } + + void ena_com_set_mmio_read_mode(struct ena_com_dev *ena_dev, bool readless_supported) +@@ -1961,6 +1966,7 @@ void ena_com_aenq_intr_handler(struct en + struct ena_admin_aenq_entry *aenq_e; + struct ena_admin_aenq_common_desc *aenq_common; + struct ena_com_aenq *aenq = &dev->aenq; ++ unsigned long long timestamp; + ena_aenq_handler handler_cb; + u16 masked_head, processed = 0; + u8 phase; +@@ -1978,10 +1984,11 @@ void ena_com_aenq_intr_handler(struct en + */ + dma_rmb(); + ++ timestamp = ++ (unsigned long long)aenq_common->timestamp_low | ++ ((unsigned long long)aenq_common->timestamp_high << 32); + pr_debug("AENQ! Group[%x] Syndrom[%x] timestamp: [%llus]\n", +- aenq_common->group, aenq_common->syndrom, +- (u64)aenq_common->timestamp_low + +- ((u64)aenq_common->timestamp_high << 32)); ++ aenq_common->group, aenq_common->syndrom, timestamp); + + /* Handle specific event*/ + handler_cb = ena_com_get_specific_aenq_cb(dev, +@@ -2623,8 +2630,8 @@ int ena_com_allocate_host_info(struct en + if (unlikely(!host_attr->host_info)) + return -ENOMEM; + +- host_attr->host_info->ena_spec_version = +- ((ENA_COMMON_SPEC_VERSION_MAJOR << ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) | ++ host_attr->host_info->ena_spec_version = ((ENA_COMMON_SPEC_VERSION_MAJOR << ++ ENA_REGS_VERSION_MAJOR_VERSION_SHIFT) | + (ENA_COMMON_SPEC_VERSION_MINOR)); + + return 0; +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -2604,15 +2604,14 @@ static void ena_destroy_device(struct en + + dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); + adapter->dev_up_before_reset = dev_up; +- + if (!graceful) + ena_com_set_admin_running_state(ena_dev, false); + + if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) + ena_down(adapter); + +- /* Before releasing the ENA resources, a device reset is required. +- * (to prevent the device from accessing them). ++ /* Stop the device from sending AENQ events (in case reset flag is set ++ * and device is up, ena_close already reset the device + * In case the reset flag is set and the device is up, ena_down() + * already perform the reset, so it can be skipped. + */ +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -61,6 +61,17 @@ + #define ENA_ADMIN_MSIX_VEC 1 + #define ENA_MAX_MSIX_VEC(io_queues) (ENA_ADMIN_MSIX_VEC + (io_queues)) + ++/* The ENA buffer length fields is 16 bit long. So when PAGE_SIZE == 64kB the ++ * driver passes 0. ++ * Since the max packet size the ENA handles is ~9kB limit the buffer length to ++ * 16kB. ++ */ ++#if PAGE_SIZE > SZ_16K ++#define ENA_PAGE_SIZE SZ_16K ++#else ++#define ENA_PAGE_SIZE PAGE_SIZE ++#endif ++ + #define ENA_MIN_MSIX_VEC 2 + + #define ENA_REG_BAR 0 +@@ -362,15 +373,4 @@ void ena_dump_stats_to_buf(struct ena_ad + + int ena_get_sset_count(struct net_device *netdev, int sset); + +-/* The ENA buffer length fields is 16 bit long. So when PAGE_SIZE == 64kB the +- * driver passas 0. +- * Since the max packet size the ENA handles is ~9kB limit the buffer length to +- * 16kB. +- */ +-#if PAGE_SIZE > SZ_16K +-#define ENA_PAGE_SIZE SZ_16K +-#else +-#define ENA_PAGE_SIZE PAGE_SIZE +-#endif +- + #endif /* !(ENA_H) */ diff --git a/debian/patches/features/all/ena/0009-net-ena-limit-refill-Rx-threshold-to-256-to-avoid-la.patch b/debian/patches/features/all/ena/0009-net-ena-limit-refill-Rx-threshold-to-256-to-avoid-la.patch new file mode 100644 index 000000000..3eaae9950 --- /dev/null +++ b/debian/patches/features/all/ena/0009-net-ena-limit-refill-Rx-threshold-to-256-to-avoid-la.patch @@ -0,0 +1,54 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:23 +0300 +Subject: [PATCH 09/19] net: ena: limit refill Rx threshold to 256 to avoid + latency issues +Origin: https://git.kernel.org/linus/0574bb806dad29a3dada0ee42b01645477d48282 + +Currently Rx refill is done when the number of required descriptors is +above 1/8 queue size. With a default of 1024 entries per queue the +threshold is 128 descriptors. +There is intention to increase the queue size to 8196 entries. +In this case threshold of 1024 descriptors is too large and can hurt +latency. +Add another limitation to Rx threshold to be at most 256 descriptors. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 +++- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 5 +++-- + 2 files changed, 6 insertions(+), 3 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -1122,7 +1122,9 @@ static int ena_clean_rx_irq(struct ena_r + rx_ring->next_to_clean = next_to_clean; + + refill_required = ena_com_free_desc(rx_ring->ena_com_io_sq); +- refill_threshold = rx_ring->ring_size / ENA_RX_REFILL_THRESH_DIVIDER; ++ refill_threshold = ++ min_t(int, rx_ring->ring_size / ENA_RX_REFILL_THRESH_DIVIDER, ++ ENA_RX_REFILL_THRESH_PACKET); + + /* Optimization, try to batch new rx buffers */ + if (refill_required > refill_threshold) { +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -106,10 +106,11 @@ + */ + #define ENA_TX_POLL_BUDGET_DIVIDER 4 + +-/* Refill Rx queue when number of available descriptors is below +- * QUEUE_SIZE / ENA_RX_REFILL_THRESH_DIVIDER ++/* Refill Rx queue when number of required descriptors is above ++ * QUEUE_SIZE / ENA_RX_REFILL_THRESH_DIVIDER or ENA_RX_REFILL_THRESH_PACKET + */ + #define ENA_RX_REFILL_THRESH_DIVIDER 8 ++#define ENA_RX_REFILL_THRESH_PACKET 256 + + /* Number of queues to check for missing queues per timer service */ + #define ENA_MONITORED_TX_QUEUES 4 diff --git a/debian/patches/features/all/ena/0010-net-ena-change-rx-copybreak-default-to-reduce-kernel.patch b/debian/patches/features/all/ena/0010-net-ena-change-rx-copybreak-default-to-reduce-kernel.patch new file mode 100644 index 000000000..6e493b217 --- /dev/null +++ b/debian/patches/features/all/ena/0010-net-ena-change-rx-copybreak-default-to-reduce-kernel.patch @@ -0,0 +1,28 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:24 +0300 +Subject: [PATCH 10/19] net: ena: change rx copybreak default to reduce kernel + memory pressure +Origin: https://git.kernel.org/linus/87731f0c681c9682c5521e5197d89e561b7da395 + +Improves socket memory utilization when receiving packets larger +than 128 bytes (the previous rx copybreak) and smaller than 256 bytes. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -81,7 +81,7 @@ + #define ENA_DEFAULT_RING_SIZE (1024) + + #define ENA_TX_WAKEUP_THRESH (MAX_SKB_FRAGS + 2) +-#define ENA_DEFAULT_RX_COPYBREAK (128 - NET_IP_ALIGN) ++#define ENA_DEFAULT_RX_COPYBREAK (256 - NET_IP_ALIGN) + + /* limit the buffer size to 600 bytes to handle MTU changes from very + * small to very large, in which case the number of buffers per packet diff --git a/debian/patches/features/all/ena/0011-net-ena-remove-redundant-parameter-in-ena_com_admin_.patch b/debian/patches/features/all/ena/0011-net-ena-remove-redundant-parameter-in-ena_com_admin_.patch new file mode 100644 index 000000000..ac5ab95e5 --- /dev/null +++ b/debian/patches/features/all/ena/0011-net-ena-remove-redundant-parameter-in-ena_com_admin_.patch @@ -0,0 +1,76 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:25 +0300 +Subject: [PATCH 11/19] net: ena: remove redundant parameter in + ena_com_admin_init() +Origin: https://git.kernel.org/linus/f1e90f6e2c1fb0e491f910540314015324fed1e2 + +Remove redundant spinlock acquire parameter from ena_com_admin_init() + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++---- + drivers/net/ethernet/amazon/ena/ena_com.h | 5 +---- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 +- + 3 files changed, 4 insertions(+), 9 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -1701,8 +1701,7 @@ void ena_com_mmio_reg_read_request_write + } + + int ena_com_admin_init(struct ena_com_dev *ena_dev, +- struct ena_aenq_handlers *aenq_handlers, +- bool init_spinlock) ++ struct ena_aenq_handlers *aenq_handlers) + { + struct ena_com_admin_queue *admin_queue = &ena_dev->admin_queue; + u32 aq_caps, acq_caps, dev_sts, addr_low, addr_high; +@@ -1728,8 +1727,7 @@ int ena_com_admin_init(struct ena_com_de + + atomic_set(&admin_queue->outstanding_cmds, 0); + +- if (init_spinlock) +- spin_lock_init(&admin_queue->q_lock); ++ spin_lock_init(&admin_queue->q_lock); + + ret = ena_com_init_comp_ctxt(admin_queue); + if (ret) +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -436,8 +436,6 @@ void ena_com_mmio_reg_read_request_destr + /* ena_com_admin_init - Init the admin and the async queues + * @ena_dev: ENA communication layer struct + * @aenq_handlers: Those handlers to be called upon event. +- * @init_spinlock: Indicate if this method should init the admin spinlock or +- * the spinlock was init before (for example, in a case of FLR). + * + * Initialize the admin submission and completion queues. + * Initialize the asynchronous events notification queues. +@@ -445,8 +443,7 @@ void ena_com_mmio_reg_read_request_destr + * @return - 0 on success, negative value on failure. + */ + int ena_com_admin_init(struct ena_com_dev *ena_dev, +- struct ena_aenq_handlers *aenq_handlers, +- bool init_spinlock); ++ struct ena_aenq_handlers *aenq_handlers); + + /* ena_com_admin_destroy - Destroy the admin and the async events queues. + * @ena_dev: ENA communication layer struct +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -2508,7 +2508,7 @@ static int ena_device_init(struct ena_co + } + + /* ENA admin level init */ +- rc = ena_com_admin_init(ena_dev, &aenq_handlers, true); ++ rc = ena_com_admin_init(ena_dev, &aenq_handlers); + if (rc) { + dev_err(dev, + "Can not initialize ena admin queue with device\n"); diff --git a/debian/patches/features/all/ena/0012-net-ena-update-driver-version-to-2.0.1.patch b/debian/patches/features/all/ena/0012-net-ena-update-driver-version-to-2.0.1.patch new file mode 100644 index 000000000..ce4d8d8e0 --- /dev/null +++ b/debian/patches/features/all/ena/0012-net-ena-update-driver-version-to-2.0.1.patch @@ -0,0 +1,28 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:26 +0300 +Subject: [PATCH 12/19] net: ena: update driver version to 2.0.1 +Origin: https://git.kernel.org/linus/3a7b9d8ddd200bdafaa3ef75b8544d2403eaa03b + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -43,9 +43,9 @@ + #include "ena_com.h" + #include "ena_eth_com.h" + +-#define DRV_MODULE_VER_MAJOR 1 +-#define DRV_MODULE_VER_MINOR 5 +-#define DRV_MODULE_VER_SUBMINOR 0 ++#define DRV_MODULE_VER_MAJOR 2 ++#define DRV_MODULE_VER_MINOR 0 ++#define DRV_MODULE_VER_SUBMINOR 1 + + #define DRV_MODULE_NAME "ena" + #ifndef DRV_MODULE_VERSION diff --git a/debian/patches/features/all/ena/0013-net-ena-fix-indentations-in-ena_defs-for-better-read.patch b/debian/patches/features/all/ena/0013-net-ena-fix-indentations-in-ena_defs-for-better-read.patch new file mode 100644 index 000000000..2e0ad4279 --- /dev/null +++ b/debian/patches/features/all/ena/0013-net-ena-fix-indentations-in-ena_defs-for-better-read.patch @@ -0,0 +1,1000 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Thu, 11 Oct 2018 11:26:27 +0300 +Subject: [PATCH 13/19] net: ena: fix indentations in ena_defs for better + readability +Origin: https://git.kernel.org/linus/be26667cb3947c90322467f1d15ad86b02350e00 + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + .../net/ethernet/amazon/ena/ena_admin_defs.h | 334 +++++++----------- + .../net/ethernet/amazon/ena/ena_eth_io_defs.h | 223 ++++++------ + .../net/ethernet/amazon/ena/ena_regs_defs.h | 206 +++++------ + 3 files changed, 338 insertions(+), 425 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +@@ -32,119 +32,81 @@ + #ifndef _ENA_ADMIN_H_ + #define _ENA_ADMIN_H_ + +-enum ena_admin_aq_opcode { +- ENA_ADMIN_CREATE_SQ = 1, +- +- ENA_ADMIN_DESTROY_SQ = 2, +- +- ENA_ADMIN_CREATE_CQ = 3, +- +- ENA_ADMIN_DESTROY_CQ = 4, +- +- ENA_ADMIN_GET_FEATURE = 8, + +- ENA_ADMIN_SET_FEATURE = 9, +- +- ENA_ADMIN_GET_STATS = 11, ++enum ena_admin_aq_opcode { ++ ENA_ADMIN_CREATE_SQ = 1, ++ ENA_ADMIN_DESTROY_SQ = 2, ++ ENA_ADMIN_CREATE_CQ = 3, ++ ENA_ADMIN_DESTROY_CQ = 4, ++ ENA_ADMIN_GET_FEATURE = 8, ++ ENA_ADMIN_SET_FEATURE = 9, ++ ENA_ADMIN_GET_STATS = 11, + }; + + enum ena_admin_aq_completion_status { +- ENA_ADMIN_SUCCESS = 0, +- +- ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE = 1, +- +- ENA_ADMIN_BAD_OPCODE = 2, +- +- ENA_ADMIN_UNSUPPORTED_OPCODE = 3, +- +- ENA_ADMIN_MALFORMED_REQUEST = 4, +- ++ ENA_ADMIN_SUCCESS = 0, ++ ENA_ADMIN_RESOURCE_ALLOCATION_FAILURE = 1, ++ ENA_ADMIN_BAD_OPCODE = 2, ++ ENA_ADMIN_UNSUPPORTED_OPCODE = 3, ++ ENA_ADMIN_MALFORMED_REQUEST = 4, + /* Additional status is provided in ACQ entry extended_status */ +- ENA_ADMIN_ILLEGAL_PARAMETER = 5, +- +- ENA_ADMIN_UNKNOWN_ERROR = 6, +- +- ENA_ADMIN_RESOURCE_BUSY = 7, ++ ENA_ADMIN_ILLEGAL_PARAMETER = 5, ++ ENA_ADMIN_UNKNOWN_ERROR = 6, ++ ENA_ADMIN_RESOURCE_BUSY = 7, + }; + + enum ena_admin_aq_feature_id { +- ENA_ADMIN_DEVICE_ATTRIBUTES = 1, +- +- ENA_ADMIN_MAX_QUEUES_NUM = 2, +- +- ENA_ADMIN_HW_HINTS = 3, +- +- ENA_ADMIN_LLQ = 4, +- +- ENA_ADMIN_RSS_HASH_FUNCTION = 10, +- +- ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11, +- +- ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG = 12, +- +- ENA_ADMIN_MTU = 14, +- +- ENA_ADMIN_RSS_HASH_INPUT = 18, +- +- ENA_ADMIN_INTERRUPT_MODERATION = 20, +- +- ENA_ADMIN_AENQ_CONFIG = 26, +- +- ENA_ADMIN_LINK_CONFIG = 27, +- +- ENA_ADMIN_HOST_ATTR_CONFIG = 28, +- +- ENA_ADMIN_FEATURES_OPCODE_NUM = 32, ++ ENA_ADMIN_DEVICE_ATTRIBUTES = 1, ++ ENA_ADMIN_MAX_QUEUES_NUM = 2, ++ ENA_ADMIN_HW_HINTS = 3, ++ ENA_ADMIN_LLQ = 4, ++ ENA_ADMIN_RSS_HASH_FUNCTION = 10, ++ ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11, ++ ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG = 12, ++ ENA_ADMIN_MTU = 14, ++ ENA_ADMIN_RSS_HASH_INPUT = 18, ++ ENA_ADMIN_INTERRUPT_MODERATION = 20, ++ ENA_ADMIN_AENQ_CONFIG = 26, ++ ENA_ADMIN_LINK_CONFIG = 27, ++ ENA_ADMIN_HOST_ATTR_CONFIG = 28, ++ ENA_ADMIN_FEATURES_OPCODE_NUM = 32, + }; + + enum ena_admin_placement_policy_type { + /* descriptors and headers are in host memory */ +- ENA_ADMIN_PLACEMENT_POLICY_HOST = 1, +- ++ ENA_ADMIN_PLACEMENT_POLICY_HOST = 1, + /* descriptors and headers are in device memory (a.k.a Low Latency + * Queue) + */ +- ENA_ADMIN_PLACEMENT_POLICY_DEV = 3, ++ ENA_ADMIN_PLACEMENT_POLICY_DEV = 3, + }; + + enum ena_admin_link_types { +- ENA_ADMIN_LINK_SPEED_1G = 0x1, +- +- ENA_ADMIN_LINK_SPEED_2_HALF_G = 0x2, +- +- ENA_ADMIN_LINK_SPEED_5G = 0x4, +- +- ENA_ADMIN_LINK_SPEED_10G = 0x8, +- +- ENA_ADMIN_LINK_SPEED_25G = 0x10, +- +- ENA_ADMIN_LINK_SPEED_40G = 0x20, +- +- ENA_ADMIN_LINK_SPEED_50G = 0x40, +- +- ENA_ADMIN_LINK_SPEED_100G = 0x80, +- +- ENA_ADMIN_LINK_SPEED_200G = 0x100, +- +- ENA_ADMIN_LINK_SPEED_400G = 0x200, ++ ENA_ADMIN_LINK_SPEED_1G = 0x1, ++ ENA_ADMIN_LINK_SPEED_2_HALF_G = 0x2, ++ ENA_ADMIN_LINK_SPEED_5G = 0x4, ++ ENA_ADMIN_LINK_SPEED_10G = 0x8, ++ ENA_ADMIN_LINK_SPEED_25G = 0x10, ++ ENA_ADMIN_LINK_SPEED_40G = 0x20, ++ ENA_ADMIN_LINK_SPEED_50G = 0x40, ++ ENA_ADMIN_LINK_SPEED_100G = 0x80, ++ ENA_ADMIN_LINK_SPEED_200G = 0x100, ++ ENA_ADMIN_LINK_SPEED_400G = 0x200, + }; + + enum ena_admin_completion_policy_type { + /* completion queue entry for each sq descriptor */ +- ENA_ADMIN_COMPLETION_POLICY_DESC = 0, +- ++ ENA_ADMIN_COMPLETION_POLICY_DESC = 0, + /* completion queue entry upon request in sq descriptor */ +- ENA_ADMIN_COMPLETION_POLICY_DESC_ON_DEMAND = 1, +- ++ ENA_ADMIN_COMPLETION_POLICY_DESC_ON_DEMAND = 1, + /* current queue head pointer is updated in OS memory upon sq + * descriptor request + */ +- ENA_ADMIN_COMPLETION_POLICY_HEAD_ON_DEMAND = 2, +- ++ ENA_ADMIN_COMPLETION_POLICY_HEAD_ON_DEMAND = 2, + /* current queue head pointer is updated in OS memory for each sq + * descriptor + */ +- ENA_ADMIN_COMPLETION_POLICY_HEAD = 3, ++ ENA_ADMIN_COMPLETION_POLICY_HEAD = 3, + }; + + /* basic stats return ena_admin_basic_stats while extanded stats return a +@@ -152,15 +114,13 @@ enum ena_admin_completion_policy_type { + * device id + */ + enum ena_admin_get_stats_type { +- ENA_ADMIN_GET_STATS_TYPE_BASIC = 0, +- +- ENA_ADMIN_GET_STATS_TYPE_EXTENDED = 1, ++ ENA_ADMIN_GET_STATS_TYPE_BASIC = 0, ++ ENA_ADMIN_GET_STATS_TYPE_EXTENDED = 1, + }; + + enum ena_admin_get_stats_scope { +- ENA_ADMIN_SPECIFIC_QUEUE = 0, +- +- ENA_ADMIN_ETH_TRAFFIC = 1, ++ ENA_ADMIN_SPECIFIC_QUEUE = 0, ++ ENA_ADMIN_ETH_TRAFFIC = 1, + }; + + struct ena_admin_aq_common_desc { +@@ -231,7 +191,9 @@ struct ena_admin_acq_common_desc { + + u16 extended_status; + +- /* serves as a hint what AQ entries can be revoked */ ++ /* indicates to the driver which AQ entry has been consumed by the ++ * device and could be reused ++ */ + u16 sq_head_indx; + }; + +@@ -300,9 +262,8 @@ struct ena_admin_aq_create_sq_cmd { + }; + + enum ena_admin_sq_direction { +- ENA_ADMIN_SQ_DIRECTION_TX = 1, +- +- ENA_ADMIN_SQ_DIRECTION_RX = 2, ++ ENA_ADMIN_SQ_DIRECTION_TX = 1, ++ ENA_ADMIN_SQ_DIRECTION_RX = 2, + }; + + struct ena_admin_acq_create_sq_resp_desc { +@@ -664,9 +625,8 @@ struct ena_admin_feature_offload_desc { + }; + + enum ena_admin_hash_functions { +- ENA_ADMIN_TOEPLITZ = 1, +- +- ENA_ADMIN_CRC32 = 2, ++ ENA_ADMIN_TOEPLITZ = 1, ++ ENA_ADMIN_CRC32 = 2, + }; + + struct ena_admin_feature_rss_flow_hash_control { +@@ -692,50 +652,35 @@ struct ena_admin_feature_rss_flow_hash_f + + /* RSS flow hash protocols */ + enum ena_admin_flow_hash_proto { +- ENA_ADMIN_RSS_TCP4 = 0, +- +- ENA_ADMIN_RSS_UDP4 = 1, +- +- ENA_ADMIN_RSS_TCP6 = 2, +- +- ENA_ADMIN_RSS_UDP6 = 3, +- +- ENA_ADMIN_RSS_IP4 = 4, +- +- ENA_ADMIN_RSS_IP6 = 5, +- +- ENA_ADMIN_RSS_IP4_FRAG = 6, +- +- ENA_ADMIN_RSS_NOT_IP = 7, +- ++ ENA_ADMIN_RSS_TCP4 = 0, ++ ENA_ADMIN_RSS_UDP4 = 1, ++ ENA_ADMIN_RSS_TCP6 = 2, ++ ENA_ADMIN_RSS_UDP6 = 3, ++ ENA_ADMIN_RSS_IP4 = 4, ++ ENA_ADMIN_RSS_IP6 = 5, ++ ENA_ADMIN_RSS_IP4_FRAG = 6, ++ ENA_ADMIN_RSS_NOT_IP = 7, + /* TCPv6 with extension header */ +- ENA_ADMIN_RSS_TCP6_EX = 8, +- ++ ENA_ADMIN_RSS_TCP6_EX = 8, + /* IPv6 with extension header */ +- ENA_ADMIN_RSS_IP6_EX = 9, +- +- ENA_ADMIN_RSS_PROTO_NUM = 16, ++ ENA_ADMIN_RSS_IP6_EX = 9, ++ ENA_ADMIN_RSS_PROTO_NUM = 16, + }; + + /* RSS flow hash fields */ + enum ena_admin_flow_hash_fields { + /* Ethernet Dest Addr */ +- ENA_ADMIN_RSS_L2_DA = BIT(0), +- ++ ENA_ADMIN_RSS_L2_DA = BIT(0), + /* Ethernet Src Addr */ +- ENA_ADMIN_RSS_L2_SA = BIT(1), +- ++ ENA_ADMIN_RSS_L2_SA = BIT(1), + /* ipv4/6 Dest Addr */ +- ENA_ADMIN_RSS_L3_DA = BIT(2), +- ++ ENA_ADMIN_RSS_L3_DA = BIT(2), + /* ipv4/6 Src Addr */ +- ENA_ADMIN_RSS_L3_SA = BIT(3), +- ++ ENA_ADMIN_RSS_L3_SA = BIT(3), + /* tcp/udp Dest Port */ +- ENA_ADMIN_RSS_L4_DP = BIT(4), +- ++ ENA_ADMIN_RSS_L4_DP = BIT(4), + /* tcp/udp Src Port */ +- ENA_ADMIN_RSS_L4_SP = BIT(5), ++ ENA_ADMIN_RSS_L4_SP = BIT(5), + }; + + struct ena_admin_proto_input { +@@ -774,19 +719,13 @@ struct ena_admin_feature_rss_flow_hash_i + }; + + enum ena_admin_os_type { +- ENA_ADMIN_OS_LINUX = 1, +- +- ENA_ADMIN_OS_WIN = 2, +- +- ENA_ADMIN_OS_DPDK = 3, +- +- ENA_ADMIN_OS_FREEBSD = 4, +- +- ENA_ADMIN_OS_IPXE = 5, +- +- ENA_ADMIN_OS_ESXI = 6, +- +- ENA_ADMIN_OS_GROUPS_NUM = 6, ++ ENA_ADMIN_OS_LINUX = 1, ++ ENA_ADMIN_OS_WIN = 2, ++ ENA_ADMIN_OS_DPDK = 3, ++ ENA_ADMIN_OS_FREEBSD = 4, ++ ENA_ADMIN_OS_IPXE = 5, ++ ENA_ADMIN_OS_ESXI = 6, ++ ENA_ADMIN_OS_GROUPS_NUM = 6, + }; + + struct ena_admin_host_info { +@@ -981,25 +920,18 @@ struct ena_admin_aenq_common_desc { + + /* asynchronous event notification groups */ + enum ena_admin_aenq_group { +- ENA_ADMIN_LINK_CHANGE = 0, +- +- ENA_ADMIN_FATAL_ERROR = 1, +- +- ENA_ADMIN_WARNING = 2, +- +- ENA_ADMIN_NOTIFICATION = 3, +- +- ENA_ADMIN_KEEP_ALIVE = 4, +- +- ENA_ADMIN_AENQ_GROUPS_NUM = 5, ++ ENA_ADMIN_LINK_CHANGE = 0, ++ ENA_ADMIN_FATAL_ERROR = 1, ++ ENA_ADMIN_WARNING = 2, ++ ENA_ADMIN_NOTIFICATION = 3, ++ ENA_ADMIN_KEEP_ALIVE = 4, ++ ENA_ADMIN_AENQ_GROUPS_NUM = 5, + }; + + enum ena_admin_aenq_notification_syndrom { +- ENA_ADMIN_SUSPEND = 0, +- +- ENA_ADMIN_RESUME = 1, +- +- ENA_ADMIN_UPDATE_HINTS = 2, ++ ENA_ADMIN_SUSPEND = 0, ++ ENA_ADMIN_RESUME = 1, ++ ENA_ADMIN_UPDATE_HINTS = 2, + }; + + struct ena_admin_aenq_entry { +@@ -1034,27 +966,27 @@ struct ena_admin_ena_mmio_req_read_less_ + }; + + /* aq_common_desc */ +-#define ENA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0) +-#define ENA_ADMIN_AQ_COMMON_DESC_PHASE_MASK BIT(0) +-#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_SHIFT 1 +-#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_MASK BIT(1) +-#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_SHIFT 2 +-#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK BIT(2) ++#define ENA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0) ++#define ENA_ADMIN_AQ_COMMON_DESC_PHASE_MASK BIT(0) ++#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_SHIFT 1 ++#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_MASK BIT(1) ++#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_SHIFT 2 ++#define ENA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT_MASK BIT(2) + + /* sq */ +-#define ENA_ADMIN_SQ_SQ_DIRECTION_SHIFT 5 +-#define ENA_ADMIN_SQ_SQ_DIRECTION_MASK GENMASK(7, 5) ++#define ENA_ADMIN_SQ_SQ_DIRECTION_SHIFT 5 ++#define ENA_ADMIN_SQ_SQ_DIRECTION_MASK GENMASK(7, 5) + + /* acq_common_desc */ +-#define ENA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0) +-#define ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK BIT(0) ++#define ENA_ADMIN_ACQ_COMMON_DESC_COMMAND_ID_MASK GENMASK(11, 0) ++#define ENA_ADMIN_ACQ_COMMON_DESC_PHASE_MASK BIT(0) + + /* aq_create_sq_cmd */ +-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_SHIFT 5 +-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_MASK GENMASK(7, 5) +-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_PLACEMENT_POLICY_MASK GENMASK(3, 0) +-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_SHIFT 4 +-#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_MASK GENMASK(6, 4) ++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_SHIFT 5 ++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_SQ_DIRECTION_MASK GENMASK(7, 5) ++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_PLACEMENT_POLICY_MASK GENMASK(3, 0) ++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_SHIFT 4 ++#define ENA_ADMIN_AQ_CREATE_SQ_CMD_COMPLETION_POLICY_MASK GENMASK(6, 4) + #define ENA_ADMIN_AQ_CREATE_SQ_CMD_IS_PHYSICALLY_CONTIGUOUS_MASK BIT(0) + + /* aq_create_cq_cmd */ +@@ -1063,12 +995,12 @@ struct ena_admin_ena_mmio_req_read_less_ + #define ENA_ADMIN_AQ_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS_MASK GENMASK(4, 0) + + /* get_set_feature_common_desc */ +-#define ENA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK GENMASK(1, 0) ++#define ENA_ADMIN_GET_SET_FEATURE_COMMON_DESC_SELECT_MASK GENMASK(1, 0) + + /* get_feature_link_desc */ +-#define ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK BIT(0) +-#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_SHIFT 1 +-#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_MASK BIT(1) ++#define ENA_ADMIN_GET_FEATURE_LINK_DESC_AUTONEG_MASK BIT(0) ++#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_SHIFT 1 ++#define ENA_ADMIN_GET_FEATURE_LINK_DESC_DUPLEX_MASK BIT(1) + + /* feature_offload_desc */ + #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L3_CSUM_IPV4_MASK BIT(0) +@@ -1080,19 +1012,19 @@ struct ena_admin_ena_mmio_req_read_less_ + #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_PART_MASK BIT(3) + #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_SHIFT 4 + #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TX_L4_IPV6_CSUM_FULL_MASK BIT(4) +-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_SHIFT 5 +-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK BIT(5) +-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_SHIFT 6 +-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK BIT(6) +-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_SHIFT 7 +-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_MASK BIT(7) ++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_SHIFT 5 ++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV4_MASK BIT(5) ++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_SHIFT 6 ++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_IPV6_MASK BIT(6) ++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_SHIFT 7 ++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_TSO_ECN_MASK BIT(7) + #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L3_CSUM_IPV4_MASK BIT(0) + #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_SHIFT 1 + #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV4_CSUM_MASK BIT(1) + #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_SHIFT 2 + #define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_L4_IPV6_CSUM_MASK BIT(2) +-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_SHIFT 3 +-#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_MASK BIT(3) ++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_SHIFT 3 ++#define ENA_ADMIN_FEATURE_OFFLOAD_DESC_RX_HASH_MASK BIT(3) + + /* feature_rss_flow_hash_function */ + #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_FUNCTION_FUNCS_MASK GENMASK(7, 0) +@@ -1100,32 +1032,32 @@ struct ena_admin_ena_mmio_req_read_less_ + + /* feature_rss_flow_hash_input */ + #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_SHIFT 1 +-#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_MASK BIT(1) ++#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L3_SORT_MASK BIT(1) + #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_SHIFT 2 +-#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_MASK BIT(2) ++#define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_L4_SORT_MASK BIT(2) + #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_SHIFT 1 + #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L3_SORT_MASK BIT(1) + #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_SHIFT 2 + #define ENA_ADMIN_FEATURE_RSS_FLOW_HASH_INPUT_ENABLE_L4_SORT_MASK BIT(2) + + /* host_info */ +-#define ENA_ADMIN_HOST_INFO_MAJOR_MASK GENMASK(7, 0) +-#define ENA_ADMIN_HOST_INFO_MINOR_SHIFT 8 +-#define ENA_ADMIN_HOST_INFO_MINOR_MASK GENMASK(15, 8) +-#define ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT 16 +-#define ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK GENMASK(23, 16) +-#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT 24 +-#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_MASK GENMASK(31, 24) +-#define ENA_ADMIN_HOST_INFO_FUNCTION_MASK GENMASK(2, 0) +-#define ENA_ADMIN_HOST_INFO_DEVICE_SHIFT 3 +-#define ENA_ADMIN_HOST_INFO_DEVICE_MASK GENMASK(7, 3) +-#define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8 +-#define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 8) ++#define ENA_ADMIN_HOST_INFO_MAJOR_MASK GENMASK(7, 0) ++#define ENA_ADMIN_HOST_INFO_MINOR_SHIFT 8 ++#define ENA_ADMIN_HOST_INFO_MINOR_MASK GENMASK(15, 8) ++#define ENA_ADMIN_HOST_INFO_SUB_MINOR_SHIFT 16 ++#define ENA_ADMIN_HOST_INFO_SUB_MINOR_MASK GENMASK(23, 16) ++#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT 24 ++#define ENA_ADMIN_HOST_INFO_MODULE_TYPE_MASK GENMASK(31, 24) ++#define ENA_ADMIN_HOST_INFO_FUNCTION_MASK GENMASK(2, 0) ++#define ENA_ADMIN_HOST_INFO_DEVICE_SHIFT 3 ++#define ENA_ADMIN_HOST_INFO_DEVICE_MASK GENMASK(7, 3) ++#define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8 ++#define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 8) + + /* aenq_common_desc */ +-#define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0) ++#define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0) + + /* aenq_link_change_desc */ +-#define ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK BIT(0) ++#define ENA_ADMIN_AENQ_LINK_CHANGE_DESC_LINK_STATUS_MASK BIT(0) + + #endif /*_ENA_ADMIN_H_ */ +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_io_defs.h +@@ -33,25 +33,18 @@ + #define _ENA_ETH_IO_H_ + + enum ena_eth_io_l3_proto_index { +- ENA_ETH_IO_L3_PROTO_UNKNOWN = 0, +- +- ENA_ETH_IO_L3_PROTO_IPV4 = 8, +- +- ENA_ETH_IO_L3_PROTO_IPV6 = 11, +- +- ENA_ETH_IO_L3_PROTO_FCOE = 21, +- +- ENA_ETH_IO_L3_PROTO_ROCE = 22, ++ ENA_ETH_IO_L3_PROTO_UNKNOWN = 0, ++ ENA_ETH_IO_L3_PROTO_IPV4 = 8, ++ ENA_ETH_IO_L3_PROTO_IPV6 = 11, ++ ENA_ETH_IO_L3_PROTO_FCOE = 21, ++ ENA_ETH_IO_L3_PROTO_ROCE = 22, + }; + + enum ena_eth_io_l4_proto_index { +- ENA_ETH_IO_L4_PROTO_UNKNOWN = 0, +- +- ENA_ETH_IO_L4_PROTO_TCP = 12, +- +- ENA_ETH_IO_L4_PROTO_UDP = 13, +- +- ENA_ETH_IO_L4_PROTO_ROUTEABLE_ROCE = 23, ++ ENA_ETH_IO_L4_PROTO_UNKNOWN = 0, ++ ENA_ETH_IO_L4_PROTO_TCP = 12, ++ ENA_ETH_IO_L4_PROTO_UDP = 13, ++ ENA_ETH_IO_L4_PROTO_ROUTEABLE_ROCE = 23, + }; + + struct ena_eth_io_tx_desc { +@@ -307,116 +300,116 @@ struct ena_eth_io_numa_node_cfg_reg { + }; + + /* tx_desc */ +-#define ENA_ETH_IO_TX_DESC_LENGTH_MASK GENMASK(15, 0) +-#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_SHIFT 16 +-#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_MASK GENMASK(21, 16) +-#define ENA_ETH_IO_TX_DESC_META_DESC_SHIFT 23 +-#define ENA_ETH_IO_TX_DESC_META_DESC_MASK BIT(23) +-#define ENA_ETH_IO_TX_DESC_PHASE_SHIFT 24 +-#define ENA_ETH_IO_TX_DESC_PHASE_MASK BIT(24) +-#define ENA_ETH_IO_TX_DESC_FIRST_SHIFT 26 +-#define ENA_ETH_IO_TX_DESC_FIRST_MASK BIT(26) +-#define ENA_ETH_IO_TX_DESC_LAST_SHIFT 27 +-#define ENA_ETH_IO_TX_DESC_LAST_MASK BIT(27) +-#define ENA_ETH_IO_TX_DESC_COMP_REQ_SHIFT 28 +-#define ENA_ETH_IO_TX_DESC_COMP_REQ_MASK BIT(28) +-#define ENA_ETH_IO_TX_DESC_L3_PROTO_IDX_MASK GENMASK(3, 0) +-#define ENA_ETH_IO_TX_DESC_DF_SHIFT 4 +-#define ENA_ETH_IO_TX_DESC_DF_MASK BIT(4) +-#define ENA_ETH_IO_TX_DESC_TSO_EN_SHIFT 7 +-#define ENA_ETH_IO_TX_DESC_TSO_EN_MASK BIT(7) +-#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_SHIFT 8 +-#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_MASK GENMASK(12, 8) +-#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_SHIFT 13 +-#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_MASK BIT(13) +-#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_SHIFT 14 +-#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_MASK BIT(14) +-#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_SHIFT 15 +-#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_MASK BIT(15) +-#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_SHIFT 17 +-#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_MASK BIT(17) +-#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT 22 +-#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK GENMASK(31, 22) +-#define ENA_ETH_IO_TX_DESC_ADDR_HI_MASK GENMASK(15, 0) +-#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT 24 +-#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK GENMASK(31, 24) ++#define ENA_ETH_IO_TX_DESC_LENGTH_MASK GENMASK(15, 0) ++#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_SHIFT 16 ++#define ENA_ETH_IO_TX_DESC_REQ_ID_HI_MASK GENMASK(21, 16) ++#define ENA_ETH_IO_TX_DESC_META_DESC_SHIFT 23 ++#define ENA_ETH_IO_TX_DESC_META_DESC_MASK BIT(23) ++#define ENA_ETH_IO_TX_DESC_PHASE_SHIFT 24 ++#define ENA_ETH_IO_TX_DESC_PHASE_MASK BIT(24) ++#define ENA_ETH_IO_TX_DESC_FIRST_SHIFT 26 ++#define ENA_ETH_IO_TX_DESC_FIRST_MASK BIT(26) ++#define ENA_ETH_IO_TX_DESC_LAST_SHIFT 27 ++#define ENA_ETH_IO_TX_DESC_LAST_MASK BIT(27) ++#define ENA_ETH_IO_TX_DESC_COMP_REQ_SHIFT 28 ++#define ENA_ETH_IO_TX_DESC_COMP_REQ_MASK BIT(28) ++#define ENA_ETH_IO_TX_DESC_L3_PROTO_IDX_MASK GENMASK(3, 0) ++#define ENA_ETH_IO_TX_DESC_DF_SHIFT 4 ++#define ENA_ETH_IO_TX_DESC_DF_MASK BIT(4) ++#define ENA_ETH_IO_TX_DESC_TSO_EN_SHIFT 7 ++#define ENA_ETH_IO_TX_DESC_TSO_EN_MASK BIT(7) ++#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_SHIFT 8 ++#define ENA_ETH_IO_TX_DESC_L4_PROTO_IDX_MASK GENMASK(12, 8) ++#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_SHIFT 13 ++#define ENA_ETH_IO_TX_DESC_L3_CSUM_EN_MASK BIT(13) ++#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_SHIFT 14 ++#define ENA_ETH_IO_TX_DESC_L4_CSUM_EN_MASK BIT(14) ++#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_SHIFT 15 ++#define ENA_ETH_IO_TX_DESC_ETHERNET_FCS_DIS_MASK BIT(15) ++#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_SHIFT 17 ++#define ENA_ETH_IO_TX_DESC_L4_CSUM_PARTIAL_MASK BIT(17) ++#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_SHIFT 22 ++#define ENA_ETH_IO_TX_DESC_REQ_ID_LO_MASK GENMASK(31, 22) ++#define ENA_ETH_IO_TX_DESC_ADDR_HI_MASK GENMASK(15, 0) ++#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_SHIFT 24 ++#define ENA_ETH_IO_TX_DESC_HEADER_LENGTH_MASK GENMASK(31, 24) + + /* tx_meta_desc */ +-#define ENA_ETH_IO_TX_META_DESC_REQ_ID_LO_MASK GENMASK(9, 0) +-#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_SHIFT 14 +-#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK BIT(14) +-#define ENA_ETH_IO_TX_META_DESC_MSS_HI_SHIFT 16 +-#define ENA_ETH_IO_TX_META_DESC_MSS_HI_MASK GENMASK(19, 16) +-#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_SHIFT 20 +-#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK BIT(20) +-#define ENA_ETH_IO_TX_META_DESC_META_STORE_SHIFT 21 +-#define ENA_ETH_IO_TX_META_DESC_META_STORE_MASK BIT(21) +-#define ENA_ETH_IO_TX_META_DESC_META_DESC_SHIFT 23 +-#define ENA_ETH_IO_TX_META_DESC_META_DESC_MASK BIT(23) +-#define ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT 24 +-#define ENA_ETH_IO_TX_META_DESC_PHASE_MASK BIT(24) +-#define ENA_ETH_IO_TX_META_DESC_FIRST_SHIFT 26 +-#define ENA_ETH_IO_TX_META_DESC_FIRST_MASK BIT(26) +-#define ENA_ETH_IO_TX_META_DESC_LAST_SHIFT 27 +-#define ENA_ETH_IO_TX_META_DESC_LAST_MASK BIT(27) +-#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_SHIFT 28 +-#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_MASK BIT(28) +-#define ENA_ETH_IO_TX_META_DESC_REQ_ID_HI_MASK GENMASK(5, 0) +-#define ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK GENMASK(7, 0) +-#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT 8 +-#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK GENMASK(15, 8) +-#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT 16 +-#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK GENMASK(21, 16) +-#define ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT 22 +-#define ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK GENMASK(31, 22) ++#define ENA_ETH_IO_TX_META_DESC_REQ_ID_LO_MASK GENMASK(9, 0) ++#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_SHIFT 14 ++#define ENA_ETH_IO_TX_META_DESC_EXT_VALID_MASK BIT(14) ++#define ENA_ETH_IO_TX_META_DESC_MSS_HI_SHIFT 16 ++#define ENA_ETH_IO_TX_META_DESC_MSS_HI_MASK GENMASK(19, 16) ++#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_SHIFT 20 ++#define ENA_ETH_IO_TX_META_DESC_ETH_META_TYPE_MASK BIT(20) ++#define ENA_ETH_IO_TX_META_DESC_META_STORE_SHIFT 21 ++#define ENA_ETH_IO_TX_META_DESC_META_STORE_MASK BIT(21) ++#define ENA_ETH_IO_TX_META_DESC_META_DESC_SHIFT 23 ++#define ENA_ETH_IO_TX_META_DESC_META_DESC_MASK BIT(23) ++#define ENA_ETH_IO_TX_META_DESC_PHASE_SHIFT 24 ++#define ENA_ETH_IO_TX_META_DESC_PHASE_MASK BIT(24) ++#define ENA_ETH_IO_TX_META_DESC_FIRST_SHIFT 26 ++#define ENA_ETH_IO_TX_META_DESC_FIRST_MASK BIT(26) ++#define ENA_ETH_IO_TX_META_DESC_LAST_SHIFT 27 ++#define ENA_ETH_IO_TX_META_DESC_LAST_MASK BIT(27) ++#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_SHIFT 28 ++#define ENA_ETH_IO_TX_META_DESC_COMP_REQ_MASK BIT(28) ++#define ENA_ETH_IO_TX_META_DESC_REQ_ID_HI_MASK GENMASK(5, 0) ++#define ENA_ETH_IO_TX_META_DESC_L3_HDR_LEN_MASK GENMASK(7, 0) ++#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_SHIFT 8 ++#define ENA_ETH_IO_TX_META_DESC_L3_HDR_OFF_MASK GENMASK(15, 8) ++#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_SHIFT 16 ++#define ENA_ETH_IO_TX_META_DESC_L4_HDR_LEN_IN_WORDS_MASK GENMASK(21, 16) ++#define ENA_ETH_IO_TX_META_DESC_MSS_LO_SHIFT 22 ++#define ENA_ETH_IO_TX_META_DESC_MSS_LO_MASK GENMASK(31, 22) + + /* tx_cdesc */ +-#define ENA_ETH_IO_TX_CDESC_PHASE_MASK BIT(0) ++#define ENA_ETH_IO_TX_CDESC_PHASE_MASK BIT(0) + + /* rx_desc */ +-#define ENA_ETH_IO_RX_DESC_PHASE_MASK BIT(0) +-#define ENA_ETH_IO_RX_DESC_FIRST_SHIFT 2 +-#define ENA_ETH_IO_RX_DESC_FIRST_MASK BIT(2) +-#define ENA_ETH_IO_RX_DESC_LAST_SHIFT 3 +-#define ENA_ETH_IO_RX_DESC_LAST_MASK BIT(3) +-#define ENA_ETH_IO_RX_DESC_COMP_REQ_SHIFT 4 +-#define ENA_ETH_IO_RX_DESC_COMP_REQ_MASK BIT(4) ++#define ENA_ETH_IO_RX_DESC_PHASE_MASK BIT(0) ++#define ENA_ETH_IO_RX_DESC_FIRST_SHIFT 2 ++#define ENA_ETH_IO_RX_DESC_FIRST_MASK BIT(2) ++#define ENA_ETH_IO_RX_DESC_LAST_SHIFT 3 ++#define ENA_ETH_IO_RX_DESC_LAST_MASK BIT(3) ++#define ENA_ETH_IO_RX_DESC_COMP_REQ_SHIFT 4 ++#define ENA_ETH_IO_RX_DESC_COMP_REQ_MASK BIT(4) + + /* rx_cdesc_base */ +-#define ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK GENMASK(4, 0) +-#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_SHIFT 5 +-#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_MASK GENMASK(6, 5) +-#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_SHIFT 8 +-#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_MASK GENMASK(12, 8) +-#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_SHIFT 13 +-#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_MASK BIT(13) +-#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT 14 +-#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK BIT(14) +-#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT 15 +-#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK BIT(15) +-#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_SHIFT 16 +-#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_MASK BIT(16) +-#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT 24 +-#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK BIT(24) +-#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT 25 +-#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_MASK BIT(25) +-#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT 26 +-#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK BIT(26) +-#define ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT 27 +-#define ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK BIT(27) +-#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_SHIFT 30 +-#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_MASK BIT(30) ++#define ENA_ETH_IO_RX_CDESC_BASE_L3_PROTO_IDX_MASK GENMASK(4, 0) ++#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_SHIFT 5 ++#define ENA_ETH_IO_RX_CDESC_BASE_SRC_VLAN_CNT_MASK GENMASK(6, 5) ++#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_SHIFT 8 ++#define ENA_ETH_IO_RX_CDESC_BASE_L4_PROTO_IDX_MASK GENMASK(12, 8) ++#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_SHIFT 13 ++#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM_ERR_MASK BIT(13) ++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_SHIFT 14 ++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_ERR_MASK BIT(14) ++#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_SHIFT 15 ++#define ENA_ETH_IO_RX_CDESC_BASE_IPV4_FRAG_MASK BIT(15) ++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_SHIFT 16 ++#define ENA_ETH_IO_RX_CDESC_BASE_L4_CSUM_CHECKED_MASK BIT(16) ++#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_SHIFT 24 ++#define ENA_ETH_IO_RX_CDESC_BASE_PHASE_MASK BIT(24) ++#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_SHIFT 25 ++#define ENA_ETH_IO_RX_CDESC_BASE_L3_CSUM2_MASK BIT(25) ++#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_SHIFT 26 ++#define ENA_ETH_IO_RX_CDESC_BASE_FIRST_MASK BIT(26) ++#define ENA_ETH_IO_RX_CDESC_BASE_LAST_SHIFT 27 ++#define ENA_ETH_IO_RX_CDESC_BASE_LAST_MASK BIT(27) ++#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_SHIFT 30 ++#define ENA_ETH_IO_RX_CDESC_BASE_BUFFER_MASK BIT(30) + + /* intr_reg */ +-#define ENA_ETH_IO_INTR_REG_RX_INTR_DELAY_MASK GENMASK(14, 0) +-#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_SHIFT 15 +-#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_MASK GENMASK(29, 15) +-#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_SHIFT 30 +-#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK BIT(30) ++#define ENA_ETH_IO_INTR_REG_RX_INTR_DELAY_MASK GENMASK(14, 0) ++#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_SHIFT 15 ++#define ENA_ETH_IO_INTR_REG_TX_INTR_DELAY_MASK GENMASK(29, 15) ++#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_SHIFT 30 ++#define ENA_ETH_IO_INTR_REG_INTR_UNMASK_MASK BIT(30) + + /* numa_node_cfg_reg */ +-#define ENA_ETH_IO_NUMA_NODE_CFG_REG_NUMA_MASK GENMASK(7, 0) +-#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_SHIFT 31 +-#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK BIT(31) ++#define ENA_ETH_IO_NUMA_NODE_CFG_REG_NUMA_MASK GENMASK(7, 0) ++#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_SHIFT 31 ++#define ENA_ETH_IO_NUMA_NODE_CFG_REG_ENABLED_MASK BIT(31) + + #endif /*_ENA_ETH_IO_H_ */ +Index: linux/drivers/net/ethernet/amazon/ena/ena_regs_defs.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_regs_defs.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_regs_defs.h +@@ -33,137 +33,125 @@ + #define _ENA_REGS_H_ + + enum ena_regs_reset_reason_types { +- ENA_REGS_RESET_NORMAL = 0, +- +- ENA_REGS_RESET_KEEP_ALIVE_TO = 1, +- +- ENA_REGS_RESET_ADMIN_TO = 2, +- +- ENA_REGS_RESET_MISS_TX_CMPL = 3, +- +- ENA_REGS_RESET_INV_RX_REQ_ID = 4, +- +- ENA_REGS_RESET_INV_TX_REQ_ID = 5, +- +- ENA_REGS_RESET_TOO_MANY_RX_DESCS = 6, +- +- ENA_REGS_RESET_INIT_ERR = 7, +- +- ENA_REGS_RESET_DRIVER_INVALID_STATE = 8, +- +- ENA_REGS_RESET_OS_TRIGGER = 9, +- +- ENA_REGS_RESET_OS_NETDEV_WD = 10, +- +- ENA_REGS_RESET_SHUTDOWN = 11, +- +- ENA_REGS_RESET_USER_TRIGGER = 12, +- +- ENA_REGS_RESET_GENERIC = 13, +- +- ENA_REGS_RESET_MISS_INTERRUPT = 14, ++ ENA_REGS_RESET_NORMAL = 0, ++ ENA_REGS_RESET_KEEP_ALIVE_TO = 1, ++ ENA_REGS_RESET_ADMIN_TO = 2, ++ ENA_REGS_RESET_MISS_TX_CMPL = 3, ++ ENA_REGS_RESET_INV_RX_REQ_ID = 4, ++ ENA_REGS_RESET_INV_TX_REQ_ID = 5, ++ ENA_REGS_RESET_TOO_MANY_RX_DESCS = 6, ++ ENA_REGS_RESET_INIT_ERR = 7, ++ ENA_REGS_RESET_DRIVER_INVALID_STATE = 8, ++ ENA_REGS_RESET_OS_TRIGGER = 9, ++ ENA_REGS_RESET_OS_NETDEV_WD = 10, ++ ENA_REGS_RESET_SHUTDOWN = 11, ++ ENA_REGS_RESET_USER_TRIGGER = 12, ++ ENA_REGS_RESET_GENERIC = 13, ++ ENA_REGS_RESET_MISS_INTERRUPT = 14, + }; + + /* ena_registers offsets */ +-#define ENA_REGS_VERSION_OFF 0x0 +-#define ENA_REGS_CONTROLLER_VERSION_OFF 0x4 +-#define ENA_REGS_CAPS_OFF 0x8 +-#define ENA_REGS_CAPS_EXT_OFF 0xc +-#define ENA_REGS_AQ_BASE_LO_OFF 0x10 +-#define ENA_REGS_AQ_BASE_HI_OFF 0x14 +-#define ENA_REGS_AQ_CAPS_OFF 0x18 +-#define ENA_REGS_ACQ_BASE_LO_OFF 0x20 +-#define ENA_REGS_ACQ_BASE_HI_OFF 0x24 +-#define ENA_REGS_ACQ_CAPS_OFF 0x28 +-#define ENA_REGS_AQ_DB_OFF 0x2c +-#define ENA_REGS_ACQ_TAIL_OFF 0x30 +-#define ENA_REGS_AENQ_CAPS_OFF 0x34 +-#define ENA_REGS_AENQ_BASE_LO_OFF 0x38 +-#define ENA_REGS_AENQ_BASE_HI_OFF 0x3c +-#define ENA_REGS_AENQ_HEAD_DB_OFF 0x40 +-#define ENA_REGS_AENQ_TAIL_OFF 0x44 +-#define ENA_REGS_INTR_MASK_OFF 0x4c +-#define ENA_REGS_DEV_CTL_OFF 0x54 +-#define ENA_REGS_DEV_STS_OFF 0x58 +-#define ENA_REGS_MMIO_REG_READ_OFF 0x5c +-#define ENA_REGS_MMIO_RESP_LO_OFF 0x60 +-#define ENA_REGS_MMIO_RESP_HI_OFF 0x64 +-#define ENA_REGS_RSS_IND_ENTRY_UPDATE_OFF 0x68 ++ ++/* 0 base */ ++#define ENA_REGS_VERSION_OFF 0x0 ++#define ENA_REGS_CONTROLLER_VERSION_OFF 0x4 ++#define ENA_REGS_CAPS_OFF 0x8 ++#define ENA_REGS_CAPS_EXT_OFF 0xc ++#define ENA_REGS_AQ_BASE_LO_OFF 0x10 ++#define ENA_REGS_AQ_BASE_HI_OFF 0x14 ++#define ENA_REGS_AQ_CAPS_OFF 0x18 ++#define ENA_REGS_ACQ_BASE_LO_OFF 0x20 ++#define ENA_REGS_ACQ_BASE_HI_OFF 0x24 ++#define ENA_REGS_ACQ_CAPS_OFF 0x28 ++#define ENA_REGS_AQ_DB_OFF 0x2c ++#define ENA_REGS_ACQ_TAIL_OFF 0x30 ++#define ENA_REGS_AENQ_CAPS_OFF 0x34 ++#define ENA_REGS_AENQ_BASE_LO_OFF 0x38 ++#define ENA_REGS_AENQ_BASE_HI_OFF 0x3c ++#define ENA_REGS_AENQ_HEAD_DB_OFF 0x40 ++#define ENA_REGS_AENQ_TAIL_OFF 0x44 ++#define ENA_REGS_INTR_MASK_OFF 0x4c ++#define ENA_REGS_DEV_CTL_OFF 0x54 ++#define ENA_REGS_DEV_STS_OFF 0x58 ++#define ENA_REGS_MMIO_REG_READ_OFF 0x5c ++#define ENA_REGS_MMIO_RESP_LO_OFF 0x60 ++#define ENA_REGS_MMIO_RESP_HI_OFF 0x64 ++#define ENA_REGS_RSS_IND_ENTRY_UPDATE_OFF 0x68 + + /* version register */ +-#define ENA_REGS_VERSION_MINOR_VERSION_MASK 0xff +-#define ENA_REGS_VERSION_MAJOR_VERSION_SHIFT 8 +-#define ENA_REGS_VERSION_MAJOR_VERSION_MASK 0xff00 ++#define ENA_REGS_VERSION_MINOR_VERSION_MASK 0xff ++#define ENA_REGS_VERSION_MAJOR_VERSION_SHIFT 8 ++#define ENA_REGS_VERSION_MAJOR_VERSION_MASK 0xff00 + + /* controller_version register */ +-#define ENA_REGS_CONTROLLER_VERSION_SUBMINOR_VERSION_MASK 0xff +-#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_SHIFT 8 +-#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK 0xff00 +-#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT 16 +-#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK 0xff0000 +-#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_SHIFT 24 +-#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_MASK 0xff000000 ++#define ENA_REGS_CONTROLLER_VERSION_SUBMINOR_VERSION_MASK 0xff ++#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_SHIFT 8 ++#define ENA_REGS_CONTROLLER_VERSION_MINOR_VERSION_MASK 0xff00 ++#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_SHIFT 16 ++#define ENA_REGS_CONTROLLER_VERSION_MAJOR_VERSION_MASK 0xff0000 ++#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_SHIFT 24 ++#define ENA_REGS_CONTROLLER_VERSION_IMPL_ID_MASK 0xff000000 + + /* caps register */ +-#define ENA_REGS_CAPS_CONTIGUOUS_QUEUE_REQUIRED_MASK 0x1 +-#define ENA_REGS_CAPS_RESET_TIMEOUT_SHIFT 1 +-#define ENA_REGS_CAPS_RESET_TIMEOUT_MASK 0x3e +-#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_SHIFT 8 +-#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_MASK 0xff00 +-#define ENA_REGS_CAPS_ADMIN_CMD_TO_SHIFT 16 +-#define ENA_REGS_CAPS_ADMIN_CMD_TO_MASK 0xf0000 ++#define ENA_REGS_CAPS_CONTIGUOUS_QUEUE_REQUIRED_MASK 0x1 ++#define ENA_REGS_CAPS_RESET_TIMEOUT_SHIFT 1 ++#define ENA_REGS_CAPS_RESET_TIMEOUT_MASK 0x3e ++#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_SHIFT 8 ++#define ENA_REGS_CAPS_DMA_ADDR_WIDTH_MASK 0xff00 ++#define ENA_REGS_CAPS_ADMIN_CMD_TO_SHIFT 16 ++#define ENA_REGS_CAPS_ADMIN_CMD_TO_MASK 0xf0000 + + /* aq_caps register */ +-#define ENA_REGS_AQ_CAPS_AQ_DEPTH_MASK 0xffff +-#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_SHIFT 16 +-#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_MASK 0xffff0000 ++#define ENA_REGS_AQ_CAPS_AQ_DEPTH_MASK 0xffff ++#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_SHIFT 16 ++#define ENA_REGS_AQ_CAPS_AQ_ENTRY_SIZE_MASK 0xffff0000 + + /* acq_caps register */ +-#define ENA_REGS_ACQ_CAPS_ACQ_DEPTH_MASK 0xffff +-#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_SHIFT 16 +-#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_MASK 0xffff0000 ++#define ENA_REGS_ACQ_CAPS_ACQ_DEPTH_MASK 0xffff ++#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_SHIFT 16 ++#define ENA_REGS_ACQ_CAPS_ACQ_ENTRY_SIZE_MASK 0xffff0000 + + /* aenq_caps register */ +-#define ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK 0xffff +-#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT 16 +-#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK 0xffff0000 ++#define ENA_REGS_AENQ_CAPS_AENQ_DEPTH_MASK 0xffff ++#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_SHIFT 16 ++#define ENA_REGS_AENQ_CAPS_AENQ_ENTRY_SIZE_MASK 0xffff0000 + + /* dev_ctl register */ +-#define ENA_REGS_DEV_CTL_DEV_RESET_MASK 0x1 +-#define ENA_REGS_DEV_CTL_AQ_RESTART_SHIFT 1 +-#define ENA_REGS_DEV_CTL_AQ_RESTART_MASK 0x2 +-#define ENA_REGS_DEV_CTL_QUIESCENT_SHIFT 2 +-#define ENA_REGS_DEV_CTL_QUIESCENT_MASK 0x4 +-#define ENA_REGS_DEV_CTL_IO_RESUME_SHIFT 3 +-#define ENA_REGS_DEV_CTL_IO_RESUME_MASK 0x8 +-#define ENA_REGS_DEV_CTL_RESET_REASON_SHIFT 28 +-#define ENA_REGS_DEV_CTL_RESET_REASON_MASK 0xf0000000 ++#define ENA_REGS_DEV_CTL_DEV_RESET_MASK 0x1 ++#define ENA_REGS_DEV_CTL_AQ_RESTART_SHIFT 1 ++#define ENA_REGS_DEV_CTL_AQ_RESTART_MASK 0x2 ++#define ENA_REGS_DEV_CTL_QUIESCENT_SHIFT 2 ++#define ENA_REGS_DEV_CTL_QUIESCENT_MASK 0x4 ++#define ENA_REGS_DEV_CTL_IO_RESUME_SHIFT 3 ++#define ENA_REGS_DEV_CTL_IO_RESUME_MASK 0x8 ++#define ENA_REGS_DEV_CTL_RESET_REASON_SHIFT 28 ++#define ENA_REGS_DEV_CTL_RESET_REASON_MASK 0xf0000000 + + /* dev_sts register */ +-#define ENA_REGS_DEV_STS_READY_MASK 0x1 +-#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_SHIFT 1 +-#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_MASK 0x2 +-#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_SHIFT 2 +-#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_MASK 0x4 +-#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_SHIFT 3 +-#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_MASK 0x8 +-#define ENA_REGS_DEV_STS_RESET_FINISHED_SHIFT 4 +-#define ENA_REGS_DEV_STS_RESET_FINISHED_MASK 0x10 +-#define ENA_REGS_DEV_STS_FATAL_ERROR_SHIFT 5 +-#define ENA_REGS_DEV_STS_FATAL_ERROR_MASK 0x20 +-#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_SHIFT 6 +-#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_MASK 0x40 +-#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_SHIFT 7 +-#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_MASK 0x80 ++#define ENA_REGS_DEV_STS_READY_MASK 0x1 ++#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_SHIFT 1 ++#define ENA_REGS_DEV_STS_AQ_RESTART_IN_PROGRESS_MASK 0x2 ++#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_SHIFT 2 ++#define ENA_REGS_DEV_STS_AQ_RESTART_FINISHED_MASK 0x4 ++#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_SHIFT 3 ++#define ENA_REGS_DEV_STS_RESET_IN_PROGRESS_MASK 0x8 ++#define ENA_REGS_DEV_STS_RESET_FINISHED_SHIFT 4 ++#define ENA_REGS_DEV_STS_RESET_FINISHED_MASK 0x10 ++#define ENA_REGS_DEV_STS_FATAL_ERROR_SHIFT 5 ++#define ENA_REGS_DEV_STS_FATAL_ERROR_MASK 0x20 ++#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_SHIFT 6 ++#define ENA_REGS_DEV_STS_QUIESCENT_STATE_IN_PROGRESS_MASK 0x40 ++#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_SHIFT 7 ++#define ENA_REGS_DEV_STS_QUIESCENT_STATE_ACHIEVED_MASK 0x80 + + /* mmio_reg_read register */ +-#define ENA_REGS_MMIO_REG_READ_REQ_ID_MASK 0xffff +-#define ENA_REGS_MMIO_REG_READ_REG_OFF_SHIFT 16 +-#define ENA_REGS_MMIO_REG_READ_REG_OFF_MASK 0xffff0000 ++#define ENA_REGS_MMIO_REG_READ_REQ_ID_MASK 0xffff ++#define ENA_REGS_MMIO_REG_READ_REG_OFF_SHIFT 16 ++#define ENA_REGS_MMIO_REG_READ_REG_OFF_MASK 0xffff0000 + + /* rss_ind_entry_update register */ +-#define ENA_REGS_RSS_IND_ENTRY_UPDATE_INDEX_MASK 0xffff +-#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_SHIFT 16 +-#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_MASK 0xffff0000 ++#define ENA_REGS_RSS_IND_ENTRY_UPDATE_INDEX_MASK 0xffff ++#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_SHIFT 16 ++#define ENA_REGS_RSS_IND_ENTRY_UPDATE_CQ_IDX_MASK 0xffff0000 + + #endif /*_ENA_REGS_H_ */ diff --git a/debian/patches/features/all/ena/0015-net-ena-enable-Low-Latency-Queues.patch b/debian/patches/features/all/ena/0015-net-ena-enable-Low-Latency-Queues.patch new file mode 100644 index 000000000..6161a87ba --- /dev/null +++ b/debian/patches/features/all/ena/0015-net-ena-enable-Low-Latency-Queues.patch @@ -0,0 +1,50 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Wed, 17 Oct 2018 15:33:23 +0300 +Subject: [PATCH 15/19] net: ena: enable Low Latency Queues +Origin: https://git.kernel.org/linus/9fd255928d7ffb56d8466fab3331d0b2f40aa8c7 + +Use the new API to enable usage of LLQ. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 18 ++++-------------- + 1 file changed, 4 insertions(+), 14 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3022,20 +3022,10 @@ static int ena_calc_io_queue_num(struct + int io_sq_num, io_queue_num; + + /* In case of LLQ use the llq number in the get feature cmd */ +- if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) { +- io_sq_num = get_feat_ctx->max_queues.max_legacy_llq_num; +- +- if (io_sq_num == 0) { +- dev_err(&pdev->dev, +- "Trying to use LLQ but llq_num is 0. Fall back into regular queues\n"); +- +- ena_dev->tx_mem_queue_type = +- ENA_ADMIN_PLACEMENT_POLICY_HOST; +- io_sq_num = get_feat_ctx->max_queues.max_sq_num; +- } +- } else { ++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ++ io_sq_num = get_feat_ctx->llq.max_llq_num; ++ else + io_sq_num = get_feat_ctx->max_queues.max_sq_num; +- } + + io_queue_num = min_t(int, num_online_cpus(), ENA_MAX_NUM_IO_QUEUES); + io_queue_num = min_t(int, io_queue_num, io_sq_num); +@@ -3238,7 +3228,7 @@ static int ena_calc_queue_size(struct pc + + if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) + queue_size = min_t(u32, queue_size, +- get_feat_ctx->max_queues.max_legacy_llq_depth); ++ get_feat_ctx->llq.max_llq_depth); + + queue_size = rounddown_pow_of_two(queue_size); + diff --git a/debian/patches/features/all/ena/0016-net-ena-fix-compilation-error-in-xtensa-architecture.patch b/debian/patches/features/all/ena/0016-net-ena-fix-compilation-error-in-xtensa-architecture.patch new file mode 100644 index 000000000..b37c7a169 --- /dev/null +++ b/debian/patches/features/all/ena/0016-net-ena-fix-compilation-error-in-xtensa-architecture.patch @@ -0,0 +1,31 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Sun, 21 Oct 2018 18:07:14 +0300 +Subject: [PATCH 16/19] net: ena: fix compilation error in xtensa architecture +Origin: https://git.kernel.org/linus/00f17a8219f02139119d8b4547e032bf4888fa0d + +linux/prefetch.h is never explicitly included in ena_com, although +functions from it, such as prefetchw(), are used throughout ena_com. +This is an inclusion bug, and we fix it here by explicitly including +linux/prefetch.h. The bug was exposed when the driver was compiled +for the xtensa architecture. + +Fixes: 689b2bdaaa14 ("net: ena: add functions for handling Low Latency Queues in ena_com") +Fixes: 8c590f977638 ("ena: Fix Kconfig dependency on X86") +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.h | 1 + + 1 file changed, 1 insertion(+) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -38,6 +38,7 @@ + #include <linux/dma-mapping.h> + #include <linux/gfp.h> + #include <linux/io.h> ++#include <linux/prefetch.h> + #include <linux/sched.h> + #include <linux/sizes.h> + #include <linux/spinlock.h> diff --git a/debian/patches/features/all/ena/0017-net-ena-fix-crash-during-ena_remove.patch b/debian/patches/features/all/ena/0017-net-ena-fix-crash-during-ena_remove.patch new file mode 100644 index 000000000..59f2b13b7 --- /dev/null +++ b/debian/patches/features/all/ena/0017-net-ena-fix-crash-during-ena_remove.patch @@ -0,0 +1,97 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 19 Nov 2018 12:05:21 +0200 +Subject: [PATCH 18/19] net: ena: fix crash during ena_remove() +Origin: https://git.kernel.org/linus/58a54b9c62e206b8d5f6e59020bcb178fc271d8e + +In ena_remove() we have the following stack call: +ena_remove() + unregister_netdev() + ena_destroy_device() + netif_carrier_off() + +Calling netif_carrier_off() causes linkwatch to try to handle the +link change event on the already unregistered netdev, which leads +to a read from an unreadable memory address. + +This patch switches the order of the two functions, so that +netif_carrier_off() is called on a regiestered netdev. + +To accomplish this fix we also had to: +1. Remove the set bit ENA_FLAG_TRIGGER_RESET +2. Add a sanitiy check in ena_close() +both to prevent double device reset (when calling unregister_netdev() +ena_close is called, but the device was already deleted in +ena_destroy_device()). +3. Set the admin_queue running state to false to avoid using it after +device was reset (for example when calling ena_destroy_all_io_queues() +right after ena_com_dev_reset() in ena_down) + +Fixes: 944b28aa2982 ("net: ena: fix missing lock during device destruction") +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 21 ++++++++++---------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -1853,6 +1853,8 @@ static void ena_down(struct ena_adapter + rc = ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); + if (rc) + dev_err(&adapter->pdev->dev, "Device reset failed\n"); ++ /* stop submitting admin commands on a device that was reset */ ++ ena_com_set_admin_running_state(adapter->ena_dev, false); + } + + ena_destroy_all_io_queues(adapter); +@@ -1919,6 +1921,9 @@ static int ena_close(struct net_device * + + netif_dbg(adapter, ifdown, netdev, "%s\n", __func__); + ++ if (!test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) ++ return 0; ++ + if (test_bit(ENA_FLAG_DEV_UP, &adapter->flags)) + ena_down(adapter); + +@@ -2618,9 +2623,7 @@ static void ena_destroy_device(struct en + ena_down(adapter); + + /* Stop the device from sending AENQ events (in case reset flag is set +- * and device is up, ena_close already reset the device +- * In case the reset flag is set and the device is up, ena_down() +- * already perform the reset, so it can be skipped. ++ * and device is up, ena_down() already reset the device. + */ + if (!(test_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags) && dev_up)) + ena_com_dev_reset(adapter->ena_dev, adapter->reset_reason); +@@ -3455,6 +3458,8 @@ err_rss: + ena_com_rss_destroy(ena_dev); + err_free_msix: + ena_com_dev_reset(ena_dev, ENA_REGS_RESET_INIT_ERR); ++ /* stop submitting admin commands on a device that was reset */ ++ ena_com_set_admin_running_state(ena_dev, false); + ena_free_mgmnt_irq(adapter); + ena_disable_msix(adapter); + err_worker_destroy: +@@ -3504,18 +3509,12 @@ static void ena_remove(struct pci_dev *p + del_timer_sync(&adapter->timer_service); + cancel_work_sync(&adapter->reset_task); + +- unregister_netdev(netdev); +- +- /* If the device is running then we want to make sure the device will be +- * reset to make sure no more events will be issued by the device. +- */ +- if (test_bit(ENA_FLAG_DEVICE_RUNNING, &adapter->flags)) +- set_bit(ENA_FLAG_TRIGGER_RESET, &adapter->flags); +- + rtnl_lock(); + ena_destroy_device(adapter, true); + rtnl_unlock(); + ++ unregister_netdev(netdev); ++ + free_netdev(netdev); + + ena_com_rss_destroy(ena_dev); diff --git a/debian/patches/features/all/ena/0018-net-ena-update-driver-version-from-2.0.1-to-2.0.2.patch b/debian/patches/features/all/ena/0018-net-ena-update-driver-version-from-2.0.1-to-2.0.2.patch new file mode 100644 index 000000000..68194bdc9 --- /dev/null +++ b/debian/patches/features/all/ena/0018-net-ena-update-driver-version-from-2.0.1-to-2.0.2.patch @@ -0,0 +1,26 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 19 Nov 2018 12:05:22 +0200 +Subject: [PATCH 19/19] net: ena: update driver version from 2.0.1 to 2.0.2 +Origin: https://git.kernel.org/linus/4c23738a3f9f203a9b41c89e030eaa8ee241f90f + +Update driver version due to critical bug fixes. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -45,7 +45,7 @@ + + #define DRV_MODULE_VER_MAJOR 2 + #define DRV_MODULE_VER_MINOR 0 +-#define DRV_MODULE_VER_SUBMINOR 1 ++#define DRV_MODULE_VER_SUBMINOR 2 + + #define DRV_MODULE_NAME "ena" + #ifndef DRV_MODULE_VERSION diff --git a/debian/patches/features/all/ena/net-ena-Fix-bug-where-ring-allocation-backoff-stoppe.patch b/debian/patches/features/all/ena/net-ena-Fix-bug-where-ring-allocation-backoff-stoppe.patch new file mode 100644 index 000000000..d2e7da1ab --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-Fix-bug-where-ring-allocation-backoff-stoppe.patch @@ -0,0 +1,39 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Sun, 23 Jun 2019 10:11:10 +0300 +Subject: [PATCH] net: ena: Fix bug where ring allocation backoff stopped too + late +Origin: https://git.kernel.org/linus/3e5bfb189e1a65df132fd0e3fa00fbb6feec1431 +Bug-Debian: https://bugs.debian.org/941291 + +The current code of create_queues_with_size_backoff() allows the ring size +to become as small as ENA_MIN_RING_SIZE/2. This is a bug since we don't +want the queue ring to be smaller than ENA_MIN_RING_SIZE + +In this commit we change the loop's termination condition to look at the +queue size of the next iteration instead of that of the current one, +so that the minimal queue size again becomes ENA_MIN_RING_SIZE. + +Fixes: eece4d2ab9d2 ("net: ena: add ethtool function for changing io queue sizes") + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -1836,8 +1836,8 @@ err_setup_tx: + if (cur_rx_ring_size >= cur_tx_ring_size) + new_rx_ring_size = cur_rx_ring_size / 2; + +- if (cur_tx_ring_size < ENA_MIN_RING_SIZE || +- cur_rx_ring_size < ENA_MIN_RING_SIZE) { ++ if (new_tx_ring_size < ENA_MIN_RING_SIZE || ++ new_rx_ring_size < ENA_MIN_RING_SIZE) { + netif_err(adapter, ifup, adapter->netdev, + "Queue creation failed with the smallest possible queue size of %d for both queues. Not retrying with smaller queues\n", + ENA_MIN_RING_SIZE); diff --git a/debian/patches/features/all/ena/net-ena-add-MAX_QUEUES_EXT-get-feature-admin-command.patch b/debian/patches/features/all/ena/net-ena-add-MAX_QUEUES_EXT-get-feature-admin-command.patch new file mode 100644 index 000000000..bf790f061 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-add-MAX_QUEUES_EXT-get-feature-admin-command.patch @@ -0,0 +1,345 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Tue, 11 Jun 2019 14:58:05 +0300 +Subject: [PATCH] net: ena: add MAX_QUEUES_EXT get feature admin command +Origin: https://git.kernel.org/linus/ba8ef506fb91005fc4808370b7587ab7bf4bd918 +Bug-Debian: https://bugs.debian.org/941291 + +Add a new admin command to support different queue size for Tx/Rx +queues (the change also support different SQ/CQ sizes) + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + .../net/ethernet/amazon/ena/ena_admin_defs.h | 56 +++++++++++++- + drivers/net/ethernet/amazon/ena/ena_com.c | 76 ++++++++++++------- + drivers/net/ethernet/amazon/ena/ena_com.h | 3 + + 3 files changed, 105 insertions(+), 30 deletions(-) + +--- a/drivers/net/ethernet/amazon/ena/ena_admin_defs.h ++++ b/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +@@ -60,6 +60,7 @@ enum ena_admin_aq_feature_id { + ENA_ADMIN_MAX_QUEUES_NUM = 2, + ENA_ADMIN_HW_HINTS = 3, + ENA_ADMIN_LLQ = 4, ++ ENA_ADMIN_MAX_QUEUES_EXT = 7, + ENA_ADMIN_RSS_HASH_FUNCTION = 10, + ENA_ADMIN_STATELESS_OFFLOAD_CONFIG = 11, + ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG = 12, +@@ -421,7 +422,13 @@ struct ena_admin_get_set_feature_common_ + /* as appears in ena_admin_aq_feature_id */ + u8 feature_id; + +- u16 reserved16; ++ /* The driver specifies the max feature version it supports and the ++ * device responds with the currently supported feature version. The ++ * field is zero based ++ */ ++ u8 feature_version; ++ ++ u8 reserved8; + }; + + struct ena_admin_device_attr_feature_desc { +@@ -531,6 +538,34 @@ struct ena_admin_feature_llq_desc { + u32 max_tx_burst_size; + }; + ++struct ena_admin_queue_ext_feature_fields { ++ u32 max_tx_sq_num; ++ ++ u32 max_tx_cq_num; ++ ++ u32 max_rx_sq_num; ++ ++ u32 max_rx_cq_num; ++ ++ u32 max_tx_sq_depth; ++ ++ u32 max_tx_cq_depth; ++ ++ u32 max_rx_sq_depth; ++ ++ u32 max_rx_cq_depth; ++ ++ u32 max_tx_header_size; ++ ++ /* Maximum Descriptors number, including meta descriptor, allowed for ++ * a single Tx packet ++ */ ++ u16 max_per_packet_tx_descs; ++ ++ /* Maximum Descriptors number allowed for a single Rx packet */ ++ u16 max_per_packet_rx_descs; ++}; ++ + struct ena_admin_queue_feature_desc { + u32 max_sq_num; + +@@ -837,6 +872,19 @@ struct ena_admin_get_feat_cmd { + u32 raw[11]; + }; + ++struct ena_admin_queue_ext_feature_desc { ++ /* version */ ++ u8 version; ++ ++ u8 reserved1[3]; ++ ++ union { ++ struct ena_admin_queue_ext_feature_fields max_queue_ext; ++ ++ u32 raw[10]; ++ }; ++}; ++ + struct ena_admin_get_feat_resp { + struct ena_admin_acq_common_desc acq_common_desc; + +@@ -849,6 +897,8 @@ struct ena_admin_get_feat_resp { + + struct ena_admin_queue_feature_desc max_queue; + ++ struct ena_admin_queue_ext_feature_desc max_queue_ext; ++ + struct ena_admin_feature_aenq_desc aenq; + + struct ena_admin_get_feature_link_desc link; +@@ -913,7 +963,9 @@ struct ena_admin_aenq_common_desc { + + u16 syndrom; + +- /* 0 : phase */ ++ /* 0 : phase ++ * 7:1 : reserved - MBZ ++ */ + u8 flags; + + u8 reserved1[3]; +--- a/drivers/net/ethernet/amazon/ena/ena_com.c ++++ b/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -983,7 +983,8 @@ static int ena_com_get_feature_ex(struct + struct ena_admin_get_feat_resp *get_resp, + enum ena_admin_aq_feature_id feature_id, + dma_addr_t control_buf_dma_addr, +- u32 control_buff_size) ++ u32 control_buff_size, ++ u8 feature_ver) + { + struct ena_com_admin_queue *admin_queue; + struct ena_admin_get_feat_cmd get_cmd; +@@ -1014,7 +1015,7 @@ static int ena_com_get_feature_ex(struct + } + + get_cmd.control_buffer.length = control_buff_size; +- ++ get_cmd.feat_common.feature_version = feature_ver; + get_cmd.feat_common.feature_id = feature_id; + + ret = ena_com_execute_admin_command(admin_queue, +@@ -1034,13 +1035,15 @@ static int ena_com_get_feature_ex(struct + + static int ena_com_get_feature(struct ena_com_dev *ena_dev, + struct ena_admin_get_feat_resp *get_resp, +- enum ena_admin_aq_feature_id feature_id) ++ enum ena_admin_aq_feature_id feature_id, ++ u8 feature_ver) + { + return ena_com_get_feature_ex(ena_dev, + get_resp, + feature_id, + 0, +- 0); ++ 0, ++ feature_ver); + } + + static void ena_com_hash_key_fill_default_key(struct ena_com_dev *ena_dev) +@@ -1118,7 +1121,7 @@ static int ena_com_indirect_table_alloca + int ret; + + ret = ena_com_get_feature(ena_dev, &get_resp, +- ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG); ++ ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG, 0); + if (unlikely(ret)) + return ret; + +@@ -1538,7 +1541,7 @@ int ena_com_set_aenq_config(struct ena_c + struct ena_admin_get_feat_resp get_resp; + int ret; + +- ret = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_AENQ_CONFIG); ++ ret = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_AENQ_CONFIG, 0); + if (ret) { + pr_info("Can't get aenq configuration\n"); + return ret; +@@ -1913,7 +1916,7 @@ void ena_com_destroy_io_queue(struct ena + int ena_com_get_link_params(struct ena_com_dev *ena_dev, + struct ena_admin_get_feat_resp *resp) + { +- return ena_com_get_feature(ena_dev, resp, ENA_ADMIN_LINK_CONFIG); ++ return ena_com_get_feature(ena_dev, resp, ENA_ADMIN_LINK_CONFIG, 0); + } + + int ena_com_get_dev_attr_feat(struct ena_com_dev *ena_dev, +@@ -1923,7 +1926,7 @@ int ena_com_get_dev_attr_feat(struct ena + int rc; + + rc = ena_com_get_feature(ena_dev, &get_resp, +- ENA_ADMIN_DEVICE_ATTRIBUTES); ++ ENA_ADMIN_DEVICE_ATTRIBUTES, 0); + if (rc) + return rc; + +@@ -1931,17 +1934,34 @@ int ena_com_get_dev_attr_feat(struct ena + sizeof(get_resp.u.dev_attr)); + ena_dev->supported_features = get_resp.u.dev_attr.supported_features; + +- rc = ena_com_get_feature(ena_dev, &get_resp, +- ENA_ADMIN_MAX_QUEUES_NUM); +- if (rc) +- return rc; ++ if (ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) { ++ rc = ena_com_get_feature(ena_dev, &get_resp, ++ ENA_ADMIN_MAX_QUEUES_EXT, ++ ENA_FEATURE_MAX_QUEUE_EXT_VER); ++ if (rc) ++ return rc; + +- memcpy(&get_feat_ctx->max_queues, &get_resp.u.max_queue, +- sizeof(get_resp.u.max_queue)); +- ena_dev->tx_max_header_size = get_resp.u.max_queue.max_header_size; ++ if (get_resp.u.max_queue_ext.version != ENA_FEATURE_MAX_QUEUE_EXT_VER) ++ return -EINVAL; ++ ++ memcpy(&get_feat_ctx->max_queue_ext, &get_resp.u.max_queue_ext, ++ sizeof(get_resp.u.max_queue_ext)); ++ ena_dev->tx_max_header_size = ++ get_resp.u.max_queue_ext.max_queue_ext.max_tx_header_size; ++ } else { ++ rc = ena_com_get_feature(ena_dev, &get_resp, ++ ENA_ADMIN_MAX_QUEUES_NUM, 0); ++ memcpy(&get_feat_ctx->max_queues, &get_resp.u.max_queue, ++ sizeof(get_resp.u.max_queue)); ++ ena_dev->tx_max_header_size = ++ get_resp.u.max_queue.max_header_size; ++ ++ if (rc) ++ return rc; ++ } + + rc = ena_com_get_feature(ena_dev, &get_resp, +- ENA_ADMIN_AENQ_CONFIG); ++ ENA_ADMIN_AENQ_CONFIG, 0); + if (rc) + return rc; + +@@ -1949,7 +1969,7 @@ int ena_com_get_dev_attr_feat(struct ena + sizeof(get_resp.u.aenq)); + + rc = ena_com_get_feature(ena_dev, &get_resp, +- ENA_ADMIN_STATELESS_OFFLOAD_CONFIG); ++ ENA_ADMIN_STATELESS_OFFLOAD_CONFIG, 0); + if (rc) + return rc; + +@@ -1959,7 +1979,7 @@ int ena_com_get_dev_attr_feat(struct ena + /* Driver hints isn't mandatory admin command. So in case the + * command isn't supported set driver hints to 0 + */ +- rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_HW_HINTS); ++ rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_HW_HINTS, 0); + + if (!rc) + memcpy(&get_feat_ctx->hw_hints, &get_resp.u.hw_hints, +@@ -1970,7 +1990,7 @@ int ena_com_get_dev_attr_feat(struct ena + else + return rc; + +- rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_LLQ); ++ rc = ena_com_get_feature(ena_dev, &get_resp, ENA_ADMIN_LLQ, 0); + if (!rc) + memcpy(&get_feat_ctx->llq, &get_resp.u.llq, + sizeof(get_resp.u.llq)); +@@ -2208,7 +2228,7 @@ int ena_com_get_offload_settings(struct + struct ena_admin_get_feat_resp resp; + + ret = ena_com_get_feature(ena_dev, &resp, +- ENA_ADMIN_STATELESS_OFFLOAD_CONFIG); ++ ENA_ADMIN_STATELESS_OFFLOAD_CONFIG, 0); + if (unlikely(ret)) { + pr_err("Failed to get offload capabilities %d\n", ret); + return ret; +@@ -2237,7 +2257,7 @@ int ena_com_set_hash_function(struct ena + + /* Validate hash function is supported */ + ret = ena_com_get_feature(ena_dev, &get_resp, +- ENA_ADMIN_RSS_HASH_FUNCTION); ++ ENA_ADMIN_RSS_HASH_FUNCTION, 0); + if (unlikely(ret)) + return ret; + +@@ -2297,7 +2317,7 @@ int ena_com_fill_hash_function(struct en + rc = ena_com_get_feature_ex(ena_dev, &get_resp, + ENA_ADMIN_RSS_HASH_FUNCTION, + rss->hash_key_dma_addr, +- sizeof(*rss->hash_key)); ++ sizeof(*rss->hash_key), 0); + if (unlikely(rc)) + return rc; + +@@ -2350,7 +2370,7 @@ int ena_com_get_hash_function(struct ena + rc = ena_com_get_feature_ex(ena_dev, &get_resp, + ENA_ADMIN_RSS_HASH_FUNCTION, + rss->hash_key_dma_addr, +- sizeof(*rss->hash_key)); ++ sizeof(*rss->hash_key), 0); + if (unlikely(rc)) + return rc; + +@@ -2379,7 +2399,7 @@ int ena_com_get_hash_ctrl(struct ena_com + rc = ena_com_get_feature_ex(ena_dev, &get_resp, + ENA_ADMIN_RSS_HASH_INPUT, + rss->hash_ctrl_dma_addr, +- sizeof(*rss->hash_ctrl)); ++ sizeof(*rss->hash_ctrl), 0); + if (unlikely(rc)) + return rc; + +@@ -2615,7 +2635,7 @@ int ena_com_indirect_table_get(struct en + rc = ena_com_get_feature_ex(ena_dev, &get_resp, + ENA_ADMIN_RSS_REDIRECTION_TABLE_CONFIG, + rss->rss_ind_tbl_dma_addr, +- tbl_size); ++ tbl_size, 0); + if (unlikely(rc)) + return rc; + +@@ -2831,7 +2851,7 @@ int ena_com_init_interrupt_moderation(st + int rc; + + rc = ena_com_get_feature(ena_dev, &get_resp, +- ENA_ADMIN_INTERRUPT_MODERATION); ++ ENA_ADMIN_INTERRUPT_MODERATION, 0); + + if (rc) { + if (rc == -EOPNOTSUPP) { +--- a/drivers/net/ethernet/amazon/ena/ena_com.h ++++ b/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -102,6 +102,8 @@ + + #define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF + ++#define ENA_FEATURE_MAX_QUEUE_EXT_VER 1 ++ + enum ena_intr_moder_level { + ENA_INTR_MODER_LOWEST = 0, + ENA_INTR_MODER_LOW, +@@ -383,6 +385,7 @@ struct ena_com_dev { + + struct ena_com_dev_get_features_ctx { + struct ena_admin_queue_feature_desc max_queues; ++ struct ena_admin_queue_ext_feature_desc max_queue_ext; + struct ena_admin_device_attr_feature_desc dev_attr; + struct ena_admin_feature_aenq_desc aenq; + struct ena_admin_feature_offload_desc offload; diff --git a/debian/patches/features/all/ena/net-ena-add-ethtool-function-for-changing-io-queue-s.patch b/debian/patches/features/all/ena/net-ena-add-ethtool-function-for-changing-io-queue-s.patch new file mode 100644 index 000000000..227f39b3b --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-add-ethtool-function-for-changing-io-queue-s.patch @@ -0,0 +1,106 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Tue, 11 Jun 2019 14:58:09 +0300 +Subject: [PATCH] net: ena: add ethtool function for changing io queue sizes +Origin: https://git.kernel.org/linus/eece4d2ab9d214e3b12f5ac1ed189a05793b28a5 +Bug-Debian: https://bugs.debian.org/941291 + +Implement the set_ringparam() function of the ethtool interface +to enable the changing of io queue sizes. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 22 +++++++++++++++++++ + drivers/net/ethernet/amazon/ena/ena_netdev.c | 14 ++++++++++++ + drivers/net/ethernet/amazon/ena/ena_netdev.h | 5 ++++- + 3 files changed, 40 insertions(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -454,6 +454,27 @@ static void ena_get_ringparam(struct net + ring->rx_pending = adapter->rx_ring[0].ring_size; + } + ++static int ena_set_ringparam(struct net_device *netdev, ++ struct ethtool_ringparam *ring) ++{ ++ struct ena_adapter *adapter = netdev_priv(netdev); ++ u32 new_tx_size, new_rx_size; ++ ++ new_tx_size = ring->tx_pending < ENA_MIN_RING_SIZE ? ++ ENA_MIN_RING_SIZE : ring->tx_pending; ++ new_tx_size = rounddown_pow_of_two(new_tx_size); ++ ++ new_rx_size = ring->rx_pending < ENA_MIN_RING_SIZE ? ++ ENA_MIN_RING_SIZE : ring->rx_pending; ++ new_rx_size = rounddown_pow_of_two(new_rx_size); ++ ++ if (new_tx_size == adapter->requested_tx_ring_size && ++ new_rx_size == adapter->requested_rx_ring_size) ++ return 0; ++ ++ return ena_update_queue_sizes(adapter, new_tx_size, new_rx_size); ++} ++ + static u32 ena_flow_hash_to_flow_type(u16 hash_fields) + { + u32 data = 0; +@@ -805,6 +826,7 @@ static const struct ethtool_ops ena_etht + .get_coalesce = ena_get_coalesce, + .set_coalesce = ena_set_coalesce, + .get_ringparam = ena_get_ringparam, ++ .set_ringparam = ena_set_ringparam, + .get_sset_count = ena_get_sset_count, + .get_strings = ena_get_strings, + .get_ethtool_stats = ena_get_ethtool_stats, +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -2028,6 +2028,20 @@ static int ena_close(struct net_device * + return 0; + } + ++int ena_update_queue_sizes(struct ena_adapter *adapter, ++ u32 new_tx_size, ++ u32 new_rx_size) ++{ ++ bool dev_up; ++ ++ dev_up = test_bit(ENA_FLAG_DEV_UP, &adapter->flags); ++ ena_close(adapter->netdev); ++ adapter->requested_tx_ring_size = new_tx_size; ++ adapter->requested_rx_ring_size = new_rx_size; ++ ena_init_io_rings(adapter); ++ return dev_up ? ena_up(adapter) : 0; ++} ++ + static void ena_tx_csum(struct ena_com_tx_ctx *ena_tx_ctx, struct sk_buff *skb) + { + u32 mss = skb_shinfo(skb)->gso_size; +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -81,7 +81,6 @@ + #define ENA_DEFAULT_RING_SIZE (1024) + #define ENA_MIN_RING_SIZE (256) + +- + #define ENA_TX_WAKEUP_THRESH (MAX_SKB_FRAGS + 2) + #define ENA_DEFAULT_RX_COPYBREAK (256 - NET_IP_ALIGN) + +@@ -386,6 +385,10 @@ void ena_dump_stats_to_dmesg(struct ena_ + + void ena_dump_stats_to_buf(struct ena_adapter *adapter, u8 *buf); + ++int ena_update_queue_sizes(struct ena_adapter *adapter, ++ u32 new_tx_size, ++ u32 new_rx_size); ++ + int ena_get_sset_count(struct net_device *netdev, int sset); + + #endif /* !(ENA_H) */ diff --git a/debian/patches/features/all/ena/net-ena-add-good-checksum-counter.patch b/debian/patches/features/all/ena/net-ena-add-good-checksum-counter.patch new file mode 100644 index 000000000..cde5cdad4 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-add-good-checksum-counter.patch @@ -0,0 +1,72 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Mon, 3 Jun 2019 17:43:28 +0300 +Subject: [PATCH] net: ena: add good checksum counter +Origin: https://git.kernel.org/linus/d2eecc6ee8c92053797513e34931334dd0e85e18 +Bug-Debian: https://bugs.debian.org/941291 + +Add a new statistics to ETHTOOL to specify if the device calculated +and validated the Rx csum. + +Signed-off-by: Evgeny Shmeilin <evgeny@annapurnaLabs.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 3 ++- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 +++ + drivers/net/ethernet/amazon/ena/ena_netdev.h | 3 ++- + 3 files changed, 7 insertions(+), 2 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -88,13 +88,14 @@ static const struct ena_stats ena_stats_ + static const struct ena_stats ena_stats_rx_strings[] = { + ENA_STAT_RX_ENTRY(cnt), + ENA_STAT_RX_ENTRY(bytes), ++ ENA_STAT_RX_ENTRY(rx_copybreak_pkt), ++ ENA_STAT_RX_ENTRY(csum_good), + ENA_STAT_RX_ENTRY(refil_partial), + ENA_STAT_RX_ENTRY(bad_csum), + ENA_STAT_RX_ENTRY(page_alloc_fail), + ENA_STAT_RX_ENTRY(skb_alloc_fail), + ENA_STAT_RX_ENTRY(dma_mapping_err), + ENA_STAT_RX_ENTRY(bad_desc_num), +- ENA_STAT_RX_ENTRY(rx_copybreak_pkt), + ENA_STAT_RX_ENTRY(bad_req_id), + ENA_STAT_RX_ENTRY(empty_rx_ring), + ENA_STAT_RX_ENTRY(csum_unchecked), +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -1001,6 +1001,9 @@ static inline void ena_rx_checksum(struc + + if (likely(ena_rx_ctx->l4_csum_checked)) { + skb->ip_summed = CHECKSUM_UNNECESSARY; ++ u64_stats_update_begin(&rx_ring->syncp); ++ rx_ring->rx_stats.csum_good++; ++ u64_stats_update_end(&rx_ring->syncp); + } else { + u64_stats_update_begin(&rx_ring->syncp); + rx_ring->rx_stats.csum_unchecked++; +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -221,13 +221,14 @@ struct ena_stats_tx { + struct ena_stats_rx { + u64 cnt; + u64 bytes; ++ u64 rx_copybreak_pkt; ++ u64 csum_good; + u64 refil_partial; + u64 bad_csum; + u64 page_alloc_fail; + u64 skb_alloc_fail; + u64 dma_mapping_err; + u64 bad_desc_num; +- u64 rx_copybreak_pkt; + u64 bad_req_id; + u64 empty_rx_ring; + u64 csum_unchecked; diff --git a/debian/patches/features/all/ena/net-ena-add-handling-of-llq-max-tx-burst-size.patch b/debian/patches/features/all/ena/net-ena-add-handling-of-llq-max-tx-burst-size.patch new file mode 100644 index 000000000..4034439eb --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-add-handling-of-llq-max-tx-burst-size.patch @@ -0,0 +1,232 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Mon, 3 Jun 2019 17:43:19 +0300 +Subject: [PATCH] net: ena: add handling of llq max tx burst size +Origin: https://git.kernel.org/linus/05d62ca218f8425c70389d0416c15bd0d455b416 +Bug-Debian: https://bugs.debian.org/941291 + +There is a maximum TX burst size that the ENA device can handle. +It is exposed by the device to the driver and the driver +needs to comply with it to avoid bugs. + +In this commit we: +1. Add ena_com_is_doorbell_needed(), which calculates the number of + llq entries that will be used to hold a packet, and will return + true if they exceed the number of allowed entries in a burst. + If the function returns true, a doorbell needs to be invoked + to send this packet in the next burst. + +2. Follow the available entries in the current burst: + - Every doorbell a new burst begins + - With each write of an llq entry, the available entries in the + current burst are decreased by 1. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + .../net/ethernet/amazon/ena/ena_admin_defs.h | 5 ++ + drivers/net/ethernet/amazon/ena/ena_com.c | 7 +++ + drivers/net/ethernet/amazon/ena/ena_com.h | 2 + + drivers/net/ethernet/amazon/ena/ena_eth_com.c | 28 ++++------ + drivers/net/ethernet/amazon/ena/ena_eth_com.h | 53 +++++++++++++++++++ + drivers/net/ethernet/amazon/ena/ena_netdev.c | 7 +++ + 6 files changed, 85 insertions(+), 17 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +@@ -524,6 +524,11 @@ struct ena_admin_feature_llq_desc { + + /* the stride control the driver selected to use */ + u16 descriptors_stride_ctrl_enabled; ++ ++ /* Maximum size in bytes taken by llq entries in a single tx burst. ++ * Set to 0 when there is no such limit. ++ */ ++ u32 max_tx_burst_size; + }; + + struct ena_admin_queue_feature_desc { +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -396,6 +396,10 @@ static int ena_com_init_io_sq(struct ena + 0x0, io_sq->llq_info.desc_list_entry_size); + io_sq->llq_buf_ctrl.descs_left_in_line = + io_sq->llq_info.descs_num_before_header; ++ ++ if (io_sq->llq_info.max_entries_in_tx_burst > 0) ++ io_sq->entries_in_tx_burst_left = ++ io_sq->llq_info.max_entries_in_tx_burst; + } + + io_sq->tail = 0; +@@ -727,6 +731,9 @@ static int ena_com_config_llq_info(struc + supported_feat, llq_info->descs_num_before_header); + } + ++ llq_info->max_entries_in_tx_burst = ++ (u16)(llq_features->max_tx_burst_size / llq_default_cfg->llq_ring_entry_size_value); ++ + rc = ena_com_set_llq(ena_dev); + if (rc) + pr_err("Cannot set LLQ configuration: %d\n", rc); +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -159,6 +159,7 @@ struct ena_com_llq_info { + u16 desc_list_entry_size; + u16 descs_num_before_header; + u16 descs_per_entry; ++ u16 max_entries_in_tx_burst; + }; + + struct ena_com_io_cq { +@@ -238,6 +239,7 @@ struct ena_com_io_sq { + u8 phase; + u8 desc_entry_size; + u8 dma_addr_bits; ++ u16 entries_in_tx_burst_left; + } ____cacheline_aligned; + + struct ena_com_admin_cq { +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +@@ -82,6 +82,17 @@ static inline int ena_com_write_bounce_b + dst_tail_mask = io_sq->tail & (io_sq->q_depth - 1); + dst_offset = dst_tail_mask * llq_info->desc_list_entry_size; + ++ if (is_llq_max_tx_burst_exists(io_sq)) { ++ if (unlikely(!io_sq->entries_in_tx_burst_left)) { ++ pr_err("Error: trying to send more packets than tx burst allows\n"); ++ return -ENOSPC; ++ } ++ ++ io_sq->entries_in_tx_burst_left--; ++ pr_debug("decreasing entries_in_tx_burst_left of queue %d to %d\n", ++ io_sq->qid, io_sq->entries_in_tx_burst_left); ++ } ++ + /* Make sure everything was written into the bounce buffer before + * writing the bounce buffer to the device + */ +@@ -274,23 +285,6 @@ static inline u16 ena_com_cdesc_rx_pkt_g + return count; + } + +-static inline bool ena_com_meta_desc_changed(struct ena_com_io_sq *io_sq, +- struct ena_com_tx_ctx *ena_tx_ctx) +-{ +- int rc; +- +- if (ena_tx_ctx->meta_valid) { +- rc = memcmp(&io_sq->cached_tx_meta, +- &ena_tx_ctx->ena_meta, +- sizeof(struct ena_com_tx_meta)); +- +- if (unlikely(rc != 0)) +- return true; +- } +- +- return false; +-} +- + static inline int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, + struct ena_com_tx_ctx *ena_tx_ctx) + { +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.h +@@ -125,8 +125,55 @@ static inline bool ena_com_sq_have_enoug + return ena_com_free_desc(io_sq) > temp; + } + ++static inline bool ena_com_meta_desc_changed(struct ena_com_io_sq *io_sq, ++ struct ena_com_tx_ctx *ena_tx_ctx) ++{ ++ if (!ena_tx_ctx->meta_valid) ++ return false; ++ ++ return !!memcmp(&io_sq->cached_tx_meta, ++ &ena_tx_ctx->ena_meta, ++ sizeof(struct ena_com_tx_meta)); ++} ++ ++static inline bool is_llq_max_tx_burst_exists(struct ena_com_io_sq *io_sq) ++{ ++ return (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) && ++ io_sq->llq_info.max_entries_in_tx_burst > 0; ++} ++ ++static inline bool ena_com_is_doorbell_needed(struct ena_com_io_sq *io_sq, ++ struct ena_com_tx_ctx *ena_tx_ctx) ++{ ++ struct ena_com_llq_info *llq_info; ++ int descs_after_first_entry; ++ int num_entries_needed = 1; ++ u16 num_descs; ++ ++ if (!is_llq_max_tx_burst_exists(io_sq)) ++ return false; ++ ++ llq_info = &io_sq->llq_info; ++ num_descs = ena_tx_ctx->num_bufs; ++ ++ if (unlikely(ena_com_meta_desc_changed(io_sq, ena_tx_ctx))) ++ ++num_descs; ++ ++ if (num_descs > llq_info->descs_num_before_header) { ++ descs_after_first_entry = num_descs - llq_info->descs_num_before_header; ++ num_entries_needed += DIV_ROUND_UP(descs_after_first_entry, ++ llq_info->descs_per_entry); ++ } ++ ++ pr_debug("queue: %d num_descs: %d num_entries_needed: %d\n", io_sq->qid, ++ num_descs, num_entries_needed); ++ ++ return num_entries_needed > io_sq->entries_in_tx_burst_left; ++} ++ + static inline int ena_com_write_sq_doorbell(struct ena_com_io_sq *io_sq) + { ++ u16 max_entries_in_tx_burst = io_sq->llq_info.max_entries_in_tx_burst; + u16 tail = io_sq->tail; + + pr_debug("write submission queue doorbell for queue: %d tail: %d\n", +@@ -134,6 +181,12 @@ static inline int ena_com_write_sq_doorb + + writel(tail, io_sq->db_addr); + ++ if (is_llq_max_tx_burst_exists(io_sq)) { ++ pr_debug("reset available entries in tx burst for queue %d to %d\n", ++ io_sq->qid, max_entries_in_tx_burst); ++ io_sq->entries_in_tx_burst_left = max_entries_in_tx_burst; ++ } ++ + return 0; + } + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -2172,6 +2172,13 @@ static netdev_tx_t ena_start_xmit(struct + /* set flags and meta data */ + ena_tx_csum(&ena_tx_ctx, skb); + ++ if (unlikely(ena_com_is_doorbell_needed(tx_ring->ena_com_io_sq, &ena_tx_ctx))) { ++ netif_dbg(adapter, tx_queued, dev, ++ "llq tx max burst size of queue %d achieved, writing doorbell to send burst\n", ++ qid); ++ ena_com_write_sq_doorbell(tx_ring->ena_com_io_sq); ++ } ++ + /* prepare the packet's descriptors to dma engine */ + rc = ena_com_prepare_tx(tx_ring->ena_com_io_sq, &ena_tx_ctx, + &nb_hw_desc); diff --git a/debian/patches/features/all/ena/net-ena-add-intr_moder_rx_interval-to-struct-ena_com.patch b/debian/patches/features/all/ena/net-ena-add-intr_moder_rx_interval-to-struct-ena_com.patch new file mode 100644 index 000000000..086da850a --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-add-intr_moder_rx_interval-to-struct-ena_com.patch @@ -0,0 +1,118 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:26 +0300 +Subject: [PATCH] net: ena: add intr_moder_rx_interval to struct ena_com_dev + and use it +Origin: https://git.kernel.org/linus/15619e722b16aaa40f942b93631aa92581a7b393 +Bug-Debian: https://bugs.debian.org/941291 + +Add intr_moder_rx_interval to struct ena_com_dev and use it as the +location where the interrupt moderation rx interval is saved, instead +of the interrupt moderation table. + +This is done as a first step before removing the old interrupt moderation +code. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 20 ++++---------------- + drivers/net/ethernet/amazon/ena/ena_com.h | 8 +++++++- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 ++- + 3 files changed, 13 insertions(+), 18 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -1297,9 +1297,6 @@ static int ena_com_init_interrupt_modera + static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev, + u16 intr_delay_resolution) + { +- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl; +- unsigned int i; +- + if (!intr_delay_resolution) { + pr_err("Illegal intr_delay_resolution provided. Going to use default 1 usec resolution\n"); + intr_delay_resolution = 1; +@@ -1307,8 +1304,7 @@ static void ena_com_update_intr_delay_re + ena_dev->intr_delay_resolution = intr_delay_resolution; + + /* update Rx */ +- for (i = 0; i < ENA_INTR_MAX_NUM_OF_LEVELS; i++) +- intr_moder_tbl[i].intr_moder_interval /= intr_delay_resolution; ++ ena_dev->intr_moder_rx_interval /= intr_delay_resolution; + + /* update Tx */ + ena_dev->intr_moder_tx_interval /= intr_delay_resolution; +@@ -2798,11 +2794,8 @@ int ena_com_update_nonadaptive_moderatio + return -EFAULT; + } + +- /* We use LOWEST entry of moderation table for storing +- * nonadaptive interrupt coalescing values +- */ +- ena_dev->intr_moder_tbl[ENA_INTR_MODER_LOWEST].intr_moder_interval = +- rx_coalesce_usecs / ena_dev->intr_delay_resolution; ++ ena_dev->intr_moder_rx_interval = rx_coalesce_usecs / ++ ena_dev->intr_delay_resolution; + + return 0; + } +@@ -2907,12 +2900,7 @@ unsigned int ena_com_get_nonadaptive_mod + + unsigned int ena_com_get_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev) + { +- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl; +- +- if (intr_moder_tbl) +- return intr_moder_tbl[ENA_INTR_MODER_LOWEST].intr_moder_interval; +- +- return 0; ++ return ena_dev->intr_moder_rx_interval; + } + + void ena_com_init_intr_moderation_entry(struct ena_com_dev *ena_dev, +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -93,7 +93,7 @@ + #define ENA_INTR_HIGHEST_BYTES (192 * 1024) + + #define ENA_INTR_INITIAL_TX_INTERVAL_USECS 196 +-#define ENA_INTR_INITIAL_RX_INTERVAL_USECS 4 ++#define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0 + #define ENA_INTR_DELAY_OLD_VALUE_WEIGHT 6 + #define ENA_INTR_DELAY_NEW_VALUE_WEIGHT 4 + #define ENA_INTR_MODER_LEVEL_STRIDE 2 +@@ -376,7 +376,13 @@ struct ena_com_dev { + struct ena_host_attribute host_attr; + bool adaptive_coalescing; + u16 intr_delay_resolution; ++ ++ /* interrupt moderation intervals are in usec divided by ++ * intr_delay_resolution, which is supplied by the device. ++ */ + u32 intr_moder_tx_interval; ++ u32 intr_moder_rx_interval; ++ + struct ena_intr_moder_entry *intr_moder_tbl; + + struct ena_com_llq_info llq_info; +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3487,10 +3487,11 @@ static int ena_probe(struct pci_dev *pde + calc_queue_ctx.get_feat_ctx = &get_feat_ctx; + calc_queue_ctx.pdev = pdev; + +- /* initial Tx interrupt delay, Assumes 1 usec granularity. ++ /* Initial Tx and RX interrupt delay. Assumes 1 usec granularity. + * Updated during device initialization with the real granularity + */ + ena_dev->intr_moder_tx_interval = ENA_INTR_INITIAL_TX_INTERVAL_USECS; ++ ena_dev->intr_moder_rx_interval = ENA_INTR_INITIAL_RX_INTERVAL_USECS; + io_queue_num = ena_calc_io_queue_num(pdev, ena_dev, &get_feat_ctx); + rc = ena_calc_queue_size(&calc_queue_ctx); + if (rc || io_queue_num <= 0) { diff --git a/debian/patches/features/all/ena/net-ena-add-newline-at-the-end-of-pr_err-prints.patch b/debian/patches/features/all/ena/net-ena-add-newline-at-the-end-of-pr_err-prints.patch new file mode 100644 index 000000000..3b1c6c4cb --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-add-newline-at-the-end-of-pr_err-prints.patch @@ -0,0 +1,91 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Mon, 3 Jun 2019 17:43:23 +0300 +Subject: [PATCH] net: ena: add newline at the end of pr_err prints +Origin: https://git.kernel.org/linus/9cb9c0de266f1ea52f01589f2f4019f163c01cd1 +Bug-Debian: https://bugs.debian.org/941291 + +Some pr_err prints lacked '\n' in the end. Added where missing. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -115,7 +115,7 @@ static int ena_com_admin_init_sq(struct + GFP_KERNEL); + + if (!sq->entries) { +- pr_err("memory allocation failed"); ++ pr_err("memory allocation failed\n"); + return -ENOMEM; + } + +@@ -137,7 +137,7 @@ static int ena_com_admin_init_cq(struct + GFP_KERNEL); + + if (!cq->entries) { +- pr_err("memory allocation failed"); ++ pr_err("memory allocation failed\n"); + return -ENOMEM; + } + +@@ -160,7 +160,7 @@ static int ena_com_admin_init_aenq(struc + GFP_KERNEL); + + if (!aenq->entries) { +- pr_err("memory allocation failed"); ++ pr_err("memory allocation failed\n"); + return -ENOMEM; + } + +@@ -285,7 +285,7 @@ static inline int ena_com_init_comp_ctxt + + queue->comp_ctx = devm_kzalloc(queue->q_dmadev, size, GFP_KERNEL); + if (unlikely(!queue->comp_ctx)) { +- pr_err("memory allocation failed"); ++ pr_err("memory allocation failed\n"); + return -ENOMEM; + } + +@@ -356,7 +356,7 @@ static int ena_com_init_io_sq(struct ena + } + + if (!io_sq->desc_addr.virt_addr) { +- pr_err("memory allocation failed"); ++ pr_err("memory allocation failed\n"); + return -ENOMEM; + } + } +@@ -382,7 +382,7 @@ static int ena_com_init_io_sq(struct ena + devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL); + + if (!io_sq->bounce_buf_ctrl.base_buffer) { +- pr_err("bounce buffer memory allocation failed"); ++ pr_err("bounce buffer memory allocation failed\n"); + return -ENOMEM; + } + +@@ -440,7 +440,7 @@ static int ena_com_init_io_cq(struct ena + } + + if (!io_cq->cdesc_addr.virt_addr) { +- pr_err("memory allocation failed"); ++ pr_err("memory allocation failed\n"); + return -ENOMEM; + } + +@@ -829,7 +829,7 @@ static u32 ena_com_reg_bar_read32(struct + } + + if (read_resp->reg_off != offset) { +- pr_err("Read failure: wrong offset provided"); ++ pr_err("Read failure: wrong offset provided\n"); + ret = ENA_MMIO_READ_TIMEOUT; + } else { + ret = read_resp->reg_val; diff --git a/debian/patches/features/all/ena/net-ena-add-support-for-changing-max_header_size-in-.patch b/debian/patches/features/all/ena/net-ena-add-support-for-changing-max_header_size-in-.patch new file mode 100644 index 000000000..ac5bc89e7 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-add-support-for-changing-max_header_size-in-.patch @@ -0,0 +1,54 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Mon, 3 Jun 2019 17:43:26 +0300 +Subject: [PATCH] net: ena: add support for changing max_header_size in LLQ + mode +Origin: https://git.kernel.org/linus/cdf449eccc5946d5dd4145b38347874a7423c50d +Bug-Debian: https://bugs.debian.org/941291 + +Up until now the driver always used a single setting for the sizes +of the different parts of the llq entry - 128 for entry size, 2 for +descriptors before header and 96 for maximum header size. + +The current code makes sure that the parts of the llq entry are +compatible with each other and with the initial llq entry size given +by the device. + +This commit changes this code to support any llq entry size + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -2936,8 +2936,8 @@ int ena_com_config_dev_mode(struct ena_c + struct ena_admin_feature_llq_desc *llq_features, + struct ena_llq_configurations *llq_default_cfg) + { ++ struct ena_com_llq_info *llq_info = &ena_dev->llq_info; + int rc; +- int size; + + if (!llq_features->max_llq_num) { + ena_dev->tx_mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; +@@ -2948,12 +2948,10 @@ int ena_com_config_dev_mode(struct ena_c + if (rc) + return rc; + +- /* Validate the descriptor is not too big */ +- size = ena_dev->tx_max_header_size; +- size += ena_dev->llq_info.descs_num_before_header * +- sizeof(struct ena_eth_io_tx_desc); ++ ena_dev->tx_max_header_size = llq_info->desc_list_entry_size - ++ (llq_info->descs_num_before_header * sizeof(struct ena_eth_io_tx_desc)); + +- if (unlikely(ena_dev->llq_info.desc_list_entry_size < size)) { ++ if (unlikely(ena_dev->tx_max_header_size == 0)) { + pr_err("the size of the LLQ entry is smaller than needed\n"); + return -EINVAL; + } diff --git a/debian/patches/features/all/ena/net-ena-allow-automatic-fallback-to-polling-mode.patch b/debian/patches/features/all/ena/net-ena-allow-automatic-fallback-to-polling-mode.patch new file mode 100644 index 000000000..dab6166e1 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-allow-automatic-fallback-to-polling-mode.patch @@ -0,0 +1,103 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Mon, 3 Jun 2019 17:43:25 +0300 +Subject: [PATCH] net: ena: allow automatic fallback to polling mode +Origin: https://git.kernel.org/linus/a4e262cde3cda4491ce666e7c5270954c4d926b9 +Bug-Debian: https://bugs.debian.org/941291 + +Enable fallback to polling mode for Admin queue +when identified a command response arrival +without an accompanying MSI-X interrupt + +Signed-off-by: Igor Chauskin <igorch@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 34 +++++++++++++++++------ + drivers/net/ethernet/amazon/ena/ena_com.h | 14 ++++++++++ + 2 files changed, 39 insertions(+), 9 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -762,16 +762,26 @@ static int ena_com_wait_and_process_admi + admin_queue->stats.no_completion++; + spin_unlock_irqrestore(&admin_queue->q_lock, flags); + +- if (comp_ctx->status == ENA_CMD_COMPLETED) +- pr_err("The ena device have completion but the driver didn't receive any MSI-X interrupt (cmd %d)\n", +- comp_ctx->cmd_opcode); +- else +- pr_err("The ena device doesn't send any completion for the admin cmd %d status %d\n", ++ if (comp_ctx->status == ENA_CMD_COMPLETED) { ++ pr_err("The ena device sent a completion but the driver didn't receive a MSI-X interrupt (cmd %d), autopolling mode is %s\n", ++ comp_ctx->cmd_opcode, ++ admin_queue->auto_polling ? "ON" : "OFF"); ++ /* Check if fallback to polling is enabled */ ++ if (admin_queue->auto_polling) ++ admin_queue->polling = true; ++ } else { ++ pr_err("The ena device doesn't send a completion for the admin cmd %d status %d\n", + comp_ctx->cmd_opcode, comp_ctx->status); +- +- admin_queue->running_state = false; +- ret = -ETIME; +- goto err; ++ } ++ /* Check if shifted to polling mode. ++ * This will happen if there is a completion without an interrupt ++ * and autopolling mode is enabled. Continuing normal execution in such case ++ */ ++ if (!admin_queue->polling) { ++ admin_queue->running_state = false; ++ ret = -ETIME; ++ goto err; ++ } + } + + ret = ena_com_comp_status_to_errno(comp_ctx->comp_status); +@@ -1650,6 +1660,12 @@ void ena_com_set_admin_polling_mode(stru + ena_dev->admin_queue.polling = polling; + } + ++void ena_com_set_admin_auto_polling_mode(struct ena_com_dev *ena_dev, ++ bool polling) ++{ ++ ena_dev->admin_queue.auto_polling = polling; ++} ++ + int ena_com_mmio_reg_read_request_init(struct ena_com_dev *ena_dev) + { + struct ena_com_mmio_read *mmio_read = &ena_dev->mmio_read; +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -283,6 +283,9 @@ struct ena_com_admin_queue { + /* Indicate if the admin queue should poll for completion */ + bool polling; + ++ /* Define if fallback to polling mode should occur */ ++ bool auto_polling; ++ + u16 curr_cmd_id; + + /* Indicate that the ena was initialized and can +@@ -538,6 +541,17 @@ void ena_com_set_admin_polling_mode(stru + */ + bool ena_com_get_ena_admin_polling_mode(struct ena_com_dev *ena_dev); + ++/* ena_com_set_admin_auto_polling_mode - Enable autoswitch to polling mode ++ * @ena_dev: ENA communication layer struct ++ * @polling: Enable/Disable polling mode ++ * ++ * Set the autopolling mode. ++ * If autopolling is on: ++ * In case of missing interrupt when data is available switch to polling. ++ */ ++void ena_com_set_admin_auto_polling_mode(struct ena_com_dev *ena_dev, ++ bool polling); ++ + /* ena_com_admin_q_comp_intr_handler - admin queue interrupt handler + * @ena_dev: ENA communication layer struct + * diff --git a/debian/patches/features/all/ena/net-ena-allow-queue-allocation-backoff-when-low-on-m.patch b/debian/patches/features/all/ena/net-ena-allow-queue-allocation-backoff-when-low-on-m.patch new file mode 100644 index 000000000..6f902b864 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-allow-queue-allocation-backoff-when-low-on-m.patch @@ -0,0 +1,323 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Tue, 11 Jun 2019 14:58:08 +0300 +Subject: [PATCH] net: ena: allow queue allocation backoff when low on memory +Origin: https://git.kernel.org/linus/13ca32a69e29f3a0fe72094dd930f312b3f3ee44 +Bug-Debian: https://bugs.debian.org/941291 + +If there is not enough memory to allocate io queues the driver will +try to allocate smaller queues. + +The backoff algorithm is as follows: + +1. Try to allocate TX and RX and if successful. +1.1. return success + +2. Divide by 2 the size of the larger of RX and TX queues (or both if their size is the same). + +3. If TX or RX is smaller than 256 +3.1. return failure. +4. else +4.1. go back to 1. + +Also change the tx_queue_size, rx_queue_size field names in struct +adapter to requested_tx_queue_size and requested_rx_queue_size, and +use RX and TX queue 0 for actual queue sizes. +Explanation: +The original fields were useless as they were simply used to assign +values once from them to each of the queues in the adapter in ena_probe(). +They could simply be deleted. However now that we have a backoff +feature, we have use for them. In case of backoff there is a difference +between the requested queue sizes and the actual sizes. Therefore there +is a need to save the requested queue size for future retries of queue +allocation (for example if allocation failed and then ifdown + ifup was +called we want to start the allocation from the original requested size of +the queues). + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 4 +- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 159 +++++++++++++----- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 6 +- + 3 files changed, 127 insertions(+), 42 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -450,8 +450,8 @@ static void ena_get_ringparam(struct net + + ring->tx_max_pending = adapter->max_tx_ring_size; + ring->rx_max_pending = adapter->max_rx_ring_size; +- ring->tx_pending = adapter->tx_ring_size; +- ring->rx_pending = adapter->rx_ring_size; ++ ring->tx_pending = adapter->tx_ring[0].ring_size; ++ ring->rx_pending = adapter->rx_ring[0].ring_size; + } + + static u32 ena_flow_hash_to_flow_type(u16 hash_fields) +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -182,7 +182,7 @@ static void ena_init_io_rings(struct ena + ena_init_io_rings_common(adapter, rxr, i); + + /* TX specific ring state */ +- txr->ring_size = adapter->tx_ring_size; ++ txr->ring_size = adapter->requested_tx_ring_size; + txr->tx_max_header_size = ena_dev->tx_max_header_size; + txr->tx_mem_queue_type = ena_dev->tx_mem_queue_type; + txr->sgl_size = adapter->max_tx_sgl_size; +@@ -190,7 +190,7 @@ static void ena_init_io_rings(struct ena + ena_com_get_nonadaptive_moderation_interval_tx(ena_dev); + + /* RX specific ring state */ +- rxr->ring_size = adapter->rx_ring_size; ++ rxr->ring_size = adapter->requested_rx_ring_size; + rxr->rx_copybreak = adapter->rx_copybreak; + rxr->sgl_size = adapter->max_rx_sgl_size; + rxr->smoothed_interval = +@@ -594,7 +594,6 @@ static void ena_free_rx_bufs(struct ena_ + + /* ena_refill_all_rx_bufs - allocate all queues Rx buffers + * @adapter: board private structure +- * + */ + static void ena_refill_all_rx_bufs(struct ena_adapter *adapter) + { +@@ -1635,7 +1634,7 @@ static int ena_create_io_tx_queue(struct + ctx.qid = ena_qid; + ctx.mem_queue_type = ena_dev->tx_mem_queue_type; + ctx.msix_vector = msix_vector; +- ctx.queue_size = adapter->tx_ring_size; ++ ctx.queue_size = tx_ring->ring_size; + ctx.numa_node = cpu_to_node(tx_ring->cpu); + + rc = ena_com_create_io_queue(ena_dev, &ctx); +@@ -1702,7 +1701,7 @@ static int ena_create_io_rx_queue(struct + ctx.direction = ENA_COM_IO_QUEUE_DIRECTION_RX; + ctx.mem_queue_type = ENA_ADMIN_PLACEMENT_POLICY_HOST; + ctx.msix_vector = msix_vector; +- ctx.queue_size = adapter->rx_ring_size; ++ ctx.queue_size = rx_ring->ring_size; + ctx.numa_node = cpu_to_node(rx_ring->cpu); + + rc = ena_com_create_io_queue(ena_dev, &ctx); +@@ -1749,6 +1748,112 @@ create_err: + return rc; + } + ++static void set_io_rings_size(struct ena_adapter *adapter, ++ int new_tx_size, int new_rx_size) ++{ ++ int i; ++ ++ for (i = 0; i < adapter->num_queues; i++) { ++ adapter->tx_ring[i].ring_size = new_tx_size; ++ adapter->rx_ring[i].ring_size = new_rx_size; ++ } ++} ++ ++/* This function allows queue allocation to backoff when the system is ++ * low on memory. If there is not enough memory to allocate io queues ++ * the driver will try to allocate smaller queues. ++ * ++ * The backoff algorithm is as follows: ++ * 1. Try to allocate TX and RX and if successful. ++ * 1.1. return success ++ * ++ * 2. Divide by 2 the size of the larger of RX and TX queues (or both if their size is the same). ++ * ++ * 3. If TX or RX is smaller than 256 ++ * 3.1. return failure. ++ * 4. else ++ * 4.1. go back to 1. ++ */ ++static int create_queues_with_size_backoff(struct ena_adapter *adapter) ++{ ++ int rc, cur_rx_ring_size, cur_tx_ring_size; ++ int new_rx_ring_size, new_tx_ring_size; ++ ++ /* current queue sizes might be set to smaller than the requested ++ * ones due to past queue allocation failures. ++ */ ++ set_io_rings_size(adapter, adapter->requested_tx_ring_size, ++ adapter->requested_rx_ring_size); ++ ++ while (1) { ++ rc = ena_setup_all_tx_resources(adapter); ++ if (rc) ++ goto err_setup_tx; ++ ++ rc = ena_create_all_io_tx_queues(adapter); ++ if (rc) ++ goto err_create_tx_queues; ++ ++ rc = ena_setup_all_rx_resources(adapter); ++ if (rc) ++ goto err_setup_rx; ++ ++ rc = ena_create_all_io_rx_queues(adapter); ++ if (rc) ++ goto err_create_rx_queues; ++ ++ return 0; ++ ++err_create_rx_queues: ++ ena_free_all_io_rx_resources(adapter); ++err_setup_rx: ++ ena_destroy_all_tx_queues(adapter); ++err_create_tx_queues: ++ ena_free_all_io_tx_resources(adapter); ++err_setup_tx: ++ if (rc != -ENOMEM) { ++ netif_err(adapter, ifup, adapter->netdev, ++ "Queue creation failed with error code %d\n", ++ rc); ++ return rc; ++ } ++ ++ cur_tx_ring_size = adapter->tx_ring[0].ring_size; ++ cur_rx_ring_size = adapter->rx_ring[0].ring_size; ++ ++ netif_err(adapter, ifup, adapter->netdev, ++ "Not enough memory to create queues with sizes TX=%d, RX=%d\n", ++ cur_tx_ring_size, cur_rx_ring_size); ++ ++ new_tx_ring_size = cur_tx_ring_size; ++ new_rx_ring_size = cur_rx_ring_size; ++ ++ /* Decrease the size of the larger queue, or ++ * decrease both if they are the same size. ++ */ ++ if (cur_rx_ring_size <= cur_tx_ring_size) ++ new_tx_ring_size = cur_tx_ring_size / 2; ++ if (cur_rx_ring_size >= cur_tx_ring_size) ++ new_rx_ring_size = cur_rx_ring_size / 2; ++ ++ if (cur_tx_ring_size < ENA_MIN_RING_SIZE || ++ cur_rx_ring_size < ENA_MIN_RING_SIZE) { ++ netif_err(adapter, ifup, adapter->netdev, ++ "Queue creation failed with the smallest possible queue size of %d for both queues. Not retrying with smaller queues\n", ++ ENA_MIN_RING_SIZE); ++ return rc; ++ } ++ ++ netif_err(adapter, ifup, adapter->netdev, ++ "Retrying queue creation with sizes TX=%d, RX=%d\n", ++ new_tx_ring_size, ++ new_rx_ring_size); ++ ++ set_io_rings_size(adapter, new_tx_ring_size, ++ new_rx_ring_size); ++ } ++} ++ + static int ena_up(struct ena_adapter *adapter) + { + int rc, i; +@@ -1768,25 +1873,9 @@ static int ena_up(struct ena_adapter *ad + if (rc) + goto err_req_irq; + +- /* allocate transmit descriptors */ +- rc = ena_setup_all_tx_resources(adapter); ++ rc = create_queues_with_size_backoff(adapter); + if (rc) +- goto err_setup_tx; +- +- /* allocate receive descriptors */ +- rc = ena_setup_all_rx_resources(adapter); +- if (rc) +- goto err_setup_rx; +- +- /* Create TX queues */ +- rc = ena_create_all_io_tx_queues(adapter); +- if (rc) +- goto err_create_tx_queues; +- +- /* Create RX queues */ +- rc = ena_create_all_io_rx_queues(adapter); +- if (rc) +- goto err_create_rx_queues; ++ goto err_create_queues_with_backoff; + + rc = ena_up_complete(adapter); + if (rc) +@@ -1815,14 +1904,11 @@ static int ena_up(struct ena_adapter *ad + return rc; + + err_up: +- ena_destroy_all_rx_queues(adapter); +-err_create_rx_queues: + ena_destroy_all_tx_queues(adapter); +-err_create_tx_queues: +- ena_free_all_io_rx_resources(adapter); +-err_setup_rx: + ena_free_all_io_tx_resources(adapter); +-err_setup_tx: ++ ena_destroy_all_rx_queues(adapter); ++ ena_free_all_io_rx_resources(adapter); ++err_create_queues_with_backoff: + ena_free_io_irq(adapter); + err_req_irq: + ena_del_napi(adapter); +@@ -3286,17 +3372,14 @@ static int ena_calc_queue_size(struct en + max_tx_queue_size = rounddown_pow_of_two(max_tx_queue_size); + max_rx_queue_size = rounddown_pow_of_two(max_rx_queue_size); + +- tx_queue_size = min_t(u32, tx_queue_size, max_tx_queue_size); +- rx_queue_size = min_t(u32, rx_queue_size, max_rx_queue_size); ++ tx_queue_size = clamp_val(tx_queue_size, ENA_MIN_RING_SIZE, ++ max_tx_queue_size); ++ rx_queue_size = clamp_val(rx_queue_size, ENA_MIN_RING_SIZE, ++ max_rx_queue_size); + + tx_queue_size = rounddown_pow_of_two(tx_queue_size); + rx_queue_size = rounddown_pow_of_two(rx_queue_size); + +- if (unlikely(!rx_queue_size || !tx_queue_size)) { +- dev_err(&ctx->pdev->dev, "Invalid queue size\n"); +- return -EFAULT; +- } +- + ctx->max_tx_queue_size = max_tx_queue_size; + ctx->max_rx_queue_size = max_rx_queue_size; + ctx->tx_queue_size = tx_queue_size; +@@ -3426,8 +3509,8 @@ static int ena_probe(struct pci_dev *pde + adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->reset_reason = ENA_REGS_RESET_NORMAL; + +- adapter->tx_ring_size = calc_queue_ctx.tx_queue_size; +- adapter->rx_ring_size = calc_queue_ctx.rx_queue_size; ++ adapter->requested_tx_ring_size = calc_queue_ctx.tx_queue_size; ++ adapter->requested_rx_ring_size = calc_queue_ctx.rx_queue_size; + adapter->max_tx_ring_size = calc_queue_ctx.max_tx_queue_size; + adapter->max_rx_ring_size = calc_queue_ctx.max_rx_queue_size; + adapter->max_tx_sgl_size = calc_queue_ctx.max_tx_sgl_size; +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -79,6 +79,8 @@ + #define ENA_BAR_MASK (BIT(ENA_REG_BAR) | BIT(ENA_MEM_BAR)) + + #define ENA_DEFAULT_RING_SIZE (1024) ++#define ENA_MIN_RING_SIZE (256) ++ + + #define ENA_TX_WAKEUP_THRESH (MAX_SKB_FRAGS + 2) + #define ENA_DEFAULT_RX_COPYBREAK (256 - NET_IP_ALIGN) +@@ -330,8 +332,8 @@ struct ena_adapter { + u32 tx_usecs, rx_usecs; /* interrupt moderation */ + u32 tx_frames, rx_frames; /* interrupt moderation */ + +- u32 tx_ring_size; +- u32 rx_ring_size; ++ u32 requested_tx_ring_size; ++ u32 requested_rx_ring_size; + + u32 max_tx_ring_size; + u32 max_rx_ring_size; diff --git a/debian/patches/features/all/ena/net-ena-arrange-ena_probe-function-variables-in-reve.patch b/debian/patches/features/all/ena/net-ena-arrange-ena_probe-function-variables-in-reve.patch new file mode 100644 index 000000000..af89762f1 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-arrange-ena_probe-function-variables-in-reve.patch @@ -0,0 +1,49 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Mon, 3 Jun 2019 17:43:22 +0300 +Subject: [PATCH] net: ena: arrange ena_probe() function variables in reverse + christmas tree +Origin: https://git.kernel.org/linus/83b9240428a66da3c8e24e719b985d533cf58067 +Bug-Debian: https://bugs.debian.org/941291 + +Reverse christmas tree arrangement is when strings are written from longer +to shorter with each line. Most of our functions are abiding this +arrangement but this function does not. + +In this commit we arrange the variables of ena_probe() in reverse christmas +tree. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3274,17 +3274,17 @@ static int ena_calc_queue_size(struct pc + static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + { + struct ena_com_dev_get_features_ctx get_feat_ctx; +- static int version_printed; +- struct net_device *netdev; +- struct ena_adapter *adapter; + struct ena_llq_configurations llq_config; + struct ena_com_dev *ena_dev = NULL; +- char *queue_type_str; +- static int adapters_found; ++ struct ena_adapter *adapter; ++ static int version_printed; + int io_queue_num, bars, rc; +- int queue_size; ++ struct net_device *netdev; ++ static int adapters_found; ++ char *queue_type_str; + u16 tx_sgl_size = 0; + u16 rx_sgl_size = 0; ++ int queue_size; + bool wd_state; + + dev_dbg(&pdev->dev, "%s\n", __func__); diff --git a/debian/patches/features/all/ena/net-ena-don-t-wake-up-tx-queue-when-down.patch b/debian/patches/features/all/ena/net-ena-don-t-wake-up-tx-queue-when-down.patch new file mode 100644 index 000000000..e1b214e80 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-don-t-wake-up-tx-queue-when-down.patch @@ -0,0 +1,52 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Sun, 15 Sep 2019 17:29:44 +0300 +Subject: [PATCH] net: ena: don't wake up tx queue when down +Origin: https://git.kernel.org/linus/a53651ec93a8d7ab5b26c5390e0c389048b4b4b6 +Bug-Debian: https://bugs.debian.org/941291 + +There is a race condition that can occur when calling ena_down(). +The ena_clean_tx_irq() - which is a part of the napi handler - +function might wake up the tx queue when the queue is supposed +to be down (during recovery or changing the size of the queues +for example) This causes the ena_start_xmit() function to trigger +and possibly try to access the destroyed queues. + +The race is illustrated below: + +Flow A: Flow B(napi handler) +ena_down() + netif_carrier_off() + netif_tx_disable() + ena_clean_tx_irq() + netif_tx_wake_queue() + ena_napi_disable_all() + ena_destroy_all_io_queues() + +After these flows the tx queue is active and ena_start_xmit() accesses +the destroyed queue which leads to a kernel panic. + +fixes: 1738cd3ed342 (net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)) + +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c +index 664e3ed97ea9..d118ed4c57ce 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -823,7 +823,8 @@ static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 budget) + above_thresh = + ena_com_sq_have_enough_space(tx_ring->ena_com_io_sq, + ENA_TX_WAKEUP_THRESH); +- if (netif_tx_queue_stopped(txq) && above_thresh) { ++ if (netif_tx_queue_stopped(txq) && above_thresh && ++ test_bit(ENA_FLAG_DEV_UP, &tx_ring->adapter->flags)) { + netif_tx_wake_queue(txq); + u64_stats_update_begin(&tx_ring->syncp); + tx_ring->tx_stats.queue_wakeup++; +-- +2.17.1 + diff --git a/debian/patches/features/all/ena/net-ena-enable-negotiating-larger-Rx-ring-size.patch b/debian/patches/features/all/ena/net-ena-enable-negotiating-larger-Rx-ring-size.patch new file mode 100644 index 000000000..43be08179 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-enable-negotiating-larger-Rx-ring-size.patch @@ -0,0 +1,270 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Tue, 11 Jun 2019 14:58:06 +0300 +Subject: [PATCH] net: ena: enable negotiating larger Rx ring size +Origin: https://git.kernel.org/linus/31aa9857f1733403f2eb12d51c1cec20a22483d9 +Bug-Debian: https://bugs.debian.org/941291 + +Use MAX_QUEUES_EXT get feature capability to query the device. + +Signed-off-by: Netanel Belgazal <netanel@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 144 ++++++++++++------- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 15 ++ + 2 files changed, 110 insertions(+), 49 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -2455,13 +2455,6 @@ static int ena_device_validate_params(st + return -EINVAL; + } + +- if ((get_feat_ctx->max_queues.max_cq_num < adapter->num_queues) || +- (get_feat_ctx->max_queues.max_sq_num < adapter->num_queues)) { +- netif_err(adapter, drv, netdev, +- "Error, device doesn't support enough queues\n"); +- return -EINVAL; +- } +- + if (get_feat_ctx->dev_attr.max_mtu < netdev->mtu) { + netif_err(adapter, drv, netdev, + "Error, device max mtu is smaller than netdev MTU\n"); +@@ -3035,18 +3028,32 @@ static int ena_calc_io_queue_num(struct + struct ena_com_dev *ena_dev, + struct ena_com_dev_get_features_ctx *get_feat_ctx) + { +- int io_sq_num, io_queue_num; ++ int io_tx_sq_num, io_tx_cq_num, io_rx_num, io_queue_num; ++ ++ if (ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) { ++ struct ena_admin_queue_ext_feature_fields *max_queue_ext = ++ &get_feat_ctx->max_queue_ext.max_queue_ext; ++ io_rx_num = min_t(int, max_queue_ext->max_rx_sq_num, ++ max_queue_ext->max_rx_cq_num); + +- /* In case of LLQ use the llq number in the get feature cmd */ ++ io_tx_sq_num = max_queue_ext->max_tx_sq_num; ++ io_tx_cq_num = max_queue_ext->max_tx_cq_num; ++ } else { ++ struct ena_admin_queue_feature_desc *max_queues = ++ &get_feat_ctx->max_queues; ++ io_tx_sq_num = max_queues->max_sq_num; ++ io_tx_cq_num = max_queues->max_cq_num; ++ io_rx_num = min_t(int, io_tx_sq_num, io_tx_cq_num); ++ } ++ ++ /* In case of LLQ use the llq fields for the tx SQ/CQ */ + if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) +- io_sq_num = get_feat_ctx->llq.max_llq_num; +- else +- io_sq_num = get_feat_ctx->max_queues.max_sq_num; ++ io_tx_sq_num = get_feat_ctx->llq.max_llq_num; + + io_queue_num = min_t(int, num_online_cpus(), ENA_MAX_NUM_IO_QUEUES); +- io_queue_num = min_t(int, io_queue_num, io_sq_num); +- io_queue_num = min_t(int, io_queue_num, +- get_feat_ctx->max_queues.max_cq_num); ++ io_queue_num = min_t(int, io_queue_num, io_rx_num); ++ io_queue_num = min_t(int, io_queue_num, io_tx_sq_num); ++ io_queue_num = min_t(int, io_queue_num, io_tx_cq_num); + /* 1 IRQ for for mgmnt and 1 IRQs for each IO direction */ + io_queue_num = min_t(int, io_queue_num, pci_msix_vec_count(pdev) - 1); + if (unlikely(!io_queue_num)) { +@@ -3229,36 +3236,73 @@ static inline void set_default_llq_confi + llq_config->llq_ring_entry_size_value = 128; + } + +-static int ena_calc_queue_size(struct pci_dev *pdev, +- struct ena_com_dev *ena_dev, +- u16 *max_tx_sgl_size, +- u16 *max_rx_sgl_size, +- struct ena_com_dev_get_features_ctx *get_feat_ctx) +-{ +- u32 queue_size = ENA_DEFAULT_RING_SIZE; +- +- queue_size = min_t(u32, queue_size, +- get_feat_ctx->max_queues.max_cq_depth); +- queue_size = min_t(u32, queue_size, +- get_feat_ctx->max_queues.max_sq_depth); ++static int ena_calc_queue_size(struct ena_calc_queue_size_ctx *ctx) ++{ ++ struct ena_admin_feature_llq_desc *llq = &ctx->get_feat_ctx->llq; ++ struct ena_com_dev *ena_dev = ctx->ena_dev; ++ u32 tx_queue_size = ENA_DEFAULT_RING_SIZE; ++ u32 rx_queue_size = ENA_DEFAULT_RING_SIZE; ++ u32 max_tx_queue_size; ++ u32 max_rx_queue_size; ++ ++ if (ctx->ena_dev->supported_features & BIT(ENA_ADMIN_MAX_QUEUES_EXT)) { ++ struct ena_admin_queue_ext_feature_fields *max_queue_ext = ++ &ctx->get_feat_ctx->max_queue_ext.max_queue_ext; ++ max_rx_queue_size = min_t(u32, max_queue_ext->max_rx_cq_depth, ++ max_queue_ext->max_rx_sq_depth); ++ max_tx_queue_size = max_queue_ext->max_tx_cq_depth; ++ ++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ++ max_tx_queue_size = min_t(u32, max_tx_queue_size, ++ llq->max_llq_depth); ++ else ++ max_tx_queue_size = min_t(u32, max_tx_queue_size, ++ max_queue_ext->max_tx_sq_depth); ++ ++ ctx->max_tx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS, ++ max_queue_ext->max_per_packet_tx_descs); ++ ctx->max_rx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS, ++ max_queue_ext->max_per_packet_rx_descs); ++ } else { ++ struct ena_admin_queue_feature_desc *max_queues = ++ &ctx->get_feat_ctx->max_queues; ++ max_rx_queue_size = min_t(u32, max_queues->max_cq_depth, ++ max_queues->max_sq_depth); ++ max_tx_queue_size = max_queues->max_cq_depth; ++ ++ if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ++ max_tx_queue_size = min_t(u32, max_tx_queue_size, ++ llq->max_llq_depth); ++ else ++ max_tx_queue_size = min_t(u32, max_tx_queue_size, ++ max_queues->max_sq_depth); + +- if (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) +- queue_size = min_t(u32, queue_size, +- get_feat_ctx->llq.max_llq_depth); ++ ctx->max_tx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS, ++ max_queues->max_packet_tx_descs); ++ ctx->max_rx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS, ++ max_queues->max_packet_rx_descs); ++ } + +- queue_size = rounddown_pow_of_two(queue_size); ++ max_tx_queue_size = rounddown_pow_of_two(max_tx_queue_size); ++ max_rx_queue_size = rounddown_pow_of_two(max_rx_queue_size); + +- if (unlikely(!queue_size)) { +- dev_err(&pdev->dev, "Invalid queue size\n"); ++ tx_queue_size = min_t(u32, tx_queue_size, max_tx_queue_size); ++ rx_queue_size = min_t(u32, rx_queue_size, max_rx_queue_size); ++ ++ tx_queue_size = rounddown_pow_of_two(tx_queue_size); ++ rx_queue_size = rounddown_pow_of_two(rx_queue_size); ++ ++ if (unlikely(!rx_queue_size || !tx_queue_size)) { ++ dev_err(&ctx->pdev->dev, "Invalid queue size\n"); + return -EFAULT; + } + +- *max_tx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS, +- get_feat_ctx->max_queues.max_packet_tx_descs); +- *max_rx_sgl_size = min_t(u16, ENA_PKT_MAX_BUFS, +- get_feat_ctx->max_queues.max_packet_rx_descs); ++ ctx->max_tx_queue_size = max_tx_queue_size; ++ ctx->max_rx_queue_size = max_rx_queue_size; ++ ctx->tx_queue_size = tx_queue_size; ++ ctx->rx_queue_size = rx_queue_size; + +- return queue_size; ++ return 0; + } + + /* ena_probe - Device Initialization Routine +@@ -3274,6 +3318,7 @@ static int ena_calc_queue_size(struct pc + static int ena_probe(struct pci_dev *pdev, const struct pci_device_id *ent) + { + struct ena_com_dev_get_features_ctx get_feat_ctx; ++ struct ena_calc_queue_size_ctx calc_queue_ctx = { 0 }; + struct ena_llq_configurations llq_config; + struct ena_com_dev *ena_dev = NULL; + struct ena_adapter *adapter; +@@ -3281,9 +3326,6 @@ static int ena_probe(struct pci_dev *pde + struct net_device *netdev; + static int adapters_found; + char *queue_type_str; +- u16 tx_sgl_size = 0; +- u16 rx_sgl_size = 0; +- int queue_size; + bool wd_state; + + dev_dbg(&pdev->dev, "%s\n", __func__); +@@ -3340,20 +3382,25 @@ static int ena_probe(struct pci_dev *pde + goto err_device_destroy; + } + ++ calc_queue_ctx.ena_dev = ena_dev; ++ calc_queue_ctx.get_feat_ctx = &get_feat_ctx; ++ calc_queue_ctx.pdev = pdev; ++ + /* initial Tx interrupt delay, Assumes 1 usec granularity. + * Updated during device initialization with the real granularity + */ + ena_dev->intr_moder_tx_interval = ENA_INTR_INITIAL_TX_INTERVAL_USECS; + io_queue_num = ena_calc_io_queue_num(pdev, ena_dev, &get_feat_ctx); +- queue_size = ena_calc_queue_size(pdev, ena_dev, &tx_sgl_size, +- &rx_sgl_size, &get_feat_ctx); +- if ((queue_size <= 0) || (io_queue_num <= 0)) { ++ rc = ena_calc_queue_size(&calc_queue_ctx); ++ if (rc || io_queue_num <= 0) { + rc = -EFAULT; + goto err_device_destroy; + } + +- dev_info(&pdev->dev, "creating %d io queues. queue size: %d. LLQ is %s\n", +- io_queue_num, queue_size, ++ dev_info(&pdev->dev, "creating %d io queues. rx queue size: %d tx queue size. %d LLQ is %s\n", ++ io_queue_num, ++ calc_queue_ctx.rx_queue_size, ++ calc_queue_ctx.tx_queue_size, + (ena_dev->tx_mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) ? + "ENABLED" : "DISABLED"); + +@@ -3379,11 +3426,10 @@ static int ena_probe(struct pci_dev *pde + adapter->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + adapter->reset_reason = ENA_REGS_RESET_NORMAL; + +- adapter->tx_ring_size = queue_size; +- adapter->rx_ring_size = queue_size; +- +- adapter->max_tx_sgl_size = tx_sgl_size; +- adapter->max_rx_sgl_size = rx_sgl_size; ++ adapter->tx_ring_size = calc_queue_ctx.tx_queue_size; ++ adapter->rx_ring_size = calc_queue_ctx.rx_queue_size; ++ adapter->max_tx_sgl_size = calc_queue_ctx.max_tx_sgl_size; ++ adapter->max_rx_sgl_size = calc_queue_ctx.max_rx_sgl_size; + + adapter->num_queues = io_queue_num; + adapter->last_monitored_tx_qid = 0; +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -154,6 +154,18 @@ struct ena_napi { + u32 qid; + }; + ++struct ena_calc_queue_size_ctx { ++ struct ena_com_dev_get_features_ctx *get_feat_ctx; ++ struct ena_com_dev *ena_dev; ++ struct pci_dev *pdev; ++ u16 tx_queue_size; ++ u16 rx_queue_size; ++ u16 max_tx_queue_size; ++ u16 max_rx_queue_size; ++ u16 max_tx_sgl_size; ++ u16 max_rx_sgl_size; ++}; ++ + struct ena_tx_buffer { + struct sk_buff *skb; + /* num of ena desc for this specific skb +@@ -321,6 +333,9 @@ struct ena_adapter { + u32 tx_ring_size; + u32 rx_ring_size; + ++ u32 max_tx_ring_size; ++ u32 max_rx_ring_size; ++ + u32 msg_enable; + + u16 max_tx_sgl_size; diff --git a/debian/patches/features/all/ena/net-ena-enable-the-interrupt_moderation-in-driver_su.patch b/debian/patches/features/all/ena/net-ena-enable-the-interrupt_moderation-in-driver_su.patch new file mode 100644 index 000000000..3eb7e408c --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-enable-the-interrupt_moderation-in-driver_su.patch @@ -0,0 +1,63 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:29 +0300 +Subject: [PATCH] net: ena: enable the interrupt_moderation in + driver_supported_features +Origin: https://git.kernel.org/linus/bd21b0cc3a63d1c658b230db084b0f392b78cab2 +Bug-Debian: https://bugs.debian.org/941291 + +Add driver_supported_features to host_host info which is a new API used to +communicate to the device which features are supported by the driver. + +Add the interrupt_moderation bit to host_info->driver_supported_features +and enable it to signal the device that this driver supports interrupt +moderation properly. + +Reserved bits are for features implemented in the future + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_admin_defs.h | 8 ++++++++ + drivers/net/ethernet/amazon/ena/ena_netdev.c | 3 +++ + 2 files changed, 11 insertions(+) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_admin_defs.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_admin_defs.h +@@ -808,6 +808,12 @@ struct ena_admin_host_info { + u16 num_cpus; + + u16 reserved; ++ ++ /* 1 :0 : reserved ++ * 2 : interrupt_moderation ++ * 31:3 : reserved ++ */ ++ u32 driver_supported_features; + }; + + struct ena_admin_rss_ind_table_entry { +@@ -1110,6 +1116,8 @@ struct ena_admin_ena_mmio_req_read_less_ + #define ENA_ADMIN_HOST_INFO_DEVICE_MASK GENMASK(7, 3) + #define ENA_ADMIN_HOST_INFO_BUS_SHIFT 8 + #define ENA_ADMIN_HOST_INFO_BUS_MASK GENMASK(15, 8) ++#define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_SHIFT 2 ++#define ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK BIT(2) + + /* aenq_common_desc */ + #define ENA_ADMIN_AENQ_COMMON_DESC_PHASE_MASK BIT(0) +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -2440,6 +2440,9 @@ static void ena_config_host_info(struct + ("K"[0] << ENA_ADMIN_HOST_INFO_MODULE_TYPE_SHIFT); + host_info->num_cpus = num_online_cpus(); + ++ host_info->driver_supported_features = ++ ENA_ADMIN_HOST_INFO_INTERRUPT_MODERATION_MASK; ++ + rc = ena_com_set_host_attributes(ena_dev); + if (rc) { + if (rc == -EOPNOTSUPP) diff --git a/debian/patches/features/all/ena/net-ena-fix-incorrect-update-of-intr_delay_resolutio.patch b/debian/patches/features/all/ena/net-ena-fix-incorrect-update-of-intr_delay_resolutio.patch new file mode 100644 index 000000000..e194ecde9 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-fix-incorrect-update-of-intr_delay_resolutio.patch @@ -0,0 +1,89 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:36 +0300 +Subject: [PATCH] net: ena: fix incorrect update of intr_delay_resolution +Origin: https://git.kernel.org/linus/79226cea4a5ebbd84a4eee1762526f664c7beb62 +Bug-Debian: https://bugs.debian.org/941291 + +ena_dev->intr_moder_rx/tx_interval save the intervals received from the +user after dividing them by ena_dev->intr_delay_resolution. Therefore +when intr_delay_resolution changes, the code needs to first mutiply +intr_moder_rx/tx_interval by the previous intr_delay_resolution to get +the value originally given by the user, and only then divide it by the +new intr_delay_resolution. + +Current code does not first multiply intr_moder_rx/tx_interval by the old +intr_delay_resolution. This commit fixes it. + +Also initialize ena_dev->intr_delay_resolution to be 1. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 21 ++++++++++++++++---- + drivers/net/ethernet/amazon/ena/ena_com.h | 1 + + drivers/net/ethernet/amazon/ena/ena_netdev.c | 1 + + 3 files changed, 19 insertions(+), 4 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -1281,17 +1281,30 @@ static int ena_com_ind_tbl_convert_from_ + static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev, + u16 intr_delay_resolution) + { ++ /* Initial value of intr_delay_resolution might be 0 */ ++ u16 prev_intr_delay_resolution = ++ ena_dev->intr_delay_resolution ? ++ ena_dev->intr_delay_resolution : ++ ENA_DEFAULT_INTR_DELAY_RESOLUTION; ++ + if (!intr_delay_resolution) { + pr_err("Illegal intr_delay_resolution provided. Going to use default 1 usec resolution\n"); +- intr_delay_resolution = 1; ++ intr_delay_resolution = ENA_DEFAULT_INTR_DELAY_RESOLUTION; + } +- ena_dev->intr_delay_resolution = intr_delay_resolution; + + /* update Rx */ +- ena_dev->intr_moder_rx_interval /= intr_delay_resolution; ++ ena_dev->intr_moder_rx_interval = ++ ena_dev->intr_moder_rx_interval * ++ prev_intr_delay_resolution / ++ intr_delay_resolution; + + /* update Tx */ +- ena_dev->intr_moder_tx_interval /= intr_delay_resolution; ++ ena_dev->intr_moder_tx_interval = ++ ena_dev->intr_moder_tx_interval * ++ prev_intr_delay_resolution / ++ intr_delay_resolution; ++ ++ ena_dev->intr_delay_resolution = intr_delay_resolution; + } + + /*****************************************************************************/ +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -74,6 +74,7 @@ + + #define ENA_INTR_INITIAL_TX_INTERVAL_USECS 196 + #define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0 ++#define ENA_DEFAULT_INTR_DELAY_RESOLUTION 1 + + #define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3502,6 +3502,7 @@ static int ena_probe(struct pci_dev *pde + */ + ena_dev->intr_moder_tx_interval = ENA_INTR_INITIAL_TX_INTERVAL_USECS; + ena_dev->intr_moder_rx_interval = ENA_INTR_INITIAL_RX_INTERVAL_USECS; ++ ena_dev->intr_delay_resolution = ENA_DEFAULT_INTR_DELAY_RESOLUTION; + io_queue_num = ena_calc_io_queue_num(pdev, ena_dev, &get_feat_ctx); + rc = ena_calc_queue_size(&calc_queue_ctx); + if (rc || io_queue_num <= 0) { diff --git a/debian/patches/features/all/ena/net-ena-fix-retrieval-of-nonadaptive-interrupt-moder.patch b/debian/patches/features/all/ena/net-ena-fix-retrieval-of-nonadaptive-interrupt-moder.patch new file mode 100644 index 000000000..353f87dbf --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-fix-retrieval-of-nonadaptive-interrupt-moder.patch @@ -0,0 +1,45 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:35 +0300 +Subject: [PATCH] net: ena: fix retrieval of nonadaptive interrupt moderation + intervals +Origin: https://git.kernel.org/linus/0eda847953d8dfb4b713ea62420f66157e230e13 +Bug-Debian: https://bugs.debian.org/941291 + +Nonadaptive interrupt moderation intervals are assigned the value set +by the user in ethtool -C divided by ena_dev->intr_delay_resolution. + +Therefore when the user tries to get the nonadaptive interrupt moderation +intervals with ethtool -c the code needs to multiply the saved value +by ena_dev->intr_delay_resolution. + +The current code erroneously divides instead of multiplying in ethtool -c. +This patch fixes this. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -310,14 +310,15 @@ static int ena_get_coalesce(struct net_d + /* the devie doesn't support interrupt moderation */ + return -EOPNOTSUPP; + } ++ + coalesce->tx_coalesce_usecs = +- ena_com_get_nonadaptive_moderation_interval_tx(ena_dev) / ++ ena_com_get_nonadaptive_moderation_interval_tx(ena_dev) * + ena_dev->intr_delay_resolution; + + if (!ena_com_get_adaptive_moderation_enabled(ena_dev)) + coalesce->rx_coalesce_usecs = + ena_com_get_nonadaptive_moderation_interval_rx(ena_dev) +- / ena_dev->intr_delay_resolution; ++ * ena_dev->intr_delay_resolution; + + coalesce->use_adaptive_rx_coalesce = + ena_com_get_adaptive_moderation_enabled(ena_dev); diff --git a/debian/patches/features/all/ena/net-ena-fix-return-value-of-ena_com_config_llq_info.patch b/debian/patches/features/all/ena/net-ena-fix-return-value-of-ena_com_config_llq_info.patch new file mode 100644 index 000000000..f757bf178 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-fix-return-value-of-ena_com_config_llq_info.patch @@ -0,0 +1,34 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Wed, 1 May 2019 16:47:07 +0300 +Subject: [PATCH] net: ena: fix return value of ena_com_config_llq_info() +Origin: https://git.kernel.org/linus/9a27de0c6ba10fe1af74d16d3524425e52c1ba3e +Bug-Debian: https://bugs.debian.org/941291 + +ena_com_config_llq_info() returns 0 even if ena_com_set_llq() fails. +Return the failure code of ena_com_set_llq() in case it fails. + +fixes: 689b2bdaaa14 ("net: ena: add functions for handling Low Latency Queues in ena_com") + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/amazon/ena/ena_com.c b/drivers/net/ethernet/amazon/ena/ena_com.c +index f9bc0b831a1a..4fe437fe771b 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_com.c ++++ b/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -731,7 +731,7 @@ static int ena_com_config_llq_info(struct ena_com_dev *ena_dev, + if (rc) + pr_err("Cannot set LLQ configuration: %d\n", rc); + +- return 0; ++ return rc; + } + + static int ena_com_wait_and_process_admin_cq_interrupts(struct ena_comp_ctx *comp_ctx, +-- +2.17.1 + diff --git a/debian/patches/features/all/ena/net-ena-fix-set-freed-objects-to-NULL-to-avoid-faili.patch b/debian/patches/features/all/ena/net-ena-fix-set-freed-objects-to-NULL-to-avoid-faili.patch new file mode 100644 index 000000000..bc30849de --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-fix-set-freed-objects-to-NULL-to-avoid-faili.patch @@ -0,0 +1,91 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Wed, 1 May 2019 16:47:04 +0300 +Subject: [PATCH] net: ena: fix: set freed objects to NULL to avoid failing + future allocations +Origin: https://git.kernel.org/linus/8ee8ee7fe87bf64738ab4e31be036a7165608b27 +Bug-Debian: https://bugs.debian.org/941291 + +In some cases when a queue related allocation fails, successful past +allocations are freed but the pointer that pointed to them is not +set to NULL. This is a problem for 2 reasons: +1. This is generally a bad practice since this pointer might be +accidentally accessed in the future. +2. Future allocations using the same pointer check if the pointer +is NULL and fail if it is not. + +Fixed this by setting such pointers to NULL in the allocation of +queue related objects. + +Also refactored the code of ena_setup_tx_resources() to goto-style +error handling to avoid code duplication of resource freeing. + +Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)") +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 25 ++++++++++++-------- + 1 file changed, 15 insertions(+), 10 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -224,28 +224,23 @@ static int ena_setup_tx_resources(struct + if (!tx_ring->tx_buffer_info) { + tx_ring->tx_buffer_info = vzalloc(size); + if (!tx_ring->tx_buffer_info) +- return -ENOMEM; ++ goto err_tx_buffer_info; + } + + size = sizeof(u16) * tx_ring->ring_size; + tx_ring->free_tx_ids = vzalloc_node(size, node); + if (!tx_ring->free_tx_ids) { + tx_ring->free_tx_ids = vzalloc(size); +- if (!tx_ring->free_tx_ids) { +- vfree(tx_ring->tx_buffer_info); +- return -ENOMEM; +- } ++ if (!tx_ring->free_tx_ids) ++ goto err_free_tx_ids; + } + + size = tx_ring->tx_max_header_size; + tx_ring->push_buf_intermediate_buf = vzalloc_node(size, node); + if (!tx_ring->push_buf_intermediate_buf) { + tx_ring->push_buf_intermediate_buf = vzalloc(size); +- if (!tx_ring->push_buf_intermediate_buf) { +- vfree(tx_ring->tx_buffer_info); +- vfree(tx_ring->free_tx_ids); +- return -ENOMEM; +- } ++ if (!tx_ring->push_buf_intermediate_buf) ++ goto err_push_buf_intermediate_buf; + } + + /* Req id ring for TX out of order completions */ +@@ -259,6 +254,15 @@ static int ena_setup_tx_resources(struct + tx_ring->next_to_clean = 0; + tx_ring->cpu = ena_irq->cpu; + return 0; ++ ++err_push_buf_intermediate_buf: ++ vfree(tx_ring->free_tx_ids); ++ tx_ring->free_tx_ids = NULL; ++err_free_tx_ids: ++ vfree(tx_ring->tx_buffer_info); ++ tx_ring->tx_buffer_info = NULL; ++err_tx_buffer_info: ++ return -ENOMEM; + } + + /* ena_free_tx_resources - Free I/O Tx Resources per Queue +@@ -378,6 +382,7 @@ static int ena_setup_rx_resources(struct + rx_ring->free_rx_ids = vzalloc(size); + if (!rx_ring->free_rx_ids) { + vfree(rx_ring->rx_buffer_info); ++ rx_ring->rx_buffer_info = NULL; + return -ENOMEM; + } + } diff --git a/debian/patches/features/all/ena/net-ena-fix-update-of-interrupt-moderation-register.patch b/debian/patches/features/all/ena/net-ena-fix-update-of-interrupt-moderation-register.patch new file mode 100644 index 000000000..72137a523 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-fix-update-of-interrupt-moderation-register.patch @@ -0,0 +1,39 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:34 +0300 +Subject: [PATCH] net: ena: fix update of interrupt moderation register +Origin: https://git.kernel.org/linus/7b8a28787e2ba671eaeb073e3b62fb4786338a09 +Bug-Debian: https://bugs.debian.org/941291 + +Current implementation always updates the interrupt register with +the smoothed_interval of the rx_ring. However this should be +done only in case of adaptive interrupt moderation. If non-adaptive +interrupt moderation is used, the non-adaptive interrupt moderation +interval should be used. This commit fixes that. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -1188,12 +1188,15 @@ static void ena_unmask_interrupt(struct + struct ena_ring *rx_ring) + { + struct ena_eth_io_intr_reg intr_reg; ++ u32 rx_interval = ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev) ? ++ rx_ring->smoothed_interval : ++ ena_com_get_nonadaptive_moderation_interval_rx(rx_ring->ena_dev); + + /* Update intr register: rx intr delay, + * tx intr delay and interrupt unmask + */ + ena_com_update_intr_reg(&intr_reg, +- rx_ring->smoothed_interval, ++ rx_interval, + tx_ring->smoothed_interval, + true); + diff --git a/debian/patches/features/all/ena/net-ena-improve-latency-by-disabling-adaptive-interr.patch b/debian/patches/features/all/ena/net-ena-improve-latency-by-disabling-adaptive-interr.patch new file mode 100644 index 000000000..ec5dc707c --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-improve-latency-by-disabling-adaptive-interr.patch @@ -0,0 +1,41 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Wed, 1 May 2019 16:47:08 +0300 +Subject: [PATCH] net: ena: improve latency by disabling adaptive interrupt + moderation by default +Origin: https://git.kernel.org/linus/78cb421d185cfb4fcea94e7c3ff6e6ea77bb8c11 +Bug-Debian: https://bugs.debian.org/941291 + +Adaptive interrupt moderation was erroneously enabled by default +in the driver. + +In case the device supports adaptive interrupt moderation it will +be automatically used, which may potentially increase latency. + +The adaptive moderation can be enabled from ethtool command in +case the feature is supported by the device. + +Fixes: 1738cd3ed342 ("net: ena: Add a driver for Amazon Elastic Network Adapters (ENA)") +Signed-off-by: Guy Tzalik <gtzalik@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -2801,7 +2801,11 @@ int ena_com_init_interrupt_moderation(st + /* if moderation is supported by device we set adaptive moderation */ + delay_resolution = get_resp.u.intr_moderation.intr_delay_resolution; + ena_com_update_intr_delay_resolution(ena_dev, delay_resolution); +- ena_com_enable_adaptive_moderation(ena_dev); ++ ++ /* Disable adaptive moderation by default - can be enabled from ++ * ethtool ++ */ ++ ena_com_disable_adaptive_moderation(ena_dev); + + return 0; + err: diff --git a/debian/patches/features/all/ena/net-ena-make-ethtool-show-correct-current-and-max-qu.patch b/debian/patches/features/all/ena/net-ena-make-ethtool-show-correct-current-and-max-qu.patch new file mode 100644 index 000000000..3367bc9f9 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-make-ethtool-show-correct-current-and-max-qu.patch @@ -0,0 +1,53 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Tue, 11 Jun 2019 14:58:07 +0300 +Subject: [PATCH] net: ena: make ethtool show correct current and max queue + sizes +Origin: https://git.kernel.org/linus/9f9ae3f98b8d8b8aa709831057759dbb52ba5083 +Bug-Debian: https://bugs.debian.org/941291 + +Currently ethtool -g shows the same size for current and max queue +sizes. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 10 ++++------ + drivers/net/ethernet/amazon/ena/ena_netdev.c | 2 ++ + 2 files changed, 6 insertions(+), 6 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -447,13 +447,11 @@ static void ena_get_ringparam(struct net + struct ethtool_ringparam *ring) + { + struct ena_adapter *adapter = netdev_priv(netdev); +- struct ena_ring *tx_ring = &adapter->tx_ring[0]; +- struct ena_ring *rx_ring = &adapter->rx_ring[0]; + +- ring->rx_max_pending = rx_ring->ring_size; +- ring->tx_max_pending = tx_ring->ring_size; +- ring->rx_pending = rx_ring->ring_size; +- ring->tx_pending = tx_ring->ring_size; ++ ring->tx_max_pending = adapter->max_tx_ring_size; ++ ring->rx_max_pending = adapter->max_rx_ring_size; ++ ring->tx_pending = adapter->tx_ring_size; ++ ring->rx_pending = adapter->rx_ring_size; + } + + static u32 ena_flow_hash_to_flow_type(u16 hash_fields) +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3428,6 +3428,8 @@ static int ena_probe(struct pci_dev *pde + + adapter->tx_ring_size = calc_queue_ctx.tx_queue_size; + adapter->rx_ring_size = calc_queue_ctx.rx_queue_size; ++ adapter->max_tx_ring_size = calc_queue_ctx.max_tx_queue_size; ++ adapter->max_rx_ring_size = calc_queue_ctx.max_rx_queue_size; + adapter->max_tx_sgl_size = calc_queue_ctx.max_tx_sgl_size; + adapter->max_rx_sgl_size = calc_queue_ctx.max_rx_sgl_size; + diff --git a/debian/patches/features/all/ena/net-ena-optimise-calculations-for-CQ-doorbell.patch b/debian/patches/features/all/ena/net-ena-optimise-calculations-for-CQ-doorbell.patch new file mode 100644 index 000000000..c790eae13 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-optimise-calculations-for-CQ-doorbell.patch @@ -0,0 +1,50 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Mon, 3 Jun 2019 17:43:27 +0300 +Subject: [PATCH] net: ena: optimise calculations for CQ doorbell +Origin: https://git.kernel.org/linus/d91860989dd4bce582ed6c3647a0d41d6fd895b3 +Bug-Debian: https://bugs.debian.org/941291 + +This patch initially checks if CQ doorbell +is needed before proceeding with the calculations. + +Signed-off-by: Igor Chauskin <igorch@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_eth_com.h | 20 ++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/drivers/net/ethernet/amazon/ena/ena_eth_com.h b/drivers/net/ethernet/amazon/ena/ena_eth_com.h +index 0a3d9180e40e..77986c0ea52c 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_eth_com.h ++++ b/drivers/net/ethernet/amazon/ena/ena_eth_com.h +@@ -195,15 +195,17 @@ static inline int ena_com_update_dev_comp_head(struct ena_com_io_cq *io_cq) + u16 unreported_comp, head; + bool need_update; + +- head = io_cq->head; +- unreported_comp = head - io_cq->last_head_update; +- need_update = unreported_comp > (io_cq->q_depth / ENA_COMP_HEAD_THRESH); +- +- if (io_cq->cq_head_db_reg && need_update) { +- pr_debug("Write completion queue doorbell for queue %d: head: %d\n", +- io_cq->qid, head); +- writel(head, io_cq->cq_head_db_reg); +- io_cq->last_head_update = head; ++ if (unlikely(io_cq->cq_head_db_reg)) { ++ head = io_cq->head; ++ unreported_comp = head - io_cq->last_head_update; ++ need_update = unreported_comp > (io_cq->q_depth / ENA_COMP_HEAD_THRESH); ++ ++ if (unlikely(need_update)) { ++ pr_debug("Write completion queue doorbell for queue %d: head: %d\n", ++ io_cq->qid, head); ++ writel(head, io_cq->cq_head_db_reg); ++ io_cq->last_head_update = head; ++ } + } + + return 0; +-- +2.17.1 + diff --git a/debian/patches/features/all/ena/net-ena-reimplement-set-get_coalesce.patch b/debian/patches/features/all/ena/net-ena-reimplement-set-get_coalesce.patch new file mode 100644 index 000000000..c88ebef3a --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-reimplement-set-get_coalesce.patch @@ -0,0 +1,158 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:28 +0300 +Subject: [PATCH] net: ena: reimplement set/get_coalesce() +Origin: https://git.kernel.org/linus/b3db86dc4b82ffc63e33c78dafc09d5c78ac4fe4 +Bug-Debian: https://bugs.debian.org/941291 + +1. Remove old adaptive interrupt moderation code from set/get_coalesce() +2. Add ena_update_rx_rings_intr_moderation() function for updating + nonadaptive interrupt moderation intervals similarly to + ena_update_tx_rings_intr_moderation(). +3. Remove checks of multiple unsupported received interrupt coalescing + parameters. This makes code cleaner and cancels the need to update + it every time a new coalescing parameter is invented. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_ethtool.c | 84 ++++++------------- + 1 file changed, 26 insertions(+), 58 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_ethtool.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_ethtool.c +@@ -305,7 +305,6 @@ static int ena_get_coalesce(struct net_d + { + struct ena_adapter *adapter = netdev_priv(net_dev); + struct ena_com_dev *ena_dev = adapter->ena_dev; +- struct ena_intr_moder_entry intr_moder_entry; + + if (!ena_com_interrupt_moderation_supported(ena_dev)) { + /* the devie doesn't support interrupt moderation */ +@@ -314,23 +313,12 @@ static int ena_get_coalesce(struct net_d + coalesce->tx_coalesce_usecs = + ena_com_get_nonadaptive_moderation_interval_tx(ena_dev) / + ena_dev->intr_delay_resolution; +- if (!ena_com_get_adaptive_moderation_enabled(ena_dev)) { ++ ++ if (!ena_com_get_adaptive_moderation_enabled(ena_dev)) + coalesce->rx_coalesce_usecs = + ena_com_get_nonadaptive_moderation_interval_rx(ena_dev) + / ena_dev->intr_delay_resolution; +- } else { +- ena_com_get_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_LOWEST, &intr_moder_entry); +- coalesce->rx_coalesce_usecs_low = intr_moder_entry.intr_moder_interval; +- coalesce->rx_max_coalesced_frames_low = intr_moder_entry.pkts_per_interval; +- +- ena_com_get_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_MID, &intr_moder_entry); +- coalesce->rx_coalesce_usecs = intr_moder_entry.intr_moder_interval; +- coalesce->rx_max_coalesced_frames = intr_moder_entry.pkts_per_interval; +- +- ena_com_get_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_HIGHEST, &intr_moder_entry); +- coalesce->rx_coalesce_usecs_high = intr_moder_entry.intr_moder_interval; +- coalesce->rx_max_coalesced_frames_high = intr_moder_entry.pkts_per_interval; +- } ++ + coalesce->use_adaptive_rx_coalesce = + ena_com_get_adaptive_moderation_enabled(ena_dev); + +@@ -348,12 +336,22 @@ static void ena_update_tx_rings_intr_mod + adapter->tx_ring[i].smoothed_interval = val; + } + ++static void ena_update_rx_rings_intr_moderation(struct ena_adapter *adapter) ++{ ++ unsigned int val; ++ int i; ++ ++ val = ena_com_get_nonadaptive_moderation_interval_rx(adapter->ena_dev); ++ ++ for (i = 0; i < adapter->num_queues; i++) ++ adapter->rx_ring[i].smoothed_interval = val; ++} ++ + static int ena_set_coalesce(struct net_device *net_dev, + struct ethtool_coalesce *coalesce) + { + struct ena_adapter *adapter = netdev_priv(net_dev); + struct ena_com_dev *ena_dev = adapter->ena_dev; +- struct ena_intr_moder_entry intr_moder_entry; + int rc; + + if (!ena_com_interrupt_moderation_supported(ena_dev)) { +@@ -361,22 +359,6 @@ static int ena_set_coalesce(struct net_d + return -EOPNOTSUPP; + } + +- if (coalesce->rx_coalesce_usecs_irq || +- coalesce->rx_max_coalesced_frames_irq || +- coalesce->tx_coalesce_usecs_irq || +- coalesce->tx_max_coalesced_frames || +- coalesce->tx_max_coalesced_frames_irq || +- coalesce->stats_block_coalesce_usecs || +- coalesce->use_adaptive_tx_coalesce || +- coalesce->pkt_rate_low || +- coalesce->tx_coalesce_usecs_low || +- coalesce->tx_max_coalesced_frames_low || +- coalesce->pkt_rate_high || +- coalesce->tx_coalesce_usecs_high || +- coalesce->tx_max_coalesced_frames_high || +- coalesce->rate_sample_interval) +- return -EINVAL; +- + rc = ena_com_update_nonadaptive_moderation_interval_tx(ena_dev, + coalesce->tx_coalesce_usecs); + if (rc) +@@ -384,37 +366,23 @@ static int ena_set_coalesce(struct net_d + + ena_update_tx_rings_intr_moderation(adapter); + +- if (ena_com_get_adaptive_moderation_enabled(ena_dev)) { +- if (!coalesce->use_adaptive_rx_coalesce) { +- ena_com_disable_adaptive_moderation(ena_dev); +- rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev, +- coalesce->rx_coalesce_usecs); +- return rc; +- } +- } else { /* was in non-adaptive mode */ +- if (coalesce->use_adaptive_rx_coalesce) { ++ if (coalesce->use_adaptive_rx_coalesce) { ++ if (!ena_com_get_adaptive_moderation_enabled(ena_dev)) + ena_com_enable_adaptive_moderation(ena_dev); +- } else { +- rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev, +- coalesce->rx_coalesce_usecs); +- return rc; +- } ++ return 0; + } + +- intr_moder_entry.intr_moder_interval = coalesce->rx_coalesce_usecs_low; +- intr_moder_entry.pkts_per_interval = coalesce->rx_max_coalesced_frames_low; +- intr_moder_entry.bytes_per_interval = ENA_INTR_BYTE_COUNT_NOT_SUPPORTED; +- ena_com_init_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_LOWEST, &intr_moder_entry); +- +- intr_moder_entry.intr_moder_interval = coalesce->rx_coalesce_usecs; +- intr_moder_entry.pkts_per_interval = coalesce->rx_max_coalesced_frames; +- intr_moder_entry.bytes_per_interval = ENA_INTR_BYTE_COUNT_NOT_SUPPORTED; +- ena_com_init_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_MID, &intr_moder_entry); +- +- intr_moder_entry.intr_moder_interval = coalesce->rx_coalesce_usecs_high; +- intr_moder_entry.pkts_per_interval = coalesce->rx_max_coalesced_frames_high; +- intr_moder_entry.bytes_per_interval = ENA_INTR_BYTE_COUNT_NOT_SUPPORTED; +- ena_com_init_intr_moderation_entry(adapter->ena_dev, ENA_INTR_MODER_HIGHEST, &intr_moder_entry); ++ rc = ena_com_update_nonadaptive_moderation_interval_rx(ena_dev, ++ coalesce->rx_coalesce_usecs); ++ if (rc) ++ return rc; ++ ++ ena_update_rx_rings_intr_moderation(adapter); ++ ++ if (!coalesce->use_adaptive_rx_coalesce) { ++ if (ena_com_get_adaptive_moderation_enabled(ena_dev)) ++ ena_com_disable_adaptive_moderation(ena_dev); ++ } + + return 0; + } diff --git a/debian/patches/features/all/ena/net-ena-remove-all-old-adaptive-rx-interrupt-moderat.patch b/debian/patches/features/all/ena/net-ena-remove-all-old-adaptive-rx-interrupt-moderat.patch new file mode 100644 index 000000000..2f3c2839d --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-remove-all-old-adaptive-rx-interrupt-moderat.patch @@ -0,0 +1,361 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:33 +0300 +Subject: [PATCH] net: ena: remove all old adaptive rx interrupt moderation + code from ena_com +Origin: https://git.kernel.org/linus/3ced8cbdf7ddb3160ffa714a91040dd18f39a12c +Bug-Debian: https://bugs.debian.org/941291 + +Remove previous implementation of adaptive rx interrupt moderation +from ena_com files. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 110 ----------------- + drivers/net/ethernet/amazon/ena/ena_com.h | 142 ---------------------- + 2 files changed, 252 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -1278,22 +1278,6 @@ static int ena_com_ind_tbl_convert_from_ + return 0; + } + +-static int ena_com_init_interrupt_moderation_table(struct ena_com_dev *ena_dev) +-{ +- size_t size; +- +- size = sizeof(struct ena_intr_moder_entry) * ENA_INTR_MAX_NUM_OF_LEVELS; +- +- ena_dev->intr_moder_tbl = +- devm_kzalloc(ena_dev->dmadev, size, GFP_KERNEL); +- if (!ena_dev->intr_moder_tbl) +- return -ENOMEM; +- +- ena_com_config_default_interrupt_moderation_table(ena_dev); +- +- return 0; +-} +- + static void ena_com_update_intr_delay_resolution(struct ena_com_dev *ena_dev, + u16 intr_delay_resolution) + { +@@ -2802,13 +2786,6 @@ int ena_com_update_nonadaptive_moderatio + &ena_dev->intr_moder_rx_interval); + } + +-void ena_com_destroy_interrupt_moderation(struct ena_com_dev *ena_dev) +-{ +- if (ena_dev->intr_moder_tbl) +- devm_kfree(ena_dev->dmadev, ena_dev->intr_moder_tbl); +- ena_dev->intr_moder_tbl = NULL; +-} +- + int ena_com_init_interrupt_moderation(struct ena_com_dev *ena_dev) + { + struct ena_admin_get_feat_resp get_resp; +@@ -2833,10 +2810,6 @@ int ena_com_init_interrupt_moderation(st + return rc; + } + +- rc = ena_com_init_interrupt_moderation_table(ena_dev); +- if (rc) +- goto err; +- + /* if moderation is supported by device we set adaptive moderation */ + delay_resolution = get_resp.u.intr_moderation.intr_delay_resolution; + ena_com_update_intr_delay_resolution(ena_dev, delay_resolution); +@@ -2845,52 +2818,6 @@ int ena_com_init_interrupt_moderation(st + ena_com_disable_adaptive_moderation(ena_dev); + + return 0; +-err: +- ena_com_destroy_interrupt_moderation(ena_dev); +- return rc; +-} +- +-void ena_com_config_default_interrupt_moderation_table(struct ena_com_dev *ena_dev) +-{ +- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl; +- +- if (!intr_moder_tbl) +- return; +- +- intr_moder_tbl[ENA_INTR_MODER_LOWEST].intr_moder_interval = +- ENA_INTR_LOWEST_USECS; +- intr_moder_tbl[ENA_INTR_MODER_LOWEST].pkts_per_interval = +- ENA_INTR_LOWEST_PKTS; +- intr_moder_tbl[ENA_INTR_MODER_LOWEST].bytes_per_interval = +- ENA_INTR_LOWEST_BYTES; +- +- intr_moder_tbl[ENA_INTR_MODER_LOW].intr_moder_interval = +- ENA_INTR_LOW_USECS; +- intr_moder_tbl[ENA_INTR_MODER_LOW].pkts_per_interval = +- ENA_INTR_LOW_PKTS; +- intr_moder_tbl[ENA_INTR_MODER_LOW].bytes_per_interval = +- ENA_INTR_LOW_BYTES; +- +- intr_moder_tbl[ENA_INTR_MODER_MID].intr_moder_interval = +- ENA_INTR_MID_USECS; +- intr_moder_tbl[ENA_INTR_MODER_MID].pkts_per_interval = +- ENA_INTR_MID_PKTS; +- intr_moder_tbl[ENA_INTR_MODER_MID].bytes_per_interval = +- ENA_INTR_MID_BYTES; +- +- intr_moder_tbl[ENA_INTR_MODER_HIGH].intr_moder_interval = +- ENA_INTR_HIGH_USECS; +- intr_moder_tbl[ENA_INTR_MODER_HIGH].pkts_per_interval = +- ENA_INTR_HIGH_PKTS; +- intr_moder_tbl[ENA_INTR_MODER_HIGH].bytes_per_interval = +- ENA_INTR_HIGH_BYTES; +- +- intr_moder_tbl[ENA_INTR_MODER_HIGHEST].intr_moder_interval = +- ENA_INTR_HIGHEST_USECS; +- intr_moder_tbl[ENA_INTR_MODER_HIGHEST].pkts_per_interval = +- ENA_INTR_HIGHEST_PKTS; +- intr_moder_tbl[ENA_INTR_MODER_HIGHEST].bytes_per_interval = +- ENA_INTR_HIGHEST_BYTES; + } + + unsigned int ena_com_get_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev) +@@ -2903,43 +2830,6 @@ unsigned int ena_com_get_nonadaptive_mod + return ena_dev->intr_moder_rx_interval; + } + +-void ena_com_init_intr_moderation_entry(struct ena_com_dev *ena_dev, +- enum ena_intr_moder_level level, +- struct ena_intr_moder_entry *entry) +-{ +- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl; +- +- if (level >= ENA_INTR_MAX_NUM_OF_LEVELS) +- return; +- +- intr_moder_tbl[level].intr_moder_interval = entry->intr_moder_interval; +- if (ena_dev->intr_delay_resolution) +- intr_moder_tbl[level].intr_moder_interval /= +- ena_dev->intr_delay_resolution; +- intr_moder_tbl[level].pkts_per_interval = entry->pkts_per_interval; +- +- /* use hardcoded value until ethtool supports bytecount parameter */ +- if (entry->bytes_per_interval != ENA_INTR_BYTE_COUNT_NOT_SUPPORTED) +- intr_moder_tbl[level].bytes_per_interval = entry->bytes_per_interval; +-} +- +-void ena_com_get_intr_moderation_entry(struct ena_com_dev *ena_dev, +- enum ena_intr_moder_level level, +- struct ena_intr_moder_entry *entry) +-{ +- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl; +- +- if (level >= ENA_INTR_MAX_NUM_OF_LEVELS) +- return; +- +- entry->intr_moder_interval = intr_moder_tbl[level].intr_moder_interval; +- if (ena_dev->intr_delay_resolution) +- entry->intr_moder_interval *= ena_dev->intr_delay_resolution; +- entry->pkts_per_interval = +- intr_moder_tbl[level].pkts_per_interval; +- entry->bytes_per_interval = intr_moder_tbl[level].bytes_per_interval; +-} +- + int ena_com_config_dev_mode(struct ena_com_dev *ena_dev, + struct ena_admin_feature_llq_desc *llq_features, + struct ena_llq_configurations *llq_default_cfg) +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.h +@@ -72,46 +72,13 @@ + /*****************************************************************************/ + /* ENA adaptive interrupt moderation settings */ + +-#define ENA_INTR_LOWEST_USECS (0) +-#define ENA_INTR_LOWEST_PKTS (3) +-#define ENA_INTR_LOWEST_BYTES (2 * 1524) +- +-#define ENA_INTR_LOW_USECS (32) +-#define ENA_INTR_LOW_PKTS (12) +-#define ENA_INTR_LOW_BYTES (16 * 1024) +- +-#define ENA_INTR_MID_USECS (80) +-#define ENA_INTR_MID_PKTS (48) +-#define ENA_INTR_MID_BYTES (64 * 1024) +- +-#define ENA_INTR_HIGH_USECS (128) +-#define ENA_INTR_HIGH_PKTS (96) +-#define ENA_INTR_HIGH_BYTES (128 * 1024) +- +-#define ENA_INTR_HIGHEST_USECS (192) +-#define ENA_INTR_HIGHEST_PKTS (128) +-#define ENA_INTR_HIGHEST_BYTES (192 * 1024) +- + #define ENA_INTR_INITIAL_TX_INTERVAL_USECS 196 + #define ENA_INTR_INITIAL_RX_INTERVAL_USECS 0 +-#define ENA_INTR_DELAY_OLD_VALUE_WEIGHT 6 +-#define ENA_INTR_DELAY_NEW_VALUE_WEIGHT 4 +-#define ENA_INTR_MODER_LEVEL_STRIDE 2 +-#define ENA_INTR_BYTE_COUNT_NOT_SUPPORTED 0xFFFFFF + + #define ENA_HW_HINTS_NO_TIMEOUT 0xFFFF + + #define ENA_FEATURE_MAX_QUEUE_EXT_VER 1 + +-enum ena_intr_moder_level { +- ENA_INTR_MODER_LOWEST = 0, +- ENA_INTR_MODER_LOW, +- ENA_INTR_MODER_MID, +- ENA_INTR_MODER_HIGH, +- ENA_INTR_MODER_HIGHEST, +- ENA_INTR_MAX_NUM_OF_LEVELS, +-}; +- + struct ena_llq_configurations { + enum ena_admin_llq_header_location llq_header_location; + enum ena_admin_llq_ring_entry_size llq_ring_entry_size; +@@ -120,12 +87,6 @@ struct ena_llq_configurations { + u16 llq_ring_entry_size_value; + }; + +-struct ena_intr_moder_entry { +- unsigned int intr_moder_interval; +- unsigned int pkts_per_interval; +- unsigned int bytes_per_interval; +-}; +- + enum queue_direction { + ENA_COM_IO_QUEUE_DIRECTION_TX, + ENA_COM_IO_QUEUE_DIRECTION_RX +@@ -920,11 +881,6 @@ int ena_com_execute_admin_command(struct + */ + int ena_com_init_interrupt_moderation(struct ena_com_dev *ena_dev); + +-/* ena_com_destroy_interrupt_moderation - Destroy interrupt moderation resources +- * @ena_dev: ENA communication layer struct +- */ +-void ena_com_destroy_interrupt_moderation(struct ena_com_dev *ena_dev); +- + /* ena_com_interrupt_moderation_supported - Return if interrupt moderation + * capability is supported by the device. + * +@@ -932,12 +888,6 @@ void ena_com_destroy_interrupt_moderatio + */ + bool ena_com_interrupt_moderation_supported(struct ena_com_dev *ena_dev); + +-/* ena_com_config_default_interrupt_moderation_table - Restore the interrupt +- * moderation table back to the default parameters. +- * @ena_dev: ENA communication layer struct +- */ +-void ena_com_config_default_interrupt_moderation_table(struct ena_com_dev *ena_dev); +- + /* ena_com_update_nonadaptive_moderation_interval_tx - Update the + * non-adaptive interval in Tx direction. + * @ena_dev: ENA communication layer struct +@@ -974,29 +924,6 @@ unsigned int ena_com_get_nonadaptive_mod + */ + unsigned int ena_com_get_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev); + +-/* ena_com_init_intr_moderation_entry - Update a single entry in the interrupt +- * moderation table. +- * @ena_dev: ENA communication layer struct +- * @level: Interrupt moderation table level +- * @entry: Entry value +- * +- * Update a single entry in the interrupt moderation table. +- */ +-void ena_com_init_intr_moderation_entry(struct ena_com_dev *ena_dev, +- enum ena_intr_moder_level level, +- struct ena_intr_moder_entry *entry); +- +-/* ena_com_get_intr_moderation_entry - Init ena_intr_moder_entry. +- * @ena_dev: ENA communication layer struct +- * @level: Interrupt moderation table level +- * @entry: Entry to fill. +- * +- * Initialize the entry according to the adaptive interrupt moderation table. +- */ +-void ena_com_get_intr_moderation_entry(struct ena_com_dev *ena_dev, +- enum ena_intr_moder_level level, +- struct ena_intr_moder_entry *entry); +- + /* ena_com_config_dev_mode - Configure the placement policy of the device. + * @ena_dev: ENA communication layer struct + * @llq_features: LLQ feature descriptor, retrieve via +@@ -1022,75 +949,6 @@ static inline void ena_com_disable_adapt + ena_dev->adaptive_coalescing = false; + } + +-/* ena_com_calculate_interrupt_delay - Calculate new interrupt delay +- * @ena_dev: ENA communication layer struct +- * @pkts: Number of packets since the last update +- * @bytes: Number of bytes received since the last update. +- * @smoothed_interval: Returned interval +- * @moder_tbl_idx: Current table level as input update new level as return +- * value. +- */ +-static inline void ena_com_calculate_interrupt_delay(struct ena_com_dev *ena_dev, +- unsigned int pkts, +- unsigned int bytes, +- unsigned int *smoothed_interval, +- unsigned int *moder_tbl_idx) +-{ +- enum ena_intr_moder_level curr_moder_idx, new_moder_idx; +- struct ena_intr_moder_entry *curr_moder_entry; +- struct ena_intr_moder_entry *pred_moder_entry; +- struct ena_intr_moder_entry *new_moder_entry; +- struct ena_intr_moder_entry *intr_moder_tbl = ena_dev->intr_moder_tbl; +- unsigned int interval; +- +- /* We apply adaptive moderation on Rx path only. +- * Tx uses static interrupt moderation. +- */ +- if (!pkts || !bytes) +- /* Tx interrupt, or spurious interrupt, +- * in both cases we just use same delay values +- */ +- return; +- +- curr_moder_idx = (enum ena_intr_moder_level)(*moder_tbl_idx); +- if (unlikely(curr_moder_idx >= ENA_INTR_MAX_NUM_OF_LEVELS)) { +- pr_err("Wrong moderation index %u\n", curr_moder_idx); +- return; +- } +- +- curr_moder_entry = &intr_moder_tbl[curr_moder_idx]; +- new_moder_idx = curr_moder_idx; +- +- if (curr_moder_idx == ENA_INTR_MODER_LOWEST) { +- if ((pkts > curr_moder_entry->pkts_per_interval) || +- (bytes > curr_moder_entry->bytes_per_interval)) +- new_moder_idx = +- (enum ena_intr_moder_level)(curr_moder_idx + ENA_INTR_MODER_LEVEL_STRIDE); +- } else { +- pred_moder_entry = &intr_moder_tbl[curr_moder_idx - ENA_INTR_MODER_LEVEL_STRIDE]; +- +- if ((pkts <= pred_moder_entry->pkts_per_interval) || +- (bytes <= pred_moder_entry->bytes_per_interval)) +- new_moder_idx = +- (enum ena_intr_moder_level)(curr_moder_idx - ENA_INTR_MODER_LEVEL_STRIDE); +- else if ((pkts > curr_moder_entry->pkts_per_interval) || +- (bytes > curr_moder_entry->bytes_per_interval)) { +- if (curr_moder_idx != ENA_INTR_MODER_HIGHEST) +- new_moder_idx = +- (enum ena_intr_moder_level)(curr_moder_idx + ENA_INTR_MODER_LEVEL_STRIDE); +- } +- } +- new_moder_entry = &intr_moder_tbl[new_moder_idx]; +- +- interval = new_moder_entry->intr_moder_interval; +- *smoothed_interval = ( +- (interval * ENA_INTR_DELAY_NEW_VALUE_WEIGHT + +- ENA_INTR_DELAY_OLD_VALUE_WEIGHT * (*smoothed_interval)) + 5) / +- 10; +- +- *moder_tbl_idx = new_moder_idx; +-} +- + /* ena_com_update_intr_reg - Prepare interrupt register + * @intr_reg: interrupt register to update. + * @rx_delay_interval: Rx interval in usecs diff --git a/debian/patches/features/all/ena/net-ena-remove-code-duplication-in-ena_com_update_no.patch b/debian/patches/features/all/ena/net-ena-remove-code-duplication-in-ena_com_update_no.patch new file mode 100644 index 000000000..3dcad5609 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-remove-code-duplication-in-ena_com_update_no.patch @@ -0,0 +1,71 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:30 +0300 +Subject: [PATCH] net: ena: remove code duplication in + ena_com_update_nonadaptive_moderation_interval _*() +Origin: https://git.kernel.org/linus/57e3a5f24bb5bf265988e973a911845abcbf6a00 +Bug-Debian: https://bugs.debian.org/941291 + +Remove code duplication in: +ena_com_update_nonadaptive_moderation_interval_tx() +ena_com_update_nonadaptive_moderation_interval_rx() +functions. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 30 ++++++++++++----------- + 1 file changed, 16 insertions(+), 14 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -2772,32 +2772,34 @@ bool ena_com_interrupt_moderation_suppor + ENA_ADMIN_INTERRUPT_MODERATION); + } + +-int ena_com_update_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev, +- u32 tx_coalesce_usecs) ++static int ena_com_update_nonadaptive_moderation_interval(u32 coalesce_usecs, ++ u32 intr_delay_resolution, ++ u32 *intr_moder_interval) + { +- if (!ena_dev->intr_delay_resolution) { ++ if (!intr_delay_resolution) { + pr_err("Illegal interrupt delay granularity value\n"); + return -EFAULT; + } + +- ena_dev->intr_moder_tx_interval = tx_coalesce_usecs / +- ena_dev->intr_delay_resolution; ++ *intr_moder_interval = coalesce_usecs / intr_delay_resolution; + + return 0; + } + ++int ena_com_update_nonadaptive_moderation_interval_tx(struct ena_com_dev *ena_dev, ++ u32 tx_coalesce_usecs) ++{ ++ return ena_com_update_nonadaptive_moderation_interval(tx_coalesce_usecs, ++ ena_dev->intr_delay_resolution, ++ &ena_dev->intr_moder_tx_interval); ++} ++ + int ena_com_update_nonadaptive_moderation_interval_rx(struct ena_com_dev *ena_dev, + u32 rx_coalesce_usecs) + { +- if (!ena_dev->intr_delay_resolution) { +- pr_err("Illegal interrupt delay granularity value\n"); +- return -EFAULT; +- } +- +- ena_dev->intr_moder_rx_interval = rx_coalesce_usecs / +- ena_dev->intr_delay_resolution; +- +- return 0; ++ return ena_com_update_nonadaptive_moderation_interval(rx_coalesce_usecs, ++ ena_dev->intr_delay_resolution, ++ &ena_dev->intr_moder_rx_interval); + } + + void ena_com_destroy_interrupt_moderation(struct ena_com_dev *ena_dev) diff --git a/debian/patches/features/all/ena/net-ena-remove-ena_restore_ethtool_params-and-releva.patch b/debian/patches/features/all/ena/net-ena-remove-ena_restore_ethtool_params-and-releva.patch new file mode 100644 index 000000000..1dad10a1a --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-remove-ena_restore_ethtool_params-and-releva.patch @@ -0,0 +1,59 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:32 +0300 +Subject: [PATCH] net: ena: remove ena_restore_ethtool_params() and relevant + fields +Origin: https://git.kernel.org/linus/64d1fb9dfc6c5d8589312fa847fee14ec14ee12b +Bug-Debian: https://bugs.debian.org/941291 + +Deleted unused 4 fields from struct ena_adapter and their only user +ena_restore_ethtool_params(). + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 10 ---------- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 3 --- + 2 files changed, 13 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -1564,14 +1564,6 @@ static void ena_napi_enable_all(struct e + napi_enable(&adapter->ena_napi[i].napi); + } + +-static void ena_restore_ethtool_params(struct ena_adapter *adapter) +-{ +- adapter->tx_usecs = 0; +- adapter->rx_usecs = 0; +- adapter->tx_frames = 1; +- adapter->rx_frames = 1; +-} +- + /* Configure the Rx forwarding */ + static int ena_rss_configure(struct ena_adapter *adapter) + { +@@ -1621,8 +1613,6 @@ static int ena_up_complete(struct ena_ad + /* enable transmits */ + netif_tx_start_all_queues(adapter->netdev); + +- ena_restore_ethtool_params(adapter); +- + ena_napi_enable_all(adapter); + + return 0; +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -330,9 +330,6 @@ struct ena_adapter { + + u32 missing_tx_completion_threshold; + +- u32 tx_usecs, rx_usecs; /* interrupt moderation */ +- u32 tx_frames, rx_frames; /* interrupt moderation */ +- + u32 requested_tx_ring_size; + u32 requested_rx_ring_size; + diff --git a/debian/patches/features/all/ena/net-ena-remove-inline-keyword-from-functions-in-.c.patch b/debian/patches/features/all/ena/net-ena-remove-inline-keyword-from-functions-in-.c.patch new file mode 100644 index 000000000..8d4a2b349 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-remove-inline-keyword-from-functions-in-.c.patch @@ -0,0 +1,244 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Tue, 11 Jun 2019 14:58:10 +0300 +Subject: [PATCH] net: ena: remove inline keyword from functions in *.c +Origin: https://git.kernel.org/linus/c2b542044761965db0e4cc400ab6abf670fc25b7 +Bug-Debian: https://bugs.debian.org/941291 + +Let the compiler decide if the function should be inline in *.c files + +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 6 ++--- + drivers/net/ethernet/amazon/ena/ena_eth_com.c | 26 +++++++++---------- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 16 ++++++------ + 3 files changed, 24 insertions(+), 24 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -91,7 +91,7 @@ struct ena_com_stats_ctx { + struct ena_admin_acq_get_stats_resp get_resp; + }; + +-static inline int ena_com_mem_addr_set(struct ena_com_dev *ena_dev, ++static int ena_com_mem_addr_set(struct ena_com_dev *ena_dev, + struct ena_common_mem_addr *ena_addr, + dma_addr_t addr) + { +@@ -190,7 +190,7 @@ static int ena_com_admin_init_aenq(struc + return 0; + } + +-static inline void comp_ctxt_release(struct ena_com_admin_queue *queue, ++static void comp_ctxt_release(struct ena_com_admin_queue *queue, + struct ena_comp_ctx *comp_ctx) + { + comp_ctx->occupied = false; +@@ -277,7 +277,7 @@ static struct ena_comp_ctx *__ena_com_su + return comp_ctx; + } + +-static inline int ena_com_init_comp_ctxt(struct ena_com_admin_queue *queue) ++static int ena_com_init_comp_ctxt(struct ena_com_admin_queue *queue) + { + size_t size = queue->q_depth * sizeof(struct ena_comp_ctx); + struct ena_comp_ctx *comp_ctx; +Index: linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_eth_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_eth_com.c +@@ -32,7 +32,7 @@ + + #include "ena_eth_com.h" + +-static inline struct ena_eth_io_rx_cdesc_base *ena_com_get_next_rx_cdesc( ++static struct ena_eth_io_rx_cdesc_base *ena_com_get_next_rx_cdesc( + struct ena_com_io_cq *io_cq) + { + struct ena_eth_io_rx_cdesc_base *cdesc; +@@ -59,7 +59,7 @@ static inline struct ena_eth_io_rx_cdesc + return cdesc; + } + +-static inline void *get_sq_desc_regular_queue(struct ena_com_io_sq *io_sq) ++static void *get_sq_desc_regular_queue(struct ena_com_io_sq *io_sq) + { + u16 tail_masked; + u32 offset; +@@ -71,7 +71,7 @@ static inline void *get_sq_desc_regular_ + return (void *)((uintptr_t)io_sq->desc_addr.virt_addr + offset); + } + +-static inline int ena_com_write_bounce_buffer_to_dev(struct ena_com_io_sq *io_sq, ++static int ena_com_write_bounce_buffer_to_dev(struct ena_com_io_sq *io_sq, + u8 *bounce_buffer) + { + struct ena_com_llq_info *llq_info = &io_sq->llq_info; +@@ -111,7 +111,7 @@ static inline int ena_com_write_bounce_b + return 0; + } + +-static inline int ena_com_write_header_to_bounce(struct ena_com_io_sq *io_sq, ++static int ena_com_write_header_to_bounce(struct ena_com_io_sq *io_sq, + u8 *header_src, + u16 header_len) + { +@@ -142,7 +142,7 @@ static inline int ena_com_write_header_t + return 0; + } + +-static inline void *get_sq_desc_llq(struct ena_com_io_sq *io_sq) ++static void *get_sq_desc_llq(struct ena_com_io_sq *io_sq) + { + struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; + u8 *bounce_buffer; +@@ -162,7 +162,7 @@ static inline void *get_sq_desc_llq(stru + return sq_desc; + } + +-static inline int ena_com_close_bounce_buffer(struct ena_com_io_sq *io_sq) ++static int ena_com_close_bounce_buffer(struct ena_com_io_sq *io_sq) + { + struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; + struct ena_com_llq_info *llq_info = &io_sq->llq_info; +@@ -189,7 +189,7 @@ static inline int ena_com_close_bounce_b + return 0; + } + +-static inline void *get_sq_desc(struct ena_com_io_sq *io_sq) ++static void *get_sq_desc(struct ena_com_io_sq *io_sq) + { + if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) + return get_sq_desc_llq(io_sq); +@@ -197,7 +197,7 @@ static inline void *get_sq_desc(struct e + return get_sq_desc_regular_queue(io_sq); + } + +-static inline int ena_com_sq_update_llq_tail(struct ena_com_io_sq *io_sq) ++static int ena_com_sq_update_llq_tail(struct ena_com_io_sq *io_sq) + { + struct ena_com_llq_pkt_ctrl *pkt_ctrl = &io_sq->llq_buf_ctrl; + struct ena_com_llq_info *llq_info = &io_sq->llq_info; +@@ -225,7 +225,7 @@ static inline int ena_com_sq_update_llq_ + return 0; + } + +-static inline int ena_com_sq_update_tail(struct ena_com_io_sq *io_sq) ++static int ena_com_sq_update_tail(struct ena_com_io_sq *io_sq) + { + if (io_sq->mem_queue_type == ENA_ADMIN_PLACEMENT_POLICY_DEV) + return ena_com_sq_update_llq_tail(io_sq); +@@ -239,7 +239,7 @@ static inline int ena_com_sq_update_tail + return 0; + } + +-static inline struct ena_eth_io_rx_cdesc_base * ++static struct ena_eth_io_rx_cdesc_base * + ena_com_rx_cdesc_idx_to_ptr(struct ena_com_io_cq *io_cq, u16 idx) + { + idx &= (io_cq->q_depth - 1); +@@ -248,7 +248,7 @@ static inline struct ena_eth_io_rx_cdesc + idx * io_cq->cdesc_entry_size_in_bytes); + } + +-static inline u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq, ++static u16 ena_com_cdesc_rx_pkt_get(struct ena_com_io_cq *io_cq, + u16 *first_cdesc_idx) + { + struct ena_eth_io_rx_cdesc_base *cdesc; +@@ -285,7 +285,7 @@ static inline u16 ena_com_cdesc_rx_pkt_g + return count; + } + +-static inline int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, ++static int ena_com_create_and_store_tx_meta_desc(struct ena_com_io_sq *io_sq, + struct ena_com_tx_ctx *ena_tx_ctx) + { + struct ena_eth_io_tx_meta_desc *meta_desc = NULL; +@@ -334,7 +334,7 @@ static inline int ena_com_create_and_sto + return ena_com_sq_update_tail(io_sq); + } + +-static inline void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx, ++static void ena_com_rx_set_flags(struct ena_com_rx_ctx *ena_rx_ctx, + struct ena_eth_io_rx_cdesc_base *cdesc) + { + ena_rx_ctx->l3_proto = cdesc->status & +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -326,7 +326,7 @@ static void ena_free_all_io_tx_resources + ena_free_tx_resources(adapter, i); + } + +-static inline int validate_rx_req_id(struct ena_ring *rx_ring, u16 req_id) ++static int validate_rx_req_id(struct ena_ring *rx_ring, u16 req_id) + { + if (likely(req_id < rx_ring->ring_size)) + return 0; +@@ -460,7 +460,7 @@ static void ena_free_all_io_rx_resources + ena_free_rx_resources(adapter, i); + } + +-static inline int ena_alloc_rx_page(struct ena_ring *rx_ring, ++static int ena_alloc_rx_page(struct ena_ring *rx_ring, + struct ena_rx_buffer *rx_info, gfp_t gfp) + { + struct ena_com_buf *ena_buf; +@@ -620,7 +620,7 @@ static void ena_free_all_rx_bufs(struct + ena_free_rx_bufs(adapter, i); + } + +-static inline void ena_unmap_tx_skb(struct ena_ring *tx_ring, ++static void ena_unmap_tx_skb(struct ena_ring *tx_ring, + struct ena_tx_buffer *tx_info) + { + struct ena_com_buf *ena_buf; +@@ -956,7 +956,7 @@ static struct sk_buff *ena_rx_skb(struct + * @ena_rx_ctx: received packet context/metadata + * @skb: skb currently being received and modified + */ +-static inline void ena_rx_checksum(struct ena_ring *rx_ring, ++static void ena_rx_checksum(struct ena_ring *rx_ring, + struct ena_com_rx_ctx *ena_rx_ctx, + struct sk_buff *skb) + { +@@ -1156,7 +1156,7 @@ error: + return 0; + } + +-inline void ena_adjust_intr_moderation(struct ena_ring *rx_ring, ++void ena_adjust_intr_moderation(struct ena_ring *rx_ring, + struct ena_ring *tx_ring) + { + /* We apply adaptive moderation on Rx path only. +@@ -1175,7 +1175,7 @@ inline void ena_adjust_intr_moderation(s + rx_ring->per_napi_bytes = 0; + } + +-static inline void ena_unmask_interrupt(struct ena_ring *tx_ring, ++static void ena_unmask_interrupt(struct ena_ring *tx_ring, + struct ena_ring *rx_ring) + { + struct ena_eth_io_intr_reg intr_reg; +@@ -1195,7 +1195,7 @@ static inline void ena_unmask_interrupt( + ena_com_unmask_intr(rx_ring->ena_com_io_cq, &intr_reg); + } + +-static inline void ena_update_ring_numa_node(struct ena_ring *tx_ring, ++static void ena_update_ring_numa_node(struct ena_ring *tx_ring, + struct ena_ring *rx_ring) + { + int cpu = get_cpu(); +@@ -3331,7 +3331,7 @@ static void ena_release_bars(struct ena_ + pci_release_selected_regions(pdev, release_bars); + } + +-static inline void set_default_llq_configurations(struct ena_llq_configurations *llq_config) ++static void set_default_llq_configurations(struct ena_llq_configurations *llq_config) + { + llq_config->llq_header_location = ENA_ADMIN_INLINE_HEADER; + llq_config->llq_ring_entry_size = ENA_ADMIN_LIST_ENTRY_SIZE_128B; diff --git a/debian/patches/features/all/ena/net-ena-remove-old-adaptive-interrupt-moderation-cod.patch b/debian/patches/features/all/ena/net-ena-remove-old-adaptive-interrupt-moderation-cod.patch new file mode 100644 index 000000000..17cb06e09 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-remove-old-adaptive-interrupt-moderation-cod.patch @@ -0,0 +1,83 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:31 +0300 +Subject: [PATCH] net: ena: remove old adaptive interrupt moderation code from + ena_netdev +Origin: https://git.kernel.org/linus/242d81fd3dd9f301b0c20564aafec8efdb2bbe5b +Bug-Debian: https://bugs.debian.org/941291 + +1. Out of the fields {per_napi_bytes, per_napi_packets} in struct ena_ring, + only rx_ring->per_napi_packets are used to determine if napi did work + for dim. + This commit removes all other uses of these fields. +2. Remove ena_ring->moder_tbl_idx, which is not used by dim. +3. Remove all calls to ena_com_destroy_interrupt_moderation(), since all it + did was to destroy the interrupt moderation table, which is removed as + part of removing old interrupt moderation code. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 8 -------- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 -- + 2 files changed, 10 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -158,7 +158,6 @@ static void ena_init_io_rings_common(str + ring->adapter = adapter; + ring->ena_dev = adapter->ena_dev; + ring->per_napi_packets = 0; +- ring->per_napi_bytes = 0; + ring->cpu = 0; + ring->first_interrupt = false; + ring->no_interrupt_event_cnt = 0; +@@ -835,9 +834,6 @@ static int ena_clean_tx_irq(struct ena_r + __netif_tx_unlock(txq); + } + +- tx_ring->per_napi_bytes += tx_bytes; +- tx_ring->per_napi_packets += tx_pkts; +- + return tx_pkts; + } + +@@ -1121,7 +1117,6 @@ static int ena_clean_rx_irq(struct ena_r + } while (likely(res_budget)); + + work_done = budget - res_budget; +- rx_ring->per_napi_bytes += total_len; + rx_ring->per_napi_packets += work_done; + u64_stats_update_begin(&rx_ring->syncp); + rx_ring->rx_stats.bytes += total_len; +@@ -3643,7 +3638,6 @@ err_free_msix: + ena_free_mgmnt_irq(adapter); + ena_disable_msix(adapter); + err_worker_destroy: +- ena_com_destroy_interrupt_moderation(ena_dev); + del_timer(&adapter->timer_service); + err_netdev_destroy: + free_netdev(netdev); +@@ -3704,8 +3698,6 @@ static void ena_remove(struct pci_dev *p + + pci_disable_device(pdev); + +- ena_com_destroy_interrupt_moderation(ena_dev); +- + vfree(ena_dev); + } + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -280,8 +280,6 @@ struct ena_ring { + struct ena_com_rx_buf_info ena_bufs[ENA_PKT_MAX_BUFS]; + u32 smoothed_interval; + u32 per_napi_packets; +- u32 per_napi_bytes; +- enum ena_intr_moder_level moder_tbl_idx; + u16 non_empty_napi_events; + struct u64_stats_sync syncp; + union { diff --git a/debian/patches/features/all/ena/net-ena-replace-free_tx-rx_ids-union-with-single-fre.patch b/debian/patches/features/all/ena/net-ena-replace-free_tx-rx_ids-union-with-single-fre.patch new file mode 100644 index 000000000..c63ce87c6 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-replace-free_tx-rx_ids-union-with-single-fre.patch @@ -0,0 +1,198 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Mon, 3 Jun 2019 17:43:21 +0300 +Subject: [PATCH] net: ena: replace free_tx/rx_ids union with single free_ids + field in ena_ring +Origin: https://git.kernel.org/linus/f917249833c7a00ea8be39b1bcb3ec8ef3aea45f +Bug-Debian: https://bugs.debian.org/941291 + +struct ena_ring holds a union of free_rx_ids and free_tx_ids. +Both of the above fields mean the exact same thing and are used +exactly the same way. +Furthermore, these fields are always used with a prefix of the +type of ring. So for tx it will be tx_ring->free_tx_ids, and for +rx it will be rx_ring->free_rx_ids, which shows how redundant the +"_tx" and "_rx" parts are. +Furthermore still, this may lead to confusing code like where +tx_ring->free_rx_ids which works correctly but looks like a mess. + +This commit removes the aforementioned redundancy by replacing the +free_rx/tx_ids union with a single free_ids field. +It also changes a single goto label name from err_free_tx_ids: to +err_tx_free_ids: for consistency with the above new notation. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 48 ++++++++++---------- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 11 ++--- + 2 files changed, 28 insertions(+), 31 deletions(-) + +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.c b/drivers/net/ethernet/amazon/ena/ena_netdev.c +index 33fab4f41d7c..b80b5eddca91 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -228,11 +228,11 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid) + } + + size = sizeof(u16) * tx_ring->ring_size; +- tx_ring->free_tx_ids = vzalloc_node(size, node); +- if (!tx_ring->free_tx_ids) { +- tx_ring->free_tx_ids = vzalloc(size); +- if (!tx_ring->free_tx_ids) +- goto err_free_tx_ids; ++ tx_ring->free_ids = vzalloc_node(size, node); ++ if (!tx_ring->free_ids) { ++ tx_ring->free_ids = vzalloc(size); ++ if (!tx_ring->free_ids) ++ goto err_tx_free_ids; + } + + size = tx_ring->tx_max_header_size; +@@ -245,7 +245,7 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid) + + /* Req id ring for TX out of order completions */ + for (i = 0; i < tx_ring->ring_size; i++) +- tx_ring->free_tx_ids[i] = i; ++ tx_ring->free_ids[i] = i; + + /* Reset tx statistics */ + memset(&tx_ring->tx_stats, 0x0, sizeof(tx_ring->tx_stats)); +@@ -256,9 +256,9 @@ static int ena_setup_tx_resources(struct ena_adapter *adapter, int qid) + return 0; + + err_push_buf_intermediate_buf: +- vfree(tx_ring->free_tx_ids); +- tx_ring->free_tx_ids = NULL; +-err_free_tx_ids: ++ vfree(tx_ring->free_ids); ++ tx_ring->free_ids = NULL; ++err_tx_free_ids: + vfree(tx_ring->tx_buffer_info); + tx_ring->tx_buffer_info = NULL; + err_tx_buffer_info: +@@ -278,8 +278,8 @@ static void ena_free_tx_resources(struct ena_adapter *adapter, int qid) + vfree(tx_ring->tx_buffer_info); + tx_ring->tx_buffer_info = NULL; + +- vfree(tx_ring->free_tx_ids); +- tx_ring->free_tx_ids = NULL; ++ vfree(tx_ring->free_ids); ++ tx_ring->free_ids = NULL; + + vfree(tx_ring->push_buf_intermediate_buf); + tx_ring->push_buf_intermediate_buf = NULL; +@@ -377,10 +377,10 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter, + } + + size = sizeof(u16) * rx_ring->ring_size; +- rx_ring->free_rx_ids = vzalloc_node(size, node); +- if (!rx_ring->free_rx_ids) { +- rx_ring->free_rx_ids = vzalloc(size); +- if (!rx_ring->free_rx_ids) { ++ rx_ring->free_ids = vzalloc_node(size, node); ++ if (!rx_ring->free_ids) { ++ rx_ring->free_ids = vzalloc(size); ++ if (!rx_ring->free_ids) { + vfree(rx_ring->rx_buffer_info); + rx_ring->rx_buffer_info = NULL; + return -ENOMEM; +@@ -389,7 +389,7 @@ static int ena_setup_rx_resources(struct ena_adapter *adapter, + + /* Req id ring for receiving RX pkts out of order */ + for (i = 0; i < rx_ring->ring_size; i++) +- rx_ring->free_rx_ids[i] = i; ++ rx_ring->free_ids[i] = i; + + /* Reset rx statistics */ + memset(&rx_ring->rx_stats, 0x0, sizeof(rx_ring->rx_stats)); +@@ -415,8 +415,8 @@ static void ena_free_rx_resources(struct ena_adapter *adapter, + vfree(rx_ring->rx_buffer_info); + rx_ring->rx_buffer_info = NULL; + +- vfree(rx_ring->free_rx_ids); +- rx_ring->free_rx_ids = NULL; ++ vfree(rx_ring->free_ids); ++ rx_ring->free_ids = NULL; + } + + /* ena_setup_all_rx_resources - allocate I/O Rx queues resources for all queues +@@ -531,7 +531,7 @@ static int ena_refill_rx_bufs(struct ena_ring *rx_ring, u32 num) + for (i = 0; i < num; i++) { + struct ena_rx_buffer *rx_info; + +- req_id = rx_ring->free_rx_ids[next_to_use]; ++ req_id = rx_ring->free_ids[next_to_use]; + rc = validate_rx_req_id(rx_ring, req_id); + if (unlikely(rc < 0)) + break; +@@ -797,7 +797,7 @@ static int ena_clean_tx_irq(struct ena_ring *tx_ring, u32 budget) + tx_pkts++; + total_done += tx_info->tx_descs; + +- tx_ring->free_tx_ids[next_to_clean] = req_id; ++ tx_ring->free_ids[next_to_clean] = req_id; + next_to_clean = ENA_TX_RING_IDX_NEXT(next_to_clean, + tx_ring->ring_size); + } +@@ -911,7 +911,7 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, + + skb_put(skb, len); + skb->protocol = eth_type_trans(skb, rx_ring->netdev); +- rx_ring->free_rx_ids[*next_to_clean] = req_id; ++ rx_ring->free_ids[*next_to_clean] = req_id; + *next_to_clean = ENA_RX_RING_IDX_ADD(*next_to_clean, descs, + rx_ring->ring_size); + return skb; +@@ -935,7 +935,7 @@ static struct sk_buff *ena_rx_skb(struct ena_ring *rx_ring, + + rx_info->page = NULL; + +- rx_ring->free_rx_ids[*next_to_clean] = req_id; ++ rx_ring->free_ids[*next_to_clean] = req_id; + *next_to_clean = + ENA_RX_RING_IDX_NEXT(*next_to_clean, + rx_ring->ring_size); +@@ -1088,7 +1088,7 @@ static int ena_clean_rx_irq(struct ena_ring *rx_ring, struct napi_struct *napi, + /* exit if we failed to retrieve a buffer */ + if (unlikely(!skb)) { + for (i = 0; i < ena_rx_ctx.descs; i++) { +- rx_ring->free_tx_ids[next_to_clean] = ++ rx_ring->free_ids[next_to_clean] = + rx_ring->ena_bufs[i].req_id; + next_to_clean = + ENA_RX_RING_IDX_NEXT(next_to_clean, +@@ -2152,7 +2152,7 @@ static netdev_tx_t ena_start_xmit(struct sk_buff *skb, struct net_device *dev) + skb_tx_timestamp(skb); + + next_to_use = tx_ring->next_to_use; +- req_id = tx_ring->free_tx_ids[next_to_use]; ++ req_id = tx_ring->free_ids[next_to_use]; + tx_info = &tx_ring->tx_buffer_info[req_id]; + tx_info->num_of_bufs = 0; + +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h +index 0681e18b0019..74c316081499 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -221,13 +221,10 @@ struct ena_stats_rx { + }; + + struct ena_ring { +- union { +- /* Holds the empty requests for TX/RX +- * out of order completions +- */ +- u16 *free_tx_ids; +- u16 *free_rx_ids; +- }; ++ /* Holds the empty requests for TX/RX ++ * out of order completions ++ */ ++ u16 *free_ids; + + union { + struct ena_tx_buffer *tx_buffer_info; +-- +2.17.1 + diff --git a/debian/patches/features/all/ena/net-ena-switch-to-dim-algorithm-for-rx-adaptive-inte.patch b/debian/patches/features/all/ena/net-ena-switch-to-dim-algorithm-for-rx-adaptive-inte.patch new file mode 100644 index 000000000..eb5269408 --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-switch-to-dim-algorithm-for-rx-adaptive-inte.patch @@ -0,0 +1,163 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 16 Sep 2019 14:31:27 +0300 +Subject: [PATCH] net: ena: switch to dim algorithm for rx adaptive interrupt + moderation +Origin: https://git.kernel.org/linus/282faf61a053be43910fcc42d86ecf16c0d30123 +Bug-Debian: https://bugs.debian.org/941291 + +Use the dim library for the rx adaptive interrupt moderation implementation + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_com.c | 4 +- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 55 +++++++++++++------- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 3 ++ + 3 files changed, 41 insertions(+), 21 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_com.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_com.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_com.c +@@ -2839,9 +2839,7 @@ int ena_com_init_interrupt_moderation(st + delay_resolution = get_resp.u.intr_moderation.intr_delay_resolution; + ena_com_update_intr_delay_resolution(ena_dev, delay_resolution); + +- /* Disable adaptive moderation by default - can be enabled from +- * ethtool +- */ ++ /* Disable adaptive moderation by default - can be enabled later */ + ena_com_disable_adaptive_moderation(ena_dev); + + return 0; +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -196,6 +196,7 @@ static void ena_init_io_rings(struct ena + rxr->smoothed_interval = + ena_com_get_nonadaptive_moderation_interval_rx(ena_dev); + rxr->empty_rx_queue = 0; ++ adapter->ena_napi[i].dim.mode = NET_DIM_CQ_PERIOD_MODE_START_FROM_EQE; + } + } + +@@ -712,6 +713,7 @@ static void ena_destroy_all_rx_queues(st + + for (i = 0; i < adapter->num_queues; i++) { + ena_qid = ENA_IO_RXQ_IDX(i); ++ cancel_work_sync(&adapter->ena_napi[i].dim.work); + ena_com_destroy_io_queue(adapter->ena_dev, ena_qid); + } + } +@@ -1156,23 +1158,35 @@ error: + return 0; + } + +-void ena_adjust_intr_moderation(struct ena_ring *rx_ring, +- struct ena_ring *tx_ring) ++static void ena_dim_work(struct work_struct *w) + { +- /* We apply adaptive moderation on Rx path only. +- * Tx uses static interrupt moderation. +- */ +- ena_com_calculate_interrupt_delay(rx_ring->ena_dev, +- rx_ring->per_napi_packets, +- rx_ring->per_napi_bytes, +- &rx_ring->smoothed_interval, +- &rx_ring->moder_tbl_idx); +- +- /* Reset per napi packets/bytes */ +- tx_ring->per_napi_packets = 0; +- tx_ring->per_napi_bytes = 0; ++ struct net_dim *dim = container_of(w, struct net_dim, work); ++ struct net_dim_cq_moder cur_moder = ++ net_dim_get_rx_moderation(dim->mode, dim->profile_ix); ++ struct ena_napi *ena_napi = container_of(dim, struct ena_napi, dim); ++ ++ ena_napi->rx_ring->smoothed_interval = cur_moder.usec; ++ dim->state = NET_DIM_START_MEASURE; ++} ++ ++static void ena_adjust_adaptive_rx_intr_moderation(struct ena_napi *ena_napi) ++{ ++ struct net_dim_sample dim_sample; ++ struct ena_ring *rx_ring = ena_napi->rx_ring; ++ ++ if (!rx_ring->per_napi_packets) ++ return; ++ ++ rx_ring->non_empty_napi_events++; ++ ++ net_dim_sample(rx_ring->non_empty_napi_events, ++ rx_ring->rx_stats.cnt, ++ rx_ring->rx_stats.bytes, ++ &dim_sample); ++ ++ net_dim(&ena_napi->dim, dim_sample); ++ + rx_ring->per_napi_packets = 0; +- rx_ring->per_napi_bytes = 0; + } + + static void ena_unmask_interrupt(struct ena_ring *tx_ring, +@@ -1261,9 +1275,11 @@ static int ena_io_poll(struct napi_struc + * from the interrupt context (vs from sk_busy_loop) + */ + if (napi_complete_done(napi, rx_work_done)) { +- /* Tx and Rx share the same interrupt vector */ ++ /* We apply adaptive moderation on Rx path only. ++ * Tx uses static interrupt moderation. ++ */ + if (ena_com_get_adaptive_moderation_enabled(rx_ring->ena_dev)) +- ena_adjust_intr_moderation(rx_ring, tx_ring); ++ ena_adjust_adaptive_rx_intr_moderation(ena_napi); + + ena_unmask_interrupt(tx_ring, rx_ring); + } +@@ -1741,13 +1757,16 @@ static int ena_create_all_io_rx_queues(s + rc = ena_create_io_rx_queue(adapter, i); + if (rc) + goto create_err; ++ INIT_WORK(&adapter->ena_napi[i].dim.work, ena_dim_work); + } + + return 0; + + create_err: +- while (i--) ++ while (i--) { ++ cancel_work_sync(&adapter->ena_napi[i].dim.work); + ena_com_destroy_io_queue(ena_dev, ENA_IO_RXQ_IDX(i)); ++ } + + return rc; + } +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -34,6 +34,7 @@ + #define ENA_H + + #include <linux/bitops.h> ++#include <linux/net_dim.h> + #include <linux/etherdevice.h> + #include <linux/inetdevice.h> + #include <linux/interrupt.h> +@@ -153,6 +154,7 @@ struct ena_napi { + struct ena_ring *tx_ring; + struct ena_ring *rx_ring; + u32 qid; ++ struct net_dim dim; + }; + + struct ena_calc_queue_size_ctx { +@@ -280,6 +282,7 @@ struct ena_ring { + u32 per_napi_packets; + u32 per_napi_bytes; + enum ena_intr_moder_level moder_tbl_idx; ++ u16 non_empty_napi_events; + struct u64_stats_sync syncp; + union { + struct ena_stats_tx tx_stats; diff --git a/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.2-to-2.0.3.patch b/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.2-to-2.0.3.patch new file mode 100644 index 000000000..7b3fd73ce --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.2-to-2.0.3.patch @@ -0,0 +1,27 @@ +From: Arthur Kiyanovski <akiyano@amazon.com> +Date: Mon, 11 Feb 2019 19:17:44 +0200 +Subject: [PATCH] net: ena: update driver version from 2.0.2 to 2.0.3 +Origin: https://git.kernel.org/linus/d9b8656da92223eb004b4f4db74fe48e7433f7b2 +Bug-Debian: https://bugs.debian.org/941291 + +Update driver version due to bug fix. + +Signed-off-by: Arthur Kiyanovski <akiyano@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -45,7 +45,7 @@ + + #define DRV_MODULE_VER_MAJOR 2 + #define DRV_MODULE_VER_MINOR 0 +-#define DRV_MODULE_VER_SUBMINOR 2 ++#define DRV_MODULE_VER_SUBMINOR 3 + + #define DRV_MODULE_NAME "ena" + #ifndef DRV_MODULE_VERSION diff --git a/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.3-to-2.1.0.patch b/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.3-to-2.1.0.patch new file mode 100644 index 000000000..9a62b79ac --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-update-driver-version-from-2.0.3-to-2.1.0.patch @@ -0,0 +1,32 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Tue, 11 Jun 2019 14:58:11 +0300 +Subject: [PATCH] net: ena: update driver version from 2.0.3 to 2.1.0 +Origin: https://git.kernel.org/linus/dbbc6e6877768a03092751edf89d012d561b4553 +Bug-Debian: https://bugs.debian.org/941291 + +Update driver version to match device specification. + +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.h | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/net/ethernet/amazon/ena/ena_netdev.h b/drivers/net/ethernet/amazon/ena/ena_netdev.h +index b9d590879815..f2b6e2e0504d 100644 +--- a/drivers/net/ethernet/amazon/ena/ena_netdev.h ++++ b/drivers/net/ethernet/amazon/ena/ena_netdev.h +@@ -44,8 +44,8 @@ + #include "ena_eth_com.h" + + #define DRV_MODULE_VER_MAJOR 2 +-#define DRV_MODULE_VER_MINOR 0 +-#define DRV_MODULE_VER_SUBMINOR 3 ++#define DRV_MODULE_VER_MINOR 1 ++#define DRV_MODULE_VER_SUBMINOR 0 + + #define DRV_MODULE_NAME "ena" + #ifndef DRV_MODULE_VERSION +-- +2.17.1 + diff --git a/debian/patches/features/all/ena/net-ena-use-dev_info_once-instead-of-static-variable.patch b/debian/patches/features/all/ena/net-ena-use-dev_info_once-instead-of-static-variable.patch new file mode 100644 index 000000000..8b3a55e8d --- /dev/null +++ b/debian/patches/features/all/ena/net-ena-use-dev_info_once-instead-of-static-variable.patch @@ -0,0 +1,34 @@ +From: Sameeh Jubran <sameehj@amazon.com> +Date: Mon, 3 Jun 2019 17:43:29 +0300 +Subject: [PATCH] net: ena: use dev_info_once instead of static variable +Origin: https://git.kernel.org/linus/1e9c3fbad83a70e0b00806df3f4dd2db0bc04cc4 +Bug-Debian: https://bugs.debian.org/941291 + +Signed-off-by: Sameeh Jubran <sameehj@amazon.com> +Signed-off-by: David S. Miller <davem@davemloft.net> +--- + drivers/net/ethernet/amazon/ena/ena_netdev.c | 4 +--- + 1 file changed, 1 insertion(+), 3 deletions(-) + +Index: linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +=================================================================== +--- linux.orig/drivers/net/ethernet/amazon/ena/ena_netdev.c ++++ linux/drivers/net/ethernet/amazon/ena/ena_netdev.c +@@ -3277,7 +3277,6 @@ static int ena_probe(struct pci_dev *pde + struct ena_llq_configurations llq_config; + struct ena_com_dev *ena_dev = NULL; + struct ena_adapter *adapter; +- static int version_printed; + int io_queue_num, bars, rc; + struct net_device *netdev; + static int adapters_found; +@@ -3289,8 +3288,7 @@ static int ena_probe(struct pci_dev *pde + + dev_dbg(&pdev->dev, "%s\n", __func__); + +- if (version_printed++ == 0) +- dev_info(&pdev->dev, "%s", version); ++ dev_info_once(&pdev->dev, "%s", version); + + rc = pci_enable_device_mem(pdev); + if (rc) { diff --git a/debian/patches/features/all/lockdown/0001-Add-the-ability-to-lock-down-access-to-the-running-k.patch b/debian/patches/features/all/lockdown/0001-Add-the-ability-to-lock-down-access-to-the-running-k.patch new file mode 100644 index 000000000..9a8cd7c82 --- /dev/null +++ b/debian/patches/features/all/lockdown/0001-Add-the-ability-to-lock-down-access-to-the-running-k.patch @@ -0,0 +1,164 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:31 +0000 +Subject: [01/29] Add the ability to lock down access to the running kernel + image +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=6d350e2534bfaaaa3e523484b2ca44d22377e951 + +Provide a single call to allow kernel code to determine whether the system +should be locked down, thereby disallowing various accesses that might +allow the running kernel image to be changed including the loading of +modules that aren't validly signed with a key we recognise, fiddling with +MSR registers and disallowing hibernation, + +Signed-off-by: David Howells <dhowells@redhat.com> +Acked-by: James Morris <james.l.morris@oracle.com> +--- + include/linux/kernel.h | 17 ++++++++++++++ + include/linux/security.h | 8 +++++++ + security/Kconfig | 8 +++++++ + security/Makefile | 3 +++ + security/lock_down.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ + 5 files changed, 96 insertions(+) + create mode 100644 security/lock_down.c + +Index: linux/include/linux/kernel.h +=================================================================== +--- linux.orig/include/linux/kernel.h ++++ linux/include/linux/kernel.h +@@ -341,6 +341,23 @@ static inline void refcount_error_report + { } + #endif + ++#ifdef CONFIG_LOCK_DOWN_KERNEL ++extern bool __kernel_is_locked_down(const char *what, bool first); ++#else ++static inline bool __kernel_is_locked_down(const char *what, bool first) ++{ ++ return false; ++} ++#endif ++ ++#define kernel_is_locked_down(what) \ ++ ({ \ ++ static bool message_given; \ ++ bool locked_down = __kernel_is_locked_down(what, !message_given); \ ++ message_given = true; \ ++ locked_down; \ ++ }) ++ + /* Internal, do not use. */ + int __must_check _kstrtoul(const char *s, unsigned int base, unsigned long *res); + int __must_check _kstrtol(const char *s, unsigned int base, long *res); +Index: linux/include/linux/security.h +=================================================================== +--- linux.orig/include/linux/security.h ++++ linux/include/linux/security.h +@@ -1843,5 +1843,13 @@ static inline void free_secdata(void *se + { } + #endif /* CONFIG_SECURITY */ + ++#ifdef CONFIG_LOCK_DOWN_KERNEL ++extern void __init init_lockdown(void); ++#else ++static inline void __init init_lockdown(void) ++{ ++} ++#endif ++ + #endif /* ! __LINUX_SECURITY_H */ + +Index: linux/security/Kconfig +=================================================================== +--- linux.orig/security/Kconfig ++++ linux/security/Kconfig +@@ -239,6 +239,14 @@ config STATIC_USERMODEHELPER_PATH + If you wish for all usermode helper programs to be disabled, + specify an empty string here (i.e. ""). + ++config LOCK_DOWN_KERNEL ++ bool "Allow the kernel to be 'locked down'" ++ help ++ Allow the kernel to be locked down under certain circumstances, for ++ instance if UEFI secure boot is enabled. Locking down the kernel ++ turns off various features that might otherwise allow access to the ++ kernel image (eg. setting MSR registers). ++ + source security/selinux/Kconfig + source security/smack/Kconfig + source security/tomoyo/Kconfig +Index: linux/security/Makefile +=================================================================== +--- linux.orig/security/Makefile ++++ linux/security/Makefile +@@ -30,3 +30,6 @@ obj-$(CONFIG_CGROUP_DEVICE) += device_c + # Object integrity file lists + subdir-$(CONFIG_INTEGRITY) += integrity + obj-$(CONFIG_INTEGRITY) += integrity/ ++ ++# Allow the kernel to be locked down ++obj-$(CONFIG_LOCK_DOWN_KERNEL) += lock_down.o +Index: linux/security/lock_down.c +=================================================================== +--- /dev/null ++++ linux/security/lock_down.c +@@ -0,0 +1,60 @@ ++/* Lock down the kernel ++ * ++ * Copyright (C) 2016 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++#include <linux/security.h> ++#include <linux/export.h> ++ ++static __ro_after_init bool kernel_locked_down; ++ ++/* ++ * Put the kernel into lock-down mode. ++ */ ++static void __init lock_kernel_down(const char *where) ++{ ++ if (!kernel_locked_down) { ++ kernel_locked_down = true; ++ pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n", ++ where); ++ } ++} ++ ++static int __init lockdown_param(char *ignored) ++{ ++ lock_kernel_down("command line"); ++ return 0; ++} ++ ++early_param("lockdown", lockdown_param); ++ ++/* ++ * Lock the kernel down from very early in the arch setup. This must happen ++ * prior to things like ACPI being initialised. ++ */ ++void __init init_lockdown(void) ++{ ++#ifdef CONFIG_LOCK_DOWN_IN_EFI_SECURE_BOOT ++ if (efi_enabled(EFI_SECURE_BOOT)) ++ lock_kernel_down("EFI secure boot"); ++#endif ++} ++ ++/** ++ * kernel_is_locked_down - Find out if the kernel is locked down ++ * @what: Tag to use in notice generated if lockdown is in effect ++ */ ++bool __kernel_is_locked_down(const char *what, bool first) ++{ ++ if (what && first && kernel_locked_down) ++ pr_notice("Lockdown: %s is restricted; see man kernel_lockdown.7\n", ++ what); ++ return kernel_locked_down; ++} ++EXPORT_SYMBOL(__kernel_is_locked_down); diff --git a/debian/patches/features/all/lockdown/0003-ima-require-secure_boot-rules-in-lockdown-mode.patch b/debian/patches/features/all/lockdown/0003-ima-require-secure_boot-rules-in-lockdown-mode.patch new file mode 100644 index 000000000..0ab99ba64 --- /dev/null +++ b/debian/patches/features/all/lockdown/0003-ima-require-secure_boot-rules-in-lockdown-mode.patch @@ -0,0 +1,75 @@ +From: Mimi Zohar <zohar@linux.vnet.ibm.com> +Date: Wed, 8 Nov 2017 15:11:32 +0000 +Subject: [03/29] ima: require secure_boot rules in lockdown mode +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=29c55d71a8185208c7962843a29c9a84ae27b2b0 + +Require the "secure_boot" rules, whether or not it is specified +on the boot command line, for both the builtin and custom policies +in secure boot lockdown mode. + +Signed-off-by: Mimi Zohar <zohar@linux.vnet.ibm.com> +Signed-off-by: David Howells <dhowells@redhat.com> +[bwh: Adjust context to apply after commits 6f0911a666d1 + "ima: fix updating the ima_appraise flag" and ef96837b0de4 + "ima: add build time policy"] +--- + security/integrity/ima/ima_policy.c | 39 +++++++++++++++++++++++++++---------- + 1 file changed, 29 insertions(+), 10 deletions(-) + +Index: linux/security/integrity/ima/ima_policy.c +=================================================================== +--- linux.orig/security/integrity/ima/ima_policy.c ++++ linux/security/integrity/ima/ima_policy.c +@@ -481,14 +481,21 @@ static int ima_appraise_flag(enum ima_ho + */ + void __init ima_init_policy(void) + { +- int i, measure_entries, appraise_entries, secure_boot_entries; ++ int i; ++ int measure_entries = 0; ++ int appraise_entries = 0; ++ int secure_boot_entries = 0; ++ bool kernel_locked_down = __kernel_is_locked_down(NULL, false); + + /* if !ima_policy set entries = 0 so we load NO default rules */ +- measure_entries = ima_policy ? ARRAY_SIZE(dont_measure_rules) : 0; +- appraise_entries = ima_use_appraise_tcb ? +- ARRAY_SIZE(default_appraise_rules) : 0; +- secure_boot_entries = ima_use_secure_boot ? +- ARRAY_SIZE(secure_boot_rules) : 0; ++ if (ima_policy) ++ measure_entries = ARRAY_SIZE(dont_measure_rules); ++ ++ if (ima_use_appraise_tcb) ++ appraise_entries = ARRAY_SIZE(default_appraise_rules); ++ ++ if (ima_use_secure_boot || kernel_locked_down) ++ secure_boot_entries = ARRAY_SIZE(secure_boot_rules); + + for (i = 0; i < measure_entries; i++) + list_add_tail(&dont_measure_rules[i].list, &ima_default_rules); +@@ -510,11 +517,24 @@ void __init ima_init_policy(void) + /* + * Insert the builtin "secure_boot" policy rules requiring file + * signatures, prior to any other appraise rules. ++ * In secure boot lock-down mode, also require these appraise ++ * rules for custom policies. + */ + for (i = 0; i < secure_boot_entries; i++) { ++ struct ima_rule_entry *entry; ++ ++ /* Include for builtin policies */ + list_add_tail(&secure_boot_rules[i].list, &ima_default_rules); + temp_ima_appraise |= + ima_appraise_flag(secure_boot_rules[i].func); ++ ++ /* Include for custom policies */ ++ if (kernel_locked_down) { ++ entry = kmemdup(&secure_boot_rules[i], sizeof(*entry), ++ GFP_KERNEL); ++ if (entry) ++ list_add_tail(&entry->list, &ima_policy_rules); ++ } + } + + /* diff --git a/debian/patches/features/all/lockdown/0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch b/debian/patches/features/all/lockdown/0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch new file mode 100644 index 000000000..0ab5e258c --- /dev/null +++ b/debian/patches/features/all/lockdown/0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch @@ -0,0 +1,95 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:32 +0000 +Subject: [04/29] Enforce module signatures if the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=1616ef1deccf5fdb525643a6b3efae34946a148d + +If the kernel is locked down, require that all modules have valid +signatures that we can verify or that IMA can validate the file. + +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +Reviewed-by: James Morris <james.l.morris@oracle.com> +[bwh: Adjust context to apply after commits 2c8fd268f418 + "module: Do not access sig_enforce directly" and 5fdc7db6448a + "module: setup load info before module_sig_check()"] +--- + kernel/module.c | 19 ++++++++++++------- + 1 file changed, 12 insertions(+), 7 deletions(-) + +Index: linux/kernel/module.c +=================================================================== +--- linux.orig/kernel/module.c ++++ linux/kernel/module.c +@@ -64,6 +64,7 @@ + #include <linux/bsearch.h> + #include <linux/dynamic_debug.h> + #include <linux/audit.h> ++#include <linux/ima.h> + #include <uapi/linux/module.h> + #include "module-internal.h" + +@@ -2784,7 +2785,8 @@ static inline void kmemleak_load_module( + #endif + + #ifdef CONFIG_MODULE_SIG +-static int module_sig_check(struct load_info *info, int flags) ++static int module_sig_check(struct load_info *info, int flags, ++ bool can_do_ima_check) + { + int err = -ENOKEY; + const unsigned long markerlen = sizeof(MODULE_SIG_STRING) - 1; +@@ -2808,13 +2810,16 @@ static int module_sig_check(struct load_ + } + + /* Not having a signature is only an error if we're strict. */ +- if (err == -ENOKEY && !is_module_sig_enforced()) ++ if (err == -ENOKEY && !is_module_sig_enforced() && ++ (!can_do_ima_check || !is_ima_appraise_enabled()) && ++ !kernel_is_locked_down("Loading of unsigned modules")) + err = 0; + + return err; + } + #else /* !CONFIG_MODULE_SIG */ +-static int module_sig_check(struct load_info *info, int flags) ++static int module_sig_check(struct load_info *info, int flags, ++ bool can_do_ima_check) + { + return 0; + } +@@ -3662,7 +3667,7 @@ static int unknown_module_param_cb(char + /* Allocate and load the module: note that size of section 0 is always + zero, and we rely on this for optional sections. */ + static int load_module(struct load_info *info, const char __user *uargs, +- int flags) ++ int flags, bool can_do_ima_check) + { + struct module *mod; + long err = 0; +@@ -3681,7 +3686,7 @@ static int load_module(struct load_info + goto free_copy; + } + +- err = module_sig_check(info, flags); ++ err = module_sig_check(info, flags, can_do_ima_check); + if (err) + goto free_copy; + +@@ -3876,7 +3881,7 @@ SYSCALL_DEFINE3(init_module, void __user + if (err) + return err; + +- return load_module(&info, uargs, 0); ++ return load_module(&info, uargs, 0, false); + } + + SYSCALL_DEFINE3(finit_module, int, fd, const char __user *, uargs, int, flags) +@@ -3903,7 +3908,7 @@ SYSCALL_DEFINE3(finit_module, int, fd, c + info.hdr = hdr; + info.len = size; + +- return load_module(&info, uargs, flags); ++ return load_module(&info, uargs, flags, true); + } + + static inline int within(unsigned long addr, void *start, unsigned long size) diff --git a/debian/patches/features/all/lockdown/0005-Restrict-dev-mem-kmem-port-when-the-kernel-is-locked.patch b/debian/patches/features/all/lockdown/0005-Restrict-dev-mem-kmem-port-when-the-kernel-is-locked.patch new file mode 100644 index 000000000..625f8f763 --- /dev/null +++ b/debian/patches/features/all/lockdown/0005-Restrict-dev-mem-kmem-port-when-the-kernel-is-locked.patch @@ -0,0 +1,35 @@ +From: Matthew Garrett <matthew.garrett@nebula.com> +Date: Wed, 8 Nov 2017 15:11:32 +0000 +Subject: [05/29] Restrict /dev/{mem,kmem,port} when the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=8214bb0d847928bf08a7d8475f84c06541c5a352 + +Allowing users to read and write to core kernel memory makes it possible +for the kernel to be subverted, avoiding module loading restrictions, and +also to steal cryptographic information. + +Disallow /dev/mem and /dev/kmem from being opened this when the kernel has +been locked down to prevent this. + +Also disallow /dev/port from being opened to prevent raw ioport access and +thus DMA from being used to accomplish the same thing. + +Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +--- + drivers/char/mem.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: linux/drivers/char/mem.c +=================================================================== +--- linux.orig/drivers/char/mem.c ++++ linux/drivers/char/mem.c +@@ -807,6 +807,8 @@ static loff_t memory_lseek(struct file * + + static int open_port(struct inode *inode, struct file *filp) + { ++ if (kernel_is_locked_down("/dev/mem,kmem,port")) ++ return -EPERM; + return capable(CAP_SYS_RAWIO) ? 0 : -EPERM; + } + diff --git a/debian/patches/features/all/lockdown/0006-kexec-Disable-at-runtime-if-the-kernel-is-locked-dow.patch b/debian/patches/features/all/lockdown/0006-kexec-Disable-at-runtime-if-the-kernel-is-locked-dow.patch new file mode 100644 index 000000000..522387d9a --- /dev/null +++ b/debian/patches/features/all/lockdown/0006-kexec-Disable-at-runtime-if-the-kernel-is-locked-dow.patch @@ -0,0 +1,42 @@ +From: Matthew Garrett <matthew.garrett@nebula.com> +Date: Wed, 8 Nov 2017 15:11:32 +0000 +Subject: [06/29] kexec: Disable at runtime if the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=6081db9ba435b757a3a3473d0cd50ee2252ccaeb + +kexec permits the loading and execution of arbitrary code in ring 0, which +is something that lock-down is meant to prevent. It makes sense to disable +kexec in this situation. + +This does not affect kexec_file_load() which can check for a signature on the +image to be booted. + +Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Acked-by: Dave Young <dyoung@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +Reviewed-by: James Morris <james.l.morris@oracle.com> +cc: kexec@lists.infradead.org +[bwh: Adjust context to apply after commit a210fd32a46b + "kexec: add call to LSM hook in original kexec_load syscall"] +--- + kernel/kexec.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: linux/kernel/kexec.c +=================================================================== +--- linux.orig/kernel/kexec.c ++++ linux/kernel/kexec.c +@@ -208,6 +208,13 @@ static inline int kexec_load_check(unsig + return result; + + /* ++ * kexec can be used to circumvent module loading restrictions, so ++ * prevent loading in that case ++ */ ++ if (kernel_is_locked_down("kexec of unsigned images")) ++ return -EPERM; ++ ++ /* + * Verify we have a legal set of flags + * This leaves us room for future extensions. + */ diff --git a/debian/patches/features/all/lockdown/0007-Copy-secure_boot-flag-in-boot-params-across-kexec-re.patch b/debian/patches/features/all/lockdown/0007-Copy-secure_boot-flag-in-boot-params-across-kexec-re.patch new file mode 100644 index 000000000..2024c04a6 --- /dev/null +++ b/debian/patches/features/all/lockdown/0007-Copy-secure_boot-flag-in-boot-params-across-kexec-re.patch @@ -0,0 +1,36 @@ +From: Dave Young <dyoung@redhat.com> +Date: Wed, 8 Nov 2017 15:11:32 +0000 +Subject: [07/29] Copy secure_boot flag in boot params across kexec reboot +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a6b7f780bdaa731f3e2970d65dcd52fe9ba2409d + +Kexec reboot in case secure boot being enabled does not keep the secure +boot mode in new kernel, so later one can load unsigned kernel via legacy +kexec_load. In this state, the system is missing the protections provided +by secure boot. + +Adding a patch to fix this by retain the secure_boot flag in original +kernel. + +secure_boot flag in boot_params is set in EFI stub, but kexec bypasses the +stub. Fixing this issue by copying secure_boot flag across kexec reboot. + +Signed-off-by: Dave Young <dyoung@redhat.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: kexec@lists.infradead.org +--- + arch/x86/kernel/kexec-bzimage64.c | 1 + + 1 file changed, 1 insertion(+) + +Index: linux/arch/x86/kernel/kexec-bzimage64.c +=================================================================== +--- linux.orig/arch/x86/kernel/kexec-bzimage64.c ++++ linux/arch/x86/kernel/kexec-bzimage64.c +@@ -182,6 +182,7 @@ setup_efi_state(struct boot_params *para + if (efi_enabled(EFI_OLD_MEMMAP)) + return 0; + ++ params->secure_boot = boot_params.secure_boot; + ei->efi_loader_signature = current_ei->efi_loader_signature; + ei->efi_systab = current_ei->efi_systab; + ei->efi_systab_hi = current_ei->efi_systab_hi; diff --git a/debian/patches/features/all/lockdown/0008-kexec_file-Restrict-at-runtime-if-the-kernel-is-lock.patch b/debian/patches/features/all/lockdown/0008-kexec_file-Restrict-at-runtime-if-the-kernel-is-lock.patch new file mode 100644 index 000000000..056936427 --- /dev/null +++ b/debian/patches/features/all/lockdown/0008-kexec_file-Restrict-at-runtime-if-the-kernel-is-lock.patch @@ -0,0 +1,40 @@ +From: Chun-Yi Lee <joeyli.kernel@gmail.com> +Date: Wed, 8 Nov 2017 15:11:33 +0000 +Subject: [08/29] kexec_file: Restrict at runtime if the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=eed4aca0409692d7d24bc64f5c98d346cd0506c4 + +When KEXEC_VERIFY_SIG is not enabled, kernel should not load images through +kexec_file systemcall if the kernel is locked down unless IMA can be used +to validate the image. + +This code was showed in Matthew's patch but not in git: +https://lkml.org/lkml/2015/3/13/778 + +Cc: Matthew Garrett <mjg59@srcf.ucam.org> +Signed-off-by: Chun-Yi Lee <jlee@suse.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: James Morris <james.l.morris@oracle.com> +cc: kexec@lists.infradead.org +--- + kernel/kexec_file.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +Index: linux/kernel/kexec_file.c +=================================================================== +--- linux.orig/kernel/kexec_file.c ++++ linux/kernel/kexec_file.c +@@ -328,6 +328,14 @@ SYSCALL_DEFINE5(kexec_file_load, int, ke + if (!capable(CAP_SYS_BOOT) || kexec_load_disabled) + return -EPERM; + ++ /* Don't permit images to be loaded into trusted kernels if we're not ++ * going to verify the signature on them ++ */ ++ if (!IS_ENABLED(CONFIG_KEXEC_VERIFY_SIG) && ++ !is_ima_appraise_enabled() && ++ kernel_is_locked_down("kexec of unsigned images")) ++ return -EPERM; ++ + /* Make sure we have a legal set of flags */ + if (flags != (flags & KEXEC_FILE_FLAGS)) + return -EINVAL; diff --git a/debian/patches/features/all/lockdown/0009-hibernate-Disable-when-the-kernel-is-locked-down.patch b/debian/patches/features/all/lockdown/0009-hibernate-Disable-when-the-kernel-is-locked-down.patch new file mode 100644 index 000000000..56060f80a --- /dev/null +++ b/debian/patches/features/all/lockdown/0009-hibernate-Disable-when-the-kernel-is-locked-down.patch @@ -0,0 +1,31 @@ +From: Josh Boyer <jwboyer@fedoraproject.org> +Date: Wed, 8 Nov 2017 15:11:33 +0000 +Subject: [09/29] hibernate: Disable when the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=480ddca2a40c2efd1c01cfa20d8f6c1377ddafe3 + +There is currently no way to verify the resume image when returning +from hibernate. This might compromise the signed modules trust model, +so until we can work with signed hibernate images we disable it when the +kernel is locked down. + +Signed-off-by: Josh Boyer <jwboyer@fedoraproject.org> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: linux-pm@vger.kernel.org +--- + kernel/power/hibernate.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/kernel/power/hibernate.c +=================================================================== +--- linux.orig/kernel/power/hibernate.c ++++ linux/kernel/power/hibernate.c +@@ -70,7 +70,7 @@ static const struct platform_hibernation + + bool hibernation_available(void) + { +- return (nohibernate == 0); ++ return nohibernate == 0 && !kernel_is_locked_down("Hibernation"); + } + + /** diff --git a/debian/patches/features/all/lockdown/0010-uswsusp-Disable-when-the-kernel-is-locked-down.patch b/debian/patches/features/all/lockdown/0010-uswsusp-Disable-when-the-kernel-is-locked-down.patch new file mode 100644 index 000000000..79b5f3461 --- /dev/null +++ b/debian/patches/features/all/lockdown/0010-uswsusp-Disable-when-the-kernel-is-locked-down.patch @@ -0,0 +1,32 @@ +From: Matthew Garrett <mjg59@srcf.ucam.org> +Date: Wed, 8 Nov 2017 15:11:33 +0000 +Subject: [10/29] uswsusp: Disable when the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=706def46d58e9c69e91db506305485731f615e44 + +uswsusp allows a user process to dump and then restore kernel state, which +makes it possible to modify the running kernel. Disable this if the kernel +is locked down. + +Signed-off-by: Matthew Garrett <mjg59@srcf.ucam.org> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +Reviewed-by: James Morris <james.l.morris@oracle.com> +cc: linux-pm@vger.kernel.org +--- + kernel/power/user.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: linux/kernel/power/user.c +=================================================================== +--- linux.orig/kernel/power/user.c ++++ linux/kernel/power/user.c +@@ -52,6 +52,9 @@ static int snapshot_open(struct inode *i + if (!hibernation_available()) + return -EPERM; + ++ if (kernel_is_locked_down("/dev/snapshot")) ++ return -EPERM; ++ + lock_system_sleep(); + + if (!atomic_add_unless(&snapshot_device_available, -1, 0)) { diff --git a/debian/patches/features/all/lockdown/0011-PCI-Lock-down-BAR-access-when-the-kernel-is-locked-d.patch b/debian/patches/features/all/lockdown/0011-PCI-Lock-down-BAR-access-when-the-kernel-is-locked-d.patch new file mode 100644 index 000000000..1f9186ab3 --- /dev/null +++ b/debian/patches/features/all/lockdown/0011-PCI-Lock-down-BAR-access-when-the-kernel-is-locked-d.patch @@ -0,0 +1,104 @@ +From: Matthew Garrett <matthew.garrett@nebula.com> +Date: Wed, 8 Nov 2017 15:11:33 +0000 +Subject: [11/29] PCI: Lock down BAR access when the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=d107d11fd7ac982a34b1233722cb3e72f9fe5a20 + +Any hardware that can potentially generate DMA has to be locked down in +order to avoid it being possible for an attacker to modify kernel code, +allowing them to circumvent disabled module loading or module signing. +Default to paranoid - in future we can potentially relax this for +sufficiently IOMMU-isolated devices. + +Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Acked-by: Bjorn Helgaas <bhelgaas@google.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: linux-pci@vger.kernel.org +--- + drivers/pci/pci-sysfs.c | 9 +++++++++ + drivers/pci/proc.c | 9 ++++++++- + drivers/pci/syscall.c | 3 ++- + 3 files changed, 19 insertions(+), 2 deletions(-) + +Index: linux/drivers/pci/pci-sysfs.c +=================================================================== +--- linux.orig/drivers/pci/pci-sysfs.c ++++ linux/drivers/pci/pci-sysfs.c +@@ -905,6 +905,9 @@ static ssize_t pci_write_config(struct f + loff_t init_off = off; + u8 *data = (u8 *) buf; + ++ if (kernel_is_locked_down("Direct PCI access")) ++ return -EPERM; ++ + if (off > dev->cfg_size) + return 0; + if (off + count > dev->cfg_size) { +@@ -1167,6 +1170,9 @@ static int pci_mmap_resource(struct kobj + enum pci_mmap_state mmap_type; + struct resource *res = &pdev->resource[bar]; + ++ if (kernel_is_locked_down("Direct PCI access")) ++ return -EPERM; ++ + if (res->flags & IORESOURCE_MEM && iomem_is_exclusive(res->start)) + return -EINVAL; + +@@ -1242,6 +1248,9 @@ static ssize_t pci_write_resource_io(str + struct bin_attribute *attr, char *buf, + loff_t off, size_t count) + { ++ if (kernel_is_locked_down("Direct PCI access")) ++ return -EPERM; ++ + return pci_resource_io(filp, kobj, attr, buf, off, count, true); + } + +Index: linux/drivers/pci/proc.c +=================================================================== +--- linux.orig/drivers/pci/proc.c ++++ linux/drivers/pci/proc.c +@@ -117,6 +117,9 @@ static ssize_t proc_bus_pci_write(struct + int size = dev->cfg_size; + int cnt; + ++ if (kernel_is_locked_down("Direct PCI access")) ++ return -EPERM; ++ + if (pos >= size) + return 0; + if (nbytes >= size) +@@ -196,6 +199,9 @@ static long proc_bus_pci_ioctl(struct fi + #endif /* HAVE_PCI_MMAP */ + int ret = 0; + ++ if (kernel_is_locked_down("Direct PCI access")) ++ return -EPERM; ++ + switch (cmd) { + case PCIIOC_CONTROLLER: + ret = pci_domain_nr(dev->bus); +@@ -237,7 +243,8 @@ static int proc_bus_pci_mmap(struct file + struct pci_filp_private *fpriv = file->private_data; + int i, ret, write_combine = 0, res_bit = IORESOURCE_MEM; + +- if (!capable(CAP_SYS_RAWIO)) ++ if (!capable(CAP_SYS_RAWIO) || ++ kernel_is_locked_down("Direct PCI access")) + return -EPERM; + + if (fpriv->mmap_state == pci_mmap_io) { +Index: linux/drivers/pci/syscall.c +=================================================================== +--- linux.orig/drivers/pci/syscall.c ++++ linux/drivers/pci/syscall.c +@@ -90,7 +90,8 @@ SYSCALL_DEFINE5(pciconfig_write, unsigne + u32 dword; + int err = 0; + +- if (!capable(CAP_SYS_ADMIN)) ++ if (!capable(CAP_SYS_ADMIN) || ++ kernel_is_locked_down("Direct PCI access")) + return -EPERM; + + dev = pci_get_domain_bus_and_slot(0, bus, dfn); diff --git a/debian/patches/features/all/lockdown/0012-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch b/debian/patches/features/all/lockdown/0012-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch new file mode 100644 index 000000000..3a9d69dcb --- /dev/null +++ b/debian/patches/features/all/lockdown/0012-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch @@ -0,0 +1,46 @@ +From: Matthew Garrett <matthew.garrett@nebula.com> +Date: Wed, 8 Nov 2017 15:11:34 +0000 +Subject: [12/29] x86: Lock down IO port access when the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=00ebba940247d4c37c06da4aedecf6b80db213cf + +IO port access would permit users to gain access to PCI configuration +registers, which in turn (on a lot of hardware) give access to MMIO +register space. This would potentially permit root to trigger arbitrary +DMA, so lock it down by default. + +This also implicitly locks down the KDADDIO, KDDELIO, KDENABIO and +KDDISABIO console ioctls. + +Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: Thomas Gleixner <tglx@linutronix.de> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: x86@kernel.org +--- + arch/x86/kernel/ioport.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +Index: linux/arch/x86/kernel/ioport.c +=================================================================== +--- linux.orig/arch/x86/kernel/ioport.c ++++ linux/arch/x86/kernel/ioport.c +@@ -31,7 +31,8 @@ long ksys_ioperm(unsigned long from, uns + + if ((from + num <= from) || (from + num > IO_BITMAP_BITS)) + return -EINVAL; +- if (turn_on && !capable(CAP_SYS_RAWIO)) ++ if (turn_on && (!capable(CAP_SYS_RAWIO) || ++ kernel_is_locked_down("ioperm"))) + return -EPERM; + + /* +@@ -126,7 +127,8 @@ SYSCALL_DEFINE1(iopl, unsigned int, leve + return -EINVAL; + /* Trying to gain more privileges? */ + if (level > old) { +- if (!capable(CAP_SYS_RAWIO)) ++ if (!capable(CAP_SYS_RAWIO) || ++ kernel_is_locked_down("iopl")) + return -EPERM; + } + regs->flags = (regs->flags & ~X86_EFLAGS_IOPL) | diff --git a/debian/patches/features/all/lockdown/0013-x86-msr-Restrict-MSR-access-when-the-kernel-is-locke.patch b/debian/patches/features/all/lockdown/0013-x86-msr-Restrict-MSR-access-when-the-kernel-is-locke.patch new file mode 100644 index 000000000..1a7a4d879 --- /dev/null +++ b/debian/patches/features/all/lockdown/0013-x86-msr-Restrict-MSR-access-when-the-kernel-is-locke.patch @@ -0,0 +1,50 @@ +From: Matthew Garrett <matthew.garrett@nebula.com> +Date: Wed, 8 Nov 2017 15:11:34 +0000 +Subject: [13/29] x86/msr: Restrict MSR access when the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=696dcddb285558b4febf318fe620a344d2b2fa47 + +Writing to MSRs should not be allowed if the kernel is locked down, since +it could lead to execution of arbitrary code in kernel mode. Based on a +patch by Kees Cook. + +MSR accesses are logged for the purposes of building up a whitelist as per +Alan Cox's suggestion. + +Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Acked-by: Kees Cook <keescook@chromium.org> +Reviewed-by: Thomas Gleixner <tglx@linutronix.de> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: x86@kernel.org +--- + arch/x86/kernel/msr.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +Index: linux/arch/x86/kernel/msr.c +=================================================================== +--- linux.orig/arch/x86/kernel/msr.c ++++ linux/arch/x86/kernel/msr.c +@@ -84,6 +84,11 @@ static ssize_t msr_write(struct file *fi + int err = 0; + ssize_t bytes = 0; + ++ if (kernel_is_locked_down("Direct MSR access")) { ++ pr_info("Direct access to MSR %x\n", reg); ++ return -EPERM; ++ } ++ + if (count % 8) + return -EINVAL; /* Invalid chunk size */ + +@@ -135,6 +140,11 @@ static long msr_ioctl(struct file *file, + err = -EFAULT; + break; + } ++ if (kernel_is_locked_down("Direct MSR access")) { ++ pr_info("Direct access to MSR %x\n", regs[1]); /* Display %ecx */ ++ err = -EPERM; ++ break; ++ } + err = wrmsr_safe_regs_on_cpu(cpu, regs); + if (err) + break; diff --git a/debian/patches/features/all/lockdown/0014-asus-wmi-Restrict-debugfs-interface-when-the-kernel-.patch b/debian/patches/features/all/lockdown/0014-asus-wmi-Restrict-debugfs-interface-when-the-kernel-.patch new file mode 100644 index 000000000..295b46e88 --- /dev/null +++ b/debian/patches/features/all/lockdown/0014-asus-wmi-Restrict-debugfs-interface-when-the-kernel-.patch @@ -0,0 +1,55 @@ +From: Matthew Garrett <matthew.garrett@nebula.com> +Date: Wed, 8 Nov 2017 15:11:34 +0000 +Subject: [14/29] asus-wmi: Restrict debugfs interface when the kernel is + locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=2e6d31b3176ee27d216bb92a3b108f6b19d4719a + +We have no way of validating what all of the Asus WMI methods do on a given +machine - and there's a risk that some will allow hardware state to be +manipulated in such a way that arbitrary code can be executed in the +kernel, circumventing module loading restrictions. Prevent that if the +kernel is locked down. + +Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: acpi4asus-user@lists.sourceforge.net +cc: platform-driver-x86@vger.kernel.org +--- + drivers/platform/x86/asus-wmi.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +Index: linux/drivers/platform/x86/asus-wmi.c +=================================================================== +--- linux.orig/drivers/platform/x86/asus-wmi.c ++++ linux/drivers/platform/x86/asus-wmi.c +@@ -2002,6 +2002,9 @@ static int show_dsts(struct seq_file *m, + int err; + u32 retval = -1; + ++ if (kernel_is_locked_down("Asus WMI")) ++ return -EPERM; ++ + err = asus_wmi_get_devstate(asus, asus->debug.dev_id, &retval); + + if (err < 0) +@@ -2018,6 +2021,9 @@ static int show_devs(struct seq_file *m, + int err; + u32 retval = -1; + ++ if (kernel_is_locked_down("Asus WMI")) ++ return -EPERM; ++ + err = asus_wmi_set_devstate(asus->debug.dev_id, asus->debug.ctrl_param, + &retval); + +@@ -2042,6 +2048,9 @@ static int show_call(struct seq_file *m, + union acpi_object *obj; + acpi_status status; + ++ if (kernel_is_locked_down("Asus WMI")) ++ return -EPERM; ++ + status = wmi_evaluate_method(ASUS_WMI_MGMT_GUID, + 0, asus->debug.method_id, + &input, &output); diff --git a/debian/patches/features/all/lockdown/0015-ACPI-Limit-access-to-custom_method-when-the-kernel-i.patch b/debian/patches/features/all/lockdown/0015-ACPI-Limit-access-to-custom_method-when-the-kernel-i.patch new file mode 100644 index 000000000..17778da72 --- /dev/null +++ b/debian/patches/features/all/lockdown/0015-ACPI-Limit-access-to-custom_method-when-the-kernel-i.patch @@ -0,0 +1,32 @@ +From: Matthew Garrett <matthew.garrett@nebula.com> +Date: Wed, 8 Nov 2017 15:11:34 +0000 +Subject: [15/29] ACPI: Limit access to custom_method when the kernel is locked + down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=5ff99c830aacf02f25816a0da427216fb63ba16d + +custom_method effectively allows arbitrary access to system memory, making +it possible for an attacker to circumvent restrictions on module loading. +Disable it if the kernel is locked down. + +Signed-off-by: Matthew Garrett <matthew.garrett@nebula.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: linux-acpi@vger.kernel.org +--- + drivers/acpi/custom_method.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: linux/drivers/acpi/custom_method.c +=================================================================== +--- linux.orig/drivers/acpi/custom_method.c ++++ linux/drivers/acpi/custom_method.c +@@ -29,6 +29,9 @@ static ssize_t cm_write(struct file *fil + struct acpi_table_header table; + acpi_status status; + ++ if (kernel_is_locked_down("ACPI custom methods")) ++ return -EPERM; ++ + if (!(*ppos)) { + /* parse the table header to get the table length */ + if (count <= sizeof(struct acpi_table_header)) diff --git a/debian/patches/features/all/lockdown/0016-acpi-Ignore-acpi_rsdp-kernel-param-when-the-kernel-h.patch b/debian/patches/features/all/lockdown/0016-acpi-Ignore-acpi_rsdp-kernel-param-when-the-kernel-h.patch new file mode 100644 index 000000000..f8ee397c8 --- /dev/null +++ b/debian/patches/features/all/lockdown/0016-acpi-Ignore-acpi_rsdp-kernel-param-when-the-kernel-h.patch @@ -0,0 +1,32 @@ +From: Josh Boyer <jwboyer@redhat.com> +Date: Wed, 8 Nov 2017 15:11:34 +0000 +Subject: [16/29] acpi: Ignore acpi_rsdp kernel param when the kernel has been + locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=67890a0361626ec3e035264656896c77670c414b + +This option allows userspace to pass the RSDP address to the kernel, which +makes it possible for a user to modify the workings of hardware . Reject +the option when the kernel is locked down. + +Signed-off-by: Josh Boyer <jwboyer@redhat.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: Dave Young <dyoung@redhat.com> +cc: linux-acpi@vger.kernel.org +--- + drivers/acpi/osl.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/drivers/acpi/osl.c +=================================================================== +--- linux.orig/drivers/acpi/osl.c ++++ linux/drivers/acpi/osl.c +@@ -194,7 +194,7 @@ acpi_physical_address __init acpi_os_get + acpi_physical_address pa; + + #ifdef CONFIG_KEXEC +- if (acpi_rsdp) ++ if (acpi_rsdp && !kernel_is_locked_down("ACPI RSDP specification")) + return acpi_rsdp; + #endif + pa = acpi_arch_get_root_pointer(); diff --git a/debian/patches/features/all/lockdown/0017-acpi-Disable-ACPI-table-override-if-the-kernel-is-lo.patch b/debian/patches/features/all/lockdown/0017-acpi-Disable-ACPI-table-override-if-the-kernel-is-lo.patch new file mode 100644 index 000000000..fd12eedb2 --- /dev/null +++ b/debian/patches/features/all/lockdown/0017-acpi-Disable-ACPI-table-override-if-the-kernel-is-lo.patch @@ -0,0 +1,40 @@ +From: Linn Crosetto <linn@hpe.com> +Date: Wed, 8 Nov 2017 15:11:34 +0000 +Subject: [17/29] acpi: Disable ACPI table override if the kernel is locked + down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=5976d26de05569951641ebeb95f7240993b66063 + +From the kernel documentation (initrd_table_override.txt): + + If the ACPI_INITRD_TABLE_OVERRIDE compile option is true, it is possible + to override nearly any ACPI table provided by the BIOS with an + instrumented, modified one. + +When securelevel is set, the kernel should disallow any unauthenticated +changes to kernel space. ACPI tables contain code invoked by the kernel, +so do not allow ACPI tables to be overridden if the kernel is locked down. + +Signed-off-by: Linn Crosetto <linn@hpe.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: linux-acpi@vger.kernel.org +--- + drivers/acpi/tables.c | 5 +++++ + 1 file changed, 5 insertions(+) + +Index: linux/drivers/acpi/tables.c +=================================================================== +--- linux.orig/drivers/acpi/tables.c ++++ linux/drivers/acpi/tables.c +@@ -532,6 +532,11 @@ void __init acpi_table_upgrade(void) + if (table_nr == 0) + return; + ++ if (kernel_is_locked_down("ACPI table override")) { ++ pr_notice("kernel is locked down, ignoring table override\n"); ++ return; ++ } ++ + acpi_tables_addr = + memblock_find_in_range(0, ACPI_TABLE_UPGRADE_MAX_PHYS, + all_tables_size, PAGE_SIZE); diff --git a/debian/patches/features/all/lockdown/0018-acpi-Disable-APEI-error-injection-if-the-kernel-is-l.patch b/debian/patches/features/all/lockdown/0018-acpi-Disable-APEI-error-injection-if-the-kernel-is-l.patch new file mode 100644 index 000000000..396a506ac --- /dev/null +++ b/debian/patches/features/all/lockdown/0018-acpi-Disable-APEI-error-injection-if-the-kernel-is-l.patch @@ -0,0 +1,43 @@ +From: Linn Crosetto <linn@hpe.com> +Date: Wed, 8 Nov 2017 15:11:35 +0000 +Subject: [18/29] acpi: Disable APEI error injection if the kernel is locked + down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a9c239382bce17b9108f941130392151d5fff262 + +ACPI provides an error injection mechanism, EINJ, for debugging and testing +the ACPI Platform Error Interface (APEI) and other RAS features. If +supported by the firmware, ACPI specification 5.0 and later provide for a +way to specify a physical memory address to which to inject the error. + +Injecting errors through EINJ can produce errors which to the platform are +indistinguishable from real hardware errors. This can have undesirable +side-effects, such as causing the platform to mark hardware as needing +replacement. + +While it does not provide a method to load unauthenticated privileged code, +the effect of these errors may persist across reboots and affect trust in +the underlying hardware, so disable error injection through EINJ if +the kernel is locked down. + +Signed-off-by: Linn Crosetto <linn@hpe.com> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: "Lee, Chun-Yi" <jlee@suse.com> +cc: linux-acpi@vger.kernel.org +--- + drivers/acpi/apei/einj.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: linux/drivers/acpi/apei/einj.c +=================================================================== +--- linux.orig/drivers/acpi/apei/einj.c ++++ linux/drivers/acpi/apei/einj.c +@@ -518,6 +518,9 @@ static int einj_error_inject(u32 type, u + int rc; + u64 base_addr, size; + ++ if (kernel_is_locked_down("ACPI error injection")) ++ return -EPERM; ++ + /* If user manually set "flags", make sure it is legal */ + if (flags && (flags & + ~(SETWA_FLAGS_APICID|SETWA_FLAGS_MEM|SETWA_FLAGS_PCIE_SBDF))) diff --git a/debian/patches/features/all/lockdown/0020-Prohibit-PCMCIA-CIS-storage-when-the-kernel-is-locke.patch b/debian/patches/features/all/lockdown/0020-Prohibit-PCMCIA-CIS-storage-when-the-kernel-is-locke.patch new file mode 100644 index 000000000..2ed56ad5b --- /dev/null +++ b/debian/patches/features/all/lockdown/0020-Prohibit-PCMCIA-CIS-storage-when-the-kernel-is-locke.patch @@ -0,0 +1,29 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:35 +0000 +Subject: [20/29] Prohibit PCMCIA CIS storage when the kernel is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=18b2dfc74efeafbdbb8f5d4d28da6334b7e1f1ac + +Prohibit replacement of the PCMCIA Card Information Structure when the +kernel is locked down. + +Suggested-by: Dominik Brodowski <linux@dominikbrodowski.net> +Signed-off-by: David Howells <dhowells@redhat.com> +cc: linux-pcmcia@lists.infradead.org +--- + drivers/pcmcia/cistpl.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: linux/drivers/pcmcia/cistpl.c +=================================================================== +--- linux.orig/drivers/pcmcia/cistpl.c ++++ linux/drivers/pcmcia/cistpl.c +@@ -1578,6 +1578,9 @@ static ssize_t pccard_store_cis(struct f + struct pcmcia_socket *s; + int error; + ++ if (kernel_is_locked_down("Direct PCMCIA CIS storage")) ++ return -EPERM; ++ + s = to_socket(container_of(kobj, struct device, kobj)); + + if (off) diff --git a/debian/patches/features/all/lockdown/0021-Lock-down-TIOCSSERIAL.patch b/debian/patches/features/all/lockdown/0021-Lock-down-TIOCSSERIAL.patch new file mode 100644 index 000000000..d906326a9 --- /dev/null +++ b/debian/patches/features/all/lockdown/0021-Lock-down-TIOCSSERIAL.patch @@ -0,0 +1,34 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:35 +0000 +Subject: [21/29] Lock down TIOCSSERIAL +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=f5fdeda0622ca040961521819794193777a03e8a + +Lock down TIOCSSERIAL as that can be used to change the ioport and irq +settings on a serial port. This only appears to be an issue for the serial +drivers that use the core serial code. All other drivers seem to either +ignore attempts to change port/irq or give an error. + +Reported-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Signed-off-by: David Howells <dhowells@redhat.com> +cc: Jiri Slaby <jslaby@suse.com> +--- + drivers/tty/serial/serial_core.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +Index: linux/drivers/tty/serial/serial_core.c +=================================================================== +--- linux.orig/drivers/tty/serial/serial_core.c ++++ linux/drivers/tty/serial/serial_core.c +@@ -850,6 +850,12 @@ static int uart_set_info(struct tty_stru + new_flags = (__force upf_t)new_info->flags; + old_custom_divisor = uport->custom_divisor; + ++ if ((change_port || change_irq) && ++ kernel_is_locked_down("Using TIOCSSERIAL to change device addresses, irqs and dma channels")) { ++ retval = -EPERM; ++ goto exit; ++ } ++ + if (!capable(CAP_SYS_ADMIN)) { + retval = -EPERM; + if (change_irq || change_port || diff --git a/debian/patches/features/all/lockdown/0022-Lock-down-module-params-that-specify-hardware-parame.patch b/debian/patches/features/all/lockdown/0022-Lock-down-module-params-that-specify-hardware-parame.patch new file mode 100644 index 000000000..3582e3106 --- /dev/null +++ b/debian/patches/features/all/lockdown/0022-Lock-down-module-params-that-specify-hardware-parame.patch @@ -0,0 +1,80 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:36 +0000 +Subject: [22/29] Lock down module params that specify hardware parameters (eg. + ioport) +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=d20a28efda02a7ce70b943c15246ea2f07e780f4 + +Provided an annotation for module parameters that specify hardware +parameters (such as io ports, iomem addresses, irqs, dma channels, fixed +dma buffers and other types). + +Suggested-by: Alan Cox <gnomes@lxorguk.ukuu.org.uk> +Signed-off-by: David Howells <dhowells@redhat.com> +--- + kernel/params.c | 26 +++++++++++++++++++++----- + 1 file changed, 21 insertions(+), 5 deletions(-) + +Index: linux/kernel/params.c +=================================================================== +--- linux.orig/kernel/params.c ++++ linux/kernel/params.c +@@ -108,13 +108,19 @@ bool parameq(const char *a, const char * + return parameqn(a, b, strlen(a)+1); + } + +-static void param_check_unsafe(const struct kernel_param *kp) ++static bool param_check_unsafe(const struct kernel_param *kp, ++ const char *doing) + { + if (kp->flags & KERNEL_PARAM_FL_UNSAFE) { + pr_notice("Setting dangerous option %s - tainting kernel\n", + kp->name); + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + } ++ ++ if (kp->flags & KERNEL_PARAM_FL_HWPARAM && ++ kernel_is_locked_down("Command line-specified device addresses, irqs and dma channels")) ++ return false; ++ return true; + } + + static int parse_one(char *param, +@@ -144,8 +150,10 @@ static int parse_one(char *param, + pr_debug("handling %s with %p\n", param, + params[i].ops->set); + kernel_param_lock(params[i].mod); +- param_check_unsafe(¶ms[i]); +- err = params[i].ops->set(val, ¶ms[i]); ++ if (param_check_unsafe(¶ms[i], doing)) ++ err = params[i].ops->set(val, ¶ms[i]); ++ else ++ err = -EPERM; + kernel_param_unlock(params[i].mod); + return err; + } +@@ -553,6 +561,12 @@ static ssize_t param_attr_show(struct mo + return count; + } + ++#ifdef CONFIG_MODULES ++#define mod_name(mod) (mod)->name ++#else ++#define mod_name(mod) "unknown" ++#endif ++ + /* sysfs always hands a nul-terminated string in buf. We rely on that. */ + static ssize_t param_attr_store(struct module_attribute *mattr, + struct module_kobject *mk, +@@ -565,8 +579,10 @@ static ssize_t param_attr_store(struct m + return -EPERM; + + kernel_param_lock(mk->mod); +- param_check_unsafe(attribute->param); +- err = attribute->param->ops->set(buf, attribute->param); ++ if (param_check_unsafe(attribute->param, mod_name(mk->mod))) ++ err = attribute->param->ops->set(buf, attribute->param); ++ else ++ err = -EPERM; + kernel_param_unlock(mk->mod); + if (!err) + return len; diff --git a/debian/patches/features/all/lockdown/0023-x86-mmiotrace-Lock-down-the-testmmiotrace-module.patch b/debian/patches/features/all/lockdown/0023-x86-mmiotrace-Lock-down-the-testmmiotrace-module.patch new file mode 100644 index 000000000..47edb3442 --- /dev/null +++ b/debian/patches/features/all/lockdown/0023-x86-mmiotrace-Lock-down-the-testmmiotrace-module.patch @@ -0,0 +1,33 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:36 +0000 +Subject: [23/29] x86/mmiotrace: Lock down the testmmiotrace module +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=20af3be0bcf6a78e3632770561fba6531dd3b444 + +The testmmiotrace module shouldn't be permitted when the kernel is locked +down as it can be used to arbitrarily read and write MMIO space. + +Suggested-by: Thomas Gleixner <tglx@linutronix.de> +Signed-off-by: David Howells <dhowells@redhat.com +cc: Thomas Gleixner <tglx@linutronix.de> +cc: Steven Rostedt <rostedt@goodmis.org> +cc: Ingo Molnar <mingo@kernel.org> +cc: "H. Peter Anvin" <hpa@zytor.com> +cc: x86@kernel.org +--- + arch/x86/mm/testmmiotrace.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: linux/arch/x86/mm/testmmiotrace.c +=================================================================== +--- linux.orig/arch/x86/mm/testmmiotrace.c ++++ linux/arch/x86/mm/testmmiotrace.c +@@ -115,6 +115,9 @@ static int __init init(void) + { + unsigned long size = (read_far) ? (8 << 20) : (16 << 10); + ++ if (kernel_is_locked_down("MMIO trace testing")) ++ return -EPERM; ++ + if (mmio_address == 0) { + pr_err("you have to use the module argument mmio_address.\n"); + pr_err("DO NOT LOAD THIS MODULE UNLESS YOU REALLY KNOW WHAT YOU ARE DOING!\n"); diff --git a/debian/patches/features/all/lockdown/0024-debugfs-Disallow-use-of-debugfs-files-when-the-kerne.patch b/debian/patches/features/all/lockdown/0024-debugfs-Disallow-use-of-debugfs-files-when-the-kerne.patch new file mode 100644 index 000000000..2dd3fa020 --- /dev/null +++ b/debian/patches/features/all/lockdown/0024-debugfs-Disallow-use-of-debugfs-files-when-the-kerne.patch @@ -0,0 +1,53 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:36 +0000 +Subject: [24/29] debugfs: Disallow use of debugfs files when the kernel is + locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=118cc5e1c27e1a75640cf2379c1299e12791063e + +Disallow opening of debugfs files when the kernel is locked down as various +drivers give raw access to hardware through debugfs. + +Accesses to tracefs should use /sys/kernel/tracing/ rather than +/sys/kernel/debug/tracing/. Possibly a symlink should be emplaced. + +Normal device interaction should be done through configfs or a miscdev, not +debugfs. + +Note that this makes it unnecessary to specifically lock down show_dsts(), +show_devs() and show_call() in the asus-wmi driver. + +Signed-off-by: David Howells <dhowells@redhat.com> +cc: Andy Shevchenko <andy.shevchenko@gmail.com> +cc: acpi4asus-user@lists.sourceforge.net +cc: platform-driver-x86@vger.kernel.org +cc: Matthew Garrett <matthew.garrett@nebula.com> +cc: Thomas Gleixner <tglx@linutronix.de> +[bwh: Forward-ported to 4.15] +--- + fs/debugfs/file.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +Index: linux/fs/debugfs/file.c +=================================================================== +--- linux.orig/fs/debugfs/file.c ++++ linux/fs/debugfs/file.c +@@ -142,6 +142,9 @@ static int open_proxy_open(struct inode + const struct file_operations *real_fops = NULL; + int r; + ++ if (kernel_is_locked_down("debugfs")) ++ return -EPERM; ++ + r = debugfs_file_get(dentry); + if (r) + return r == -EIO ? -ENOENT : r; +@@ -267,6 +270,9 @@ static int full_proxy_open(struct inode + struct file_operations *proxy_fops = NULL; + int r; + ++ if (kernel_is_locked_down("debugfs")) ++ return -EPERM; ++ + r = debugfs_file_get(dentry); + if (r) + return r == -EIO ? -ENOENT : r; diff --git a/debian/patches/features/all/lockdown/0025-Lock-down-proc-kcore.patch b/debian/patches/features/all/lockdown/0025-Lock-down-proc-kcore.patch new file mode 100644 index 000000000..58df9739b --- /dev/null +++ b/debian/patches/features/all/lockdown/0025-Lock-down-proc-kcore.patch @@ -0,0 +1,27 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:37 +0000 +Subject: [25/29] Lock down /proc/kcore +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=797378dc4498207c3abc1101cfdc9ef2581d8c71 + +Disallow access to /proc/kcore when the kernel is locked down to prevent +access to cryptographic data. + +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: James Morris <james.l.morris@oracle.com> +--- + fs/proc/kcore.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: linux/fs/proc/kcore.c +=================================================================== +--- linux.orig/fs/proc/kcore.c ++++ linux/fs/proc/kcore.c +@@ -545,6 +545,8 @@ out: + + static int open_kcore(struct inode *inode, struct file *filp) + { ++ if (kernel_is_locked_down("/proc/kcore")) ++ return -EPERM; + if (!capable(CAP_SYS_RAWIO)) + return -EPERM; + diff --git a/debian/patches/features/all/lockdown/0026-Lock-down-kprobes.patch b/debian/patches/features/all/lockdown/0026-Lock-down-kprobes.patch new file mode 100644 index 000000000..e7d9f0b4e --- /dev/null +++ b/debian/patches/features/all/lockdown/0026-Lock-down-kprobes.patch @@ -0,0 +1,29 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 16:14:12 +0000 +Subject: [26/29] Lock down kprobes +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=cfacbbe6ef95336d99817fb8063c19bd36dfaa3d + +Disallow the creation of kprobes when the kernel is locked down by +preventing their registration. This prevents kprobes from being used to +access kernel memory, either to make modifications or to steal crypto data. + +Reported-by: Alexei Starovoitov <alexei.starovoitov@gmail.com> +Signed-off-by: David Howells <dhowells@redhat.com> +--- + kernel/kprobes.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: linux/kernel/kprobes.c +=================================================================== +--- linux.orig/kernel/kprobes.c ++++ linux/kernel/kprobes.c +@@ -1548,6 +1548,9 @@ int register_kprobe(struct kprobe *p) + struct module *probed_mod; + kprobe_opcode_t *addr; + ++ if (kernel_is_locked_down("Use of kprobes")) ++ return -EPERM; ++ + /* Adjust probe address from symbol */ + addr = kprobe_addr(p); + if (IS_ERR(addr)) diff --git a/debian/patches/features/all/lockdown/0027-bpf-Restrict-kernel-image-access-functions-when-the-.patch b/debian/patches/features/all/lockdown/0027-bpf-Restrict-kernel-image-access-functions-when-the-.patch new file mode 100644 index 000000000..87273834c --- /dev/null +++ b/debian/patches/features/all/lockdown/0027-bpf-Restrict-kernel-image-access-functions-when-the-.patch @@ -0,0 +1,39 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 24 May 2017 14:56:05 +0100 +Subject: [27/29] bpf: Restrict kernel image access functions when the kernel + is locked down +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a13e9f58894129d9fd02fdb81b56ac7590704155 + +There are some bpf functions can be used to read kernel memory: +bpf_probe_read, bpf_probe_write_user and bpf_trace_printk. These allow +private keys in kernel memory (e.g. the hibernation image signing key) to +be read by an eBPF program and kernel memory to be altered without +restriction. + +Completely prohibit the use of BPF when the kernel is locked down. + +Suggested-by: Alexei Starovoitov <alexei.starovoitov@gmail.com> +Signed-off-by: David Howells <dhowells@redhat.com> +cc: netdev@vger.kernel.org +cc: Chun-Yi Lee <jlee@suse.com> +cc: Alexei Starovoitov <alexei.starovoitov@gmail.com> +[bwh: Adjust context to apply after commit dcab51f19b29 + "bpf: Expose check_uarg_tail_zero()"] +--- + kernel/bpf/syscall.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: linux/kernel/bpf/syscall.c +=================================================================== +--- linux.orig/kernel/bpf/syscall.c ++++ linux/kernel/bpf/syscall.c +@@ -2378,6 +2378,9 @@ SYSCALL_DEFINE3(bpf, int, cmd, union bpf + if (sysctl_unprivileged_bpf_disabled && !capable(CAP_SYS_ADMIN)) + return -EPERM; + ++ if (kernel_is_locked_down("BPF")) ++ return -EPERM; ++ + err = bpf_check_uarg_tail_zero(uattr, sizeof(attr), size); + if (err) + return err; diff --git a/debian/patches/features/all/lockdown/0028-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch b/debian/patches/features/all/lockdown/0028-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch new file mode 100644 index 000000000..be357055b --- /dev/null +++ b/debian/patches/features/all/lockdown/0028-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch @@ -0,0 +1,152 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:37 +0000 +Subject: [28/29] efi: Add an EFI_SECURE_BOOT flag to indicate secure boot mode +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=eb4a8603eb727afaeb9c6123eda2eda4b2757bf3 + +UEFI machines can be booted in Secure Boot mode. Add an EFI_SECURE_BOOT +flag that can be passed to efi_enabled() to find out whether secure boot is +enabled. + +Move the switch-statement in x86's setup_arch() that inteprets the +secure_boot boot parameter to generic code and set the bit there. + +Suggested-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Signed-off-by: David Howells <dhowells@redhat.com> +Reviewed-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +cc: linux-efi@vger.kernel.org +--- + arch/x86/kernel/setup.c | 14 +------------- + drivers/firmware/efi/Makefile | 1 + + drivers/firmware/efi/secureboot.c | 38 ++++++++++++++++++++++++++++++++++++++ + include/linux/efi.h | 16 ++++++++++------ + 4 files changed, 50 insertions(+), 19 deletions(-) + create mode 100644 drivers/firmware/efi/secureboot.c + +Index: linux/arch/x86/kernel/setup.c +=================================================================== +--- linux.orig/arch/x86/kernel/setup.c ++++ linux/arch/x86/kernel/setup.c +@@ -1159,19 +1159,7 @@ void __init setup_arch(char **cmdline_p) + /* Allocate bigger log buffer */ + setup_log_buf(1); + +- if (efi_enabled(EFI_BOOT)) { +- switch (boot_params.secure_boot) { +- case efi_secureboot_mode_disabled: +- pr_info("Secure boot disabled\n"); +- break; +- case efi_secureboot_mode_enabled: +- pr_info("Secure boot enabled\n"); +- break; +- default: +- pr_info("Secure boot could not be determined\n"); +- break; +- } +- } ++ efi_set_secure_boot(boot_params.secure_boot); + + reserve_initrd(); + +Index: linux/drivers/firmware/efi/Makefile +=================================================================== +--- linux.orig/drivers/firmware/efi/Makefile ++++ linux/drivers/firmware/efi/Makefile +@@ -24,6 +24,7 @@ obj-$(CONFIG_EFI_FAKE_MEMMAP) += fake_m + obj-$(CONFIG_EFI_BOOTLOADER_CONTROL) += efibc.o + obj-$(CONFIG_EFI_TEST) += test/ + obj-$(CONFIG_EFI_DEV_PATH_PARSER) += dev-path-parser.o ++obj-$(CONFIG_EFI) += secureboot.o + obj-$(CONFIG_APPLE_PROPERTIES) += apple-properties.o + + arm-obj-$(CONFIG_EFI) := arm-init.o arm-runtime.o +Index: linux/drivers/firmware/efi/secureboot.c +=================================================================== +--- /dev/null ++++ linux/drivers/firmware/efi/secureboot.c +@@ -0,0 +1,38 @@ ++/* Core kernel secure boot support. ++ * ++ * Copyright (C) 2017 Red Hat, Inc. All Rights Reserved. ++ * Written by David Howells (dhowells@redhat.com) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public Licence ++ * as published by the Free Software Foundation; either version ++ * 2 of the Licence, or (at your option) any later version. ++ */ ++ ++#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ++ ++#include <linux/efi.h> ++#include <linux/kernel.h> ++#include <linux/printk.h> ++ ++/* ++ * Decide what to do when UEFI secure boot mode is enabled. ++ */ ++void __init efi_set_secure_boot(enum efi_secureboot_mode mode) ++{ ++ if (efi_enabled(EFI_BOOT)) { ++ switch (mode) { ++ case efi_secureboot_mode_disabled: ++ pr_info("Secure boot disabled\n"); ++ break; ++ case efi_secureboot_mode_enabled: ++ set_bit(EFI_SECURE_BOOT, &efi.flags); ++ pr_info("Secure boot enabled\n"); ++ break; ++ default: ++ pr_warning("Secure boot could not be determined (mode %u)\n", ++ mode); ++ break; ++ } ++ } ++} +Index: linux/include/linux/efi.h +=================================================================== +--- linux.orig/include/linux/efi.h ++++ linux/include/linux/efi.h +@@ -1152,6 +1152,14 @@ extern int __init efi_setup_pcdp_console + #define EFI_DBG 8 /* Print additional debug info at runtime */ + #define EFI_NX_PE_DATA 9 /* Can runtime data regions be mapped non-executable? */ + #define EFI_MEM_ATTR 10 /* Did firmware publish an EFI_MEMORY_ATTRIBUTES table? */ ++#define EFI_SECURE_BOOT 11 /* Are we in Secure Boot mode? */ ++ ++enum efi_secureboot_mode { ++ efi_secureboot_mode_unset, ++ efi_secureboot_mode_unknown, ++ efi_secureboot_mode_disabled, ++ efi_secureboot_mode_enabled, ++}; + + #ifdef CONFIG_EFI + /* +@@ -1164,6 +1172,7 @@ static inline bool efi_enabled(int featu + extern void efi_reboot(enum reboot_mode reboot_mode, const char *__unused); + + extern bool efi_is_table_address(unsigned long phys_addr); ++extern void __init efi_set_secure_boot(enum efi_secureboot_mode mode); + #else + static inline bool efi_enabled(int feature) + { +@@ -1182,6 +1191,7 @@ static inline bool efi_is_table_address( + { + return false; + } ++static inline void efi_set_secure_boot(enum efi_secureboot_mode mode) {} + #endif + + extern int efi_status_to_err(efi_status_t status); +@@ -1572,12 +1582,6 @@ static inline bool efi_runtime_disabled( + + extern void efi_call_virt_check_flags(unsigned long flags, const char *call); + +-enum efi_secureboot_mode { +- efi_secureboot_mode_unset, +- efi_secureboot_mode_unknown, +- efi_secureboot_mode_disabled, +- efi_secureboot_mode_enabled, +-}; + enum efi_secureboot_mode efi_get_secureboot(efi_system_table_t *sys_table); + + #ifdef CONFIG_RESET_ATTACK_MITIGATION diff --git a/debian/patches/features/all/lockdown/0029-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch b/debian/patches/features/all/lockdown/0029-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch new file mode 100644 index 000000000..9ab10afb3 --- /dev/null +++ b/debian/patches/features/all/lockdown/0029-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch @@ -0,0 +1,83 @@ +From: David Howells <dhowells@redhat.com> +Date: Wed, 8 Nov 2017 15:11:37 +0000 +Subject: [29/29] efi: Lock down the kernel if booted in secure boot mode +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/dhowells/linux-fs.git/commit?id=a364bd945ffc141a7b17cb331bda0d8ad68f7e72 + +UEFI Secure Boot provides a mechanism for ensuring that the firmware will +only load signed bootloaders and kernels. Certain use cases may also +require that all kernel modules also be signed. Add a configuration option +that to lock down the kernel - which includes requiring validly signed +modules - if the kernel is secure-booted. + +Signed-off-by: David Howells <dhowells@redhat.com> +Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +cc: linux-efi@vger.kernel.org +--- + arch/x86/kernel/setup.c | 6 ++++-- + security/Kconfig | 14 ++++++++++++++ + security/lock_down.c | 1 + + 3 files changed, 19 insertions(+), 2 deletions(-) + +--- a/arch/x86/kernel/setup.c ++++ b/arch/x86/kernel/setup.c +@@ -65,6 +65,7 @@ + #include <linux/dma-mapping.h> + #include <linux/ctype.h> + #include <linux/uaccess.h> ++#include <linux/security.h> + + #include <linux/percpu.h> + #include <linux/crash_dump.h> +@@ -1005,6 +1006,9 @@ void __init setup_arch(char **cmdline_p) + if (efi_enabled(EFI_BOOT)) + efi_init(); + ++ efi_set_secure_boot(boot_params.secure_boot); ++ init_lockdown(); ++ + dmi_scan_machine(); + dmi_memdev_walk(); + dmi_set_dump_stack_arch_desc(); +@@ -1159,8 +1163,6 @@ void __init setup_arch(char **cmdline_p) + /* Allocate bigger log buffer */ + setup_log_buf(1); + +- efi_set_secure_boot(boot_params.secure_boot); +- + reserve_initrd(); + + acpi_table_upgrade(); +--- a/security/Kconfig ++++ b/security/Kconfig +@@ -247,6 +247,21 @@ config LOCK_DOWN_KERNEL + turns off various features that might otherwise allow access to the + kernel image (eg. setting MSR registers). + ++config LOCK_DOWN_IN_EFI_SECURE_BOOT ++ bool "Lock down the kernel in EFI Secure Boot mode" ++ default n ++ select LOCK_DOWN_KERNEL ++ depends on EFI ++ help ++ UEFI Secure Boot provides a mechanism for ensuring that the firmware ++ will only load signed bootloaders and kernels. Secure boot mode may ++ be determined from EFI variables provided by the system firmware if ++ not indicated by the boot parameters. ++ ++ Enabling this option turns on results in kernel lockdown being ++ triggered if EFI Secure Boot is set. ++ ++ + source security/selinux/Kconfig + source security/smack/Kconfig + source security/tomoyo/Kconfig +--- a/security/lock_down.c ++++ b/security/lock_down.c +@@ -11,6 +11,7 @@ + + #include <linux/security.h> + #include <linux/export.h> ++#include <linux/efi.h> + + static __ro_after_init bool kernel_locked_down; + diff --git a/debian/patches/features/all/lockdown/0032-efi-Restrict-efivar_ssdt_load-when-the-kernel-is-loc.patch b/debian/patches/features/all/lockdown/0032-efi-Restrict-efivar_ssdt_load-when-the-kernel-is-loc.patch new file mode 100644 index 000000000..bb2f4f60b --- /dev/null +++ b/debian/patches/features/all/lockdown/0032-efi-Restrict-efivar_ssdt_load-when-the-kernel-is-loc.patch @@ -0,0 +1,36 @@ +From: Matthew Garrett <matthewgarrett@google.com> +Date: Wed, 31 Jul 2019 15:16:16 -0700 +Subject: efi: Restrict efivar_ssdt_load when the kernel is locked down +Origin: https://patchwork.kernel.org/patch/11069659/ + +efivar_ssdt_load allows the kernel to import arbitrary ACPI code from an +EFI variable, which gives arbitrary code execution in ring 0. Prevent +that when the kernel is locked down. + +Signed-off-by: Matthew Garrett <mjg59@google.com> +Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Reviewed-by: Kees Cook <keescook@chromium.org> +Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org> +Cc: linux-efi@vger.kernel.org +[bwh: Convert back to the non-LSM lockdown API] +--- +--- a/drivers/firmware/efi/efi.c ++++ b/drivers/firmware/efi/efi.c +@@ -30,6 +30,7 @@ + #include <linux/acpi.h> + #include <linux/ucs2_string.h> + #include <linux/memblock.h> ++#include <linux/security.h> + + #include <asm/early_ioremap.h> + +@@ -241,6 +242,9 @@ static void generic_ops_unregister(void) + static char efivar_ssdt[EFIVAR_SSDT_NAME_MAX] __initdata; + static int __init efivar_ssdt_setup(char *str) + { ++ if (kernel_is_locked_down("ACPI tables")) ++ return -EPERM; ++ + if (strlen(str) < sizeof(efivar_ssdt)) + memcpy(efivar_ssdt, str, strlen(str)); + else diff --git a/debian/patches/features/all/lockdown/ACPI-configfs-Disallow-loading-ACPI-tables-when-lock.patch b/debian/patches/features/all/lockdown/ACPI-configfs-Disallow-loading-ACPI-tables-when-lock.patch new file mode 100644 index 000000000..4970a4bd4 --- /dev/null +++ b/debian/patches/features/all/lockdown/ACPI-configfs-Disallow-loading-ACPI-tables-when-lock.patch @@ -0,0 +1,44 @@ +From: "Jason A. Donenfeld" <Jason@zx2c4.com> +Date: Mon, 15 Jun 2020 04:43:32 -0600 +Subject: ACPI: configfs: Disallow loading ACPI tables when locked down +Origin: https://git.kernel.org/linus/75b0cea7bf307f362057cc778efe89af4c615354 +Bug-Debian-Security: https://security-tracker.debian.org/tracker/CVE-2020-15780 + +Like other vectors already patched, this one here allows the root +user to load ACPI tables, which enables arbitrary physical address +writes, which in turn makes it possible to disable lockdown. + +Prevents this by checking the lockdown status before allowing a new +ACPI table to be installed. The link in the trailer shows a PoC of +how this might be used. + +Link: https://git.zx2c4.com/american-unsigned-language/tree/american-unsigned-language-2.sh +Cc: 5.4+ <stable@vger.kernel.org> # 5.4+ +Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> +Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +[Salvatore Bonaccorso: Backport to v4.19.y: Use kernel_is_locked_down instead +of security_locked_down] +--- + drivers/acpi/acpi_configfs.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/drivers/acpi/acpi_configfs.c ++++ b/drivers/acpi/acpi_configfs.c +@@ -14,6 +14,7 @@ + #include <linux/module.h> + #include <linux/configfs.h> + #include <linux/acpi.h> ++#include <linux/security.h> + + #include "acpica/accommon.h" + #include "acpica/actables.h" +@@ -33,6 +34,9 @@ static ssize_t acpi_table_aml_write(stru + struct acpi_table *table; + int ret; + ++ if (kernel_is_locked_down("Modifying ACPI tables")) ++ return -EPERM; ++ + table = container_of(cfg, struct acpi_table, cfg); + + if (table->header) { diff --git a/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch b/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch new file mode 100644 index 000000000..beb09c3e6 --- /dev/null +++ b/debian/patches/features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch @@ -0,0 +1,97 @@ +From: Linn Crosetto <linn@hpe.com> +Date: Tue, 30 Aug 2016 11:54:38 -0600 +Subject: arm64: add kernel config option to lock down when in Secure Boot mode +Bug-Debian: https://bugs.debian.org/831827 +Forwarded: no + +Add a kernel configuration option to lock down the kernel, to restrict +userspace's ability to modify the running kernel when UEFI Secure Boot is +enabled. Based on the x86 patch by Matthew Garrett. + +Determine the state of Secure Boot in the EFI stub and pass this to the +kernel using the FDT. + +Signed-off-by: Linn Crosetto <linn@hpe.com> +[bwh: Forward-ported to 4.10: adjust context] +[Lukas Wunner: Forward-ported to 4.11: drop parts applied upstream] +[bwh: Forward-ported to 4.15 and lockdown patch set: + - Pass result of efi_get_secureboot() in stub through to + efi_set_secure_boot() in main kernel + - Use lockdown API and naming] +[bwh: Forward-ported to 4.19.3: adjust context in update_fdt()] +[dannf: Moved init_lockdown() call after uefi_init(), fixing SB detection] +--- + arch/arm64/Kconfig | 13 +++++++++++++ + drivers/firmware/efi/arm-init.c | 7 +++++++ + drivers/firmware/efi/efi.c | 3 ++- + drivers/firmware/efi/libstub/arm-stub.c | 2 +- + drivers/firmware/efi/libstub/efistub.h | 1 + + drivers/firmware/efi/libstub/fdt.c | 7 +++++++ + include/linux/efi.h | 1 + + 7 files changed, 32 insertions(+), 2 deletions(-) + +Index: linux/drivers/firmware/efi/arm-init.c +=================================================================== +--- linux.orig/drivers/firmware/efi/arm-init.c ++++ linux/drivers/firmware/efi/arm-init.c +@@ -21,6 +21,7 @@ + #include <linux/of_fdt.h> + #include <linux/platform_device.h> + #include <linux/screen_info.h> ++#include <linux/security.h> + + #include <asm/efi.h> + +@@ -257,6 +258,9 @@ void __init efi_init(void) + return; + } + ++ efi_set_secure_boot(params.secure_boot); ++ init_lockdown(); ++ + reserve_regions(); + efi_esrt_init(); + +Index: linux/drivers/firmware/efi/efi.c +=================================================================== +--- linux.orig/drivers/firmware/efi/efi.c ++++ linux/drivers/firmware/efi/efi.c +@@ -660,7 +660,8 @@ static __initdata struct params fdt_para + UEFI_PARAM("MemMap Address", "linux,uefi-mmap-start", mmap), + UEFI_PARAM("MemMap Size", "linux,uefi-mmap-size", mmap_size), + UEFI_PARAM("MemMap Desc. Size", "linux,uefi-mmap-desc-size", desc_size), +- UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver) ++ UEFI_PARAM("MemMap Desc. Version", "linux,uefi-mmap-desc-ver", desc_ver), ++ UEFI_PARAM("Secure Boot Enabled", "linux,uefi-secure-boot", secure_boot) + }; + + static __initdata struct params xen_fdt_params[] = { +Index: linux/drivers/firmware/efi/libstub/fdt.c +=================================================================== +--- linux.orig/drivers/firmware/efi/libstub/fdt.c ++++ linux/drivers/firmware/efi/libstub/fdt.c +@@ -159,6 +159,12 @@ static efi_status_t update_fdt(efi_syste + } + } + ++ fdt_val32 = cpu_to_fdt32(efi_get_secureboot(sys_table)); ++ status = fdt_setprop(fdt, node, "linux,uefi-secure-boot", ++ &fdt_val32, sizeof(fdt_val32)); ++ if (status) ++ goto fdt_set_fail; ++ + /* shrink the FDT back to its minimum size */ + fdt_pack(fdt); + +Index: linux/include/linux/efi.h +=================================================================== +--- linux.orig/include/linux/efi.h ++++ linux/include/linux/efi.h +@@ -786,6 +786,7 @@ struct efi_fdt_params { + u32 mmap_size; + u32 desc_size; + u32 desc_ver; ++ u32 secure_boot; + }; + + typedef struct { diff --git a/debian/patches/features/all/lockdown/enable-cold-boot-attack-mitigation.patch b/debian/patches/features/all/lockdown/enable-cold-boot-attack-mitigation.patch new file mode 100644 index 000000000..7a3b8e9bb --- /dev/null +++ b/debian/patches/features/all/lockdown/enable-cold-boot-attack-mitigation.patch @@ -0,0 +1,50 @@ +From: Matthew Garrett <mjg59@coreos.com> +Date: Tue, 12 Jan 2016 12:51:27 -0800 +Subject: [18/18] Enable cold boot attack mitigation +Origin: https://github.com/mjg59/linux/commit/02d999574936dd234a508c0112a0200c135a5c34 + +[Lukas Wunner: Forward-ported to 4.11: adjust context] +--- + arch/x86/boot/compressed/eboot.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +Index: linux/arch/x86/boot/compressed/eboot.c +=================================================================== +--- linux.orig/arch/x86/boot/compressed/eboot.c ++++ linux/arch/x86/boot/compressed/eboot.c +@@ -372,6 +372,22 @@ void setup_graphics(struct boot_params * + } + } + ++#define MEMORY_ONLY_RESET_CONTROL_GUID \ ++ EFI_GUID (0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29) ++ ++static void enable_reset_attack_mitigation(void) ++{ ++ u8 val = 1; ++ efi_guid_t var_guid = MEMORY_ONLY_RESET_CONTROL_GUID; ++ ++ /* Ignore the return value here - there's not really a lot we can do */ ++ efi_early->call((unsigned long)sys_table->runtime->set_variable, ++ L"MemoryOverwriteRequestControl", &var_guid, ++ EFI_VARIABLE_NON_VOLATILE | ++ EFI_VARIABLE_BOOTSERVICE_ACCESS | ++ EFI_VARIABLE_RUNTIME_ACCESS, sizeof(val), val); ++} ++ + /* + * Because the x86 boot code expects to be passed a boot_params we + * need to create one ourselves (usually the bootloader would create +@@ -783,6 +799,12 @@ efi_main(struct efi_config *c, struct bo + efi_parse_options((char *)cmdline_paddr); + + /* ++ * Ask the firmware to clear memory if we don't have a clean ++ * shutdown ++ */ ++ enable_reset_attack_mitigation(); ++ ++ /* + * If the boot loader gave us a value for secure_boot then we use that, + * otherwise we ask the BIOS. + */ diff --git a/debian/patches/features/all/lockdown/lockdown-refer-to-debian-wiki-until-manual-page-exists.patch b/debian/patches/features/all/lockdown/lockdown-refer-to-debian-wiki-until-manual-page-exists.patch new file mode 100644 index 000000000..586be8cab --- /dev/null +++ b/debian/patches/features/all/lockdown/lockdown-refer-to-debian-wiki-until-manual-page-exists.patch @@ -0,0 +1,34 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Sun, 21 Apr 2019 00:17:13 +0100 +Subject: lockdown: Refer to Debian wiki until manual page exists +Forwarded: not-needed + +The lockdown denial log message currently refers to a +"kernel_lockdown.7" manual page, which is supposed to document it. +That manual page hasn't been accepted by the man-pages project and +doesn't even seem to have been submitted yet. For now, refer to the +Debian wiki. + +--- +Index: linux/security/lock_down.c +=================================================================== +--- linux.orig/security/lock_down.c ++++ linux/security/lock_down.c +@@ -28,7 +28,7 @@ static void __init lock_kernel_down(cons + { + if (!kernel_locked_down) { + kernel_locked_down = true; +- pr_notice("Kernel is locked down from %s; see man kernel_lockdown.7\n", ++ pr_notice("Kernel is locked down from %s; see https://wiki.debian.org/SecureBoot\n", + where); + } + } +@@ -60,7 +60,7 @@ void __init init_lockdown(void) + bool __kernel_is_locked_down(const char *what, bool first) + { + if (what && first && kernel_locked_down) +- pr_notice("Lockdown: %s is restricted; see man kernel_lockdown.7\n", ++ pr_notice("Lockdown: %s is restricted; see https://wiki.debian.org/SecureBoot\n", + what); + return kernel_locked_down; + } diff --git a/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch b/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch new file mode 100644 index 000000000..f02392f10 --- /dev/null +++ b/debian/patches/features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch @@ -0,0 +1,41 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Fri, 03 Jun 2016 00:48:39 +0100 +Subject: mtd: Disable slram and phram when locked down +Forwarded: no + +The slram and phram drivers both allow mapping regions of physical +address space such that they can then be read and written by userland +through the MTD interface. This is probably usable to manipulate +hardware into overwriting kernel code on many systems. Prevent that +if locked down. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/drivers/mtd/devices/phram.c +=================================================================== +--- linux.orig/drivers/mtd/devices/phram.c ++++ linux/drivers/mtd/devices/phram.c +@@ -219,6 +219,9 @@ static int phram_setup(const char *val) + uint64_t len; + int i, ret; + ++ if (kernel_is_locked_down("Command line-specified device addresses")) ++ return -EPERM; ++ + if (strnlen(val, sizeof(buf)) >= sizeof(buf)) + parse_err("parameter too long\n"); + +Index: linux/drivers/mtd/devices/slram.c +=================================================================== +--- linux.orig/drivers/mtd/devices/slram.c ++++ linux/drivers/mtd/devices/slram.c +@@ -226,6 +226,9 @@ static int parse_cmdline(char *devname, + unsigned long devstart; + unsigned long devlength; + ++ if (kernel_is_locked_down("Command line-specified device addresses")) ++ return -EPERM; ++ + if ((!devname) || (!szstart) || (!szlength)) { + unregister_devices(); + return(-EINVAL); diff --git a/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch b/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch new file mode 100644 index 000000000..22cd1283a --- /dev/null +++ b/debian/patches/features/all/security-perf-allow-further-restriction-of-perf_event_open.patch @@ -0,0 +1,81 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 11 Jan 2016 15:23:55 +0000 +Subject: security,perf: Allow further restriction of perf_event_open +Forwarded: https://lkml.org/lkml/2016/1/11/587 + +When kernel.perf_event_open is set to 3 (or greater), disallow all +access to performance events by users without CAP_SYS_ADMIN. +Add a Kconfig symbol CONFIG_SECURITY_PERF_EVENTS_RESTRICT that +makes this value the default. + +This is based on a similar feature in grsecurity +(CONFIG_GRKERNSEC_PERF_HARDEN). This version doesn't include making +the variable read-only. It also allows enabling further restriction +at run-time regardless of whether the default is changed. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- +Index: linux/include/linux/perf_event.h +=================================================================== +--- linux.orig/include/linux/perf_event.h ++++ linux/include/linux/perf_event.h +@@ -1189,6 +1189,11 @@ extern int perf_cpu_time_max_percent_han + int perf_event_max_stack_handler(struct ctl_table *table, int write, + void __user *buffer, size_t *lenp, loff_t *ppos); + ++static inline bool perf_paranoid_any(void) ++{ ++ return sysctl_perf_event_paranoid > 2; ++} ++ + static inline bool perf_paranoid_tracepoint_raw(void) + { + return sysctl_perf_event_paranoid > -1; +Index: linux/kernel/events/core.c +=================================================================== +--- linux.orig/kernel/events/core.c ++++ linux/kernel/events/core.c +@@ -397,8 +397,13 @@ static cpumask_var_t perf_online_mask; + * 0 - disallow raw tracepoint access for unpriv + * 1 - disallow cpu events for unpriv + * 2 - disallow kernel profiling for unpriv ++ * 3 - disallow all unpriv perf event use + */ ++#ifdef CONFIG_SECURITY_PERF_EVENTS_RESTRICT ++int sysctl_perf_event_paranoid __read_mostly = 3; ++#else + int sysctl_perf_event_paranoid __read_mostly = 2; ++#endif + + /* Minimum for 512 kiB + 1 user control page */ + int sysctl_perf_event_mlock __read_mostly = 512 + (PAGE_SIZE / 1024); /* 'free' kiB per user */ +@@ -10485,6 +10490,9 @@ SYSCALL_DEFINE5(perf_event_open, + if (flags & ~PERF_FLAG_ALL) + return -EINVAL; + ++ if (perf_paranoid_any() && !capable(CAP_SYS_ADMIN)) ++ return -EACCES; ++ + err = perf_copy_attr(attr_uptr, &attr); + if (err) + return err; +Index: linux/security/Kconfig +=================================================================== +--- linux.orig/security/Kconfig ++++ linux/security/Kconfig +@@ -18,6 +18,15 @@ config SECURITY_DMESG_RESTRICT + + If you are unsure how to answer this question, answer N. + ++config SECURITY_PERF_EVENTS_RESTRICT ++ bool "Restrict unprivileged use of performance events" ++ depends on PERF_EVENTS ++ help ++ If you say Y here, the kernel.perf_event_paranoid sysctl ++ will be set to 3 by default, and no unprivileged use of the ++ perf_event_open syscall will be permitted unless it is ++ changed. ++ + config SECURITY + bool "Enable different security models" + depends on SYSFS diff --git a/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-3-A-Plus.patch b/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-3-A-Plus.patch new file mode 100644 index 000000000..45f7696da --- /dev/null +++ b/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-3-A-Plus.patch @@ -0,0 +1,211 @@ +From: Stefan Wahren <stefan.wahren@i2se.com> +Date: Fri, 28 Dec 2018 23:09:26 +0100 +Subject: ARM: dts: add Raspberry Pi 3 A+ +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=bd80be88e05792db948bf3567a216743fdea5027 + +The Raspberry Pi 3 A+ is similar to the Pi 3 B+ but has only 512 MB RAM, +1 USB 2.0 port and no Ethernet. + +Compared to the Raspberry Pi 3 B it isn't possible to control BT_ON and +WL_ON separately. + +Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> +Acked-by: Eric Anholt <eric@anholt.net> +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts | 175 +++++++++++++++++++++ + 2 files changed, 176 insertions(+) + create mode 100644 arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts + +Index: debian-kernel/arch/arm/boot/dts/Makefile +=================================================================== +--- debian-kernel.orig/arch/arm/boot/dts/Makefile ++++ debian-kernel/arch/arm/boot/dts/Makefile +@@ -79,6 +79,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2835-rpi-a-plus.dtb \ + bcm2835-rpi-cm1-io1.dtb \ + bcm2836-rpi-2-b.dtb \ ++ bcm2837-rpi-3-a-plus.dtb \ + bcm2837-rpi-3-b.dtb \ + bcm2837-rpi-3-b-plus.dtb \ + bcm2837-rpi-cm3-io3.dtb \ +Index: debian-kernel/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts +=================================================================== +--- /dev/null ++++ debian-kernel/arch/arm/boot/dts/bcm2837-rpi-3-a-plus.dts +@@ -0,0 +1,175 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/dts-v1/; ++#include "bcm2837.dtsi" ++#include "bcm2836-rpi.dtsi" ++#include "bcm283x-rpi-usb-host.dtsi" ++ ++/ { ++ compatible = "raspberrypi,3-model-a-plus", "brcm,bcm2837"; ++ model = "Raspberry Pi 3 Model A+"; ++ ++ chosen { ++ /* 8250 auxiliary UART instead of pl011 */ ++ stdout-path = "serial1:115200n8"; ++ }; ++ ++ memory { ++ reg = <0 0x20000000>; ++ }; ++ ++ leds { ++ act { ++ gpios = <&gpio 29 GPIO_ACTIVE_HIGH>; ++ }; ++ ++ pwr { ++ label = "PWR"; ++ gpios = <&expgpio 2 GPIO_ACTIVE_LOW>; ++ }; ++ }; ++}; ++ ++&firmware { ++ expgpio: gpio { ++ compatible = "raspberrypi,firmware-gpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-line-names = "", ++ "BT_WL_ON", ++ "STATUS_LED_R", ++ "", ++ "", ++ "CAM_GPIO0", ++ "CAM_GPIO1", ++ ""; ++ status = "okay"; ++ }; ++}; ++ ++&gpio { ++ /* ++ * This is mostly based on the official GPU firmware DT blob. ++ * ++ * Legend: ++ * "NC" = not connected (no rail from the SoC) ++ * "FOO" = GPIO line named "FOO" on the schematic ++ * "FOO_N" = GPIO line named "FOO" on schematic, active low ++ */ ++ gpio-line-names = "ID_SDA", ++ "ID_SCL", ++ "SDA1", ++ "SCL1", ++ "GPIO_GCLK", ++ "GPIO5", ++ "GPIO6", ++ "SPI_CE1_N", ++ "SPI_CE0_N", ++ "SPI_MISO", ++ "SPI_MOSI", ++ "SPI_SCLK", ++ "GPIO12", ++ "GPIO13", ++ /* Serial port */ ++ "TXD1", ++ "RXD1", ++ "GPIO16", ++ "GPIO17", ++ "GPIO18", ++ "GPIO19", ++ "GPIO20", ++ "GPIO21", ++ "GPIO22", ++ "GPIO23", ++ "GPIO24", ++ "GPIO25", ++ "GPIO26", ++ "GPIO27", ++ "HDMI_HPD_N", ++ "STATUS_LED_G", ++ /* Used by BT module */ ++ "CTS0", ++ "RTS0", ++ "TXD0", ++ "RXD0", ++ /* Used by Wifi */ ++ "SD1_CLK", ++ "SD1_CMD", ++ "SD1_DATA0", ++ "SD1_DATA1", ++ "SD1_DATA2", ++ "SD1_DATA3", ++ "PWM0_OUT", ++ "PWM1_OUT", ++ "", /* GPIO42 */ ++ "WIFI_CLK", ++ "SDA0", ++ "SCL0", ++ "SMPS_SCL", ++ "SMPS_SDA", ++ /* Used by SD Card */ ++ "SD_CLK_R", ++ "SD_CMD_R", ++ "SD_DATA0_R", ++ "SD_DATA1_R", ++ "SD_DATA2_R", ++ "SD_DATA3_R"; ++}; ++ ++&hdmi { ++ hpd-gpios = <&gpio 28 GPIO_ACTIVE_LOW>; ++}; ++ ++&pwm { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&pwm0_gpio40 &pwm1_gpio41>; ++ status = "okay"; ++}; ++ ++/* ++ * SDHCI is used to control the SDIO for wireless ++ * ++ * WL_REG_ON and BT_REG_ON of the CYW43455 Wifi/BT module are driven ++ * by a single GPIO. We can't give GPIO control to one of the drivers, ++ * otherwise the other part would get unexpectedly disturbed. ++ */ ++&sdhci { ++ #address-cells = <1>; ++ #size-cells = <0>; ++ pinctrl-names = "default"; ++ pinctrl-0 = <&emmc_gpio34>; ++ status = "okay"; ++ bus-width = <4>; ++ non-removable; ++ ++ brcmf: wifi@1 { ++ reg = <1>; ++ compatible = "brcm,bcm4329-fmac"; ++ }; ++}; ++ ++/* SDHOST is used to drive the SD card */ ++&sdhost { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhost_gpio48>; ++ status = "okay"; ++ bus-width = <4>; ++}; ++ ++/* uart0 communicates with the BT module */ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_ctsrts_gpio30 &uart0_gpio32 &gpclk2_gpio43>; ++ status = "okay"; ++ ++ bluetooth { ++ compatible = "brcm,bcm43438-bt"; ++ max-speed = <2000000>; ++ }; ++}; ++ ++/* uart1 is mapped to the pin header */ ++&uart1 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart1_gpio14>; ++ status = "okay"; ++}; diff --git a/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-Compute-Module-3-and-IO-boa.patch b/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-Compute-Module-3-and-IO-boa.patch new file mode 100644 index 000000000..e746f9e1a --- /dev/null +++ b/debian/patches/features/arm/ARM-dts-add-Raspberry-Pi-Compute-Module-3-and-IO-boa.patch @@ -0,0 +1,183 @@ +From: Stefan Wahren <stefan.wahren@i2se.com> +Date: Mon, 27 Aug 2018 19:31:17 +0200 +Subject: ARM: dts: add Raspberry Pi Compute Module 3 and IO board +Origin: https://git.kernel.org/linus/a54fe8a6cf66828499b121c3c39c194b43b8ed94 + +The Raspberry Pi Compute Module 3 (CM3) and the Raspberry Pi +Compute Module 3 Lite (CM3L) are SoMs which contains a BCM2837 processor, +1 GB RAM and a GPIO expander. The CM3 has a 4 GB eMMC, but on the CM3L +the eMMC is unpopulated and it's up to the user to connect their +own SD/MMC device. The dtsi file is designed to work for both modules. +There is also a matching carrier board which is called +Compute Module IO Board V3. + +Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> +--- + arch/arm/boot/dts/Makefile | 1 + + arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts | 87 +++++++++++++++++++++++++++++++ + arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi | 52 ++++++++++++++++++ + 3 files changed, 140 insertions(+) + create mode 100644 arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts + create mode 100644 arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi + +Index: linux/arch/arm/boot/dts/Makefile +=================================================================== +--- linux.orig/arch/arm/boot/dts/Makefile ++++ linux/arch/arm/boot/dts/Makefile +@@ -81,6 +81,7 @@ dtb-$(CONFIG_ARCH_BCM2835) += \ + bcm2836-rpi-2-b.dtb \ + bcm2837-rpi-3-b.dtb \ + bcm2837-rpi-3-b-plus.dtb \ ++ bcm2837-rpi-cm3-io3.dtb \ + bcm2835-rpi-zero.dtb \ + bcm2835-rpi-zero-w.dtb + dtb-$(CONFIG_ARCH_BCM_5301X) += \ +Index: linux/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts +=================================================================== +--- /dev/null ++++ linux/arch/arm/boot/dts/bcm2837-rpi-cm3-io3.dts +@@ -0,0 +1,87 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/dts-v1/; ++#include "bcm2837-rpi-cm3.dtsi" ++#include "bcm283x-rpi-usb-host.dtsi" ++ ++/ { ++ compatible = "raspberrypi,3-compute-module", "brcm,bcm2837"; ++ model = "Raspberry Pi Compute Module 3 IO board V3.0"; ++}; ++ ++&gpio { ++ /* ++ * This is based on the official GPU firmware DT blob. ++ * ++ * Legend: ++ * "NC" = not connected (no rail from the SoC) ++ * "FOO" = GPIO line named "FOO" on the schematic ++ * "FOO_N" = GPIO line named "FOO" on schematic, active low ++ */ ++ gpio-line-names = "GPIO0", ++ "GPIO1", ++ "GPIO2", ++ "GPIO3", ++ "GPIO4", ++ "GPIO5", ++ "GPIO6", ++ "GPIO7", ++ "GPIO8", ++ "GPIO9", ++ "GPIO10", ++ "GPIO11", ++ "GPIO12", ++ "GPIO13", ++ "GPIO14", ++ "GPIO15", ++ "GPIO16", ++ "GPIO17", ++ "GPIO18", ++ "GPIO19", ++ "GPIO20", ++ "GPIO21", ++ "GPIO22", ++ "GPIO23", ++ "GPIO24", ++ "GPIO25", ++ "GPIO26", ++ "GPIO27", ++ "GPIO28", ++ "GPIO29", ++ "GPIO30", ++ "GPIO31", ++ "GPIO32", ++ "GPIO33", ++ "GPIO34", ++ "GPIO35", ++ "GPIO36", ++ "GPIO37", ++ "GPIO38", ++ "GPIO39", ++ "GPIO40", ++ "GPIO41", ++ "GPIO42", ++ "GPIO43", ++ "GPIO44", ++ "GPIO45", ++ "GPIO46", ++ "GPIO47", ++ /* Used by eMMC */ ++ "SD_CLK_R", ++ "SD_CMD_R", ++ "SD_DATA0_R", ++ "SD_DATA1_R", ++ "SD_DATA2_R", ++ "SD_DATA3_R"; ++ ++ pinctrl-0 = <&gpioout &alt0>; ++}; ++ ++&hdmi { ++ hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; ++}; ++ ++&uart0 { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&uart0_gpio14>; ++ status = "okay"; ++}; +Index: linux/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi +=================================================================== +--- /dev/null ++++ linux/arch/arm/boot/dts/bcm2837-rpi-cm3.dtsi +@@ -0,0 +1,52 @@ ++// SPDX-License-Identifier: GPL-2.0 ++/dts-v1/; ++#include "bcm2837.dtsi" ++#include "bcm2835-rpi.dtsi" ++ ++/ { ++ memory { ++ reg = <0 0x40000000>; ++ }; ++ ++ reg_3v3: fixed-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "3V3"; ++ regulator-min-microvolt = <3300000>; ++ regulator-max-microvolt = <3300000>; ++ regulator-always-on; ++ }; ++ ++ reg_1v8: fixed-regulator { ++ compatible = "regulator-fixed"; ++ regulator-name = "1V8"; ++ regulator-min-microvolt = <1800000>; ++ regulator-max-microvolt = <1800000>; ++ regulator-always-on; ++ }; ++}; ++ ++&firmware { ++ expgpio: gpio { ++ compatible = "raspberrypi,firmware-gpio"; ++ gpio-controller; ++ #gpio-cells = <2>; ++ gpio-line-names = "HDMI_HPD_N", ++ "EMMC_EN_N", ++ "NC", ++ "NC", ++ "NC", ++ "NC", ++ "NC", ++ "NC"; ++ status = "okay"; ++ }; ++}; ++ ++&sdhost { ++ pinctrl-names = "default"; ++ pinctrl-0 = <&sdhost_gpio48>; ++ bus-width = <4>; ++ vmmc-supply = <®_3v3>; ++ vqmmc-supply = <®_1v8>; ++ status = "okay"; ++}; diff --git a/debian/patches/features/arm/ARM-dts-bcm283x-Correct-vchiq-compatible-string.patch b/debian/patches/features/arm/ARM-dts-bcm283x-Correct-vchiq-compatible-string.patch new file mode 100644 index 000000000..8dfed0cb1 --- /dev/null +++ b/debian/patches/features/arm/ARM-dts-bcm283x-Correct-vchiq-compatible-string.patch @@ -0,0 +1,35 @@ +From: Romain Perier <romain.perier@gmail.com> +Date: Wed, 16 Oct 2019 19:03:00 +0200 +Subject: ARM: dts: bcm283x: Correct vchiq compatible string + +This allows VCHIQ to determine the correct cache line size, use the new +"brcm,bcm2836-vchiq" compatible string on BCM2836. It is based on commit +499770 ("ARM: dts: bcm283x: Correct vchiq compatible string") + +Signed-off-by: Romain Perier <romain.perier@gmail.com> +--- + arch/arm/boot/dts/bcm2835-rpi.dtsi | 2 +- + arch/arm/boot/dts/bcm2836-rpi.dtsi | 6 ++++++ + 2 files changed, 7 insertions(+), 1 deletion(-) + create mode 100644 arch/arm/boot/dts/bcm2836-rpi.dtsi + +--- a/arch/arm/boot/dts/bcm2835-rpi.dtsi ++++ b/arch/arm/boot/dts/bcm2835-rpi.dtsi +@@ -30,7 +30,7 @@ + #power-domain-cells = <1>; + }; + +- mailbox@7e00b840 { ++ vchiq: mmailbox@7e00b840 { + compatible = "brcm,bcm2835-vchiq"; + reg = <0x7e00b840 0x3c>; + interrupts = <0 2>; +--- /dev/null ++++ b/arch/arm/boot/dts/bcm2836-rpi.dtsi +@@ -0,0 +1,6 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include "bcm2835-rpi.dtsi" ++ ++&vchiq { ++ compatible = "brcm,bcm2836-vchiq", "brcm,bcm2835-vchiq"; ++}; diff --git a/debian/patches/features/arm/staging-vc04_services-Use-correct-cache-line-size.patch b/debian/patches/features/arm/staging-vc04_services-Use-correct-cache-line-size.patch new file mode 100644 index 000000000..b77ae1b02 --- /dev/null +++ b/debian/patches/features/arm/staging-vc04_services-Use-correct-cache-line-size.patch @@ -0,0 +1,133 @@ +From: Phil Elwell <phil@raspberrypi.org> +Date: Mon, 17 Sep 2018 09:22:21 +0100 +Subject: staging/vc04_services: Use correct cache line size +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=c683db8860a80562a2bb5b451d77b3e471d24f36 + +Use the compatible string in the DTB to select the correct cache line +size for the SoC - 32 for BCM2835, and 64 for BCM2836 and BCM2837. + +Signed-off-by: Phil Elwell <phil@raspberrypi.org> +Tested-by: Stefan Wahren <stefan.wahren@i2se.com> +Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> +--- + .../interface/vchiq_arm/vchiq_2835_arm.c | 4 ++- + .../interface/vchiq_arm/vchiq_arm.c | 35 +++++++++++++------ + .../interface/vchiq_arm/vchiq_arm.h | 5 +++ + 3 files changed, 33 insertions(+), 11 deletions(-) + +diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +index 3bece6b86831..dd67b80c0f99 100644 +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c +@@ -109,7 +109,8 @@ free_pagelist(struct vchiq_pagelist_info *pagelistinfo, + int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) + { + struct device *dev = &pdev->dev; +- struct rpi_firmware *fw = platform_get_drvdata(pdev); ++ struct vchiq_drvdata *drvdata = platform_get_drvdata(pdev); ++ struct rpi_firmware *fw = drvdata->fw; + VCHIQ_SLOT_ZERO_T *vchiq_slot_zero; + struct resource *res; + void *slot_mem; +@@ -127,6 +128,7 @@ int vchiq_platform_init(struct platform_device *pdev, VCHIQ_STATE_T *state) + if (err < 0) + return err; + ++ g_cache_line_size = drvdata->cache_line_size; + g_fragments_size = 2 * g_cache_line_size; + + /* Allocate space for the channels in coherent memory */ +diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +index fe431302a030..45de21c210c1 100644 +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +@@ -170,6 +170,14 @@ static struct device *vchiq_dev; + static DEFINE_SPINLOCK(msg_queue_spinlock); + static struct platform_device *bcm2835_camera; + ++static struct vchiq_drvdata bcm2835_drvdata = { ++ .cache_line_size = 32, ++}; ++ ++static struct vchiq_drvdata bcm2836_drvdata = { ++ .cache_line_size = 64, ++}; ++ + static const char *const ioctl_names[] = { + "CONNECT", + "SHUTDOWN", +@@ -3578,12 +3586,25 @@ void vchiq_platform_conn_state_changed(VCHIQ_STATE_T *state, + } + } + ++static const struct of_device_id vchiq_of_match[] = { ++ { .compatible = "brcm,bcm2835-vchiq", .data = &bcm2835_drvdata }, ++ { .compatible = "brcm,bcm2836-vchiq", .data = &bcm2836_drvdata }, ++ {}, ++}; ++MODULE_DEVICE_TABLE(of, vchiq_of_match); ++ + static int vchiq_probe(struct platform_device *pdev) + { + struct device_node *fw_node; +- struct rpi_firmware *fw; ++ const struct of_device_id *of_id; ++ struct vchiq_drvdata *drvdata; + int err; + ++ of_id = of_match_node(vchiq_of_match, pdev->dev.of_node); ++ drvdata = (struct vchiq_drvdata *)of_id->data; ++ if (!drvdata) ++ return -EINVAL; ++ + fw_node = of_find_compatible_node(NULL, NULL, + "raspberrypi,bcm2835-firmware"); + if (!fw_node) { +@@ -3591,12 +3612,12 @@ static int vchiq_probe(struct platform_device *pdev) + return -ENOENT; + } + +- fw = rpi_firmware_get(fw_node); ++ drvdata->fw = rpi_firmware_get(fw_node); + of_node_put(fw_node); +- if (!fw) ++ if (!drvdata->fw) + return -EPROBE_DEFER; + +- platform_set_drvdata(pdev, fw); ++ platform_set_drvdata(pdev, drvdata); + + err = vchiq_platform_init(pdev, &g_state); + if (err != 0) +@@ -3666,12 +3687,6 @@ static int vchiq_remove(struct platform_device *pdev) + return 0; + } + +-static const struct of_device_id vchiq_of_match[] = { +- { .compatible = "brcm,bcm2835-vchiq", }, +- {}, +-}; +-MODULE_DEVICE_TABLE(of, vchiq_of_match); +- + static struct platform_driver vchiq_driver = { + .driver = { + .name = "bcm2835_vchiq", +diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +index 40bb0c63b1a9..2f3ebc99cbcf 100644 +--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h ++++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.h +@@ -123,6 +123,11 @@ typedef struct vchiq_arm_state_struct { + + } VCHIQ_ARM_STATE_T; + ++struct vchiq_drvdata { ++ const unsigned int cache_line_size; ++ struct rpi_firmware *fw; ++}; ++ + extern int vchiq_arm_log_level; + extern int vchiq_susp_log_level; + +-- +2.23.0 + diff --git a/debian/patches/features/arm64/arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-f.patch b/debian/patches/features/arm64/arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-f.patch new file mode 100644 index 000000000..c87b9f1a9 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-f.patch @@ -0,0 +1,55 @@ +From: Andre Przywara <andre.przywara@arm.com> +Date: Mon, 30 Jul 2018 13:31:20 +0100 +Subject: arm64: dts: allwinner: a64: Add Pine64-LTS device tree file +Origin: https://git.kernel.org/linus/b3ee15a509ffd7473b77b21cb921b3128efdd005 + +The Pine64-LTS is a variant of the Pine64 board, from the software +visible side resembling a SoPine module on a baseboard, though the +board has the SoC and DRAM integrated on one PCB. +Due to this it basically shares the DT with the SoPine baseboard, which +we mimic in our DT by inclucing the boardboard .dts into the new file, +just overwriting the model name. +Having a separate .dts for this seems useful, since we don't know yet if +there are subtle differences between the two. Also the SoC on the LTS +board is technically an "R18" instead of the original "A64", although as +far as we know this is just a relabelled version of the original SoC. + +Signed-off-by: Andre Przywara <andre.przywara@arm.com> +Acked-by: Maxime Ripard <maxime.ripard@bootlin.com> +Signed-off-by: Chen-Yu Tsai <wens@csie.org> +--- + arch/arm64/boot/dts/allwinner/Makefile | 1 + + .../boot/dts/allwinner/sun50i-a64-pine64-lts.dts | 13 +++++++++++++ + 2 files changed, 14 insertions(+) + create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts + +Index: linux/arch/arm64/boot/dts/allwinner/Makefile +=================================================================== +--- linux.orig/arch/arm64/boot/dts/allwinner/Makefile ++++ linux/arch/arm64/boot/dts/allwinner/Makefile +@@ -4,6 +4,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-b + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-nanopi-a64.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-olinuxino.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-orangepi-win.dtb ++dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-lts.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pine64-plus.dtb sun50i-a64-pine64.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-pinebook.dtb + dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a64-sopine-baseboard.dtb +Index: linux/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts +=================================================================== +--- /dev/null ++++ linux/arch/arm64/boot/dts/allwinner/sun50i-a64-pine64-lts.dts +@@ -0,0 +1,13 @@ ++/* ++ * SPDX-License-Identifier: (GPL-2.0+ OR MIT) ++ * ++ * Copyright (c) 2018 ARM Ltd. ++ */ ++ ++#include "sun50i-a64-sopine-baseboard.dts" ++ ++/ { ++ model = "Pine64 LTS"; ++ compatible = "pine64,pine64-lts", "allwinner,sun50i-r18", ++ "allwinner,sun50i-a64"; ++}; diff --git a/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-Compute-Module-I.patch b/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-Compute-Module-I.patch new file mode 100644 index 000000000..1d34ce743 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-Compute-Module-I.patch @@ -0,0 +1,35 @@ +From: Stefan Wahren <stefan.wahren@i2se.com> +Date: Mon, 27 Aug 2018 19:33:28 +0200 +Subject: arm64: dts: broadcom: Add reference to Compute Module IO Board V3 +Origin: https://git.kernel.org/linus/a7eb26392b893bff92b1eb6483f4af3d2eb19510 + +This adds a reference to the dts of the Compute Module IO Board V3 in arm, +so we don't need to maintain the content in arm64. + +Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> +--- + arch/arm64/boot/dts/broadcom/Makefile | 3 ++- + arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts | 2 ++ + 2 files changed, 4 insertions(+), 1 deletion(-) + create mode 100644 arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts + +Index: linux/arch/arm64/boot/dts/broadcom/Makefile +=================================================================== +--- linux.orig/arch/arm64/boot/dts/broadcom/Makefile ++++ linux/arch/arm64/boot/dts/broadcom/Makefile +@@ -1,6 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb \ +- bcm2837-rpi-3-b-plus.dtb ++ bcm2837-rpi-3-b-plus.dtb \ ++ bcm2837-rpi-cm3-io3.dts + + subdir-y += northstar2 + subdir-y += stingray +Index: linux/arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts +=================================================================== +--- /dev/null ++++ linux/arch/arm64/boot/dts/broadcom/bcm2837-rpi-cm3-io3.dts +@@ -0,0 +1,2 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include "arm/bcm2837-rpi-cm3-io3.dts" diff --git a/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-RPi-3-A-Plus.patch b/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-RPi-3-A-Plus.patch new file mode 100644 index 000000000..745cc8d09 --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-broadcom-Add-reference-to-RPi-3-A-Plus.patch @@ -0,0 +1,35 @@ +From: Stefan Wahren <stefan.wahren@i2se.com> +Date: Fri, 28 Dec 2018 23:09:27 +0100 +Subject: arm64: dts: broadcom: Add reference to RPi 3 A+ +Origin: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=441d8020d8fc8654698f5518cdf76832f84101f4 + +This adds a reference to the dts of the Raspberry Pi 3 A+, +so we don't need to maintain the content in arm64. + +Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com> +Reviewed-by: Eric Anholt <eric@anholt.net> +--- + arch/arm64/boot/dts/broadcom/Makefile | 3 ++- + arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-a-plus.dts | 2 ++ + 2 files changed, 4 insertions(+), 1 deletion(-) + create mode 100644 arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-a-plus.dts + +Index: debian-kernel/arch/arm64/boot/dts/broadcom/Makefile +=================================================================== +--- debian-kernel.orig/arch/arm64/boot/dts/broadcom/Makefile ++++ debian-kernel/arch/arm64/boot/dts/broadcom/Makefile +@@ -1,5 +1,6 @@ + # SPDX-License-Identifier: GPL-2.0 +-dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb \ ++dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-a-plus.dtb \ ++ bcm2837-rpi-3-b.dtb \ + bcm2837-rpi-3-b-plus.dtb \ + bcm2837-rpi-cm3-io3.dtb + +Index: debian-kernel/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-a-plus.dts +=================================================================== +--- /dev/null ++++ debian-kernel/arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-a-plus.dts +@@ -0,0 +1,2 @@ ++// SPDX-License-Identifier: GPL-2.0 ++#include "arm/bcm2837-rpi-3-a-plus.dts" diff --git a/debian/patches/features/arm64/arm64-dts-broadcom-Use-the-.dtb-name-in-the-rule-rat.patch b/debian/patches/features/arm64/arm64-dts-broadcom-Use-the-.dtb-name-in-the-rule-rat.patch new file mode 100644 index 000000000..d2c9849bb --- /dev/null +++ b/debian/patches/features/arm64/arm64-dts-broadcom-Use-the-.dtb-name-in-the-rule-rat.patch @@ -0,0 +1,32 @@ +From: Liviu Dudau <liviu@dudau.co.uk> +Date: Mon, 24 Sep 2018 11:22:28 +0100 +Subject: arm64: dts: broadcom: Use the .dtb name in the rule, rather than .dts +Origin: https://git.kernel.org/linus/74cf77e8be35795b4cc57b7010bc348295e421b9 + +Commit a7eb26392b893 ("arm64: dts: broadcom: Add reference to Compute +Module IO Board V3") adds the bcm2837-rpi-cm3-io3.dts file as a target +in the Makefile, rather than the .dtb name. This will skip the +generation of the .dtb file at compile time and will fail the dtbs_install +target. + +Fixes: a7eb26392b893 ("arm64: dts: broadcom: Add reference to Compute Module IO Board V3") +Signed-off-by: Liviu Dudau <liviu@dudau.co.uk> +Acked-by: Stefan Wahren <stefan.wahren@i2se.com> +Signed-off-by: Olof Johansson <olof@lixom.net> +--- + arch/arm64/boot/dts/broadcom/Makefile | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: linux/arch/arm64/boot/dts/broadcom/Makefile +=================================================================== +--- linux.orig/arch/arm64/boot/dts/broadcom/Makefile ++++ linux/arch/arm64/boot/dts/broadcom/Makefile +@@ -1,7 +1,7 @@ + # SPDX-License-Identifier: GPL-2.0 + dtb-$(CONFIG_ARCH_BCM2835) += bcm2837-rpi-3-b.dtb \ + bcm2837-rpi-3-b-plus.dtb \ +- bcm2837-rpi-cm3-io3.dts ++ bcm2837-rpi-cm3-io3.dtb + + subdir-y += northstar2 + subdir-y += stingray diff --git a/debian/patches/features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch b/debian/patches/features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch new file mode 100644 index 000000000..73f420b6c --- /dev/null +++ b/debian/patches/features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch @@ -0,0 +1,65 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Date: Sun, 20 Jul 2014 19:16:31 +0200 +Subject: MIPS: Loongson 3: Add Loongson LS3A RS780E 1-way machine definition +Forwarded: no + +Add a Loongson LS3A RS780E 1-way machine definition, which only differs +from other Loongson 3 based machines by the UART base clock speed. + +Signed-off-by: Aurelien Jarno <aurelien@aurel32.net> +[bwh: Forward-ported to 4.2] +--- + arch/mips/include/asm/bootinfo.h | 1 + + arch/mips/loongson64/common/machtype.c | 1 + + arch/mips/loongson64/common/serial.c | 1 + + arch/mips/loongson64/common/uart_base.c | 1 + + 4 files changed, 4 insertions(+) + +Index: linux/arch/mips/include/asm/bootinfo.h +=================================================================== +--- linux.orig/arch/mips/include/asm/bootinfo.h ++++ linux/arch/mips/include/asm/bootinfo.h +@@ -71,6 +71,7 @@ enum loongson_machine_type { + MACH_LEMOTE_NAS, + MACH_LEMOTE_LL2F, + MACH_LOONGSON_GENERIC, ++ MACH_LOONGSON_3A780E1W, + MACH_LOONGSON_END + }; + +Index: linux/arch/mips/loongson64/common/machtype.c +=================================================================== +--- linux.orig/arch/mips/loongson64/common/machtype.c ++++ linux/arch/mips/loongson64/common/machtype.c +@@ -28,6 +28,7 @@ static const char *system_types[] = { + [MACH_LEMOTE_NAS] = "lemote-nas-2f", + [MACH_LEMOTE_LL2F] = "lemote-lynloong-2f", + [MACH_LOONGSON_GENERIC] = "generic-loongson-machine", ++ [MACH_LOONGSON_3A780E1W] = "loongson-ls3a-rs780e-1w", + [MACH_LOONGSON_END] = NULL, + }; + +Index: linux/arch/mips/loongson64/common/serial.c +=================================================================== +--- linux.orig/arch/mips/loongson64/common/serial.c ++++ linux/arch/mips/loongson64/common/serial.c +@@ -48,6 +48,7 @@ static struct plat_serial8250_port uart8 + [MACH_LEMOTE_NAS] = {PORT_M(3, 3686400), {} }, + [MACH_LEMOTE_LL2F] = {PORT(3, 1843200), {} }, + [MACH_LOONGSON_GENERIC] = {PORT_M(2, 25000000), {} }, ++ [MACH_LOONGSON_3A780E1W] = {PORT_M(2, 33177600), {} }, + [MACH_LOONGSON_END] = {}, + }; + +Index: linux/arch/mips/loongson64/common/uart_base.c +=================================================================== +--- linux.orig/arch/mips/loongson64/common/uart_base.c ++++ linux/arch/mips/loongson64/common/uart_base.c +@@ -25,6 +25,7 @@ void prom_init_loongson_uart_base(void) + { + switch (mips_machtype) { + case MACH_LOONGSON_GENERIC: ++ case MACH_LOONGSON_3A780E1W: + /* The CPU provided serial port (CPU) */ + loongson_uart_base[0] = LOONGSON_REG_BASE + 0x1e0; + break; diff --git a/debian/patches/features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch b/debian/patches/features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch new file mode 100644 index 000000000..3de14026f --- /dev/null +++ b/debian/patches/features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch @@ -0,0 +1,29 @@ +From: Aurelien Jarno <aurelien@aurel32.net> +Subject: MIPS: increase MAX_PHYSMEM_BITS on Loongson 3 only +Bug-Debian: https://bugs.debian.org/764223 +Forwarded: no + +Commit c4617318 broke Loongson-2 support and maybe even more by increasing +the value of MAX_PHYSMEM_BITS. At it is currently only needed on +Loongson-3, define it conditionally. + +Note: this should be replace by upstream fix when available. + +Index: linux/arch/mips/include/asm/sparsemem.h +=================================================================== +--- linux.orig/arch/mips/include/asm/sparsemem.h ++++ linux/arch/mips/include/asm/sparsemem.h +@@ -12,7 +12,12 @@ + #else + # define SECTION_SIZE_BITS 28 + #endif +-#define MAX_PHYSMEM_BITS 48 ++ ++#if defined(CONFIG_CPU_LOONGSON3) ++# define MAX_PHYSMEM_BITS 48 ++#else ++# define MAX_PHYSMEM_BITS 35 ++#endif + + #endif /* CONFIG_SPARSEMEM */ + #endif /* _MIPS_SPARSEMEM_H */ diff --git a/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-for-boot-params-.patch b/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-for-boot-params-.patch new file mode 100644 index 000000000..d56f9f289 --- /dev/null +++ b/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-for-boot-params-.patch @@ -0,0 +1,101 @@ +From: Juergen Gross <jgross@suse.com> +Date: Wed, 10 Oct 2018 08:14:56 +0200 +Subject: x86/acpi, x86/boot: Take RSDP address for boot params if available +Origin: https://git.kernel.org/linus/e7b66d16fe41722350ba87f5788052ef53ee28bb + +In case the RSDP address in struct boot_params is specified don't try +to find the table by searching, but take the address directly as set +by the boot loader. + +Signed-off-by: Juergen Gross <jgross@suse.com> +Cc: Andy Lutomirski <luto@kernel.org> +Cc: Andy Shevchenko <andriy.shevchenko@linux.intel.com> +Cc: Baoquan He <bhe@redhat.com> +Cc: Borislav Petkov <bp@alien8.de> +Cc: Jia Zhang <qianyue.zj@alibaba-inc.com> +Cc: Len Brown <len.brown@intel.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Pavel Machek <pavel@ucw.cz> +Cc: Pavel Tatashin <pasha.tatashin@oracle.com> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Rafael J. Wysocki <rafael.j.wysocki@intel.com> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: boris.ostrovsky@oracle.com +Cc: linux-kernel@vger.kernel.org +Cc: linux-pm@vger.kernel.org +Cc: xen-devel@lists.xenproject.org +Link: http://lkml.kernel.org/r/20181010061456.22238-4-jgross@suse.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +--- + arch/x86/include/asm/acpi.h | 7 +++++++ + arch/x86/kernel/acpi/boot.c | 6 ++++++ + arch/x86/kernel/x86_init.c | 3 +-- + 3 files changed, 14 insertions(+), 2 deletions(-) + +Index: linux/arch/x86/include/asm/acpi.h +=================================================================== +--- linux.orig/arch/x86/include/asm/acpi.h ++++ linux/arch/x86/include/asm/acpi.h +@@ -142,6 +142,8 @@ static inline u64 acpi_arch_get_root_poi + + void acpi_generic_reduced_hw_init(void); + ++u64 x86_default_get_root_pointer(void); ++ + #else /* !CONFIG_ACPI */ + + #define acpi_lapic 0 +@@ -153,6 +155,11 @@ static inline void disable_acpi(void) { + + static inline void acpi_generic_reduced_hw_init(void) { } + ++static inline u64 x86_default_get_root_pointer(void) ++{ ++ return 0; ++} ++ + #endif /* !CONFIG_ACPI */ + + #define ARCH_HAS_POWER_INIT 1 +Index: linux/arch/x86/kernel/acpi/boot.c +=================================================================== +--- linux.orig/arch/x86/kernel/acpi/boot.c ++++ linux/arch/x86/kernel/acpi/boot.c +@@ -48,6 +48,7 @@ + #include <asm/mpspec.h> + #include <asm/smp.h> + #include <asm/i8259.h> ++#include <asm/setup.h> + + #include "sleep.h" /* To include x86_acpi_suspend_lowlevel */ + static int __initdata acpi_force = 0; +@@ -1771,3 +1772,8 @@ void __init arch_reserve_mem_area(acpi_p + e820__range_add(addr, size, E820_TYPE_ACPI); + e820__update_table_print(); + } ++ ++u64 x86_default_get_root_pointer(void) ++{ ++ return boot_params.hdr.acpi_rsdp_addr; ++} +Index: linux/arch/x86/kernel/x86_init.c +=================================================================== +--- linux.orig/arch/x86/kernel/x86_init.c ++++ linux/arch/x86/kernel/x86_init.c +@@ -31,7 +31,6 @@ static int __init iommu_init_noop(void) + static void iommu_shutdown_noop(void) { } + static bool __init bool_x86_init_noop(void) { return false; } + static void x86_op_int_noop(int cpu) { } +-static u64 u64_x86_init_noop(void) { return 0; } + + /* + * The platform setup functions are preset with the default functions +@@ -96,7 +95,7 @@ struct x86_init_ops x86_init __initdata + }, + + .acpi = { +- .get_root_pointer = u64_x86_init_noop, ++ .get_root_pointer = x86_default_get_root_pointer, + .reduced_hw_early_init = acpi_generic_reduced_hw_init, + }, + }; diff --git a/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-from-boot-params.patch b/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-from-boot-params.patch new file mode 100644 index 000000000..5382acce3 --- /dev/null +++ b/debian/patches/features/x86/x86-acpi-x86-boot-Take-RSDP-address-from-boot-params.patch @@ -0,0 +1,51 @@ +From: Juergen Gross <jgross@suse.com> +Date: Tue, 20 Nov 2018 08:25:29 +0100 +Subject: x86/acpi, x86/boot: Take RSDP address from boot params if available +Origin: https://git.kernel.org/linus/e6e094e053af75cbc164e950814d3d084fb1e698 + +In case the RSDP address in struct boot_params is specified don't try +to find the table by searching, but take the address directly as set +by the boot loader. + +Suggested-by: "H. Peter Anvin" <hpa@zytor.com> +Signed-off-by: Juergen Gross <jgross@suse.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: boris.ostrovsky@oracle.com +Cc: bp@alien8.de +Cc: daniel.kiper@oracle.com +Cc: sstabellini@kernel.org +Cc: xen-devel@lists.xenproject.org +Link: http://lkml.kernel.org/r/20181120072529.5489-3-jgross@suse.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +--- + arch/x86/include/uapi/asm/bootparam.h | 3 ++- + arch/x86/kernel/acpi/boot.c | 2 +- + 2 files changed, 3 insertions(+), 2 deletions(-) + +Index: linux/arch/x86/include/uapi/asm/bootparam.h +=================================================================== +--- linux.orig/arch/x86/include/uapi/asm/bootparam.h ++++ linux/arch/x86/include/uapi/asm/bootparam.h +@@ -155,7 +155,8 @@ struct boot_params { + __u8 _pad2[4]; /* 0x054 */ + __u64 tboot_addr; /* 0x058 */ + struct ist_info ist_info; /* 0x060 */ +- __u8 _pad3[16]; /* 0x070 */ ++ __u64 acpi_rsdp_addr; /* 0x070 */ ++ __u8 _pad3[8]; /* 0x078 */ + __u8 hd0_info[16]; /* obsolete! */ /* 0x080 */ + __u8 hd1_info[16]; /* obsolete! */ /* 0x090 */ + struct sys_desc_table sys_desc_table; /* obsolete! */ /* 0x0a0 */ +Index: linux/arch/x86/kernel/acpi/boot.c +=================================================================== +--- linux.orig/arch/x86/kernel/acpi/boot.c ++++ linux/arch/x86/kernel/acpi/boot.c +@@ -1775,5 +1775,5 @@ void __init arch_reserve_mem_area(acpi_p + + u64 x86_default_get_root_pointer(void) + { +- return 0; ++ return boot_params.acpi_rsdp_addr; + } diff --git a/debian/patches/features/x86/x86-boot-Add-ACPI-RSDP-address-to-setup_header.patch b/debian/patches/features/x86/x86-boot-Add-ACPI-RSDP-address-to-setup_header.patch new file mode 100644 index 000000000..55b116db9 --- /dev/null +++ b/debian/patches/features/x86/x86-boot-Add-ACPI-RSDP-address-to-setup_header.patch @@ -0,0 +1,232 @@ +From: Juergen Gross <jgross@suse.com> +Date: Wed, 10 Oct 2018 08:14:55 +0200 +Subject: x86/boot: Add ACPI RSDP address to setup_header +Origin: https://git.kernel.org/linus/ae7e1238e68f2a472a125673ab506d49158c1889 + +Xen PVH guests receive the address of the RSDP table from Xen. In order +to support booting a Xen PVH guest via Grub2 using the standard x86 +boot entry we need a way for Grub2 to pass the RSDP address to the +kernel. + +For this purpose expand the struct setup_header to hold the physical +address of the RSDP address. Being zero means it isn't specified and +has to be located the legacy way (searching through low memory or +EBDA). + +While documenting the new setup_header layout and protocol version +2.14 add the missing documentation of protocol version 2.13. + +There are Grub2 versions in several distros with a downstream patch +violating the boot protocol by writing past the end of setup_header. +This requires another update of the boot protocol to enable the kernel +to distinguish between a specified RSDP address and one filled with +garbage by such a broken Grub2. + +From protocol 2.14 on Grub2 will write the version it is supporting +(but never a higher value than found to be supported by the kernel) +ored with 0x8000 to the version field of setup_header. This enables +the kernel to know up to which field Grub2 has written information +to. All fields after that are supposed to be clobbered. + +Signed-off-by: Juergen Gross <jgross@suse.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: boris.ostrovsky@oracle.com +Cc: bp@alien8.de +Cc: corbet@lwn.net +Cc: linux-doc@vger.kernel.org +Cc: xen-devel@lists.xenproject.org +Link: http://lkml.kernel.org/r/20181010061456.22238-3-jgross@suse.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +--- + Documentation/x86/boot.txt | 32 ++++++++++++++++++++++++++- + arch/x86/boot/header.S | 6 ++++- + arch/x86/include/asm/x86_init.h | 2 ++ + arch/x86/include/uapi/asm/bootparam.h | 4 ++++ + arch/x86/kernel/head32.c | 1 + + arch/x86/kernel/head64.c | 2 ++ + arch/x86/kernel/setup.c | 17 ++++++++++++++ + 7 files changed, 62 insertions(+), 2 deletions(-) + +Index: linux/Documentation/x86/boot.txt +=================================================================== +--- linux.orig/Documentation/x86/boot.txt ++++ linux/Documentation/x86/boot.txt +@@ -61,6 +61,18 @@ Protocol 2.12: (Kernel 3.8) Added the xl + to struct boot_params for loading bzImage and ramdisk + above 4G in 64bit. + ++Protocol 2.13: (Kernel 3.14) Support 32- and 64-bit flags being set in ++ xloadflags to support booting a 64-bit kernel from 32-bit ++ EFI ++ ++Protocol 2.14: (Kernel 4.20) Added acpi_rsdp_addr holding the physical ++ address of the ACPI RSDP table. ++ The bootloader updates version with: ++ 0x8000 | min(kernel-version, bootloader-version) ++ kernel-version being the protocol version supported by ++ the kernel and bootloader-version the protocol version ++ supported by the bootloader. ++ + **** MEMORY LAYOUT + + The traditional memory map for the kernel loader, used for Image or +@@ -197,6 +209,7 @@ Offset Proto Name Meaning + 0258/8 2.10+ pref_address Preferred loading address + 0260/4 2.10+ init_size Linear memory required during initialization + 0264/4 2.11+ handover_offset Offset of handover entry point ++0268/8 2.14+ acpi_rsdp_addr Physical address of RSDP table + + (1) For backwards compatibility, if the setup_sects field contains 0, the + real value is 4. +@@ -309,7 +322,7 @@ Protocol: 2.00+ + Contains the magic number "HdrS" (0x53726448). + + Field name: version +-Type: read ++Type: modify + Offset/size: 0x206/2 + Protocol: 2.00+ + +@@ -317,6 +330,12 @@ Protocol: 2.00+ + e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version + 10.17. + ++ Up to protocol version 2.13 this information is only read by the ++ bootloader. From protocol version 2.14 onwards the bootloader will ++ write the used protocol version or-ed with 0x8000 to the field. The ++ used protocol version will be the minimum of the supported protocol ++ versions of the bootloader and the kernel. ++ + Field name: realmode_swtch + Type: modify (optional) + Offset/size: 0x208/4 +@@ -744,6 +763,17 @@ Offset/size: 0x264/4 + + See EFI HANDOVER PROTOCOL below for more details. + ++Field name: acpi_rsdp_addr ++Type: write ++Offset/size: 0x268/8 ++Protocol: 2.14+ ++ ++ This field can be set by the boot loader to tell the kernel the ++ physical address of the ACPI RSDP table. ++ ++ A value of 0 indicates the kernel should fall back to the standard ++ methods to locate the RSDP. ++ + + **** THE IMAGE CHECKSUM + +Index: linux/arch/x86/boot/header.S +=================================================================== +--- linux.orig/arch/x86/boot/header.S ++++ linux/arch/x86/boot/header.S +@@ -300,7 +300,7 @@ _start: + # Part 2 of the header, from the old setup.S + + .ascii "HdrS" # header signature +- .word 0x020d # header version number (>= 0x0105) ++ .word 0x020e # header version number (>= 0x0105) + # or else old loadlin-1.5 will fail) + .globl realmode_swtch + realmode_swtch: .word 0, 0 # default_switch, SETUPSEG +@@ -558,6 +558,10 @@ pref_address: .quad LOAD_PHYSICAL_ADDR + init_size: .long INIT_SIZE # kernel initialization size + handover_offset: .long 0 # Filled in by build.c + ++acpi_rsdp_addr: .quad 0 # 64-bit physical pointer to the ++ # ACPI RSDP table, added with ++ # version 2.14 ++ + # End of setup header ##################################################### + + .section ".entrytext", "ax" +Index: linux/arch/x86/include/asm/x86_init.h +=================================================================== +--- linux.orig/arch/x86/include/asm/x86_init.h ++++ linux/arch/x86/include/asm/x86_init.h +@@ -303,4 +303,6 @@ extern void x86_init_noop(void); + extern void x86_init_uint_noop(unsigned int unused); + extern bool x86_pnpbios_disabled(void); + ++void x86_verify_bootdata_version(void); ++ + #endif +Index: linux/arch/x86/include/uapi/asm/bootparam.h +=================================================================== +--- linux.orig/arch/x86/include/uapi/asm/bootparam.h ++++ linux/arch/x86/include/uapi/asm/bootparam.h +@@ -16,6 +16,9 @@ + #define RAMDISK_PROMPT_FLAG 0x8000 + #define RAMDISK_LOAD_FLAG 0x4000 + ++/* version flags */ ++#define VERSION_WRITTEN 0x8000 ++ + /* loadflags */ + #define LOADED_HIGH (1<<0) + #define KASLR_FLAG (1<<1) +@@ -86,6 +89,7 @@ struct setup_header { + __u64 pref_address; + __u32 init_size; + __u32 handover_offset; ++ __u64 acpi_rsdp_addr; + } __attribute__((packed)); + + struct sys_desc_table { +Index: linux/arch/x86/kernel/head32.c +=================================================================== +--- linux.orig/arch/x86/kernel/head32.c ++++ linux/arch/x86/kernel/head32.c +@@ -37,6 +37,7 @@ asmlinkage __visible void __init i386_st + cr4_init_shadow(); + + sanitize_boot_params(&boot_params); ++ x86_verify_bootdata_version(); + + x86_early_init_platform_quirks(); + +Index: linux/arch/x86/kernel/head64.c +=================================================================== +--- linux.orig/arch/x86/kernel/head64.c ++++ linux/arch/x86/kernel/head64.c +@@ -477,6 +477,8 @@ void __init x86_64_start_reservations(ch + if (!boot_params.hdr.version) + copy_bootdata(__va(real_mode_data)); + ++ x86_verify_bootdata_version(); ++ + x86_early_init_platform_quirks(); + + switch (boot_params.hdr.hardware_subarch) { +Index: linux/arch/x86/kernel/setup.c +=================================================================== +--- linux.orig/arch/x86/kernel/setup.c ++++ linux/arch/x86/kernel/setup.c +@@ -1281,6 +1281,23 @@ void __init setup_arch(char **cmdline_p) + unwind_init(); + } + ++/* ++ * From boot protocol 2.14 onwards we expect the bootloader to set the ++ * version to "0x8000 | <used version>". In case we find a version >= 2.14 ++ * without the 0x8000 we assume the boot loader supports 2.13 only and ++ * reset the version accordingly. The 0x8000 flag is removed in any case. ++ */ ++void __init x86_verify_bootdata_version(void) ++{ ++ if (boot_params.hdr.version & VERSION_WRITTEN) ++ boot_params.hdr.version &= ~VERSION_WRITTEN; ++ else if (boot_params.hdr.version >= 0x020e) ++ boot_params.hdr.version = 0x020d; ++ ++ if (boot_params.hdr.version < 0x020e) ++ boot_params.hdr.acpi_rsdp_addr = 0; ++} ++ + #ifdef CONFIG_X86_32 + + static struct resource video_ram_resource = { diff --git a/debian/patches/features/x86/x86-boot-Mostly-revert-commit-ae7e1238e68f2a-Add-ACP.patch b/debian/patches/features/x86/x86-boot-Mostly-revert-commit-ae7e1238e68f2a-Add-ACP.patch new file mode 100644 index 000000000..d2b67f4ea --- /dev/null +++ b/debian/patches/features/x86/x86-boot-Mostly-revert-commit-ae7e1238e68f2a-Add-ACP.patch @@ -0,0 +1,236 @@ +From: Juergen Gross <jgross@suse.com> +Date: Tue, 20 Nov 2018 08:25:28 +0100 +Subject: x86/boot: Mostly revert commit ae7e1238e68f2a ("Add ACPI RSDP address + to setup_header") +Origin: https://git.kernel.org/linus/3841840449817ba6cf3e636008bc4e1061a03388 + +Peter Anvin pointed out that commit: + + ae7e1238e68f2a ("x86/boot: Add ACPI RSDP address to setup_header") + +should be reverted as setup_header should only contain items set by the +legacy BIOS. + +So revert said commit. Instead of fully reverting the dependent commit +of: + + e7b66d16fe4172 ("x86/acpi, x86/boot: Take RSDP address for boot params if available") + +just remove the setup_header reference in order to replace it by +a boot_params in a followup patch. + +Suggested-by: "H. Peter Anvin" <hpa@zytor.com> +Signed-off-by: Juergen Gross <jgross@suse.com> +Cc: Linus Torvalds <torvalds@linux-foundation.org> +Cc: Peter Zijlstra <peterz@infradead.org> +Cc: Thomas Gleixner <tglx@linutronix.de> +Cc: boris.ostrovsky@oracle.com +Cc: bp@alien8.de +Cc: daniel.kiper@oracle.com +Cc: sstabellini@kernel.org +Cc: xen-devel@lists.xenproject.org +Link: http://lkml.kernel.org/r/20181120072529.5489-2-jgross@suse.com +Signed-off-by: Ingo Molnar <mingo@kernel.org> +--- + Documentation/x86/boot.txt | 32 +-------------------------- + arch/x86/boot/header.S | 6 +---- + arch/x86/include/asm/x86_init.h | 2 -- + arch/x86/include/uapi/asm/bootparam.h | 4 ---- + arch/x86/kernel/acpi/boot.c | 2 +- + arch/x86/kernel/head32.c | 1 - + arch/x86/kernel/head64.c | 2 -- + arch/x86/kernel/setup.c | 17 -------------- + 8 files changed, 3 insertions(+), 63 deletions(-) + +Index: linux/Documentation/x86/boot.txt +=================================================================== +--- linux.orig/Documentation/x86/boot.txt ++++ linux/Documentation/x86/boot.txt +@@ -61,18 +61,6 @@ Protocol 2.12: (Kernel 3.8) Added the xl + to struct boot_params for loading bzImage and ramdisk + above 4G in 64bit. + +-Protocol 2.13: (Kernel 3.14) Support 32- and 64-bit flags being set in +- xloadflags to support booting a 64-bit kernel from 32-bit +- EFI +- +-Protocol 2.14: (Kernel 4.20) Added acpi_rsdp_addr holding the physical +- address of the ACPI RSDP table. +- The bootloader updates version with: +- 0x8000 | min(kernel-version, bootloader-version) +- kernel-version being the protocol version supported by +- the kernel and bootloader-version the protocol version +- supported by the bootloader. +- + **** MEMORY LAYOUT + + The traditional memory map for the kernel loader, used for Image or +@@ -209,7 +197,6 @@ Offset Proto Name Meaning + 0258/8 2.10+ pref_address Preferred loading address + 0260/4 2.10+ init_size Linear memory required during initialization + 0264/4 2.11+ handover_offset Offset of handover entry point +-0268/8 2.14+ acpi_rsdp_addr Physical address of RSDP table + + (1) For backwards compatibility, if the setup_sects field contains 0, the + real value is 4. +@@ -322,7 +309,7 @@ Protocol: 2.00+ + Contains the magic number "HdrS" (0x53726448). + + Field name: version +-Type: modify ++Type: read + Offset/size: 0x206/2 + Protocol: 2.00+ + +@@ -330,12 +317,6 @@ Protocol: 2.00+ + e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version + 10.17. + +- Up to protocol version 2.13 this information is only read by the +- bootloader. From protocol version 2.14 onwards the bootloader will +- write the used protocol version or-ed with 0x8000 to the field. The +- used protocol version will be the minimum of the supported protocol +- versions of the bootloader and the kernel. +- + Field name: realmode_swtch + Type: modify (optional) + Offset/size: 0x208/4 +@@ -763,17 +744,6 @@ Offset/size: 0x264/4 + + See EFI HANDOVER PROTOCOL below for more details. + +-Field name: acpi_rsdp_addr +-Type: write +-Offset/size: 0x268/8 +-Protocol: 2.14+ +- +- This field can be set by the boot loader to tell the kernel the +- physical address of the ACPI RSDP table. +- +- A value of 0 indicates the kernel should fall back to the standard +- methods to locate the RSDP. +- + + **** THE IMAGE CHECKSUM + +Index: linux/arch/x86/boot/header.S +=================================================================== +--- linux.orig/arch/x86/boot/header.S ++++ linux/arch/x86/boot/header.S +@@ -300,7 +300,7 @@ _start: + # Part 2 of the header, from the old setup.S + + .ascii "HdrS" # header signature +- .word 0x020e # header version number (>= 0x0105) ++ .word 0x020d # header version number (>= 0x0105) + # or else old loadlin-1.5 will fail) + .globl realmode_swtch + realmode_swtch: .word 0, 0 # default_switch, SETUPSEG +@@ -558,10 +558,6 @@ pref_address: .quad LOAD_PHYSICAL_ADDR + init_size: .long INIT_SIZE # kernel initialization size + handover_offset: .long 0 # Filled in by build.c + +-acpi_rsdp_addr: .quad 0 # 64-bit physical pointer to the +- # ACPI RSDP table, added with +- # version 2.14 +- + # End of setup header ##################################################### + + .section ".entrytext", "ax" +Index: linux/arch/x86/include/asm/x86_init.h +=================================================================== +--- linux.orig/arch/x86/include/asm/x86_init.h ++++ linux/arch/x86/include/asm/x86_init.h +@@ -303,6 +303,4 @@ extern void x86_init_noop(void); + extern void x86_init_uint_noop(unsigned int unused); + extern bool x86_pnpbios_disabled(void); + +-void x86_verify_bootdata_version(void); +- + #endif +Index: linux/arch/x86/include/uapi/asm/bootparam.h +=================================================================== +--- linux.orig/arch/x86/include/uapi/asm/bootparam.h ++++ linux/arch/x86/include/uapi/asm/bootparam.h +@@ -16,9 +16,6 @@ + #define RAMDISK_PROMPT_FLAG 0x8000 + #define RAMDISK_LOAD_FLAG 0x4000 + +-/* version flags */ +-#define VERSION_WRITTEN 0x8000 +- + /* loadflags */ + #define LOADED_HIGH (1<<0) + #define KASLR_FLAG (1<<1) +@@ -89,7 +86,6 @@ struct setup_header { + __u64 pref_address; + __u32 init_size; + __u32 handover_offset; +- __u64 acpi_rsdp_addr; + } __attribute__((packed)); + + struct sys_desc_table { +Index: linux/arch/x86/kernel/acpi/boot.c +=================================================================== +--- linux.orig/arch/x86/kernel/acpi/boot.c ++++ linux/arch/x86/kernel/acpi/boot.c +@@ -1775,5 +1775,5 @@ void __init arch_reserve_mem_area(acpi_p + + u64 x86_default_get_root_pointer(void) + { +- return boot_params.hdr.acpi_rsdp_addr; ++ return 0; + } +Index: linux/arch/x86/kernel/head32.c +=================================================================== +--- linux.orig/arch/x86/kernel/head32.c ++++ linux/arch/x86/kernel/head32.c +@@ -37,7 +37,6 @@ asmlinkage __visible void __init i386_st + cr4_init_shadow(); + + sanitize_boot_params(&boot_params); +- x86_verify_bootdata_version(); + + x86_early_init_platform_quirks(); + +Index: linux/arch/x86/kernel/head64.c +=================================================================== +--- linux.orig/arch/x86/kernel/head64.c ++++ linux/arch/x86/kernel/head64.c +@@ -477,8 +477,6 @@ void __init x86_64_start_reservations(ch + if (!boot_params.hdr.version) + copy_bootdata(__va(real_mode_data)); + +- x86_verify_bootdata_version(); +- + x86_early_init_platform_quirks(); + + switch (boot_params.hdr.hardware_subarch) { +Index: linux/arch/x86/kernel/setup.c +=================================================================== +--- linux.orig/arch/x86/kernel/setup.c ++++ linux/arch/x86/kernel/setup.c +@@ -1281,23 +1281,6 @@ void __init setup_arch(char **cmdline_p) + unwind_init(); + } + +-/* +- * From boot protocol 2.14 onwards we expect the bootloader to set the +- * version to "0x8000 | <used version>". In case we find a version >= 2.14 +- * without the 0x8000 we assume the boot loader supports 2.13 only and +- * reset the version accordingly. The 0x8000 flag is removed in any case. +- */ +-void __init x86_verify_bootdata_version(void) +-{ +- if (boot_params.hdr.version & VERSION_WRITTEN) +- boot_params.hdr.version &= ~VERSION_WRITTEN; +- else if (boot_params.hdr.version >= 0x020e) +- boot_params.hdr.version = 0x020d; +- +- if (boot_params.hdr.version < 0x020e) +- boot_params.hdr.acpi_rsdp_addr = 0; +-} +- + #ifdef CONFIG_X86_32 + + static struct resource video_ram_resource = { diff --git a/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch b/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch new file mode 100644 index 000000000..3dde15cce --- /dev/null +++ b/debian/patches/features/x86/x86-make-x32-syscall-support-conditional.patch @@ -0,0 +1,227 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 12 Feb 2018 23:59:26 +0000 +Subject: x86: Make x32 syscall support conditional on a kernel parameter +Bug-Debian: https://bugs.debian.org/708070 +Forwarded: https://lore.kernel.org/lkml/1415245982.3398.53.camel@decadent.org.uk/T/#u + +Enabling x32 in the standard amd64 kernel would increase its attack +surface while provide no benefit to the vast majority of its users. +No-one seems interested in regularly checking for vulnerabilities +specific to x32 (at least no-one with a white hat). + +Still, adding another flavour just to turn on x32 seems wasteful. And +the only differences on syscall entry are a few instructions that mask +out the x32 flag and compare the syscall number. + +Use a static key to control whether x32 syscalls are really enabled, a +Kconfig parameter to set its default value and a kernel parameter +"syscall.x32" to change it at boot time. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + Documentation/admin-guide/kernel-parameters.txt | 4 ++ + arch/x86/Kconfig | 8 ++++ + arch/x86/entry/common.c | 11 +++++- + arch/x86/entry/syscall_64.c | 41 ++++++++++++++++++++++++ + arch/x86/include/asm/elf.h | 4 +- + arch/x86/include/asm/syscall.h | 13 +++++++ + arch/x86/include/asm/unistd.h | 4 +- + 7 files changed, 80 insertions(+), 5 deletions(-) + +Index: linux/Documentation/admin-guide/kernel-parameters.txt +=================================================================== +--- linux.orig/Documentation/admin-guide/kernel-parameters.txt ++++ linux/Documentation/admin-guide/kernel-parameters.txt +@@ -4501,6 +4501,10 @@ + + switches= [HW,M68k] + ++ syscall.x32= [KNL,x86_64] Enable/disable use of x32 syscalls on ++ an x86_64 kernel where CONFIG_X86_X32 is enabled. ++ Default depends on CONFIG_X86_X32_DISABLED. ++ + sysfs.deprecated=0|1 [KNL] + Enable/disable old style sysfs layout for old udev + on older distributions. When this option is enabled +Index: linux/arch/x86/Kconfig +=================================================================== +--- linux.orig/arch/x86/Kconfig ++++ linux/arch/x86/Kconfig +@@ -2884,6 +2884,14 @@ config COMPAT_32 + select HAVE_UID16 + select OLD_SIGSUSPEND3 + ++config X86_X32_DISABLED ++ bool "x32 ABI disabled by default" ++ depends on X86_X32 ++ default n ++ help ++ Disable the x32 ABI unless explicitly enabled using the ++ kernel paramter "syscall.x32=y". ++ + config COMPAT + def_bool y + depends on IA32_EMULATION || X86_X32 +Index: linux/arch/x86/entry/common.c +=================================================================== +--- linux.orig/arch/x86/entry/common.c ++++ linux/arch/x86/entry/common.c +@@ -287,12 +287,21 @@ __visible void do_syscall_64(unsigned lo + * table. The only functional difference is the x32 bit in + * regs->orig_ax, which changes the behavior of some syscalls. + */ +- nr &= __SYSCALL_MASK; +- if (likely(nr < NR_syscalls)) { ++ if (x32_enabled) { ++ nr &= ~__X32_SYSCALL_BIT; ++ if (unlikely(nr >= NR_syscalls)) ++ goto bad; + nr = array_index_nospec(nr, NR_syscalls); ++ goto good; ++ } else { ++ nr &= ~0U; ++ if (unlikely(nr >= NR_non_x32_syscalls)) ++ goto bad; ++ nr = array_index_nospec(nr, NR_non_x32_syscalls); ++good: + regs->ax = sys_call_table[nr](regs); + } +- ++bad: + syscall_return_slowpath(regs); + } + #endif +Index: linux/arch/x86/entry/syscall_64.c +=================================================================== +--- linux.orig/arch/x86/entry/syscall_64.c ++++ linux/arch/x86/entry/syscall_64.c +@@ -4,6 +4,9 @@ + #include <linux/linkage.h> + #include <linux/sys.h> + #include <linux/cache.h> ++#include <linux/moduleparam.h> ++#undef MODULE_PARAM_PREFIX ++#define MODULE_PARAM_PREFIX "syscall." + #include <asm/asm-offsets.h> + #include <asm/syscall.h> + +@@ -23,3 +26,50 @@ asmlinkage const sys_call_ptr_t sys_call + [0 ... __NR_syscall_max] = &sys_ni_syscall, + #include <asm/syscalls_64.h> + }; ++ ++#ifdef CONFIG_X86_X32_ABI ++ ++/* Maybe enable x32 syscalls */ ++ ++#if defined(CONFIG_X86_X32_DISABLED) ++DEFINE_STATIC_KEY_FALSE(x32_enabled_skey); ++#else ++DEFINE_STATIC_KEY_TRUE(x32_enabled_skey); ++#endif ++ ++static int __init x32_param_set(const char *val, const struct kernel_param *p) ++{ ++ bool enabled; ++ int ret; ++ ++ ret = kstrtobool(val, &enabled); ++ if (ret) ++ return ret; ++ if (IS_ENABLED(CONFIG_X86_X32_DISABLED)) { ++ if (enabled) { ++ static_key_enable(&x32_enabled_skey.key); ++ pr_info("Enabled x32 syscalls\n"); ++ } ++ } else { ++ if (!enabled) { ++ static_key_disable(&x32_enabled_skey.key); ++ pr_info("Disabled x32 syscalls\n"); ++ } ++ } ++ return 0; ++} ++ ++static int x32_param_get(char *buffer, const struct kernel_param *p) ++{ ++ return sprintf(buffer, "%c\n", ++ static_key_enabled(&x32_enabled_skey) ? 'Y' : 'N'); ++} ++ ++static const struct kernel_param_ops x32_param_ops = { ++ .set = x32_param_set, ++ .get = x32_param_get, ++}; ++ ++arch_param_cb(x32, &x32_param_ops, NULL, 0444); ++ ++#endif +Index: linux/arch/x86/include/asm/elf.h +=================================================================== +--- linux.orig/arch/x86/include/asm/elf.h ++++ linux/arch/x86/include/asm/elf.h +@@ -10,6 +10,7 @@ + #include <asm/ptrace.h> + #include <asm/user.h> + #include <asm/auxvec.h> ++#include <asm/syscall.h> + + typedef unsigned long elf_greg_t; + +@@ -163,7 +164,8 @@ do { \ + + #define compat_elf_check_arch(x) \ + (elf_check_arch_ia32(x) || \ +- (IS_ENABLED(CONFIG_X86_X32_ABI) && (x)->e_machine == EM_X86_64)) ++ (IS_ENABLED(CONFIG_X86_X32_ABI) && x32_enabled && \ ++ (x)->e_machine == EM_X86_64)) + + #if __USER32_DS != __USER_DS + # error "The following code assumes __USER32_DS == __USER_DS" +Index: linux/arch/x86/include/asm/syscall.h +=================================================================== +--- linux.orig/arch/x86/include/asm/syscall.h ++++ linux/arch/x86/include/asm/syscall.h +@@ -16,6 +16,7 @@ + #include <uapi/linux/audit.h> + #include <linux/sched.h> + #include <linux/err.h> ++#include <linux/jump_label.h> + #include <asm/asm-offsets.h> /* For NR_syscalls */ + #include <asm/thread_info.h> /* for TS_COMPAT */ + #include <asm/unistd.h> +@@ -39,6 +40,18 @@ extern const sys_call_ptr_t sys_call_tab + extern const sys_call_ptr_t ia32_sys_call_table[]; + #endif + ++#if defined(CONFIG_X86_X32_ABI) ++#if defined(CONFIG_X86_X32_DISABLED) ++DECLARE_STATIC_KEY_FALSE(x32_enabled_skey); ++#define x32_enabled static_branch_unlikely(&x32_enabled_skey) ++#else ++DECLARE_STATIC_KEY_TRUE(x32_enabled_skey); ++#define x32_enabled static_branch_likely(&x32_enabled_skey) ++#endif ++#else ++#define x32_enabled 0 ++#endif ++ + /* + * Only the low 32 bits of orig_ax are meaningful, so we return int. + * This importantly ignores the high bits on 64-bit, so comparisons +Index: linux/arch/x86/include/asm/unistd.h +=================================================================== +--- linux.orig/arch/x86/include/asm/unistd.h ++++ linux/arch/x86/include/asm/unistd.h +@@ -6,9 +6,9 @@ + + + # ifdef CONFIG_X86_X32_ABI +-# define __SYSCALL_MASK (~(__X32_SYSCALL_BIT)) ++# define NR_non_x32_syscalls 512 + # else +-# define __SYSCALL_MASK (~0) ++# define NR_non_x32_syscalls NR_syscalls + # endif + + # ifdef CONFIG_X86_32 diff --git a/debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch b/debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch new file mode 100644 index 000000000..87b90de80 --- /dev/null +++ b/debian/patches/features/x86/x86-memtest-WARN-if-bad-RAM-found.patch @@ -0,0 +1,30 @@ +From: Ben Hutchings <ben@decadent.org.uk> +Date: Mon, 5 Dec 2011 04:00:58 +0000 +Subject: x86: memtest: WARN if bad RAM found +Bug-Debian: https://bugs.debian.org/613321 +Forwarded: http://thread.gmane.org/gmane.linux.kernel/1286471 + +Since this is not a particularly thorough test, if we find any bad +bits of RAM then there is a fair chance that there are other bad bits +we fail to detect. + +Signed-off-by: Ben Hutchings <ben@decadent.org.uk> +--- + mm/memtest.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +Index: linux/mm/memtest.c +=================================================================== +--- linux.orig/mm/memtest.c ++++ linux/mm/memtest.c +@@ -27,6 +27,10 @@ static u64 patterns[] __initdata = { + + static void __init reserve_bad_mem(u64 pattern, phys_addr_t start_bad, phys_addr_t end_bad) + { ++#ifdef CONFIG_X86 ++ WARN_ONCE(1, "Bad RAM detected. Use memtest86+ to perform a thorough test\n" ++ "and the memmap= parameter to reserve the bad areas."); ++#endif + pr_info(" %016llx bad mem addr %pa - %pa reserved\n", + cpu_to_be64(pattern), &start_bad, &end_bad); + memblock_reserve(start_bad, end_bad - start_bad); diff --git a/debian/patches/series b/debian/patches/series new file mode 100644 index 000000000..9563bf8b8 --- /dev/null +++ b/debian/patches/series @@ -0,0 +1,315 @@ +# Disable features broken by exclusion of upstream files +debian/dfsg/arch-powerpc-platforms-8xx-ucode-disable.patch +debian/dfsg/drivers-media-dvb-dvb-usb-af9005-disable.patch +debian/dfsg/vs6624-disable.patch +debian/dfsg/drivers-net-appletalk-cops.patch +debian/dfsg/video-remove-nvidiafb-and-rivafb.patch + +# Changes to support package build system +debian/version.patch +debian/uname-version-timestamp.patch +debian/kernelvariables.patch +debian/gitignore.patch +debian/ia64-hardcode-arch-script-output.patch +debian/mips-disable-werror.patch +debian/mips-boston-disable-its.patch +debian/arch-sh4-fix-uimage-build.patch +debian/powerpcspe-omit-uimage.patch +debian/tools-perf-version.patch +debian/tools-perf-install.patch +debian/wireless-add-debian-wireless-regdb-certificates.patch +debian/export-symbols-needed-by-android-drivers.patch +debian/android-enable-building-ashmem-and-binder-as-modules.patch + +# Fixes/improvements to firmware loading +features/all/drivers-media-dvb-usb-af9005-request_firmware.patch +debian/iwlwifi-do-not-request-unreleased-firmware.patch +bugfix/all/firmware_class-log-every-success-and-failure.patch +bugfix/all/firmware-remove-redundant-log-messages-from-drivers.patch +bugfix/all/radeon-amdgpu-firmware-is-required-for-drm-and-kms-on-r600-onward.patch +debian/firmware_class-refer-to-debian-wiki-firmware-page.patch + +# Patches from aufs4 repository, imported with debian/bin/genpatch-aufs. +# These are only the changes needed to allow aufs to be built out-of-tree. +features/all/aufs4/aufs4-base.patch +features/all/aufs4/aufs4-mmap.patch +features/all/aufs4/aufs4-standalone.patch + +# Change some defaults for security reasons +debian/af_802154-Disable-auto-loading-as-mitigation-against.patch +debian/rds-Disable-auto-loading-as-mitigation-against-local.patch +debian/decnet-Disable-auto-loading-as-mitigation-against-lo.patch +debian/dccp-disable-auto-loading-as-mitigation-against-local-exploits.patch +debian/fs-enable-link-security-restrictions-by-default.patch + +# Set various features runtime-disabled by default +debian/sched-autogroup-disabled.patch +debian/yama-disable-by-default.patch +debian/add-sysctl-to-disallow-unprivileged-CLONE_NEWUSER-by-default.patch +features/all/security-perf-allow-further-restriction-of-perf_event_open.patch + +# Disable autoloading/probing of various drivers by default +debian/cdc_ncm-cdc_mbim-use-ncm-by-default.patch +debian/snd-pcsp-disable-autoload.patch +bugfix/x86/viafb-autoload-on-olpc-xo1.5-only.patch +debian/fjes-disable-autoload.patch + +# Taint if dangerous features are used +debian/fanotify-taint-on-use-of-fanotify_access_permissions.patch +debian/btrfs-warn-about-raid5-6-being-experimental-at-mount.patch + +# Arch bug fixes +bugfix/arm/arm-dts-kirkwood-fix-sata-pinmux-ing-for-ts419.patch +bugfix/arm64/dts-rockchip-correct-voltage-selector-firefly-RK3399.patch +bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-310-15ikb-to.patch +bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v310-15isk-t.patch +bugfix/x86/platform-x86-ideapad-laptop-add-y520-15ikbn-to-no_hw.patch +bugfix/x86/platform-x86-ideapad-laptop-add-y720-15ikbn-to-no_hw.patch +bugfix/x86/platform-x86-ideapad-laptop-add-ideapad-v510-15ikb-t.patch +bugfix/x86/platform-x86-ideapad-laptop-add-several-models-to-no.patch +bugfix/x86/perf-tools-fix-unwind-build-on-i386.patch +bugfix/sh/sh-boot-do-not-use-hyphen-in-exported-variable-name.patch +bugfix/powerpc/powerpc-lib-makefile-don-t-pull-in-quad.o-for-32-bit.patch +bugfix/arm/arm-mm-export-__sync_icache_dcache-for-xen-privcmd.patch +bugfix/powerpc/powerpc-boot-fix-missing-crc32poly.h-when-building-with-kernel_xz.patch +bugfix/arm64/arm64-acpi-Add-fixup-for-HPE-m400-quirks.patch +bugfix/x86/x86-32-disable-3dnow-in-generic-config.patch +bugfix/powerpc/powerpc-fix-mcpu-options-for-spe-only-compiler.patch +bugfix/arm/ARM-dts-sun8i-h3-add-sy8106a-to-orange-pi-plus.patch +bugfix/arm64/arm64-dts-allwinner-a64-Enable-A64-timer-workaround.patch +bugfix/mips/MIPS-Loongson-Introduce-and-use-loongson_llsc_mb.patch + +# Arch features +features/mips/MIPS-increase-MAX-PHYSMEM-BITS-on-Loongson-3-only.patch +features/mips/MIPS-Loongson-3-Add-Loongson-LS3A-RS780E-1-way-machi.patch +features/x86/x86-memtest-WARN-if-bad-RAM-found.patch +features/x86/x86-make-x32-syscall-support-conditional.patch +features/x86/x86-boot-Add-ACPI-RSDP-address-to-setup_header.patch +features/x86/x86-acpi-x86-boot-Take-RSDP-address-for-boot-params-.patch +features/x86/x86-boot-Mostly-revert-commit-ae7e1238e68f2a-Add-ACP.patch +features/x86/x86-acpi-x86-boot-Take-RSDP-address-from-boot-params.patch +features/arm64/arm64-dts-allwinner-a64-Add-Pine64-LTS-device-tree-f.patch + +# Miscellaneous bug fixes +bugfix/all/kbuild-use-nostdinc-in-compile-tests.patch +bugfix/all/disable-some-marvell-phys.patch +bugfix/all/fs-add-module_softdep-declarations-for-hard-coded-cr.patch +bugfix/all/kbuild-include-addtree-remove-quotes-before-matching-path.patch +debian/revert-objtool-fix-config_stack_validation-y-warning.patch +bugfix/all/mt76-use-the-correct-hweight8-function.patch +bugfix/all/rtc-s35390a-set-uie_unsupported.patch +bugfix/all/lib-genalloc-add-gen_pool_dma_zalloc-for-zeroed-DMA.patch +bugfix/all/USB-use-genalloc-for-USB-HCs-with-local-memory.patch +bugfix/all/usb-host-ohci-sm501-init-genalloc-for-local-memory.patch +bugfix/all/USB-ohci-sm501-fix-error-return-code-in-ohci_hcd_sm5.patch +bugfix/all/USB-drop-HDC_LOCAL_MEM-flag.patch +bugfix/all/usb-dont-create-dma-pools-for-HCD.patch +bugfix/all/usb-add-a-hcd_uses_dma-helper.patch +bugfix/all/usb-hcd-Fix-a-NULL-vs-IS_ERR-bug-in-usb_hcd_setup_lo.patch +bugfix/all/net_sched-let-qdisc_put-accept-null-pointer.patch +bugfix/all/swiotlb-skip-swiotlb_bounce-when-orig_addr-is-zero.patch + +# Miscellaneous features +features/all/e1000e-Add-support-for-Comet-Lake.patch + +# Lockdown (formerly 'securelevel') patchset +features/all/lockdown/0001-Add-the-ability-to-lock-down-access-to-the-running-k.patch +features/all/lockdown/0003-ima-require-secure_boot-rules-in-lockdown-mode.patch +features/all/lockdown/0004-Enforce-module-signatures-if-the-kernel-is-locked-do.patch +features/all/lockdown/0005-Restrict-dev-mem-kmem-port-when-the-kernel-is-locked.patch +features/all/lockdown/0006-kexec-Disable-at-runtime-if-the-kernel-is-locked-dow.patch +features/all/lockdown/0007-Copy-secure_boot-flag-in-boot-params-across-kexec-re.patch +features/all/lockdown/0008-kexec_file-Restrict-at-runtime-if-the-kernel-is-lock.patch +features/all/lockdown/0009-hibernate-Disable-when-the-kernel-is-locked-down.patch +features/all/lockdown/0010-uswsusp-Disable-when-the-kernel-is-locked-down.patch +features/all/lockdown/0011-PCI-Lock-down-BAR-access-when-the-kernel-is-locked-d.patch +features/all/lockdown/0012-x86-Lock-down-IO-port-access-when-the-kernel-is-lock.patch +features/all/lockdown/0013-x86-msr-Restrict-MSR-access-when-the-kernel-is-locke.patch +features/all/lockdown/0014-asus-wmi-Restrict-debugfs-interface-when-the-kernel-.patch +features/all/lockdown/0015-ACPI-Limit-access-to-custom_method-when-the-kernel-i.patch +features/all/lockdown/0016-acpi-Ignore-acpi_rsdp-kernel-param-when-the-kernel-h.patch +features/all/lockdown/0017-acpi-Disable-ACPI-table-override-if-the-kernel-is-lo.patch +features/all/lockdown/0018-acpi-Disable-APEI-error-injection-if-the-kernel-is-l.patch +features/all/lockdown/0020-Prohibit-PCMCIA-CIS-storage-when-the-kernel-is-locke.patch +features/all/lockdown/0021-Lock-down-TIOCSSERIAL.patch +features/all/lockdown/0022-Lock-down-module-params-that-specify-hardware-parame.patch +features/all/lockdown/0023-x86-mmiotrace-Lock-down-the-testmmiotrace-module.patch +features/all/lockdown/0024-debugfs-Disallow-use-of-debugfs-files-when-the-kerne.patch +features/all/lockdown/0025-Lock-down-proc-kcore.patch +features/all/lockdown/0026-Lock-down-kprobes.patch +features/all/lockdown/0027-bpf-Restrict-kernel-image-access-functions-when-the-.patch +features/all/lockdown/0028-efi-Add-an-EFI_SECURE_BOOT-flag-to-indicate-secure-b.patch +features/all/lockdown/0029-efi-Lock-down-the-kernel-if-booted-in-secure-boot-mo.patch +features/all/lockdown/0032-efi-Restrict-efivar_ssdt_load-when-the-kernel-is-loc.patch +# some missing pieces +features/all/lockdown/enable-cold-boot-attack-mitigation.patch +features/all/lockdown/mtd-disable-slram-and-phram-when-locked-down.patch +features/all/lockdown/arm64-add-kernel-config-option-to-lock-down-when.patch +features/all/lockdown/ACPI-configfs-Disallow-loading-ACPI-tables-when-lock.patch +# until the "kernel_lockdown.7" manual page exists +features/all/lockdown/lockdown-refer-to-debian-wiki-until-manual-page-exists.patch + +# load db and MOK keys into secondary keyring for kernel modules verification +features/all/db-mok-keyring/0001-KEYS-Allow-unrestricted-boot-time-addition-of-keys-t.patch +features/all/db-mok-keyring/0002-efi-Add-EFI-signature-data-types.patch +features/all/db-mok-keyring/0003-efi-Add-an-EFI-signature-blob-parser.patch +features/all/db-mok-keyring/0004-MODSIGN-Import-certificates-from-UEFI-Secure-Boot.patch +features/all/db-mok-keyring/0005-MODSIGN-Allow-the-db-UEFI-variable-to-be-suppressed.patch +features/all/db-mok-keyring/0006-Make-get_cert_list-not-complain-about-cert-lists-tha.patch +features/all/db-mok-keyring/0007-modsign-Use-secondary-trust-keyring-for-module-signi.patch +features/all/db-mok-keyring/0001-MODSIGN-do-not-load-mok-when-secure-boot-disabled.patch +features/all/db-mok-keyring/0002-MODSIGN-load-blacklist-from-MOKx.patch +features/all/db-mok-keyring/0003-MODSIGN-checking-the-blacklisted-hash-before-loading-a-kernel-module.patch +features/all/db-mok-keyring/0004-MODSIGN-check-the-attributes-of-db-and-mok.patch +features/all/db-mok-keyring/modsign-make-shash-allocation-failure-fatal.patch + +# Fix exported symbol versions +bugfix/all/module-disable-matching-missing-version-crc.patch + +# Tools bug fixes +bugfix/all/usbip-document-tcp-wrappers.patch +bugfix/all/kbuild-fix-recordmcount-dependency.patch +bugfix/all/tools-perf-man-date.patch +bugfix/all/tools-perf-remove-shebangs.patch +bugfix/all/tools-lib-traceevent-use-ldflags.patch +bugfix/x86/revert-perf-build-fix-libunwind-feature-detection-on.patch +bugfix/all/tools-build-remove-bpf-run-time-check-at-build-time.patch +bugfix/all/cpupower-bump-soname-version.patch +bugfix/all/libcpupower-hide-private-function.patch +bugfix/all/cpupower-fix-checks-for-cpu-existence.patch +bugfix/all/usbip-fix-misuse-of-strncpy.patch +bugfix/x86/tools-turbostat-Add-checks-for-failure-of-fgets-and-.patch +bugfix/all/libbpf-add-soname-to-shared-object.patch +bugfix/all/libbpf-link-shared-object-with-libelf.patch +bugfix/all/libbpf-generate-pkg-config.patch +bugfix/all/perf-script-python-Add-Python3-support-to-netdev-tim.patch +bugfix/all/perf-script-python-Add-Python3-support-to-failed-sys.patch +bugfix/all/perf-script-python-Add-Python3-support-to-mem-phys-a.patch +bugfix/all/perf-script-python-Add-Python3-support-to-net_dropmo.patch +bugfix/all/perf-script-python-Add-Python3-support-to-powerpc-hc.patch +bugfix/all/perf-script-python-Add-Python3-support-to-sctop.py.patch +bugfix/all/perf-script-python-Add-Python3-support-to-stackcolla.patch +bugfix/all/perf-script-python-Add-Python3-support-to-stat-cpi.p.patch +bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co.patch +bugfix/all/perf-script-python-Add-Python3-support-to-syscall-co-de667cce7f4f.patch +bugfix/all/perf-script-python-Remove-mixed-indentation.patch +bugfix/all/perf-script-python-Add-Python3-support-to-futex-cont.patch +bugfix/all/perf-script-python-add-Python3-support-to-check-perf.patch +bugfix/all/perf-script-python-Add-Python3-support-to-event_anal.patch +bugfix/all/perf-script-python-Add-Python3-support-to-intel-pt-e.patch +bugfix/all/perf-script-python-Add-Python3-support-to-export-to-.patch +bugfix/all/perf-script-python-Add-Python3-support-to-export-to-ebf6c5c181ab.patch + +# wireless: Disable regulatory.db direct loading (until we sort out signing) +debian/wireless-disable-regulatory.db-direct-loading.patch + +# Licence clarification +bugfix/all/documentation-media-uapi-explicitly-say-there-are-no-invariant-sections.patch + +# overlay: allow mounting in user namespaces +debian/overlayfs-permit-mounts-in-userns.patch + +# Amazon ENA ethernet driver backport from Linux 4.20 +features/all/ena/0001-net-ethernet-remove-redundant-include.patch +features/all/ena/0002-net-ena-minor-performance-improvement.patch +features/all/ena/0003-net-ena-complete-host-info-to-match-latest-ENA-spec.patch +features/all/ena/0004-net-ena-introduce-Low-Latency-Queues-data-structures.patch +features/all/ena/0005-net-ena-add-functions-for-handling-Low-Latency-Queue.patch +features/all/ena/0006-net-ena-add-functions-for-handling-Low-Latency-Queue.patch +features/all/ena/0007-net-ena-use-CSUM_CHECKED-device-indication-to-report.patch +features/all/ena/0008-net-ena-explicit-casting-and-initialization-and-clea.patch +features/all/ena/0009-net-ena-limit-refill-Rx-threshold-to-256-to-avoid-la.patch +features/all/ena/0010-net-ena-change-rx-copybreak-default-to-reduce-kernel.patch +features/all/ena/0011-net-ena-remove-redundant-parameter-in-ena_com_admin_.patch +features/all/ena/0012-net-ena-update-driver-version-to-2.0.1.patch +features/all/ena/0013-net-ena-fix-indentations-in-ena_defs-for-better-read.patch +features/all/ena/0015-net-ena-enable-Low-Latency-Queues.patch +features/all/ena/0016-net-ena-fix-compilation-error-in-xtensa-architecture.patch +features/all/ena/0017-net-ena-fix-crash-during-ena_remove.patch +features/all/ena/0018-net-ena-update-driver-version-from-2.0.1-to-2.0.2.patch + +features/all/ena/net-ena-update-driver-version-from-2.0.2-to-2.0.3.patch +features/all/ena/net-ena-fix-set-freed-objects-to-NULL-to-avoid-faili.patch +features/all/ena/net-ena-fix-return-value-of-ena_com_config_llq_info.patch +features/all/ena/net-ena-improve-latency-by-disabling-adaptive-interr.patch +features/all/ena/net-ena-add-handling-of-llq-max-tx-burst-size.patch +features/all/ena/net-ena-replace-free_tx-rx_ids-union-with-single-fre.patch +features/all/ena/net-ena-arrange-ena_probe-function-variables-in-reve.patch +features/all/ena/net-ena-add-newline-at-the-end-of-pr_err-prints.patch +features/all/ena/net-ena-allow-automatic-fallback-to-polling-mode.patch +features/all/ena/net-ena-add-support-for-changing-max_header_size-in-.patch +features/all/ena/net-ena-optimise-calculations-for-CQ-doorbell.patch +features/all/ena/net-ena-use-dev_info_once-instead-of-static-variable.patch +features/all/ena/net-ena-add-MAX_QUEUES_EXT-get-feature-admin-command.patch +features/all/ena/net-ena-enable-negotiating-larger-Rx-ring-size.patch +features/all/ena/net-ena-make-ethtool-show-correct-current-and-max-qu.patch +features/all/ena/net-ena-allow-queue-allocation-backoff-when-low-on-m.patch +features/all/ena/net-ena-add-ethtool-function-for-changing-io-queue-s.patch +features/all/ena/net-ena-update-driver-version-from-2.0.3-to-2.1.0.patch +features/all/ena/net-ena-Fix-bug-where-ring-allocation-backoff-stoppe.patch +features/all/ena/net-ena-don-t-wake-up-tx-queue-when-down.patch +features/all/ena/net-ena-add-good-checksum-counter.patch +features/all/ena/net-ena-add-intr_moder_rx_interval-to-struct-ena_com.patch +features/all/ena/net-ena-remove-inline-keyword-from-functions-in-.c.patch +features/all/ena/net-ena-switch-to-dim-algorithm-for-rx-adaptive-inte.patch +features/all/ena/net-ena-reimplement-set-get_coalesce.patch +features/all/ena/net-ena-enable-the-interrupt_moderation-in-driver_su.patch +features/all/ena/net-ena-remove-code-duplication-in-ena_com_update_no.patch +features/all/ena/net-ena-remove-old-adaptive-interrupt-moderation-cod.patch +features/all/ena/net-ena-remove-ena_restore_ethtool_params-and-releva.patch +features/all/ena/net-ena-remove-all-old-adaptive-rx-interrupt-moderat.patch +features/all/ena/net-ena-fix-update-of-interrupt-moderation-register.patch +features/all/ena/net-ena-fix-retrieval-of-nonadaptive-interrupt-moder.patch +features/all/ena/net-ena-fix-incorrect-update-of-intr_delay_resolutio.patch + +# Backported bugfixes from 4.20/4.21 for the Huawei TaiShan server platform (aka D06) +bugfix/arm64/huawei-taishan/0002-scsi-hisi_sas-Move-evaluation-of-hisi_hba-in-hisi_sa.patch +bugfix/arm64/huawei-taishan/0005-scsi-hisi_sas-unmask-interrupts-ent72-and-ent74.patch +bugfix/arm64/huawei-taishan/0006-scsi-hisi_sas-Use-block-layer-tag-instead-for-IPTT.patch +bugfix/arm64/huawei-taishan/0007-scsi-hisi_sas-Update-v3-hw-AIP_LIMIT-and-CFG_AGING_T.patch +bugfix/arm64/huawei-taishan/0008-scsi-hisi_sas-Fix-spin-lock-management-in-slot_index.patch +bugfix/arm64/huawei-taishan/0009-scsi-hisi_sas-use-dma_set_mask_and_coherent.patch +bugfix/arm64/huawei-taishan/0010-scsi-hisi_sas-Create-separate-host-attributes-per-HB.patch +bugfix/arm64/huawei-taishan/0011-scsi-hisi_sas-Add-support-for-interrupt-converge-for.patch +bugfix/arm64/huawei-taishan/0012-scsi-hisi_sas-Add-support-for-interrupt-coalescing-f.patch +bugfix/arm64/huawei-taishan/0013-scsi-hisi_sas-Relocate-some-codes-to-avoid-an-unused.patch +bugfix/arm64/huawei-taishan/0014-scsi-hisi_sas-Fix-warnings-detected-by-sparse.patch +bugfix/arm64/huawei-taishan/0015-scsi-hisi_sas-Relocate-some-code-to-reduce-complexit.patch +bugfix/arm64/huawei-taishan/0016-scsi-hisi_sas-Make-sg_tablesize-consistent-value.patch +bugfix/arm64/huawei-taishan/0017-net-hns3-remove-unnecessary-configuration-recapture-.patch +bugfix/arm64/huawei-taishan/0018-net-hns3-remove-1000M-half-support-of-phy.patch +bugfix/arm64/huawei-taishan/0019-net-hns3-synchronize-speed-and-duplex-from-phy-when-.patch +bugfix/arm64/huawei-taishan/0020-net-hns3-getting-tx-and-dv-buffer-size-through-firmw.patch +bugfix/arm64/huawei-taishan/0021-net-hns3-aligning-buffer-size-in-SSU-to-256-bytes.patch +bugfix/arm64/huawei-taishan/0022-net-hns3-fix-a-SSU-buffer-checking-bug.patch +bugfix/arm64/huawei-taishan/0023-net-hns3-change-default-tc-state-to-close.patch +bugfix/arm64/huawei-taishan/0024-net-hns3-fix-a-bug-caused-by-udelay.patch +bugfix/arm64/huawei-taishan/0025-net-hns3-remove-redundant-variable-initialization.patch +bugfix/arm64/huawei-taishan/0026-net-hns3-call-hns3_nic_net_open-while-doing-HNAE3_UP.patch +bugfix/arm64/huawei-taishan/0029-RDMA-hns-Add-constraint-on-the-setting-of-local-ACK-.patch +bugfix/arm64/huawei-taishan/0030-RDMA-hns-Modify-the-pbl-ba-page-size-for-hip08.patch +bugfix/arm64/huawei-taishan/0031-RDMA-hns-RDMA-hns-Assign-rq-head-pointer-when-enable.patch +bugfix/arm64/huawei-taishan/0033-scsi-hisi_sas-fix-calls-to-dma_set_mask_and_coherent.patch + +# Backported DTB support for Raspberry Pi Compute Module 3 from 4.20-rc1: +features/arm/ARM-dts-add-Raspberry-Pi-Compute-Module-3-and-IO-boa.patch +features/arm64/arm64-dts-broadcom-Add-reference-to-Compute-Module-I.patch +features/arm64/arm64-dts-broadcom-Use-the-.dtb-name-in-the-rule-rat.patch + +# Backported devicetree support for Raspberry Pi 3 1+ from 5.1 +features/arm/ARM-dts-add-Raspberry-Pi-3-A-Plus.patch +features/arm64/arm64-dts-broadcom-Add-reference-to-RPi-3-A-Plus.patch +features/arm/ARM-dts-bcm283x-Correct-vchiq-compatible-string.patch +features/arm/staging-vc04_services-Use-correct-cache-line-size.patch + +# Preserve PCI bridge boot configuration if requested by firmware +bugfix/all/PCI-ACPI-Evaluate-PCI-Boot-Configuration-_DSM.patch +bugfix/all/PCI-Don-t-auto-realloc-if-we-re-preserving-firmware-.patch +bugfix/arm64/arm64-PCI-Allow-resource-reallocation-if-necessary.patch +bugfix/arm64/arm64-PCI-Preserve-firmware-configuration-when-desir.patch + +# Security fixes +debian/i386-686-pae-pci-set-pci-nobios-by-default.patch +debian/ntfs-mark-it-as-broken.patch + +# ABI maintenance |