From: Greg Kroah-Hartman Date: Thu, 18 Aug 2016 10:57:31 +0000 (+0200) Subject: 4.7-stable patches X-Git-Tag: v3.14.77~21 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a5ee7454df348aad617a6607d786636ff8b1b18c;p=thirdparty%2Fkernel%2Fstable-queue.git 4.7-stable patches added patches: arm-8561-3-dma-mapping-don-t-use-outer_flush_range-when-the-l2c-is-coherent.patch arm-dts-realview-fix-pbx-a9-cache-description.patch arm-dts-sunxi-add-a-startup-delay-for-fixed-regulator-enabled-phys.patch arm-tegra-fix-erroneous-address-in-dts.patch audit-fix-a-double-fetch-in-audit_log_single_execve_arg.patch cgroupns-close-race-between-cgroup_post_fork-and-copy_cgroup_ns.patch cgroupns-fix-the-locking-in-copy_cgroup_ns.patch cgroupns-only-allow-creation-of-hierarchies-in-the-initial-cgroup-namespace.patch clk-rockchip-fix-incorrect-rk3399-spdif-dptx-divider-bits.patch iommu-amd-handle-iommu_domain_dma-in-ops-domain_free-call-back.patch iommu-amd-init-unity-mappings-only-for-dma_ops-domains.patch iommu-amd-update-alias-dte-in-update_device_table.patch iommu-exynos-suppress-unbinding-to-prevent-system-failure.patch iommu-io-pgtable-arm-fix-iova_to_phys-for-block-entries.patch iommu-vt-d-return-error-code-in-domain_context_mapping_one.patch netlabel-add-address-family-checks-to-netlbl_-sock-req-_delattr.patch revert-arm-aspeed-adapt-defconfigs-for-new-config_printk_time.patch soc-qcom-smp2p-correct-addressing-of-outgoing-value.patch tpm_crb-fix-address-space-of-the-return-pointer-in-crb_map_res.patch unicore32-mm-add-missing-parameter-to-arch_vma_access_permitted.patch w1-omap_hdq-fix-regression.patch --- diff --git a/queue-4.7/arm-8561-3-dma-mapping-don-t-use-outer_flush_range-when-the-l2c-is-coherent.patch b/queue-4.7/arm-8561-3-dma-mapping-don-t-use-outer_flush_range-when-the-l2c-is-coherent.patch new file mode 100644 index 00000000000..a93bccae0d8 --- /dev/null +++ b/queue-4.7/arm-8561-3-dma-mapping-don-t-use-outer_flush_range-when-the-l2c-is-coherent.patch @@ -0,0 +1,240 @@ +From f12708965069410691e47d1d216ec7ad1516bfd2 Mon Sep 17 00:00:00 2001 +From: Gregory CLEMENT +Date: Fri, 15 Apr 2016 11:15:18 +0100 +Subject: ARM: 8561/3: dma-mapping: Don't use outer_flush_range when the L2C is coherent + +From: Gregory CLEMENT + +commit f12708965069410691e47d1d216ec7ad1516bfd2 upstream. + +When a L2 cache controller is used in a system that provides hardware +coherency, the entire outer cache operations are useless, and can be +skipped. Moreover, on some systems, it is harmful as it causes +deadlocks between the Marvell coherency mechanism, the Marvell PCIe +controller and the Cortex-A9. + +In the current kernel implementation, the outer cache flush range +operation is triggered by the dma_alloc function. +This operation can be take place during runtime and in some +circumstances may lead to the PCIe/PL310 deadlock on Armada 375/38x +SoCs. + +This patch extends the __dma_clear_buffer() function to receive a +boolean argument related to the coherency of the system. The same +things is done for the calling functions. + +Reported-by: Nadav Haklai +Signed-off-by: Gregory CLEMENT +Signed-off-by: Russell King +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/mm/dma-mapping.c | 62 +++++++++++++++++++++++++++++++--------------- + 1 file changed, 42 insertions(+), 20 deletions(-) + +--- a/arch/arm/mm/dma-mapping.c ++++ b/arch/arm/mm/dma-mapping.c +@@ -49,6 +49,7 @@ struct arm_dma_alloc_args { + pgprot_t prot; + const void *caller; + bool want_vaddr; ++ int coherent_flag; + }; + + struct arm_dma_free_args { +@@ -59,6 +60,9 @@ struct arm_dma_free_args { + bool want_vaddr; + }; + ++#define NORMAL 0 ++#define COHERENT 1 ++ + struct arm_dma_allocator { + void *(*alloc)(struct arm_dma_alloc_args *args, + struct page **ret_page); +@@ -272,7 +276,7 @@ static u64 get_coherent_dma_mask(struct + return mask; + } + +-static void __dma_clear_buffer(struct page *page, size_t size) ++static void __dma_clear_buffer(struct page *page, size_t size, int coherent_flag) + { + /* + * Ensure that the allocated pages are zeroed, and that any data +@@ -284,17 +288,21 @@ static void __dma_clear_buffer(struct pa + while (size > 0) { + void *ptr = kmap_atomic(page); + memset(ptr, 0, PAGE_SIZE); +- dmac_flush_range(ptr, ptr + PAGE_SIZE); ++ if (coherent_flag != COHERENT) ++ dmac_flush_range(ptr, ptr + PAGE_SIZE); + kunmap_atomic(ptr); + page++; + size -= PAGE_SIZE; + } +- outer_flush_range(base, end); ++ if (coherent_flag != COHERENT) ++ outer_flush_range(base, end); + } else { + void *ptr = page_address(page); + memset(ptr, 0, size); +- dmac_flush_range(ptr, ptr + size); +- outer_flush_range(__pa(ptr), __pa(ptr) + size); ++ if (coherent_flag != COHERENT) { ++ dmac_flush_range(ptr, ptr + size); ++ outer_flush_range(__pa(ptr), __pa(ptr) + size); ++ } + } + } + +@@ -302,7 +310,8 @@ static void __dma_clear_buffer(struct pa + * Allocate a DMA buffer for 'dev' of size 'size' using the + * specified gfp mask. Note that 'size' must be page aligned. + */ +-static struct page *__dma_alloc_buffer(struct device *dev, size_t size, gfp_t gfp) ++static struct page *__dma_alloc_buffer(struct device *dev, size_t size, ++ gfp_t gfp, int coherent_flag) + { + unsigned long order = get_order(size); + struct page *page, *p, *e; +@@ -318,7 +327,7 @@ static struct page *__dma_alloc_buffer(s + for (p = page + (size >> PAGE_SHIFT), e = page + (1 << order); p < e; p++) + __free_page(p); + +- __dma_clear_buffer(page, size); ++ __dma_clear_buffer(page, size, coherent_flag); + + return page; + } +@@ -340,7 +349,8 @@ static void __dma_free_buffer(struct pag + + static void *__alloc_from_contiguous(struct device *dev, size_t size, + pgprot_t prot, struct page **ret_page, +- const void *caller, bool want_vaddr); ++ const void *caller, bool want_vaddr, ++ int coherent_flag); + + static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp, + pgprot_t prot, struct page **ret_page, +@@ -405,10 +415,13 @@ static int __init atomic_pool_init(void) + atomic_pool = gen_pool_create(PAGE_SHIFT, -1); + if (!atomic_pool) + goto out; +- ++ /* ++ * The atomic pool is only used for non-coherent allocations ++ * so we must pass NORMAL for coherent_flag. ++ */ + if (dev_get_cma_area(NULL)) + ptr = __alloc_from_contiguous(NULL, atomic_pool_size, prot, +- &page, atomic_pool_init, true); ++ &page, atomic_pool_init, true, NORMAL); + else + ptr = __alloc_remap_buffer(NULL, atomic_pool_size, gfp, prot, + &page, atomic_pool_init, true); +@@ -522,7 +535,11 @@ static void *__alloc_remap_buffer(struct + { + struct page *page; + void *ptr = NULL; +- page = __dma_alloc_buffer(dev, size, gfp); ++ /* ++ * __alloc_remap_buffer is only called when the device is ++ * non-coherent ++ */ ++ page = __dma_alloc_buffer(dev, size, gfp, NORMAL); + if (!page) + return NULL; + if (!want_vaddr) +@@ -577,7 +594,8 @@ static int __free_from_pool(void *start, + + static void *__alloc_from_contiguous(struct device *dev, size_t size, + pgprot_t prot, struct page **ret_page, +- const void *caller, bool want_vaddr) ++ const void *caller, bool want_vaddr, ++ int coherent_flag) + { + unsigned long order = get_order(size); + size_t count = size >> PAGE_SHIFT; +@@ -588,7 +606,7 @@ static void *__alloc_from_contiguous(str + if (!page) + return NULL; + +- __dma_clear_buffer(page, size); ++ __dma_clear_buffer(page, size, coherent_flag); + + if (!want_vaddr) + goto out; +@@ -638,7 +656,7 @@ static inline pgprot_t __get_dma_pgprot( + #define __get_dma_pgprot(attrs, prot) __pgprot(0) + #define __alloc_remap_buffer(dev, size, gfp, prot, ret, c, wv) NULL + #define __alloc_from_pool(size, ret_page) NULL +-#define __alloc_from_contiguous(dev, size, prot, ret, c, wv) NULL ++#define __alloc_from_contiguous(dev, size, prot, ret, c, wv, coherent_flag) NULL + #define __free_from_pool(cpu_addr, size) do { } while (0) + #define __free_from_contiguous(dev, page, cpu_addr, size, wv) do { } while (0) + #define __dma_free_remap(cpu_addr, size) do { } while (0) +@@ -649,7 +667,8 @@ static void *__alloc_simple_buffer(struc + struct page **ret_page) + { + struct page *page; +- page = __dma_alloc_buffer(dev, size, gfp); ++ /* __alloc_simple_buffer is only called when the device is coherent */ ++ page = __dma_alloc_buffer(dev, size, gfp, COHERENT); + if (!page) + return NULL; + +@@ -679,7 +698,7 @@ static void *cma_allocator_alloc(struct + { + return __alloc_from_contiguous(args->dev, args->size, args->prot, + ret_page, args->caller, +- args->want_vaddr); ++ args->want_vaddr, args->coherent_flag); + } + + static void cma_allocator_free(struct arm_dma_free_args *args) +@@ -746,6 +765,7 @@ static void *__dma_alloc(struct device * + .prot = prot, + .caller = caller, + .want_vaddr = !dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs), ++ .coherent_flag = is_coherent ? COHERENT : NORMAL, + }; + + #ifdef CONFIG_DMA_API_DEBUG +@@ -1253,7 +1273,8 @@ static inline void __free_iova(struct dm + static const int iommu_order_array[] = { 9, 8, 4, 0 }; + + static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, +- gfp_t gfp, struct dma_attrs *attrs) ++ gfp_t gfp, struct dma_attrs *attrs, ++ int coherent_flag) + { + struct page **pages; + int count = size >> PAGE_SHIFT; +@@ -1277,7 +1298,7 @@ static struct page **__iommu_alloc_buffe + if (!page) + goto error; + +- __dma_clear_buffer(page, size); ++ __dma_clear_buffer(page, size, coherent_flag); + + for (i = 0; i < count; i++) + pages[i] = page + i; +@@ -1327,7 +1348,7 @@ static struct page **__iommu_alloc_buffe + pages[i + j] = pages[i] + j; + } + +- __dma_clear_buffer(pages[i], PAGE_SIZE << order); ++ __dma_clear_buffer(pages[i], PAGE_SIZE << order, coherent_flag); + i += 1 << order; + count -= 1 << order; + } +@@ -1505,7 +1526,8 @@ static void *arm_iommu_alloc_attrs(struc + */ + gfp &= ~(__GFP_COMP); + +- pages = __iommu_alloc_buffer(dev, size, gfp, attrs); ++ /* For now always consider we are in a non-coherent case */ ++ pages = __iommu_alloc_buffer(dev, size, gfp, attrs, NORMAL); + if (!pages) + return NULL; + diff --git a/queue-4.7/arm-dts-realview-fix-pbx-a9-cache-description.patch b/queue-4.7/arm-dts-realview-fix-pbx-a9-cache-description.patch new file mode 100644 index 00000000000..a0f6084443e --- /dev/null +++ b/queue-4.7/arm-dts-realview-fix-pbx-a9-cache-description.patch @@ -0,0 +1,56 @@ +From a20303725ec31ea0fcf498f1885b1d4245a4ee56 Mon Sep 17 00:00:00 2001 +From: Robin Murphy +Date: Wed, 10 Aug 2016 14:02:17 +0200 +Subject: ARM: dts: realview: Fix PBX-A9 cache description + +From: Robin Murphy + +commit a20303725ec31ea0fcf498f1885b1d4245a4ee56 upstream. + +Clearly QEMU is very permissive in how its PL310 model may be set up, +but the real hardware turns out to be far more particular about things +actually being correct. Fix up the DT description so that the real +thing actually boots: + +- The arm,data-latency and arm,tag-latency properties need 3 cells to + be valid, otherwise we end up retaining the default 8-cycle latencies + which leads pretty quickly to lockup. +- The arm,dirty-latency property is only relevant to L210/L220, so get + rid of it. +- The cache geometry override also leads to lockup and/or general + misbehaviour. Irritatingly, the manual doesn't state the actual PL310 + configuration, but based on the boardfile code and poking registers + from the Boot Monitor, it would seem to be 8 sets of 16KB ways. + +With that, we can successfully boot to enjoy the fun of mismatched FPUs... + +Signed-off-by: Robin Murphy +Tested-by: Mark Rutland +Signed-off-by: Linus Walleij +Signed-off-by: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/arm-realview-pbx-a9.dts | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +--- a/arch/arm/boot/dts/arm-realview-pbx-a9.dts ++++ b/arch/arm/boot/dts/arm-realview-pbx-a9.dts +@@ -70,13 +70,12 @@ + * associativity as these may be erroneously set + * up by boot loader(s). + */ +- cache-size = <1048576>; // 1MB +- cache-sets = <4096>; ++ cache-size = <131072>; // 128KB ++ cache-sets = <512>; + cache-line-size = <32>; + arm,parity-disable; +- arm,tag-latency = <1>; +- arm,data-latency = <1 1>; +- arm,dirty-latency = <1>; ++ arm,tag-latency = <1 1 1>; ++ arm,data-latency = <1 1 1>; + }; + + scu: scu@1f000000 { diff --git a/queue-4.7/arm-dts-sunxi-add-a-startup-delay-for-fixed-regulator-enabled-phys.patch b/queue-4.7/arm-dts-sunxi-add-a-startup-delay-for-fixed-regulator-enabled-phys.patch new file mode 100644 index 00000000000..26fd051e4fc --- /dev/null +++ b/queue-4.7/arm-dts-sunxi-add-a-startup-delay-for-fixed-regulator-enabled-phys.patch @@ -0,0 +1,72 @@ +From fc51b632c7b047c25807023b76f3877aed19c770 Mon Sep 17 00:00:00 2001 +From: Hans de Goede +Date: Sat, 4 Jun 2016 12:58:39 +0200 +Subject: ARM: dts: sunxi: Add a startup delay for fixed regulator enabled phys + +From: Hans de Goede + +commit fc51b632c7b047c25807023b76f3877aed19c770 upstream. + +It seems that recent kernels have a shorter timeout when scanning for +ethernet phys causing us to hit a timeout on boards where the phy's +regulator gets enabled just before scanning, which leads to non working +ethernet. + +A 10ms startup delay seems to be enough to fix it, this commit adds a +20ms startup delay just to be safe. + +This has been tested on a sun4i-a10-a1000 and sun5i-a10s-wobo-i5 board, +both of which have non-working ethernet on recent kernels without this +fix. + +Signed-off-by: Hans de Goede +Signed-off-by: Maxime Ripard +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/sun4i-a10-a1000.dts | 1 + + arch/arm/boot/dts/sun4i-a10-hackberry.dts | 1 + + arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts | 1 + + arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts | 1 + + 4 files changed, 4 insertions(+) + +--- a/arch/arm/boot/dts/sun4i-a10-a1000.dts ++++ b/arch/arm/boot/dts/sun4i-a10-a1000.dts +@@ -84,6 +84,7 @@ + regulator-name = "emac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; ++ startup-delay-us = <20000>; + enable-active-high; + gpio = <&pio 7 15 GPIO_ACTIVE_HIGH>; + }; +--- a/arch/arm/boot/dts/sun4i-a10-hackberry.dts ++++ b/arch/arm/boot/dts/sun4i-a10-hackberry.dts +@@ -66,6 +66,7 @@ + regulator-name = "emac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; ++ startup-delay-us = <20000>; + enable-active-high; + gpio = <&pio 7 19 GPIO_ACTIVE_HIGH>; + }; +--- a/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts ++++ b/arch/arm/boot/dts/sun4i-a10-jesurun-q5.dts +@@ -80,6 +80,7 @@ + regulator-name = "emac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; ++ startup-delay-us = <20000>; + enable-active-high; + gpio = <&pio 7 19 GPIO_ACTIVE_HIGH>; /* PH19 */ + }; +--- a/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts ++++ b/arch/arm/boot/dts/sun5i-a10s-wobo-i5.dts +@@ -79,6 +79,7 @@ + regulator-name = "emac-3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; ++ startup-delay-us = <20000>; + enable-active-high; + gpio = <&pio 0 2 GPIO_ACTIVE_HIGH>; + }; diff --git a/queue-4.7/arm-tegra-fix-erroneous-address-in-dts.patch b/queue-4.7/arm-tegra-fix-erroneous-address-in-dts.patch new file mode 100644 index 00000000000..2c0fa5fd3de --- /dev/null +++ b/queue-4.7/arm-tegra-fix-erroneous-address-in-dts.patch @@ -0,0 +1,51 @@ +From b5c86b7496d74f6e454bcab5166efa023e1f0459 Mon Sep 17 00:00:00 2001 +From: Ralf Ramsauer +Date: Mon, 18 Jul 2016 11:46:48 +0200 +Subject: ARM: tegra: fix erroneous address in dts + +From: Ralf Ramsauer + +commit b5c86b7496d74f6e454bcab5166efa023e1f0459 upstream. + +c90bb7b enabled the high speed UARTs of the Jetson TK1. Due to a merge +quirk, wrong addresses were introduced. Fix it and use the correct +addresses. + +Thierry let me know, that there is another patch (b5896f67ab3c in +linux-next) in preparation which removes all the '0,' prefixes of unit +addresses on Tegra124 and is planned to go upstream in 4.8, so +this patch will get reverted then. + +But for the moment, this patch is necessary to fix current misbehaviour. + +Fixes: c90bb7b9b9 ("ARM: tegra: Add high speed UARTs to Jetson TK1 device tree") +Signed-off-by: Ralf Ramsauer +Acked-by: Thierry Reding +Cc: linux-tegra@vger.kernel.org +Signed-off-by: Arnd Bergmann +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/boot/dts/tegra124-jetson-tk1.dts | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts ++++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts +@@ -1386,7 +1386,7 @@ + * Pin 41: BR_UART1_TXD + * Pin 44: BR_UART1_RXD + */ +- serial@70006000 { ++ serial@0,70006000 { + compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; + status = "okay"; + }; +@@ -1398,7 +1398,7 @@ + * Pin 71: UART2_CTS_L + * Pin 74: UART2_RTS_L + */ +- serial@70006040 { ++ serial@0,70006040 { + compatible = "nvidia,tegra124-hsuart", "nvidia,tegra30-hsuart"; + status = "okay"; + }; diff --git a/queue-4.7/audit-fix-a-double-fetch-in-audit_log_single_execve_arg.patch b/queue-4.7/audit-fix-a-double-fetch-in-audit_log_single_execve_arg.patch new file mode 100644 index 00000000000..065f662b336 --- /dev/null +++ b/queue-4.7/audit-fix-a-double-fetch-in-audit_log_single_execve_arg.patch @@ -0,0 +1,416 @@ +From 43761473c254b45883a64441dd0bc85a42f3645c Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Tue, 19 Jul 2016 17:42:57 -0400 +Subject: audit: fix a double fetch in audit_log_single_execve_arg() + +From: Paul Moore + +commit 43761473c254b45883a64441dd0bc85a42f3645c upstream. + +There is a double fetch problem in audit_log_single_execve_arg() +where we first check the execve(2) argumnets for any "bad" characters +which would require hex encoding and then re-fetch the arguments for +logging in the audit record[1]. Of course this leaves a window of +opportunity for an unsavory application to munge with the data. + +This patch reworks things by only fetching the argument data once[2] +into a buffer where it is scanned and logged into the audit +records(s). In addition to fixing the double fetch, this patch +improves on the original code in a few other ways: better handling +of large arguments which require encoding, stricter record length +checking, and some performance improvements (completely unverified, +but we got rid of some strlen() calls, that's got to be a good +thing). + +As part of the development of this patch, I've also created a basic +regression test for the audit-testsuite, the test can be tracked on +GitHub at the following link: + + * https://github.com/linux-audit/audit-testsuite/issues/25 + +[1] If you pay careful attention, there is actually a triple fetch +problem due to a strnlen_user() call at the top of the function. + +[2] This is a tiny white lie, we do make a call to strnlen_user() +prior to fetching the argument data. I don't like it, but due to the +way the audit record is structured we really have no choice unless we +copy the entire argument at once (which would require a rather +wasteful allocation). The good news is that with this patch the +kernel no longer relies on this strnlen_user() value for anything +beyond recording it in the log, we also update it with a trustworthy +value whenever possible. + +Reported-by: Pengfei Wang +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/auditsc.c | 332 +++++++++++++++++++++++++++---------------------------- + 1 file changed, 164 insertions(+), 168 deletions(-) + +--- a/kernel/auditsc.c ++++ b/kernel/auditsc.c +@@ -72,6 +72,7 @@ + #include + #include + #include ++#include + #include + + #include "audit.h" +@@ -81,7 +82,8 @@ + #define AUDITSC_SUCCESS 1 + #define AUDITSC_FAILURE 2 + +-/* no execve audit message should be longer than this (userspace limits) */ ++/* no execve audit message should be longer than this (userspace limits), ++ * see the note near the top of audit_log_execve_info() about this value */ + #define MAX_EXECVE_AUDIT_LEN 7500 + + /* max length to print of cmdline/proctitle value during audit */ +@@ -987,184 +989,178 @@ static int audit_log_pid_context(struct + return rc; + } + +-/* +- * to_send and len_sent accounting are very loose estimates. We aren't +- * really worried about a hard cap to MAX_EXECVE_AUDIT_LEN so much as being +- * within about 500 bytes (next page boundary) +- * +- * why snprintf? an int is up to 12 digits long. if we just assumed when +- * logging that a[%d]= was going to be 16 characters long we would be wasting +- * space in every audit message. In one 7500 byte message we can log up to +- * about 1000 min size arguments. That comes down to about 50% waste of space +- * if we didn't do the snprintf to find out how long arg_num_len was. +- */ +-static int audit_log_single_execve_arg(struct audit_context *context, +- struct audit_buffer **ab, +- int arg_num, +- size_t *len_sent, +- const char __user *p, +- char *buf) +-{ +- char arg_num_len_buf[12]; +- const char __user *tmp_p = p; +- /* how many digits are in arg_num? 5 is the length of ' a=""' */ +- size_t arg_num_len = snprintf(arg_num_len_buf, 12, "%d", arg_num) + 5; +- size_t len, len_left, to_send; +- size_t max_execve_audit_len = MAX_EXECVE_AUDIT_LEN; +- unsigned int i, has_cntl = 0, too_long = 0; +- int ret; +- +- /* strnlen_user includes the null we don't want to send */ +- len_left = len = strnlen_user(p, MAX_ARG_STRLEN) - 1; ++static void audit_log_execve_info(struct audit_context *context, ++ struct audit_buffer **ab) ++{ ++ long len_max; ++ long len_rem; ++ long len_full; ++ long len_buf; ++ long len_abuf; ++ long len_tmp; ++ bool require_data; ++ bool encode; ++ unsigned int iter; ++ unsigned int arg; ++ char *buf_head; ++ char *buf; ++ const char __user *p = (const char __user *)current->mm->arg_start; + +- /* +- * We just created this mm, if we can't find the strings +- * we just copied into it something is _very_ wrong. Similar +- * for strings that are too long, we should not have created +- * any. +- */ +- if (WARN_ON_ONCE(len < 0 || len > MAX_ARG_STRLEN - 1)) { +- send_sig(SIGKILL, current, 0); +- return -1; ++ /* NOTE: this buffer needs to be large enough to hold all the non-arg ++ * data we put in the audit record for this argument (see the ++ * code below) ... at this point in time 96 is plenty */ ++ char abuf[96]; ++ ++ /* NOTE: we set MAX_EXECVE_AUDIT_LEN to a rather arbitrary limit, the ++ * current value of 7500 is not as important as the fact that it ++ * is less than 8k, a setting of 7500 gives us plenty of wiggle ++ * room if we go over a little bit in the logging below */ ++ WARN_ON_ONCE(MAX_EXECVE_AUDIT_LEN > 7500); ++ len_max = MAX_EXECVE_AUDIT_LEN; ++ ++ /* scratch buffer to hold the userspace args */ ++ buf_head = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL); ++ if (!buf_head) { ++ audit_panic("out of memory for argv string"); ++ return; + } ++ buf = buf_head; ++ ++ audit_log_format(*ab, "argc=%d", context->execve.argc); + +- /* walk the whole argument looking for non-ascii chars */ ++ len_rem = len_max; ++ len_buf = 0; ++ len_full = 0; ++ require_data = true; ++ encode = false; ++ iter = 0; ++ arg = 0; + do { +- if (len_left > MAX_EXECVE_AUDIT_LEN) +- to_send = MAX_EXECVE_AUDIT_LEN; +- else +- to_send = len_left; +- ret = copy_from_user(buf, tmp_p, to_send); +- /* +- * There is no reason for this copy to be short. We just +- * copied them here, and the mm hasn't been exposed to user- +- * space yet. +- */ +- if (ret) { +- WARN_ON(1); +- send_sig(SIGKILL, current, 0); +- return -1; +- } +- buf[to_send] = '\0'; +- has_cntl = audit_string_contains_control(buf, to_send); +- if (has_cntl) { +- /* +- * hex messages get logged as 2 bytes, so we can only +- * send half as much in each message +- */ +- max_execve_audit_len = MAX_EXECVE_AUDIT_LEN / 2; +- break; +- } +- len_left -= to_send; +- tmp_p += to_send; +- } while (len_left > 0); +- +- len_left = len; +- +- if (len > max_execve_audit_len) +- too_long = 1; +- +- /* rewalk the argument actually logging the message */ +- for (i = 0; len_left > 0; i++) { +- int room_left; +- +- if (len_left > max_execve_audit_len) +- to_send = max_execve_audit_len; +- else +- to_send = len_left; +- +- /* do we have space left to send this argument in this ab? */ +- room_left = MAX_EXECVE_AUDIT_LEN - arg_num_len - *len_sent; +- if (has_cntl) +- room_left -= (to_send * 2); +- else +- room_left -= to_send; +- if (room_left < 0) { +- *len_sent = 0; +- audit_log_end(*ab); +- *ab = audit_log_start(context, GFP_KERNEL, AUDIT_EXECVE); +- if (!*ab) +- return 0; +- } ++ /* NOTE: we don't ever want to trust this value for anything ++ * serious, but the audit record format insists we ++ * provide an argument length for really long arguments, ++ * e.g. > MAX_EXECVE_AUDIT_LEN, so we have no choice but ++ * to use strncpy_from_user() to obtain this value for ++ * recording in the log, although we don't use it ++ * anywhere here to avoid a double-fetch problem */ ++ if (len_full == 0) ++ len_full = strnlen_user(p, MAX_ARG_STRLEN) - 1; ++ ++ /* read more data from userspace */ ++ if (require_data) { ++ /* can we make more room in the buffer? */ ++ if (buf != buf_head) { ++ memmove(buf_head, buf, len_buf); ++ buf = buf_head; ++ } + +- /* +- * first record needs to say how long the original string was +- * so we can be sure nothing was lost. +- */ +- if ((i == 0) && (too_long)) +- audit_log_format(*ab, " a%d_len=%zu", arg_num, +- has_cntl ? 2*len : len); +- +- /* +- * normally arguments are small enough to fit and we already +- * filled buf above when we checked for control characters +- * so don't bother with another copy_from_user +- */ +- if (len >= max_execve_audit_len) +- ret = copy_from_user(buf, p, to_send); +- else +- ret = 0; +- if (ret) { +- WARN_ON(1); +- send_sig(SIGKILL, current, 0); +- return -1; +- } +- buf[to_send] = '\0'; ++ /* fetch as much as we can of the argument */ ++ len_tmp = strncpy_from_user(&buf_head[len_buf], p, ++ len_max - len_buf); ++ if (len_tmp == -EFAULT) { ++ /* unable to copy from userspace */ ++ send_sig(SIGKILL, current, 0); ++ goto out; ++ } else if (len_tmp == (len_max - len_buf)) { ++ /* buffer is not large enough */ ++ require_data = true; ++ /* NOTE: if we are going to span multiple ++ * buffers force the encoding so we stand ++ * a chance at a sane len_full value and ++ * consistent record encoding */ ++ encode = true; ++ len_full = len_full * 2; ++ p += len_tmp; ++ } else { ++ require_data = false; ++ if (!encode) ++ encode = audit_string_contains_control( ++ buf, len_tmp); ++ /* try to use a trusted value for len_full */ ++ if (len_full < len_max) ++ len_full = (encode ? ++ len_tmp * 2 : len_tmp); ++ p += len_tmp + 1; ++ } ++ len_buf += len_tmp; ++ buf_head[len_buf] = '\0'; + +- /* actually log it */ +- audit_log_format(*ab, " a%d", arg_num); +- if (too_long) +- audit_log_format(*ab, "[%d]", i); +- audit_log_format(*ab, "="); +- if (has_cntl) +- audit_log_n_hex(*ab, buf, to_send); +- else +- audit_log_string(*ab, buf); +- +- p += to_send; +- len_left -= to_send; +- *len_sent += arg_num_len; +- if (has_cntl) +- *len_sent += to_send * 2; +- else +- *len_sent += to_send; +- } +- /* include the null we didn't log */ +- return len + 1; +-} ++ /* length of the buffer in the audit record? */ ++ len_abuf = (encode ? len_buf * 2 : len_buf + 2); ++ } + +-static void audit_log_execve_info(struct audit_context *context, +- struct audit_buffer **ab) +-{ +- int i, len; +- size_t len_sent = 0; +- const char __user *p; +- char *buf; ++ /* write as much as we can to the audit log */ ++ if (len_buf > 0) { ++ /* NOTE: some magic numbers here - basically if we ++ * can't fit a reasonable amount of data into the ++ * existing audit buffer, flush it and start with ++ * a new buffer */ ++ if ((sizeof(abuf) + 8) > len_rem) { ++ len_rem = len_max; ++ audit_log_end(*ab); ++ *ab = audit_log_start(context, ++ GFP_KERNEL, AUDIT_EXECVE); ++ if (!*ab) ++ goto out; ++ } + +- p = (const char __user *)current->mm->arg_start; ++ /* create the non-arg portion of the arg record */ ++ len_tmp = 0; ++ if (require_data || (iter > 0) || ++ ((len_abuf + sizeof(abuf)) > len_rem)) { ++ if (iter == 0) { ++ len_tmp += snprintf(&abuf[len_tmp], ++ sizeof(abuf) - len_tmp, ++ " a%d_len=%lu", ++ arg, len_full); ++ } ++ len_tmp += snprintf(&abuf[len_tmp], ++ sizeof(abuf) - len_tmp, ++ " a%d[%d]=", arg, iter++); ++ } else ++ len_tmp += snprintf(&abuf[len_tmp], ++ sizeof(abuf) - len_tmp, ++ " a%d=", arg); ++ WARN_ON(len_tmp >= sizeof(abuf)); ++ abuf[sizeof(abuf) - 1] = '\0'; ++ ++ /* log the arg in the audit record */ ++ audit_log_format(*ab, "%s", abuf); ++ len_rem -= len_tmp; ++ len_tmp = len_buf; ++ if (encode) { ++ if (len_abuf > len_rem) ++ len_tmp = len_rem / 2; /* encoding */ ++ audit_log_n_hex(*ab, buf, len_tmp); ++ len_rem -= len_tmp * 2; ++ len_abuf -= len_tmp * 2; ++ } else { ++ if (len_abuf > len_rem) ++ len_tmp = len_rem - 2; /* quotes */ ++ audit_log_n_string(*ab, buf, len_tmp); ++ len_rem -= len_tmp + 2; ++ /* don't subtract the "2" because we still need ++ * to add quotes to the remaining string */ ++ len_abuf -= len_tmp; ++ } ++ len_buf -= len_tmp; ++ buf += len_tmp; ++ } + +- audit_log_format(*ab, "argc=%d", context->execve.argc); ++ /* ready to move to the next argument? */ ++ if ((len_buf == 0) && !require_data) { ++ arg++; ++ iter = 0; ++ len_full = 0; ++ require_data = true; ++ encode = false; ++ } ++ } while (arg < context->execve.argc); + +- /* +- * we need some kernel buffer to hold the userspace args. Just +- * allocate one big one rather than allocating one of the right size +- * for every single argument inside audit_log_single_execve_arg() +- * should be <8k allocation so should be pretty safe. +- */ +- buf = kmalloc(MAX_EXECVE_AUDIT_LEN + 1, GFP_KERNEL); +- if (!buf) { +- audit_panic("out of memory for argv string"); +- return; +- } ++ /* NOTE: the caller handles the final audit_log_end() call */ + +- for (i = 0; i < context->execve.argc; i++) { +- len = audit_log_single_execve_arg(context, ab, i, +- &len_sent, p, buf); +- if (len <= 0) +- break; +- p += len; +- } +- kfree(buf); ++out: ++ kfree(buf_head); + } + + static void show_special(struct audit_context *context, int *call_panic) diff --git a/queue-4.7/cgroupns-close-race-between-cgroup_post_fork-and-copy_cgroup_ns.patch b/queue-4.7/cgroupns-close-race-between-cgroup_post_fork-and-copy_cgroup_ns.patch new file mode 100644 index 00000000000..09a639a9497 --- /dev/null +++ b/queue-4.7/cgroupns-close-race-between-cgroup_post_fork-and-copy_cgroup_ns.patch @@ -0,0 +1,67 @@ +From eedd0f4cbf5f3b81e82649832091e1d9d53f0709 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 15 Jul 2016 06:35:51 -0500 +Subject: cgroupns: Close race between cgroup_post_fork and copy_cgroup_ns + +From: Eric W. Biederman + +commit eedd0f4cbf5f3b81e82649832091e1d9d53f0709 upstream. + +In most code paths involving cgroup migration cgroup_threadgroup_rwsem +is taken. There are two exceptions: + +- remove_tasks_in_empty_cpuset calls cgroup_transfer_tasks +- vhost_attach_cgroups_work calls cgroup_attach_task_all + +With cgroup_threadgroup_rwsem held it is guaranteed that cgroup_post_fork +and copy_cgroup_ns will reference the same css_set from the process calling +fork. + +Without such an interlock there process after fork could reference one +css_set from it's new cgroup namespace and another css_set from +task->cgroups, which semantically is nonsensical. + +Fixes: a79a908fd2b0 ("cgroup: introduce cgroup namespaces") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/cgroup.c | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -2962,6 +2962,7 @@ int cgroup_attach_task_all(struct task_s + int retval = 0; + + mutex_lock(&cgroup_mutex); ++ percpu_down_write(&cgroup_threadgroup_rwsem); + for_each_root(root) { + struct cgroup *from_cgrp; + +@@ -2976,6 +2977,7 @@ int cgroup_attach_task_all(struct task_s + if (retval) + break; + } ++ percpu_up_write(&cgroup_threadgroup_rwsem); + mutex_unlock(&cgroup_mutex); + + return retval; +@@ -4343,6 +4345,8 @@ int cgroup_transfer_tasks(struct cgroup + + mutex_lock(&cgroup_mutex); + ++ percpu_down_write(&cgroup_threadgroup_rwsem); ++ + /* all tasks in @from are being moved, all csets are source */ + spin_lock_irq(&css_set_lock); + list_for_each_entry(link, &from->cset_links, cset_link) +@@ -4371,6 +4375,7 @@ int cgroup_transfer_tasks(struct cgroup + } while (task && !ret); + out_err: + cgroup_migrate_finish(&preloaded_csets); ++ percpu_up_write(&cgroup_threadgroup_rwsem); + mutex_unlock(&cgroup_mutex); + return ret; + } diff --git a/queue-4.7/cgroupns-fix-the-locking-in-copy_cgroup_ns.patch b/queue-4.7/cgroupns-fix-the-locking-in-copy_cgroup_ns.patch new file mode 100644 index 00000000000..7f1aa74cdef --- /dev/null +++ b/queue-4.7/cgroupns-fix-the-locking-in-copy_cgroup_ns.patch @@ -0,0 +1,56 @@ +From 7bd8830875bfa380c68f390efbad893293749324 Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 15 Jul 2016 06:35:24 -0500 +Subject: cgroupns: Fix the locking in copy_cgroup_ns + +From: Eric W. Biederman + +commit 7bd8830875bfa380c68f390efbad893293749324 upstream. + +If "clone(CLONE_NEWCGROUP...)" is called it results in a nice lockdep +valid splat. + +In __cgroup_proc_write the lock ordering is: + cgroup_mutex -- through cgroup_kn_lock_live + cgroup_threadgroup_rwsem + +In copy_process the guts of clone the lock ordering is: + cgroup_threadgroup_rwsem -- through threadgroup_change_begin + cgroup_mutex -- through copy_namespaces -- copy_cgroup_ns + +lockdep reports some a different call chains for the first ordering of +cgroup_mutex and cgroup_threadgroup_rwsem but it is harder to trace. +This is most definitely deadlock potential under the right +circumstances. + +Fix this by by skipping the cgroup_mutex and making the locking in +copy_cgroup_ns mirror the locking in cgroup_post_fork which also runs +during fork under the cgroup_threadgroup_rwsem. + +Fixes: a79a908fd2b0 ("cgroup: introduce cgroup namespaces") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/cgroup.c | 5 +---- + 1 file changed, 1 insertion(+), 4 deletions(-) + +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -6309,14 +6309,11 @@ struct cgroup_namespace *copy_cgroup_ns( + if (!ns_capable(user_ns, CAP_SYS_ADMIN)) + return ERR_PTR(-EPERM); + +- mutex_lock(&cgroup_mutex); ++ /* It is not safe to take cgroup_mutex here */ + spin_lock_irq(&css_set_lock); +- + cset = task_css_set(current); + get_css_set(cset); +- + spin_unlock_irq(&css_set_lock); +- mutex_unlock(&cgroup_mutex); + + new_ns = alloc_cgroup_ns(); + if (IS_ERR(new_ns)) { diff --git a/queue-4.7/cgroupns-only-allow-creation-of-hierarchies-in-the-initial-cgroup-namespace.patch b/queue-4.7/cgroupns-only-allow-creation-of-hierarchies-in-the-initial-cgroup-namespace.patch new file mode 100644 index 00000000000..cc2d3867844 --- /dev/null +++ b/queue-4.7/cgroupns-only-allow-creation-of-hierarchies-in-the-initial-cgroup-namespace.patch @@ -0,0 +1,50 @@ +From 726a4994b05ff5b6f83d64b5b43c3251217366ce Mon Sep 17 00:00:00 2001 +From: "Eric W. Biederman" +Date: Fri, 15 Jul 2016 06:36:44 -0500 +Subject: cgroupns: Only allow creation of hierarchies in the initial cgroup namespace + +From: Eric W. Biederman + +commit 726a4994b05ff5b6f83d64b5b43c3251217366ce upstream. + +Unprivileged users can't use hierarchies if they create them as they do not +have privilieges to the root directory. + +Which means the only thing a hiearchy created by an unprivileged user +is good for is expanding the number of cgroup links in every css_set, +which is a DOS attack. + +We could allow hierarchies to be created in namespaces in the initial +user namespace. Unfortunately there is only a single namespace for +the names of heirarchies, so that is likely to create more confusion +than not. + +So do the simple thing and restrict hiearchy creation to the initial +cgroup namespace. + +Fixes: a79a908fd2b0 ("cgroup: introduce cgroup namespaces") +Signed-off-by: "Eric W. Biederman" +Signed-off-by: Tejun Heo +Signed-off-by: Greg Kroah-Hartman + +--- + kernel/cgroup.c | 8 ++------ + 1 file changed, 2 insertions(+), 6 deletions(-) + +--- a/kernel/cgroup.c ++++ b/kernel/cgroup.c +@@ -2215,12 +2215,8 @@ static struct dentry *cgroup_mount(struc + goto out_unlock; + } + +- /* +- * We know this subsystem has not yet been bound. Users in a non-init +- * user namespace may only mount hierarchies with no bound subsystems, +- * i.e. 'none,name=user1' +- */ +- if (!opts.none && !capable(CAP_SYS_ADMIN)) { ++ /* Hierarchies may only be created in the initial cgroup namespace. */ ++ if (ns != &init_cgroup_ns) { + ret = -EPERM; + goto out_unlock; + } diff --git a/queue-4.7/clk-rockchip-fix-incorrect-rk3399-spdif-dptx-divider-bits.patch b/queue-4.7/clk-rockchip-fix-incorrect-rk3399-spdif-dptx-divider-bits.patch new file mode 100644 index 00000000000..62a7094bea3 --- /dev/null +++ b/queue-4.7/clk-rockchip-fix-incorrect-rk3399-spdif-dptx-divider-bits.patch @@ -0,0 +1,34 @@ +From 3770821fa360525e6c726cd562a2438a0aa5d566 Mon Sep 17 00:00:00 2001 +From: Xing Zheng +Date: Thu, 30 Jun 2016 10:18:59 +0800 +Subject: clk: rockchip: fix incorrect rk3399 spdif-DPTX divider bits + +From: Xing Zheng + +commit 3770821fa360525e6c726cd562a2438a0aa5d566 upstream. + +The CLKSEL_CON32 bit_0 is controlled for spdif_8ch, not spdif_rec_dptx, +it should be bit_8, let's fix it. + +Fixes: 115510053e5e ("clk: rockchip: add clock controller for the RK3399") +Reported-by: Chris Zhong +Tested-by: Chris Zhong +Signed-off-by: Xing Zheng +Signed-off-by: Heiko Stuebner +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/clk/rockchip/clk-rk3399.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/clk/rockchip/clk-rk3399.c ++++ b/drivers/clk/rockchip/clk-rk3399.c +@@ -586,7 +586,7 @@ static struct rockchip_clk_branch rk3399 + RK3399_CLKGATE_CON(8), 15, GFLAGS), + + COMPOSITE(SCLK_SPDIF_REC_DPTX, "clk_spdif_rec_dptx", mux_pll_src_cpll_gpll_p, 0, +- RK3399_CLKSEL_CON(32), 15, 1, MFLAGS, 0, 5, DFLAGS, ++ RK3399_CLKSEL_CON(32), 15, 1, MFLAGS, 8, 5, DFLAGS, + RK3399_CLKGATE_CON(10), 6, GFLAGS), + /* i2s */ + COMPOSITE(0, "clk_i2s0_div", mux_pll_src_cpll_gpll_p, 0, diff --git a/queue-4.7/iommu-amd-handle-iommu_domain_dma-in-ops-domain_free-call-back.patch b/queue-4.7/iommu-amd-handle-iommu_domain_dma-in-ops-domain_free-call-back.patch new file mode 100644 index 00000000000..3574aaaab94 --- /dev/null +++ b/queue-4.7/iommu-amd-handle-iommu_domain_dma-in-ops-domain_free-call-back.patch @@ -0,0 +1,64 @@ +From cda7005ba2cbd0744fea343dd5b2aa637eba5b9e Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Thu, 7 Jul 2016 15:57:04 +0200 +Subject: iommu/amd: Handle IOMMU_DOMAIN_DMA in ops->domain_free call-back + +From: Joerg Roedel + +commit cda7005ba2cbd0744fea343dd5b2aa637eba5b9e upstream. + +This domain type is not yet handled in the +iommu_ops->domain_free() call-back. Fix that. + +Fixes: 0bb6e243d7fb ('iommu/amd: Support IOMMU_DOMAIN_DMA type allocation') +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu.c | 27 ++++++++++++++++++--------- + 1 file changed, 18 insertions(+), 9 deletions(-) + +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -3103,9 +3103,7 @@ static struct iommu_domain *amd_iommu_do + static void amd_iommu_domain_free(struct iommu_domain *dom) + { + struct protection_domain *domain; +- +- if (!dom) +- return; ++ struct dma_ops_domain *dma_dom; + + domain = to_pdomain(dom); + +@@ -3114,13 +3112,24 @@ static void amd_iommu_domain_free(struct + + BUG_ON(domain->dev_cnt != 0); + +- if (domain->mode != PAGE_MODE_NONE) +- free_pagetable(domain); +- +- if (domain->flags & PD_IOMMUV2_MASK) +- free_gcr3_table(domain); ++ if (!dom) ++ return; + +- protection_domain_free(domain); ++ switch (dom->type) { ++ case IOMMU_DOMAIN_DMA: ++ dma_dom = domain->priv; ++ dma_ops_domain_free(dma_dom); ++ break; ++ default: ++ if (domain->mode != PAGE_MODE_NONE) ++ free_pagetable(domain); ++ ++ if (domain->flags & PD_IOMMUV2_MASK) ++ free_gcr3_table(domain); ++ ++ protection_domain_free(domain); ++ break; ++ } + } + + static void amd_iommu_detach_device(struct iommu_domain *dom, diff --git a/queue-4.7/iommu-amd-init-unity-mappings-only-for-dma_ops-domains.patch b/queue-4.7/iommu-amd-init-unity-mappings-only-for-dma_ops-domains.patch new file mode 100644 index 00000000000..79207d1de44 --- /dev/null +++ b/queue-4.7/iommu-amd-init-unity-mappings-only-for-dma_ops-domains.patch @@ -0,0 +1,38 @@ +From b548e786ce47017107765bbeb0f100202525ea83 Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Wed, 13 Jul 2016 12:35:24 +0200 +Subject: iommu/amd: Init unity mappings only for dma_ops domains + +From: Joerg Roedel + +commit b548e786ce47017107765bbeb0f100202525ea83 upstream. + +The default domain for a device might also be +identity-mapped. In this case the kernel would crash when +unity mappings are defined for the device. Fix that by +making sure the domain is a dma_ops domain. + +Fixes: 0bb6e243d7fb ('iommu/amd: Support IOMMU_DOMAIN_DMA type allocation') +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -466,9 +466,11 @@ static void init_iommu_group(struct devi + if (!domain) + goto out; + +- dma_domain = to_pdomain(domain)->priv; ++ if (to_pdomain(domain)->flags == PD_DMA_OPS_MASK) { ++ dma_domain = to_pdomain(domain)->priv; ++ init_unity_mappings_for_device(dev, dma_domain); ++ } + +- init_unity_mappings_for_device(dev, dma_domain); + out: + iommu_group_put(group); + } diff --git a/queue-4.7/iommu-amd-update-alias-dte-in-update_device_table.patch b/queue-4.7/iommu-amd-update-alias-dte-in-update_device_table.patch new file mode 100644 index 00000000000..991a06c1b67 --- /dev/null +++ b/queue-4.7/iommu-amd-update-alias-dte-in-update_device_table.patch @@ -0,0 +1,41 @@ +From 3254de6bf74fe94c197c9f819fe62a3a3c36f073 Mon Sep 17 00:00:00 2001 +From: Joerg Roedel +Date: Tue, 26 Jul 2016 15:18:54 +0200 +Subject: iommu/amd: Update Alias-DTE in update_device_table() + +From: Joerg Roedel + +commit 3254de6bf74fe94c197c9f819fe62a3a3c36f073 upstream. + +Not doing so might cause IO-Page-Faults when a device uses +an alias request-id and the alias-dte is left in a lower +page-mode which does not cover the address allocated from +the iova-allocator. + +Fixes: 492667dacc0a ('x86/amd-iommu: Remove amd_iommu_pd_table') +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/amd_iommu.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +--- a/drivers/iommu/amd_iommu.c ++++ b/drivers/iommu/amd_iommu.c +@@ -2514,8 +2514,15 @@ static void update_device_table(struct p + { + struct iommu_dev_data *dev_data; + +- list_for_each_entry(dev_data, &domain->dev_list, list) ++ list_for_each_entry(dev_data, &domain->dev_list, list) { + set_dte_entry(dev_data->devid, domain, dev_data->ats.enabled); ++ ++ if (dev_data->devid == dev_data->alias) ++ continue; ++ ++ /* There is an alias, update device table entry for it */ ++ set_dte_entry(dev_data->alias, domain, dev_data->ats.enabled); ++ } + } + + static void update_domain(struct protection_domain *domain) diff --git a/queue-4.7/iommu-exynos-suppress-unbinding-to-prevent-system-failure.patch b/queue-4.7/iommu-exynos-suppress-unbinding-to-prevent-system-failure.patch new file mode 100644 index 00000000000..d35de00b8ed --- /dev/null +++ b/queue-4.7/iommu-exynos-suppress-unbinding-to-prevent-system-failure.patch @@ -0,0 +1,34 @@ +From b54b874fbaf5e024723e50dfb035a9916d6752b4 Mon Sep 17 00:00:00 2001 +From: Marek Szyprowski +Date: Fri, 20 May 2016 15:48:21 +0200 +Subject: iommu/exynos: Suppress unbinding to prevent system failure + +From: Marek Szyprowski + +commit b54b874fbaf5e024723e50dfb035a9916d6752b4 upstream. + +Removal of IOMMU driver cannot be done reliably, so Exynos IOMMU driver +doesn't support this operation. It is essential for system operation, so +it makes sense to prevent unbinding by disabling bind/unbind sysfs +feature for SYSMMU controller driver to avoid kernel ops or trashing +memory caused by such operation. + +Signed-off-by: Marek Szyprowski +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/exynos-iommu.c | 1 + + 1 file changed, 1 insertion(+) + +--- a/drivers/iommu/exynos-iommu.c ++++ b/drivers/iommu/exynos-iommu.c +@@ -709,6 +709,7 @@ static struct platform_driver exynos_sys + .name = "exynos-sysmmu", + .of_match_table = sysmmu_of_match, + .pm = &sysmmu_pm_ops, ++ .suppress_bind_attrs = true, + } + }; + diff --git a/queue-4.7/iommu-io-pgtable-arm-fix-iova_to_phys-for-block-entries.patch b/queue-4.7/iommu-io-pgtable-arm-fix-iova_to_phys-for-block-entries.patch new file mode 100644 index 00000000000..0d750848307 --- /dev/null +++ b/queue-4.7/iommu-io-pgtable-arm-fix-iova_to_phys-for-block-entries.patch @@ -0,0 +1,43 @@ +From 7c6d90e2bb1a98b86d73b9e8ab4d97ed5507e37c Mon Sep 17 00:00:00 2001 +From: Will Deacon +Date: Thu, 16 Jun 2016 18:21:19 +0100 +Subject: iommu/io-pgtable-arm: Fix iova_to_phys for block entries + +From: Will Deacon + +commit 7c6d90e2bb1a98b86d73b9e8ab4d97ed5507e37c upstream. + +The implementation of iova_to_phys for the long-descriptor ARM +io-pgtable code always masks with the granule size when inserting the +low virtual address bits into the physical address determined from the +page tables. In cases where the leaf entry is found before the final +level of table (i.e. due to a block mapping), this results in rounding +down to the bottom page of the block mapping. Consequently, the physical +address range batching in the vfio_unmap_unpin is defeated and we end +up taking the long way home. + +This patch fixes the problem by masking the virtual address with the +appropriate mask for the level at which the leaf descriptor is located. +The short-descriptor code already gets this right, so no change is +needed there. + +Reported-by: Robin Murphy +Tested-by: Robin Murphy +Signed-off-by: Will Deacon +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/io-pgtable-arm.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iommu/io-pgtable-arm.c ++++ b/drivers/iommu/io-pgtable-arm.c +@@ -576,7 +576,7 @@ static phys_addr_t arm_lpae_iova_to_phys + return 0; + + found_translation: +- iova &= (ARM_LPAE_GRANULE(data) - 1); ++ iova &= (ARM_LPAE_BLOCK_SIZE(lvl, data) - 1); + return ((phys_addr_t)iopte_to_pfn(pte,data) << data->pg_shift) | iova; + } + diff --git a/queue-4.7/iommu-vt-d-return-error-code-in-domain_context_mapping_one.patch b/queue-4.7/iommu-vt-d-return-error-code-in-domain_context_mapping_one.patch new file mode 100644 index 00000000000..9ffb397c63e --- /dev/null +++ b/queue-4.7/iommu-vt-d-return-error-code-in-domain_context_mapping_one.patch @@ -0,0 +1,35 @@ +From 5c365d18a73d3979db37006eaacefc0008869c0f Mon Sep 17 00:00:00 2001 +From: Wei Yang +Date: Wed, 13 Jul 2016 13:53:21 +0000 +Subject: iommu/vt-d: Return error code in domain_context_mapping_one() + +From: Wei Yang + +commit 5c365d18a73d3979db37006eaacefc0008869c0f upstream. + +In 'commit <55d940430ab9> ("iommu/vt-d: Get rid of domain->iommu_lock")', +the error handling path is changed a little, which makes the function +always return 0. + +This path fixes this. + +Signed-off-by: Wei Yang +Fixes: 55d940430ab9 ('iommu/vt-d: Get rid of domain->iommu_lock') +Signed-off-by: Joerg Roedel +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/iommu/intel-iommu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/iommu/intel-iommu.c ++++ b/drivers/iommu/intel-iommu.c +@@ -2076,7 +2076,7 @@ out_unlock: + spin_unlock(&iommu->lock); + spin_unlock_irqrestore(&device_domain_lock, flags); + +- return 0; ++ return ret; + } + + struct domain_context_mapping_data { diff --git a/queue-4.7/netlabel-add-address-family-checks-to-netlbl_-sock-req-_delattr.patch b/queue-4.7/netlabel-add-address-family-checks-to-netlbl_-sock-req-_delattr.patch new file mode 100644 index 00000000000..26ab0e35270 --- /dev/null +++ b/queue-4.7/netlabel-add-address-family-checks-to-netlbl_-sock-req-_delattr.patch @@ -0,0 +1,51 @@ +From 0e0e36774081534783aa8eeb9f6fbddf98d3c061 Mon Sep 17 00:00:00 2001 +From: Paul Moore +Date: Mon, 6 Jun 2016 15:17:20 -0400 +Subject: netlabel: add address family checks to netlbl_{sock,req}_delattr() + +From: Paul Moore + +commit 0e0e36774081534783aa8eeb9f6fbddf98d3c061 upstream. + +It seems risky to always rely on the caller to ensure the socket's +address family is correct before passing it to the NetLabel kAPI, +especially since we see at least one LSM which didn't. Add address +family checks to the *_delattr() functions to help prevent future +problems. + +Reported-by: Maninder Singh +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman + +--- + net/netlabel/netlabel_kapi.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +--- a/net/netlabel/netlabel_kapi.c ++++ b/net/netlabel/netlabel_kapi.c +@@ -824,7 +824,11 @@ socket_setattr_return: + */ + void netlbl_sock_delattr(struct sock *sk) + { +- cipso_v4_sock_delattr(sk); ++ switch (sk->sk_family) { ++ case AF_INET: ++ cipso_v4_sock_delattr(sk); ++ break; ++ } + } + + /** +@@ -987,7 +991,11 @@ req_setattr_return: + */ + void netlbl_req_delattr(struct request_sock *req) + { +- cipso_v4_req_delattr(req); ++ switch (req->rsk_ops->family) { ++ case AF_INET: ++ cipso_v4_req_delattr(req); ++ break; ++ } + } + + /** diff --git a/queue-4.7/revert-arm-aspeed-adapt-defconfigs-for-new-config_printk_time.patch b/queue-4.7/revert-arm-aspeed-adapt-defconfigs-for-new-config_printk_time.patch new file mode 100644 index 00000000000..f4d3ed5e5e1 --- /dev/null +++ b/queue-4.7/revert-arm-aspeed-adapt-defconfigs-for-new-config_printk_time.patch @@ -0,0 +1,49 @@ +From 7a376ac11fc2109dfd86442ff79982ecf16dcd6d Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Wed, 3 Aug 2016 11:07:44 +0200 +Subject: Revert "ARM: aspeed: adapt defconfigs for new CONFIG_PRINTK_TIME" + +From: Arnd Bergmann + +commit 7a376ac11fc2109dfd86442ff79982ecf16dcd6d upstream. + +The patch that this was preparing for made it into neither v4.7 nor +v4.8, so we should back this out as well to avoid the opposite +warning: + + arch/arm/configs/aspeed_g5_defconfig:62:warning: symbol value '1' invalid for PRINTK_TIME + arch/arm/configs/aspeed_g4_defconfig:61:warning: symbol value '1' invalid for PRINTK_TIME + +Sorry for not catching this earlier. + +Signed-off-by: Arnd Bergmann +Fixes: 0ef659a30055 ("ARM: aspeed: adapt defconfigs for new CONFIG_PRINTK_TIME") +Signed-off-by: Greg Kroah-Hartman + +--- + arch/arm/configs/aspeed_g4_defconfig | 2 +- + arch/arm/configs/aspeed_g5_defconfig | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +--- a/arch/arm/configs/aspeed_g4_defconfig ++++ b/arch/arm/configs/aspeed_g4_defconfig +@@ -58,7 +58,7 @@ CONFIG_SERIAL_OF_PLATFORM=y + # CONFIG_IOMMU_SUPPORT is not set + CONFIG_FIRMWARE_MEMMAP=y + CONFIG_FANOTIFY=y +-CONFIG_PRINTK_TIME=1 ++CONFIG_PRINTK_TIME=y + CONFIG_DYNAMIC_DEBUG=y + CONFIG_STRIP_ASM_SYMS=y + CONFIG_PAGE_POISONING=y +--- a/arch/arm/configs/aspeed_g5_defconfig ++++ b/arch/arm/configs/aspeed_g5_defconfig +@@ -59,7 +59,7 @@ CONFIG_SERIAL_OF_PLATFORM=y + # CONFIG_IOMMU_SUPPORT is not set + CONFIG_FIRMWARE_MEMMAP=y + CONFIG_FANOTIFY=y +-CONFIG_PRINTK_TIME=1 ++CONFIG_PRINTK_TIME=y + CONFIG_DYNAMIC_DEBUG=y + CONFIG_STRIP_ASM_SYMS=y + CONFIG_PAGE_POISONING=y diff --git a/queue-4.7/series b/queue-4.7/series index 4679925902a..2d2bafa786c 100644 --- a/queue-4.7/series +++ b/queue-4.7/series @@ -95,3 +95,24 @@ pnfs-separate-handling-of-nfs4err_layouttrylater-and-recallconflict.patch pnfs-fix-post-layoutget-error-handling-in-pnfs_update_layout.patch pnfs-handle-nfs4err_recallconflict-correctly-in-layoutget.patch pnfs-fix-layoutget-handling-of-nfs4err_bad_stateid-and-nfs4err_expired.patch +unicore32-mm-add-missing-parameter-to-arch_vma_access_permitted.patch +iommu-exynos-suppress-unbinding-to-prevent-system-failure.patch +iommu-vt-d-return-error-code-in-domain_context_mapping_one.patch +iommu-io-pgtable-arm-fix-iova_to_phys-for-block-entries.patch +iommu-amd-handle-iommu_domain_dma-in-ops-domain_free-call-back.patch +iommu-amd-init-unity-mappings-only-for-dma_ops-domains.patch +iommu-amd-update-alias-dte-in-update_device_table.patch +audit-fix-a-double-fetch-in-audit_log_single_execve_arg.patch +arm-8561-3-dma-mapping-don-t-use-outer_flush_range-when-the-l2c-is-coherent.patch +arm-dts-sunxi-add-a-startup-delay-for-fixed-regulator-enabled-phys.patch +arm-dts-realview-fix-pbx-a9-cache-description.patch +arm-tegra-fix-erroneous-address-in-dts.patch +revert-arm-aspeed-adapt-defconfigs-for-new-config_printk_time.patch +cgroupns-fix-the-locking-in-copy_cgroup_ns.patch +cgroupns-close-race-between-cgroup_post_fork-and-copy_cgroup_ns.patch +cgroupns-only-allow-creation-of-hierarchies-in-the-initial-cgroup-namespace.patch +tpm_crb-fix-address-space-of-the-return-pointer-in-crb_map_res.patch +clk-rockchip-fix-incorrect-rk3399-spdif-dptx-divider-bits.patch +soc-qcom-smp2p-correct-addressing-of-outgoing-value.patch +netlabel-add-address-family-checks-to-netlbl_-sock-req-_delattr.patch +w1-omap_hdq-fix-regression.patch diff --git a/queue-4.7/soc-qcom-smp2p-correct-addressing-of-outgoing-value.patch b/queue-4.7/soc-qcom-smp2p-correct-addressing-of-outgoing-value.patch new file mode 100644 index 00000000000..0235f8ecec8 --- /dev/null +++ b/queue-4.7/soc-qcom-smp2p-correct-addressing-of-outgoing-value.patch @@ -0,0 +1,38 @@ +From 63af8e44eaa56ffe613628742a2642c4c2f1a029 Mon Sep 17 00:00:00 2001 +From: Bjorn Andersson +Date: Thu, 9 Jun 2016 17:22:56 -0700 +Subject: soc: qcom: smp2p: Correct addressing of outgoing value + +From: Bjorn Andersson + +commit 63af8e44eaa56ffe613628742a2642c4c2f1a029 upstream. + +The valid_entries index should not be incremented until after we have +acquired the pointer to the value, or we will read and write data one +item off. + +Fixes: 50e99641413e ("soc: qcom: smp2p: Qualcomm Shared Memory Point to Point") +Signed-off-by: Bjorn Andersson +Signed-off-by: Andy Gross +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/soc/qcom/smp2p.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/soc/qcom/smp2p.c ++++ b/drivers/soc/qcom/smp2p.c +@@ -344,11 +344,12 @@ static int qcom_smp2p_outbound_entry(str + /* Allocate an entry from the smem item */ + strlcpy(buf, entry->name, SMP2P_MAX_ENTRY_NAME); + memcpy_toio(out->entries[out->valid_entries].name, buf, SMP2P_MAX_ENTRY_NAME); +- out->valid_entries++; + + /* Make the logical entry reference the physical value */ + entry->value = &out->entries[out->valid_entries].value; + ++ out->valid_entries++; ++ + entry->state = qcom_smem_state_register(node, &smp2p_state_ops, entry); + if (IS_ERR(entry->state)) { + dev_err(smp2p->dev, "failed to register qcom_smem_state\n"); diff --git a/queue-4.7/tpm_crb-fix-address-space-of-the-return-pointer-in-crb_map_res.patch b/queue-4.7/tpm_crb-fix-address-space-of-the-return-pointer-in-crb_map_res.patch new file mode 100644 index 00000000000..799d6490904 --- /dev/null +++ b/queue-4.7/tpm_crb-fix-address-space-of-the-return-pointer-in-crb_map_res.patch @@ -0,0 +1,36 @@ +From f786b752098216fedb73ba2905c8cce12358534a Mon Sep 17 00:00:00 2001 +From: Jarkko Sakkinen +Date: Fri, 17 Jun 2016 16:39:29 +0200 +Subject: tpm_crb: fix address space of the return pointer in crb_map_res() + +From: Jarkko Sakkinen + +commit f786b752098216fedb73ba2905c8cce12358534a upstream. + +When running make C=2 M=drivers/char/tpm/ + + CHECK drivers/char/tpm//tpm_crb.c +drivers/char/tpm//tpm_crb.c:248:31: warning: incorrect type in return expression (different address spaces) +drivers/char/tpm//tpm_crb.c:248:31: expected void [noderef] * +drivers/char/tpm//tpm_crb.c:248:31: got void * + +Fixes: 1bd047be37d9 ("tpm_crb: Use devm_ioremap_resource") +Signed-off-by: Jarkko Sakkinen +Tested-by: Stefan Berger +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/char/tpm/tpm_crb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/drivers/char/tpm/tpm_crb.c ++++ b/drivers/char/tpm/tpm_crb.c +@@ -246,7 +246,7 @@ static void __iomem *crb_map_res(struct + + /* Detect a 64 bit address on a 32 bit system */ + if (start != new_res.start) +- return ERR_PTR(-EINVAL); ++ return (void __iomem *) ERR_PTR(-EINVAL); + + if (!resource_contains(&priv->res, &new_res)) + return devm_ioremap_resource(dev, &new_res); diff --git a/queue-4.7/unicore32-mm-add-missing-parameter-to-arch_vma_access_permitted.patch b/queue-4.7/unicore32-mm-add-missing-parameter-to-arch_vma_access_permitted.patch new file mode 100644 index 00000000000..7dccb8958c9 --- /dev/null +++ b/queue-4.7/unicore32-mm-add-missing-parameter-to-arch_vma_access_permitted.patch @@ -0,0 +1,47 @@ +From 783011b13095430262333fd64e17666954064664 Mon Sep 17 00:00:00 2001 +From: Guenter Roeck +Date: Mon, 21 Mar 2016 04:20:53 -0700 +Subject: unicore32: mm: Add missing parameter to arch_vma_access_permitted +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Guenter Roeck + +commit 783011b13095430262333fd64e17666954064664 upstream. + +unicore32 fails to compile with the following errors. + +mm/memory.c: In function ‘__handle_mm_fault’: +mm/memory.c:3381: error: + too many arguments to function ‘arch_vma_access_permitted’ +mm/gup.c: In function ‘check_vma_flags’: +mm/gup.c:456: error: + too many arguments to function ‘arch_vma_access_permitted’ +mm/gup.c: In function ‘vma_permits_fault’: +mm/gup.c:640: error: + too many arguments to function ‘arch_vma_access_permitted’ + +Fixes: d61172b4b695b ("mm/core, x86/mm/pkeys: Differentiate instruction fetches") +Cc: Dave Hansen +Cc: Thomas Gleixner +Cc: Ingo Molnar +Signed-off-by: Guenter Roeck +Acked-by: Guan Xuetao +Signed-off-by: Greg Kroah-Hartman + +--- + arch/unicore32/include/asm/mmu_context.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/unicore32/include/asm/mmu_context.h ++++ b/arch/unicore32/include/asm/mmu_context.h +@@ -98,7 +98,7 @@ static inline void arch_bprm_mm_init(str + } + + static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, +- bool write, bool foreign) ++ bool write, bool execute, bool foreign) + { + /* by default, allow everything */ + return true; diff --git a/queue-4.7/w1-omap_hdq-fix-regression.patch b/queue-4.7/w1-omap_hdq-fix-regression.patch new file mode 100644 index 00000000000..81825b7f67d --- /dev/null +++ b/queue-4.7/w1-omap_hdq-fix-regression.patch @@ -0,0 +1,52 @@ +From ecfaf0c42fc4306b5ec4bf6be01b66f8fe9a9733 Mon Sep 17 00:00:00 2001 +From: "H. Nikolaus Schaller" +Date: Tue, 2 Aug 2016 14:07:12 -0700 +Subject: w1:omap_hdq: fix regression + +From: H. Nikolaus Schaller + +commit ecfaf0c42fc4306b5ec4bf6be01b66f8fe9a9733 upstream. + +Commit e93762bbf681 ("w1: masters: omap_hdq: add support for 1-wire +mode") added a statement to clear the hdq_irqstatus flags in +hdq_read_byte(). + +If the hdq reading process is scheduled slowly or interrupts are +disabled for a while the hardware read activity might already be +finished on entry of hdq_read_byte(). And hdq_isr() already has set the +hdq_irqstatus to 0x6 (can be seen in debug mode) denoting that both, the +TXCOMPLETE and RXCOMPLETE interrupts occurred in parallel. + +This means there is no need to wait and the hdq_read_byte() can just +read the byte from the hdq controller. + +By resetting hdq_irqstatus to 0 the read process is forced to be always +waiting again (because the if statement always succeeds) but the +hardware will not issue another RXCOMPLETE interrupt. This results in a +false timeout. + +After such a situation the hdq bus hangs. + +Link: http://lkml.kernel.org/r/b724765f87ad276a69625bc19806c8c8844c4590.1469513669.git.hns@goldelico.com +Signed-off-by: H. Nikolaus Schaller +Cc: Evgeniy Polyakov +Cc: Greg Kroah-Hartman +Signed-off-by: Andrew Morton +Signed-off-by: Linus Torvalds +Signed-off-by: Greg Kroah-Hartman + +--- + drivers/w1/masters/omap_hdq.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/drivers/w1/masters/omap_hdq.c ++++ b/drivers/w1/masters/omap_hdq.c +@@ -390,8 +390,6 @@ static int hdq_read_byte(struct hdq_data + goto out; + } + +- hdq_data->hdq_irqstatus = 0; +- + if (!(hdq_data->hdq_irqstatus & OMAP_HDQ_INT_STATUS_RXCOMPLETE)) { + hdq_reg_merge(hdq_data, OMAP_HDQ_CTRL_STATUS, + OMAP_HDQ_CTRL_STATUS_DIR | OMAP_HDQ_CTRL_STATUS_GO,