diff options
-rw-r--r-- | 0001-xfs-enhance-dinode-verifier.patch | 72 | ||||
-rw-r--r-- | 0001-xfs-set-format-back-to-extents-if-xfs_bmap_extents_t.patch | 45 | ||||
-rw-r--r-- | ACPI-irq-Workaround-firmware-issue-on-X-Gene-based-m400.patch | 64 | ||||
-rw-r--r-- | KVM-vmx-update-sec-exec-controls-for-UMIP-iff-emulating-UMIP.patch | 84 | ||||
-rw-r--r-- | arm-tegra-USB-driver-dependency-fix.patch | 610 | ||||
-rw-r--r-- | arm64-fix-usercopy-whitelist.patch | 857 | ||||
-rw-r--r-- | baseconfig/arm/CONFIG_ARM64_ERRATUM_1024718 | 1 | ||||
-rw-r--r-- | baseconfig/arm/CONFIG_USB_TEGRA_PHY | 1 | ||||
-rw-r--r-- | baseconfig/arm/aarch64/CONFIG_MV_XOR_V2 | 2 | ||||
-rw-r--r-- | kernel-aarch64-debug.config | 4 | ||||
-rw-r--r-- | kernel-aarch64.config | 4 | ||||
-rw-r--r-- | kernel-armv7hl-debug.config | 2 | ||||
-rw-r--r-- | kernel-armv7hl-lpae-debug.config | 2 | ||||
-rw-r--r-- | kernel-armv7hl-lpae.config | 2 | ||||
-rw-r--r-- | kernel-armv7hl.config | 2 | ||||
-rw-r--r-- | kernel.spec | 48 | ||||
-rw-r--r-- | sources | 2 |
17 files changed, 1793 insertions, 9 deletions
diff --git a/0001-xfs-enhance-dinode-verifier.patch b/0001-xfs-enhance-dinode-verifier.patch new file mode 100644 index 000000000..230e79387 --- /dev/null +++ b/0001-xfs-enhance-dinode-verifier.patch @@ -0,0 +1,72 @@ +From b42db0860e13067fcc7cbfba3966c9e652668bbc Mon Sep 17 00:00:00 2001 +From: Eric Sandeen <sandeen@sandeen.net> +Date: Mon, 16 Apr 2018 23:06:53 -0700 +Subject: [PATCH] xfs: enhance dinode verifier + +Add several more validations to xfs_dinode_verify: + +- For LOCAL data fork formats, di_nextents must be 0. +- For LOCAL attr fork formats, di_anextents must be 0. +- For inodes with no attr fork offset, + - format must be XFS_DINODE_FMT_EXTENTS if set at all + - di_anextents must be 0. + +Thanks to dchinner for pointing out a couple related checks I had +forgotten to add. + +Signed-off-by: Eric Sandeen <sandeen@redhat.com> +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199377 +Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> +Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> +--- + fs/xfs/libxfs/xfs_inode_buf.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c +index ef68b1de006a..1201107eabc6 100644 +--- a/fs/xfs/libxfs/xfs_inode_buf.c ++++ b/fs/xfs/libxfs/xfs_inode_buf.c +@@ -466,6 +466,8 @@ xfs_dinode_verify( + return __this_address; + if (di_size > XFS_DFORK_DSIZE(dip, mp)) + return __this_address; ++ if (dip->di_nextents) ++ return __this_address; + /* fall through */ + case XFS_DINODE_FMT_EXTENTS: + case XFS_DINODE_FMT_BTREE: +@@ -484,12 +486,31 @@ xfs_dinode_verify( + if (XFS_DFORK_Q(dip)) { + switch (dip->di_aformat) { + case XFS_DINODE_FMT_LOCAL: ++ if (dip->di_anextents) ++ return __this_address; ++ /* fall through */ + case XFS_DINODE_FMT_EXTENTS: + case XFS_DINODE_FMT_BTREE: + break; + default: + return __this_address; + } ++ } else { ++ /* ++ * If there is no fork offset, this may be a freshly-made inode ++ * in a new disk cluster, in which case di_aformat is zeroed. ++ * Otherwise, such an inode must be in EXTENTS format; this goes ++ * for freed inodes as well. ++ */ ++ switch (dip->di_aformat) { ++ case 0: ++ case XFS_DINODE_FMT_EXTENTS: ++ break; ++ default: ++ return __this_address; ++ } ++ if (dip->di_anextents) ++ return __this_address; + } + + /* only version 3 or greater inodes are extensively verified here */ +-- +2.17.0 + diff --git a/0001-xfs-set-format-back-to-extents-if-xfs_bmap_extents_t.patch b/0001-xfs-set-format-back-to-extents-if-xfs_bmap_extents_t.patch new file mode 100644 index 000000000..9c6814c65 --- /dev/null +++ b/0001-xfs-set-format-back-to-extents-if-xfs_bmap_extents_t.patch @@ -0,0 +1,45 @@ +From 2c4306f719b083d17df2963bc761777576b8ad1b Mon Sep 17 00:00:00 2001 +From: Eric Sandeen <sandeen@redhat.com> +Date: Mon, 16 Apr 2018 23:07:27 -0700 +Subject: [PATCH] xfs: set format back to extents if xfs_bmap_extents_to_btree + +If xfs_bmap_extents_to_btree fails in a mode where we call +xfs_iroot_realloc(-1) to de-allocate the root, set the +format back to extents. + +Otherwise we can assume we can dereference ifp->if_broot +based on the XFS_DINODE_FMT_BTREE format, and crash. + +Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=199423 +Signed-off-by: Eric Sandeen <sandeen@redhat.com> +Reviewed-by: Christoph Hellwig <hch@lst.de> +Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com> +Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com> +--- + fs/xfs/libxfs/xfs_bmap.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/fs/xfs/libxfs/xfs_bmap.c b/fs/xfs/libxfs/xfs_bmap.c +index 6a7c2f03ea11..040eeda8426f 100644 +--- a/fs/xfs/libxfs/xfs_bmap.c ++++ b/fs/xfs/libxfs/xfs_bmap.c +@@ -725,12 +725,16 @@ xfs_bmap_extents_to_btree( + *logflagsp = 0; + if ((error = xfs_alloc_vextent(&args))) { + xfs_iroot_realloc(ip, -1, whichfork); ++ ASSERT(ifp->if_broot == NULL); ++ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return error; + } + + if (WARN_ON_ONCE(args.fsbno == NULLFSBLOCK)) { + xfs_iroot_realloc(ip, -1, whichfork); ++ ASSERT(ifp->if_broot == NULL); ++ XFS_IFORK_FMT_SET(ip, whichfork, XFS_DINODE_FMT_EXTENTS); + xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); + return -ENOSPC; + } +-- +2.17.0 + diff --git a/ACPI-irq-Workaround-firmware-issue-on-X-Gene-based-m400.patch b/ACPI-irq-Workaround-firmware-issue-on-X-Gene-based-m400.patch new file mode 100644 index 000000000..3dcfd4969 --- /dev/null +++ b/ACPI-irq-Workaround-firmware-issue-on-X-Gene-based-m400.patch @@ -0,0 +1,64 @@ +From dbdda4277cf0422a9ccb7ea98d0263c3cdbecdf6 Mon Sep 17 00:00:00 2001 +From: Mark Salter <msalter@redhat.com> +Date: Tue, 8 May 2018 21:54:39 -0400 +Subject: [PATCH] ACPI / irq: Workaround firmware issue on X-Gene based + m400 + +The ACPI firmware on the xgene-based m400 platorms erroneously +describes its UART interrupt as ACPI_PRODUCER rather than +ACPI_CONSUMER. This leads to the UART driver being unable to +find its interrupt and the kernel unable find a console. +Work around this by avoiding the producer/consumer check +for X-Gene UARTs. + +Signed-off-by: Mark Salter <msalter@redhat.com> +--- + drivers/acpi/irq.c | 17 +++++++++++++++-- + 1 file changed, 15 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/irq.c b/drivers/acpi/irq.c +index 7c352cba0528..028c1a564cff 100644 +--- a/drivers/acpi/irq.c ++++ b/drivers/acpi/irq.c +@@ -129,6 +129,7 @@ struct acpi_irq_parse_one_ctx { + unsigned int index; + unsigned long *res_flags; + struct irq_fwspec *fwspec; ++ bool skip_producer_check; + }; + + /** +@@ -200,7 +201,8 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares, + return AE_CTRL_TERMINATE; + case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: + eirq = &ares->data.extended_irq; +- if (eirq->producer_consumer == ACPI_PRODUCER) ++ if (!ctx->skip_producer_check && ++ eirq->producer_consumer == ACPI_PRODUCER) + return AE_OK; + if (ctx->index >= eirq->interrupt_count) { + ctx->index -= eirq->interrupt_count; +@@ -235,8 +237,19 @@ static acpi_status acpi_irq_parse_one_cb(struct acpi_resource *ares, + static int acpi_irq_parse_one(acpi_handle handle, unsigned int index, + struct irq_fwspec *fwspec, unsigned long *flags) + { +- struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec }; ++ struct acpi_irq_parse_one_ctx ctx = { -EINVAL, index, flags, fwspec, false }; + ++ /* ++ * Firmware on arm64-based HPE m400 platform incorrectly marks ++ * its UART interrupt as ACPI_PRODUCER rather than ACPI_CONSUMER. ++ * Don't do the producer/consumer check for that device. ++ */ ++ if (IS_ENABLED(CONFIG_ARM64)) { ++ struct acpi_device *adev = acpi_bus_get_acpi_device(handle); ++ ++ if (adev && !strcmp(acpi_device_hid(adev), "APMC0D08")) ++ ctx.skip_producer_check = true; ++ } + acpi_walk_resources(handle, METHOD_NAME__CRS, acpi_irq_parse_one_cb, &ctx); + return ctx.rc; + } +-- +2.17.0 + diff --git a/KVM-vmx-update-sec-exec-controls-for-UMIP-iff-emulating-UMIP.patch b/KVM-vmx-update-sec-exec-controls-for-UMIP-iff-emulating-UMIP.patch new file mode 100644 index 000000000..04ce255d2 --- /dev/null +++ b/KVM-vmx-update-sec-exec-controls-for-UMIP-iff-emulating-UMIP.patch @@ -0,0 +1,84 @@ +From f96625ad37248a2fb2616f39ee8dff3ebcab3247 Mon Sep 17 00:00:00 2001 +From: Sean Christopherson <sean.j.christopherson@intel.com> +Date: Mon, 30 Apr 2018 10:01:06 -0700 +Subject: [PATCH] KVM: vmx: update sec exec controls for UMIP iff emulating + UMIP +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Update SECONDARY_EXEC_DESC for UMIP emulation if and only UMIP +is actually being emulated. Skipping the VMCS update eliminates +unnecessary VMREAD/VMWRITE when UMIP is supported in hardware, +and on platforms that don't have SECONDARY_VM_EXEC_CONTROL. The +latter case resolves a bug where KVM would fill the kernel log +with warnings due to failed VMWRITEs on older platforms. + +Fixes: 0367f205a3b7 ("KVM: vmx: add support for emulating UMIP") +Cc: stable@vger.kernel.org #4.16 +Reported-by: Paolo Zeppegno <pzeppegno@gmail.com> +Suggested-by: Paolo Bonzini <pbonzini@redhat.com> +Suggested-by: Radim Krčmář <rkrcmar@redhat.com> +Signed-off-by: Sean Christopherson <sean.j.christopherson@intel.com> +Signed-off-by: Jeremy Cline <jeremy@jcline.org> +--- + arch/x86/kvm/vmx.c | 28 +++++++++++++++------------- + 1 file changed, 15 insertions(+), 13 deletions(-) + +diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c +index 657c93409042..4861811438ff 100644 +--- a/arch/x86/kvm/vmx.c ++++ b/arch/x86/kvm/vmx.c +@@ -1314,6 +1314,12 @@ static inline bool cpu_has_vmx_vmfunc(void) + SECONDARY_EXEC_ENABLE_VMFUNC; + } + ++static bool vmx_umip_emulated(void) ++{ ++ return vmcs_config.cpu_based_2nd_exec_ctrl & ++ SECONDARY_EXEC_DESC; ++} ++ + static inline bool report_flexpriority(void) + { + return flexpriority_enabled; +@@ -4494,14 +4500,16 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) + (to_vmx(vcpu)->rmode.vm86_active ? + KVM_RMODE_VM_CR4_ALWAYS_ON : KVM_PMODE_VM_CR4_ALWAYS_ON); + +- if ((cr4 & X86_CR4_UMIP) && !boot_cpu_has(X86_FEATURE_UMIP)) { +- vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL, +- SECONDARY_EXEC_DESC); +- hw_cr4 &= ~X86_CR4_UMIP; +- } else if (!is_guest_mode(vcpu) || +- !nested_cpu_has2(get_vmcs12(vcpu), SECONDARY_EXEC_DESC)) +- vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL, ++ if (!boot_cpu_has(X86_FEATURE_UMIP) && vmx_umip_emulated()) { ++ if (cr4 & X86_CR4_UMIP) { ++ vmcs_set_bits(SECONDARY_VM_EXEC_CONTROL, + SECONDARY_EXEC_DESC); ++ hw_cr4 &= ~X86_CR4_UMIP; ++ } else if (!is_guest_mode(vcpu) || ++ !nested_cpu_has2(get_vmcs12(vcpu), SECONDARY_EXEC_DESC)) ++ vmcs_clear_bits(SECONDARY_VM_EXEC_CONTROL, ++ SECONDARY_EXEC_DESC); ++ } + + if (cr4 & X86_CR4_VMXE) { + /* +@@ -9243,12 +9251,6 @@ static bool vmx_xsaves_supported(void) + SECONDARY_EXEC_XSAVES; + } + +-static bool vmx_umip_emulated(void) +-{ +- return vmcs_config.cpu_based_2nd_exec_ctrl & +- SECONDARY_EXEC_DESC; +-} +- + static void vmx_recover_nmi_blocking(struct vcpu_vmx *vmx) + { + u32 exit_intr_info; +-- +2.17.0 + diff --git a/arm-tegra-USB-driver-dependency-fix.patch b/arm-tegra-USB-driver-dependency-fix.patch new file mode 100644 index 000000000..b1a80137b --- /dev/null +++ b/arm-tegra-USB-driver-dependency-fix.patch @@ -0,0 +1,610 @@ +From patchwork Mon Apr 9 22:02:57 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3,1/3] usb: phy: tegra: Cleanup error messages +X-Patchwork-Submitter: Dmitry Osipenko <digetx@gmail.com> +X-Patchwork-Id: 896433 +Message-Id: <c08393c7ac6964d14750e8a4b0ffa34884b1416f.1523307883.git.digetx@gmail.com> +To: Thierry Reding <thierry.reding@gmail.com>, + Jonathan Hunter <jonathanh@nvidia.com>, Felipe Balbi <balbi@kernel.org>, + Alan Stern <stern@rowland.harvard.edu>, + Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org, + linux-kernel@vger.kernel.org +Date: Tue, 10 Apr 2018 01:02:57 +0300 +From: Dmitry Osipenko <digetx@gmail.com> +List-Id: <linux-tegra.vger.kernel.org> + +Tegra's PHY driver has a mix of pr_err() and dev_err(), let's switch to +dev_err() and use common errors message formatting across the driver for +consistency. + +Signed-off-by: Dmitry Osipenko <digetx@gmail.com> +--- + drivers/usb/phy/phy-tegra-usb.c | 69 ++++++++++++++++++++++++----------------- + 1 file changed, 41 insertions(+), 28 deletions(-) + +diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c +index 0e8d23e51732..e46219e7fa93 100644 +--- a/drivers/usb/phy/phy-tegra-usb.c ++++ b/drivers/usb/phy/phy-tegra-usb.c +@@ -236,10 +236,14 @@ static void set_phcd(struct tegra_usb_phy *phy, bool enable) + + static int utmip_pad_open(struct tegra_usb_phy *phy) + { ++ int err; ++ + phy->pad_clk = devm_clk_get(phy->u_phy.dev, "utmi-pads"); + if (IS_ERR(phy->pad_clk)) { +- pr_err("%s: can't get utmip pad clock\n", __func__); +- return PTR_ERR(phy->pad_clk); ++ err = PTR_ERR(phy->pad_clk); ++ dev_err(phy->u_phy.dev, ++ "Failed to get UTMIP pad clock: %d\n", err); ++ return err; + } + + return 0; +@@ -282,7 +286,7 @@ static int utmip_pad_power_off(struct tegra_usb_phy *phy) + void __iomem *base = phy->pad_regs; + + if (!utmip_pad_count) { +- pr_err("%s: utmip pad already powered off\n", __func__); ++ dev_err(phy->u_phy.dev, "UTMIP pad already powered off\n"); + return -EINVAL; + } + +@@ -338,7 +342,8 @@ static void utmi_phy_clk_disable(struct tegra_usb_phy *phy) + set_phcd(phy, true); + + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, 0) < 0) +- pr_err("%s: timeout waiting for phy to stabilize\n", __func__); ++ dev_err(phy->u_phy.dev, ++ "Timeout waiting for PHY to stabilize on disable\n"); + } + + static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) +@@ -370,7 +375,8 @@ static void utmi_phy_clk_enable(struct tegra_usb_phy *phy) + + if (utmi_wait_register(base + USB_SUSP_CTRL, USB_PHY_CLK_VALID, + USB_PHY_CLK_VALID)) +- pr_err("%s: timeout waiting for phy to stabilize\n", __func__); ++ dev_err(phy->u_phy.dev, ++ "Timeout waiting for PHY to stabilize on enable\n"); + } + + static int utmi_phy_power_on(struct tegra_usb_phy *phy) +@@ -617,15 +623,15 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy) + + ret = gpio_direction_output(phy->reset_gpio, 0); + if (ret < 0) { +- dev_err(phy->u_phy.dev, "gpio %d not set to 0\n", +- phy->reset_gpio); ++ dev_err(phy->u_phy.dev, "GPIO %d not set to 0: %d\n", ++ phy->reset_gpio, ret); + return ret; + } + msleep(5); + ret = gpio_direction_output(phy->reset_gpio, 1); + if (ret < 0) { +- dev_err(phy->u_phy.dev, "gpio %d not set to 1\n", +- phy->reset_gpio); ++ dev_err(phy->u_phy.dev, "GPIO %d not set to 1: %d\n", ++ phy->reset_gpio, ret); + return ret; + } + +@@ -661,13 +667,13 @@ static int ulpi_phy_power_on(struct tegra_usb_phy *phy) + /* Fix VbusInvalid due to floating VBUS */ + ret = usb_phy_io_write(phy->ulpi, 0x40, 0x08); + if (ret) { +- pr_err("%s: ulpi write failed\n", __func__); ++ dev_err(phy->u_phy.dev, "ULPI write failed: %d\n", ret); + return ret; + } + + ret = usb_phy_io_write(phy->ulpi, 0x80, 0x0B); + if (ret) { +- pr_err("%s: ulpi write failed\n", __func__); ++ dev_err(phy->u_phy.dev, "ULPI write failed: %d\n", ret); + return ret; + } + +@@ -728,28 +734,30 @@ static int ulpi_open(struct tegra_usb_phy *phy) + + phy->clk = devm_clk_get(phy->u_phy.dev, "ulpi-link"); + if (IS_ERR(phy->clk)) { +- pr_err("%s: can't get ulpi clock\n", __func__); +- return PTR_ERR(phy->clk); ++ err = PTR_ERR(phy->clk); ++ dev_err(phy->u_phy.dev, "Failed to get ULPI clock: %d\n", err); ++ return err; + } + + err = devm_gpio_request(phy->u_phy.dev, phy->reset_gpio, + "ulpi_phy_reset_b"); + if (err < 0) { +- dev_err(phy->u_phy.dev, "request failed for gpio: %d\n", +- phy->reset_gpio); ++ dev_err(phy->u_phy.dev, "Request failed for GPIO %d: %d\n", ++ phy->reset_gpio, err); + return err; + } + + err = gpio_direction_output(phy->reset_gpio, 0); + if (err < 0) { +- dev_err(phy->u_phy.dev, "gpio %d direction not set to output\n", +- phy->reset_gpio); ++ dev_err(phy->u_phy.dev, ++ "GPIO %d direction not set to output: %d\n", ++ phy->reset_gpio, err); + return err; + } + + phy->ulpi = otg_ulpi_create(&ulpi_viewport_access_ops, 0); + if (!phy->ulpi) { +- dev_err(phy->u_phy.dev, "otg_ulpi_create returned NULL\n"); ++ dev_err(phy->u_phy.dev, "Failed to create ULPI OTG\n"); + err = -ENOMEM; + return err; + } +@@ -766,8 +774,10 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy) + + phy->pll_u = devm_clk_get(phy->u_phy.dev, "pll_u"); + if (IS_ERR(phy->pll_u)) { +- pr_err("Can't get pll_u clock\n"); +- return PTR_ERR(phy->pll_u); ++ err = PTR_ERR(phy->pll_u); ++ dev_err(phy->u_phy.dev, ++ "Failed to get pll_u clock: %d\n", err); ++ return err; + } + + err = clk_prepare_enable(phy->pll_u); +@@ -782,7 +792,8 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy) + } + } + if (!phy->freq) { +- pr_err("invalid pll_u parent rate %ld\n", parent_rate); ++ dev_err(phy->u_phy.dev, "Invalid pll_u parent rate %ld\n", ++ parent_rate); + err = -EINVAL; + goto fail; + } +@@ -791,7 +802,7 @@ static int tegra_usb_phy_init(struct tegra_usb_phy *phy) + err = regulator_enable(phy->vbus); + if (err) { + dev_err(phy->u_phy.dev, +- "failed to enable usb vbus regulator: %d\n", ++ "Failed to enable USB VBUS regulator: %d\n", + err); + goto fail; + } +@@ -855,7 +866,8 @@ static int read_utmi_param(struct platform_device *pdev, const char *param, + int err = of_property_read_u32(pdev->dev.of_node, param, &value); + *dest = (u8)value; + if (err < 0) +- dev_err(&pdev->dev, "Failed to read USB UTMI parameter %s: %d\n", ++ dev_err(&pdev->dev, ++ "Failed to read USB UTMI parameter %s: %d\n", + param, err); + return err; + } +@@ -871,14 +883,14 @@ static int utmi_phy_probe(struct tegra_usb_phy *tegra_phy, + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) { +- dev_err(&pdev->dev, "Failed to get UTMI Pad regs\n"); ++ dev_err(&pdev->dev, "Failed to get UTMI pad regs\n"); + return -ENXIO; + } + + tegra_phy->pad_regs = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + if (!tegra_phy->pad_regs) { +- dev_err(&pdev->dev, "Failed to remap UTMI Pad regs\n"); ++ dev_err(&pdev->dev, "Failed to remap UTMI pad regs\n"); + return -ENOMEM; + } + +@@ -1020,15 +1032,16 @@ static int tegra_usb_phy_probe(struct platform_device *pdev) + tegra_phy->reset_gpio = + of_get_named_gpio(np, "nvidia,phy-reset-gpio", 0); + if (!gpio_is_valid(tegra_phy->reset_gpio)) { +- dev_err(&pdev->dev, "invalid gpio: %d\n", +- tegra_phy->reset_gpio); ++ dev_err(&pdev->dev, ++ "Invalid GPIO: %d\n", tegra_phy->reset_gpio); + return tegra_phy->reset_gpio; + } + tegra_phy->config = NULL; + break; + + default: +- dev_err(&pdev->dev, "phy_type is invalid or unsupported\n"); ++ dev_err(&pdev->dev, "phy_type %u is invalid or unsupported\n", ++ phy_type); + return -EINVAL; + } + + +From patchwork Mon Apr 9 22:02:58 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3, + 2/3] usb: tegra: Move utmi-pads reset from ehci-tegra to tegra-phy +X-Patchwork-Submitter: Dmitry Osipenko <digetx@gmail.com> +X-Patchwork-Id: 896435 +Message-Id: <66330166c6a53e8f463ec231e3cb8195fa3036cc.1523307883.git.digetx@gmail.com> +To: Thierry Reding <thierry.reding@gmail.com>, + Jonathan Hunter <jonathanh@nvidia.com>, Felipe Balbi <balbi@kernel.org>, + Alan Stern <stern@rowland.harvard.edu>, + Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org, + linux-kernel@vger.kernel.org +Date: Tue, 10 Apr 2018 01:02:58 +0300 +From: Dmitry Osipenko <digetx@gmail.com> +List-Id: <linux-tegra.vger.kernel.org> + +UTMI pads are shared by USB controllers and reset of UTMI pads is shared +with the reset of USB1 controller. Currently reset of UTMI pads is done by +the EHCI driver and ChipIdea UDC works because EHCI driver always happen +to be probed first. Move reset controls from ehci-tegra to tegra-phy in +order to resolve the problem. + +Signed-off-by: Dmitry Osipenko <digetx@gmail.com> +--- + drivers/usb/host/ehci-tegra.c | 87 ++++++++++++++++++--------------------- + drivers/usb/phy/phy-tegra-usb.c | 79 ++++++++++++++++++++++++++++++++--- + include/linux/usb/tegra_usb_phy.h | 2 + + 3 files changed, 115 insertions(+), 53 deletions(-) + +diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c +index a6f4389f7e88..4d2cdec4cb78 100644 +--- a/drivers/usb/host/ehci-tegra.c ++++ b/drivers/usb/host/ehci-tegra.c +@@ -36,7 +36,6 @@ + #define DRV_NAME "tegra-ehci" + + static struct hc_driver __read_mostly tegra_ehci_hc_driver; +-static bool usb1_reset_attempted; + + struct tegra_ehci_soc_config { + bool has_hostpc; +@@ -51,67 +50,54 @@ struct tegra_ehci_hcd { + enum tegra_usb_phy_port_speed port_speed; + }; + +-/* +- * The 1st USB controller contains some UTMI pad registers that are global for +- * all the controllers on the chip. Those registers are also cleared when +- * reset is asserted to the 1st controller. This means that the 1st controller +- * can only be reset when no other controlled has finished probing. So we'll +- * reset the 1st controller before doing any other setup on any of the +- * controllers, and then never again. +- * +- * Since this is a PHY issue, the Tegra PHY driver should probably be doing +- * the resetting of the USB controllers. But to keep compatibility with old +- * device trees that don't have reset phandles in the PHYs, do it here. +- * Those old DTs will be vulnerable to total USB breakage if the 1st EHCI +- * device isn't the first one to finish probing, so warn them. +- */ + static int tegra_reset_usb_controller(struct platform_device *pdev) + { + struct device_node *phy_np; + struct usb_hcd *hcd = platform_get_drvdata(pdev); + struct tegra_ehci_hcd *tegra = + (struct tegra_ehci_hcd *)hcd_to_ehci(hcd)->priv; +- bool has_utmi_pad_registers = false; ++ struct reset_control *rst; ++ int err; + + phy_np = of_parse_phandle(pdev->dev.of_node, "nvidia,phy", 0); + if (!phy_np) + return -ENOENT; + +- if (of_property_read_bool(phy_np, "nvidia,has-utmi-pad-registers")) +- has_utmi_pad_registers = true; ++ /* ++ * The 1st USB controller contains some UTMI pad registers that are ++ * global for all the controllers on the chip. Those registers are ++ * also cleared when reset is asserted to the 1st controller. ++ */ ++ rst = of_reset_control_get_shared(phy_np, "utmi-pads"); ++ if (IS_ERR(rst)) { ++ dev_warn(&pdev->dev, ++ "can't get utmi-pads reset from the PHY\n"); ++ dev_warn(&pdev->dev, ++ "continuing, but please update your DT\n"); ++ } else { ++ /* ++ * PHY driver performs UTMI-pads reset in a case of ++ * non-legacy DT. ++ */ ++ reset_control_put(rst); ++ } + +- if (!usb1_reset_attempted) { +- struct reset_control *usb1_reset; ++ of_node_put(phy_np); + +- if (!has_utmi_pad_registers) +- usb1_reset = of_reset_control_get(phy_np, "utmi-pads"); +- else +- usb1_reset = tegra->rst; +- +- if (IS_ERR(usb1_reset)) { +- dev_warn(&pdev->dev, +- "can't get utmi-pads reset from the PHY\n"); +- dev_warn(&pdev->dev, +- "continuing, but please update your DT\n"); +- } else { +- reset_control_assert(usb1_reset); +- udelay(1); +- reset_control_deassert(usb1_reset); +- +- if (!has_utmi_pad_registers) +- reset_control_put(usb1_reset); +- } ++ /* reset control is shared, hence initialize it first */ ++ err = reset_control_deassert(tegra->rst); ++ if (err) ++ return err; + +- usb1_reset_attempted = true; +- } ++ err = reset_control_assert(tegra->rst); ++ if (err) ++ return err; + +- if (!has_utmi_pad_registers) { +- reset_control_assert(tegra->rst); +- udelay(1); +- reset_control_deassert(tegra->rst); +- } ++ udelay(1); + +- of_node_put(phy_np); ++ err = reset_control_deassert(tegra->rst); ++ if (err) ++ return err; + + return 0; + } +@@ -440,7 +426,7 @@ static int tegra_ehci_probe(struct platform_device *pdev) + goto cleanup_hcd_create; + } + +- tegra->rst = devm_reset_control_get(&pdev->dev, "usb"); ++ tegra->rst = devm_reset_control_get_shared(&pdev->dev, "usb"); + if (IS_ERR(tegra->rst)) { + dev_err(&pdev->dev, "Can't get ehci reset\n"); + err = PTR_ERR(tegra->rst); +@@ -452,8 +438,10 @@ static int tegra_ehci_probe(struct platform_device *pdev) + goto cleanup_hcd_create; + + err = tegra_reset_usb_controller(pdev); +- if (err) ++ if (err) { ++ dev_err(&pdev->dev, "Failed to reset controller\n"); + goto cleanup_clk_en; ++ } + + u_phy = devm_usb_get_phy_by_phandle(&pdev->dev, "nvidia,phy", 0); + if (IS_ERR(u_phy)) { +@@ -538,6 +526,9 @@ static int tegra_ehci_remove(struct platform_device *pdev) + usb_phy_shutdown(hcd->usb_phy); + usb_remove_hcd(hcd); + ++ reset_control_assert(tegra->rst); ++ udelay(1); ++ + clk_disable_unprepare(tegra->clk); + + usb_put_hcd(hcd); +diff --git a/drivers/usb/phy/phy-tegra-usb.c b/drivers/usb/phy/phy-tegra-usb.c +index e46219e7fa93..ea7ef1dc0b42 100644 +--- a/drivers/usb/phy/phy-tegra-usb.c ++++ b/drivers/usb/phy/phy-tegra-usb.c +@@ -236,17 +236,83 @@ static void set_phcd(struct tegra_usb_phy *phy, bool enable) + + static int utmip_pad_open(struct tegra_usb_phy *phy) + { +- int err; ++ int ret; + + phy->pad_clk = devm_clk_get(phy->u_phy.dev, "utmi-pads"); + if (IS_ERR(phy->pad_clk)) { +- err = PTR_ERR(phy->pad_clk); ++ ret = PTR_ERR(phy->pad_clk); + dev_err(phy->u_phy.dev, +- "Failed to get UTMIP pad clock: %d\n", err); +- return err; ++ "Failed to get UTMIP pad clock: %d\n", ret); ++ return ret; + } + +- return 0; ++ phy->pad_rst = devm_reset_control_get_optional_shared( ++ phy->u_phy.dev, "utmi-pads"); ++ if (IS_ERR(phy->pad_rst)) { ++ ret = PTR_ERR(phy->pad_rst); ++ dev_err(phy->u_phy.dev, ++ "Failed to get UTMI-pads reset: %d\n", ret); ++ return ret; ++ } ++ ++ ret = clk_prepare_enable(phy->pad_clk); ++ if (ret) { ++ dev_err(phy->u_phy.dev, ++ "Failed to enable UTMI-pads clock: %d\n", ret); ++ return ret; ++ } ++ ++ spin_lock(&utmip_pad_lock); ++ ++ ret = reset_control_deassert(phy->pad_rst); ++ if (ret) { ++ dev_err(phy->u_phy.dev, ++ "Failed to initialize UTMI-pads reset: %d\n", ret); ++ goto unlock; ++ } ++ ++ ret = reset_control_assert(phy->pad_rst); ++ if (ret) { ++ dev_err(phy->u_phy.dev, ++ "Failed to assert UTMI-pads reset: %d\n", ret); ++ goto unlock; ++ } ++ ++ udelay(1); ++ ++ ret = reset_control_deassert(phy->pad_rst); ++ if (ret) ++ dev_err(phy->u_phy.dev, ++ "Failed to deassert UTMI-pads reset: %d\n", ret); ++unlock: ++ spin_unlock(&utmip_pad_lock); ++ ++ clk_disable_unprepare(phy->pad_clk); ++ ++ return ret; ++} ++ ++static int utmip_pad_close(struct tegra_usb_phy *phy) ++{ ++ int ret; ++ ++ ret = clk_prepare_enable(phy->pad_clk); ++ if (ret) { ++ dev_err(phy->u_phy.dev, ++ "Failed to enable UTMI-pads clock: %d\n", ret); ++ return ret; ++ } ++ ++ ret = reset_control_assert(phy->pad_rst); ++ if (ret) ++ dev_err(phy->u_phy.dev, ++ "Failed to assert UTMI-pads reset: %d\n", ret); ++ ++ udelay(1); ++ ++ clk_disable_unprepare(phy->pad_clk); ++ ++ return ret; + } + + static void utmip_pad_power_on(struct tegra_usb_phy *phy) +@@ -700,6 +766,9 @@ static void tegra_usb_phy_close(struct tegra_usb_phy *phy) + if (!IS_ERR(phy->vbus)) + regulator_disable(phy->vbus); + ++ if (!phy->is_ulpi_phy) ++ utmip_pad_close(phy); ++ + clk_disable_unprepare(phy->pll_u); + } + +diff --git a/include/linux/usb/tegra_usb_phy.h b/include/linux/usb/tegra_usb_phy.h +index d641ea1660b7..0c5c3ea8b2d7 100644 +--- a/include/linux/usb/tegra_usb_phy.h ++++ b/include/linux/usb/tegra_usb_phy.h +@@ -17,6 +17,7 @@ + #define __TEGRA_USB_PHY_H + + #include <linux/clk.h> ++#include <linux/reset.h> + #include <linux/usb/otg.h> + + /* +@@ -76,6 +77,7 @@ struct tegra_usb_phy { + bool is_legacy_phy; + bool is_ulpi_phy; + int reset_gpio; ++ struct reset_control *pad_rst; + }; + + void tegra_usb_phy_preresume(struct usb_phy *phy); + +From patchwork Mon Apr 9 22:02:59 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v3,3/3] usb: phy: Add Kconfig entry for Tegra PHY driver +X-Patchwork-Submitter: Dmitry Osipenko <digetx@gmail.com> +X-Patchwork-Id: 896434 +Message-Id: <aad79a65528636ee5fd217cfb7273de10147fc13.1523307883.git.digetx@gmail.com> +To: Thierry Reding <thierry.reding@gmail.com>, + Jonathan Hunter <jonathanh@nvidia.com>, Felipe Balbi <balbi@kernel.org>, + Alan Stern <stern@rowland.harvard.edu>, + Greg Kroah-Hartman <gregkh@linuxfoundation.org> +Cc: linux-usb@vger.kernel.org, linux-tegra@vger.kernel.org, + linux-kernel@vger.kernel.org +Date: Tue, 10 Apr 2018 01:02:59 +0300 +From: Dmitry Osipenko <digetx@gmail.com> +List-Id: <linux-tegra.vger.kernel.org> + +Tegra's EHCI driver has a build dependency on Tegra's PHY driver and +currently Tegra's PHY driver is built only when Tegra's EHCI driver is +built. Add own Kconfig entry for the Tegra's PHY driver so that drivers +other than ehci-tegra (like ChipIdea UDC) could work with ehci-tegra +driver being disabled in kernels config by allowing user to manually +select the PHY driver. + +Signed-off-by: Dmitry Osipenko <digetx@gmail.com> +--- + drivers/usb/host/Kconfig | 4 +--- + drivers/usb/phy/Kconfig | 9 +++++++++ + drivers/usb/phy/Makefile | 2 +- + 3 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig +index 5d958da8e1bc..9f0aeb068acb 100644 +--- a/drivers/usb/host/Kconfig ++++ b/drivers/usb/host/Kconfig +@@ -234,9 +234,7 @@ config USB_EHCI_TEGRA + tristate "NVIDIA Tegra HCD support" + depends on ARCH_TEGRA + select USB_EHCI_ROOT_HUB_TT +- select USB_PHY +- select USB_ULPI +- select USB_ULPI_VIEWPORT ++ select USB_TEGRA_PHY + help + This driver enables support for the internal USB Host Controllers + found in NVIDIA Tegra SoCs. The controllers are EHCI compliant. +diff --git a/drivers/usb/phy/Kconfig b/drivers/usb/phy/Kconfig +index 0f8ab981d572..b9b0a44be679 100644 +--- a/drivers/usb/phy/Kconfig ++++ b/drivers/usb/phy/Kconfig +@@ -159,6 +159,15 @@ config USB_MXS_PHY + + MXS Phy is used by some of the i.MX SoCs, for example imx23/28/6x. + ++config USB_TEGRA_PHY ++ tristate "NVIDIA Tegra USB PHY Driver" ++ depends on ARCH_TEGRA ++ select USB_PHY ++ select USB_ULPI ++ help ++ This driver provides PHY support for the USB controllers found ++ on NVIDIA Tegra SoC's. ++ + config USB_ULPI + bool "Generic ULPI Transceiver Driver" + depends on ARM || ARM64 +diff --git a/drivers/usb/phy/Makefile b/drivers/usb/phy/Makefile +index 25e579fb92b8..df1d99010079 100644 +--- a/drivers/usb/phy/Makefile ++++ b/drivers/usb/phy/Makefile +@@ -16,7 +16,7 @@ obj-$(CONFIG_AM335X_CONTROL_USB) += phy-am335x-control.o + obj-$(CONFIG_AM335X_PHY_USB) += phy-am335x.o + obj-$(CONFIG_OMAP_OTG) += phy-omap-otg.o + obj-$(CONFIG_TWL6030_USB) += phy-twl6030-usb.o +-obj-$(CONFIG_USB_EHCI_TEGRA) += phy-tegra-usb.o ++obj-$(CONFIG_USB_TEGRA_PHY) += phy-tegra-usb.o + obj-$(CONFIG_USB_GPIO_VBUS) += phy-gpio-vbus-usb.o + obj-$(CONFIG_USB_ISP1301) += phy-isp1301.o + obj-$(CONFIG_USB_MV_OTG) += phy-mv-usb.o diff --git a/arm64-fix-usercopy-whitelist.patch b/arm64-fix-usercopy-whitelist.patch new file mode 100644 index 000000000..cf66dd1b3 --- /dev/null +++ b/arm64-fix-usercopy-whitelist.patch @@ -0,0 +1,857 @@ +From patchwork Wed Mar 28 09:50:48 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v2,1/2] arm64: fpsimd: Split cpu field out from struct fpsimd_state +From: Dave P Martin <Dave.Martin@arm.com> +X-Patchwork-Id: 10312693 +Message-Id: <1522230649-22008-2-git-send-email-Dave.Martin@arm.com> +To: linux-arm-kernel@lists.infradead.org +Cc: Mark Rutland <mark.rutland@arm.com>, Will Deacon <will.deacon@arm.com>, + Kees Cook <keescook@chromium.org> +Date: Wed, 28 Mar 2018 10:50:48 +0100 + +In preparation for using a common representation of the FPSIMD +state for tasks and KVM vcpus, this patch separates out the "cpu" +field that is used to track the cpu on which the state was most +recently loaded. + +This will allow common code to operate on task and vcpu contexts +without requiring the cpu field to be stored at the same offset +from the FPSIMD register data in both cases. This should avoid the +need for messing with the definition of those parts of struct +vcpu_arch that are exposed in the KVM user ABI. + +The resulting change is also convenient for grouping and defining +the set of thread_struct fields that are supposed to be accessible +to copy_{to,from}_user(), which includes user_fpsimd_state but +should exclude the cpu field. This patch does not amend the +usercopy whitelist to match: that will be addressed in a subsequent +patch. + +Signed-off-by: Dave Martin <Dave.Martin@arm.com> +--- + arch/arm64/include/asm/fpsimd.h | 29 ++------------------------ + arch/arm64/include/asm/processor.h | 4 ++-- + arch/arm64/kernel/fpsimd.c | 42 +++++++++++++++++++++----------------- + arch/arm64/kernel/ptrace.c | 10 ++++----- + arch/arm64/kernel/signal.c | 3 +-- + arch/arm64/kernel/signal32.c | 3 +-- + 6 files changed, 34 insertions(+), 57 deletions(-) + +diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h +index 8857a0f..1bfc920 100644 +--- a/arch/arm64/include/asm/fpsimd.h ++++ b/arch/arm64/include/asm/fpsimd.h +@@ -24,31 +24,6 @@ + #include <linux/cache.h> + #include <linux/stddef.h> + +-/* +- * FP/SIMD storage area has: +- * - FPSR and FPCR +- * - 32 128-bit data registers +- * +- * Note that user_fpsimd forms a prefix of this structure, which is +- * relied upon in the ptrace FP/SIMD accessors. +- */ +-struct fpsimd_state { +- union { +- struct user_fpsimd_state user_fpsimd; +- struct { +- __uint128_t vregs[32]; +- u32 fpsr; +- u32 fpcr; +- /* +- * For ptrace compatibility, pad to next 128-bit +- * boundary here if extending this struct. +- */ +- }; +- }; +- /* the id of the last cpu to have restored this state */ +- unsigned int cpu; +-}; +- + #if defined(__KERNEL__) && defined(CONFIG_COMPAT) + /* Masks for extracting the FPSR and FPCR from the FPSCR */ + #define VFP_FPSCR_STAT_MASK 0xf800009f +@@ -62,8 +37,8 @@ struct fpsimd_state { + + struct task_struct; + +-extern void fpsimd_save_state(struct fpsimd_state *state); +-extern void fpsimd_load_state(struct fpsimd_state *state); ++extern void fpsimd_save_state(struct user_fpsimd_state *state); ++extern void fpsimd_load_state(struct user_fpsimd_state *state); + + extern void fpsimd_thread_switch(struct task_struct *next); + extern void fpsimd_flush_thread(void); +diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h +index fce604e..4a04535 100644 +--- a/arch/arm64/include/asm/processor.h ++++ b/arch/arm64/include/asm/processor.h +@@ -37,7 +37,6 @@ + #include <linux/string.h> + + #include <asm/alternative.h> +-#include <asm/fpsimd.h> + #include <asm/hw_breakpoint.h> + #include <asm/lse.h> + #include <asm/pgtable-hwdef.h> +@@ -107,7 +106,8 @@ struct thread_struct { + #ifdef CONFIG_COMPAT + unsigned long tp2_value; + #endif +- struct fpsimd_state fpsimd_state; ++ struct user_fpsimd_state fpsimd_state; ++ unsigned int fpsimd_cpu; + void *sve_state; /* SVE registers, if any */ + unsigned int sve_vl; /* SVE vector length */ + unsigned int sve_vl_onexec; /* SVE vl after next exec */ +diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c +index e7226c4..c4be311 100644 +--- a/arch/arm64/kernel/fpsimd.c ++++ b/arch/arm64/kernel/fpsimd.c +@@ -64,7 +64,7 @@ + * been loaded into its FPSIMD registers most recently, or whether it has + * been used to perform kernel mode NEON in the meantime. + * +- * For (a), we add a 'cpu' field to struct fpsimd_state, which gets updated to ++ * For (a), we add a fpsimd_cpu field to thread_struct, which gets updated to + * the id of the current CPU every time the state is loaded onto a CPU. For (b), + * we add the per-cpu variable 'fpsimd_last_state' (below), which contains the + * address of the userland FPSIMD state of the task that was loaded onto the CPU +@@ -73,7 +73,7 @@ + * With this in place, we no longer have to restore the next FPSIMD state right + * when switching between tasks. Instead, we can defer this check to userland + * resume, at which time we verify whether the CPU's fpsimd_last_state and the +- * task's fpsimd_state.cpu are still mutually in sync. If this is the case, we ++ * task's fpsimd_cpu are still mutually in sync. If this is the case, we + * can omit the FPSIMD restore. + * + * As an optimization, we use the thread_info flag TIF_FOREIGN_FPSTATE to +@@ -90,14 +90,14 @@ + * flag with local_bh_disable() unless softirqs are already masked. + * + * For a certain task, the sequence may look something like this: +- * - the task gets scheduled in; if both the task's fpsimd_state.cpu field ++ * - the task gets scheduled in; if both the task's fpsimd_cpu field + * contains the id of the current CPU, and the CPU's fpsimd_last_state per-cpu + * variable points to the task's fpsimd_state, the TIF_FOREIGN_FPSTATE flag is + * cleared, otherwise it is set; + * + * - the task returns to userland; if TIF_FOREIGN_FPSTATE is set, the task's + * userland FPSIMD state is copied from memory to the registers, the task's +- * fpsimd_state.cpu field is set to the id of the current CPU, the current ++ * fpsimd_cpu field is set to the id of the current CPU, the current + * CPU's fpsimd_last_state pointer is set to this task's fpsimd_state and the + * TIF_FOREIGN_FPSTATE flag is cleared; + * +@@ -115,7 +115,7 @@ + * whatever is in the FPSIMD registers is not saved to memory, but discarded. + */ + struct fpsimd_last_state_struct { +- struct fpsimd_state *st; ++ struct user_fpsimd_state *st; + bool sve_in_use; + }; + +@@ -417,7 +417,7 @@ static void fpsimd_to_sve(struct task_struct *task) + { + unsigned int vq; + void *sst = task->thread.sve_state; +- struct fpsimd_state const *fst = &task->thread.fpsimd_state; ++ struct user_fpsimd_state const *fst = &task->thread.fpsimd_state; + unsigned int i; + + if (!system_supports_sve()) +@@ -443,7 +443,7 @@ static void sve_to_fpsimd(struct task_struct *task) + { + unsigned int vq; + void const *sst = task->thread.sve_state; +- struct fpsimd_state *fst = &task->thread.fpsimd_state; ++ struct user_fpsimd_state *fst = &task->thread.fpsimd_state; + unsigned int i; + + if (!system_supports_sve()) +@@ -539,7 +539,7 @@ void sve_sync_from_fpsimd_zeropad(struct task_struct *task) + { + unsigned int vq; + void *sst = task->thread.sve_state; +- struct fpsimd_state const *fst = &task->thread.fpsimd_state; ++ struct user_fpsimd_state const *fst = &task->thread.fpsimd_state; + unsigned int i; + + if (!test_tsk_thread_flag(task, TIF_SVE)) +@@ -908,10 +908,9 @@ void fpsimd_thread_switch(struct task_struct *next) + * the TIF_FOREIGN_FPSTATE flag so the state will be loaded + * upon the next return to userland. + */ +- struct fpsimd_state *st = &next->thread.fpsimd_state; +- +- if (__this_cpu_read(fpsimd_last_state.st) == st +- && st->cpu == smp_processor_id()) ++ if (__this_cpu_read(fpsimd_last_state.st) == ++ &next->thread.fpsimd_state ++ && next->thread.fpsimd_cpu == smp_processor_id()) + clear_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); + else + set_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); +@@ -927,7 +926,8 @@ void fpsimd_flush_thread(void) + + local_bh_disable(); + +- memset(¤t->thread.fpsimd_state, 0, sizeof(struct fpsimd_state)); ++ memset(¤t->thread.fpsimd_state, 0, ++ sizeof current->thread.fpsimd_state); + fpsimd_flush_task_state(current); + + if (system_supports_sve()) { +@@ -1004,11 +1004,10 @@ static void fpsimd_bind_to_cpu(void) + { + struct fpsimd_last_state_struct *last = + this_cpu_ptr(&fpsimd_last_state); +- struct fpsimd_state *st = ¤t->thread.fpsimd_state; + +- last->st = st; ++ last->st = ¤t->thread.fpsimd_state; + last->sve_in_use = test_thread_flag(TIF_SVE); +- st->cpu = smp_processor_id(); ++ current->thread.fpsimd_cpu = smp_processor_id(); + } + + /* +@@ -1043,7 +1042,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state) + + local_bh_disable(); + +- current->thread.fpsimd_state.user_fpsimd = *state; ++ current->thread.fpsimd_state = *state; + if (system_supports_sve() && test_thread_flag(TIF_SVE)) + fpsimd_to_sve(current); + +@@ -1055,12 +1054,17 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state) + local_bh_enable(); + } + ++void fpsimd_flush_state(unsigned int *cpu) ++{ ++ *cpu = NR_CPUS; ++} ++ + /* + * Invalidate live CPU copies of task t's FPSIMD state + */ + void fpsimd_flush_task_state(struct task_struct *t) + { +- t->thread.fpsimd_state.cpu = NR_CPUS; ++ fpsimd_flush_state(&t->thread.fpsimd_cpu); + } + + static inline void fpsimd_flush_cpu_state(void) +@@ -1159,7 +1163,7 @@ EXPORT_SYMBOL(kernel_neon_end); + + #ifdef CONFIG_EFI + +-static DEFINE_PER_CPU(struct fpsimd_state, efi_fpsimd_state); ++static DEFINE_PER_CPU(struct user_fpsimd_state, efi_fpsimd_state); + static DEFINE_PER_CPU(bool, efi_fpsimd_state_used); + static DEFINE_PER_CPU(bool, efi_sve_state_used); + +diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c +index 9ae31f7..fdeaba0de 100644 +--- a/arch/arm64/kernel/ptrace.c ++++ b/arch/arm64/kernel/ptrace.c +@@ -629,7 +629,7 @@ static int __fpr_get(struct task_struct *target, + + sve_sync_to_fpsimd(target); + +- uregs = &target->thread.fpsimd_state.user_fpsimd; ++ uregs = &target->thread.fpsimd_state; + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, + start_pos, start_pos + sizeof(*uregs)); +@@ -660,14 +660,14 @@ static int __fpr_set(struct task_struct *target, + */ + sve_sync_to_fpsimd(target); + +- newstate = target->thread.fpsimd_state.user_fpsimd; ++ newstate = target->thread.fpsimd_state; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newstate, + start_pos, start_pos + sizeof(newstate)); + if (ret) + return ret; + +- target->thread.fpsimd_state.user_fpsimd = newstate; ++ target->thread.fpsimd_state = newstate; + + return ret; + } +@@ -1169,7 +1169,7 @@ static int compat_vfp_get(struct task_struct *target, + compat_ulong_t fpscr; + int ret, vregs_end_pos; + +- uregs = &target->thread.fpsimd_state.user_fpsimd; ++ uregs = &target->thread.fpsimd_state; + + if (target == current) + fpsimd_preserve_current_state(); +@@ -1202,7 +1202,7 @@ static int compat_vfp_set(struct task_struct *target, + compat_ulong_t fpscr; + int ret, vregs_end_pos; + +- uregs = &target->thread.fpsimd_state.user_fpsimd; ++ uregs = &target->thread.fpsimd_state; + + vregs_end_pos = VFP_STATE_SIZE - sizeof(compat_ulong_t); + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, +diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c +index f60c052..d026615 100644 +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -178,8 +178,7 @@ static void __user *apply_user_offset( + + static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) + { +- struct user_fpsimd_state const *fpsimd = +- ¤t->thread.fpsimd_state.user_fpsimd; ++ struct user_fpsimd_state const *fpsimd = ¤t->thread.fpsimd_state; + int err; + + /* copy the FP and status/control registers */ +diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c +index 79feb86..4ea38d3 100644 +--- a/arch/arm64/kernel/signal32.c ++++ b/arch/arm64/kernel/signal32.c +@@ -148,8 +148,7 @@ union __fpsimd_vreg { + + static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) + { +- struct user_fpsimd_state const *fpsimd = +- ¤t->thread.fpsimd_state.user_fpsimd; ++ struct user_fpsimd_state const *fpsimd = ¤t->thread.fpsimd_state; + compat_ulong_t magic = VFP_MAGIC; + compat_ulong_t size = VFP_STORAGE_SIZE; + compat_ulong_t fpscr, fpexc; +From patchwork Wed Mar 28 09:50:49 2018 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [v2,2/2] arm64: uaccess: Fix omissions from usercopy whitelist +From: Dave P Martin <Dave.Martin@arm.com> +X-Patchwork-Id: 10312691 +Message-Id: <1522230649-22008-3-git-send-email-Dave.Martin@arm.com> +To: linux-arm-kernel@lists.infradead.org +Cc: Mark Rutland <mark.rutland@arm.com>, Will Deacon <will.deacon@arm.com>, + Kees Cook <keescook@chromium.org> +Date: Wed, 28 Mar 2018 10:50:49 +0100 + +When the hardend usercopy support was added for arm64, it was +concluded that all cases of usercopy into and out of thread_struct +were statically sized and so didn't require explicit whitelisting +of the appropriate fields in thread_struct. + +Testing with usercopy hardening enabled has revealed that this is +not the case for certain ptrace regset manipulation calls on arm64. +This occurs because the sizes of usercopies associated with the +regset API are dynamic by construction, and because arm64 does not +always stage such copies via the stack: indeed the regset API is +designed to avoid the need for that by adding some bounds checking. + +This is currently believed to affect only the fpsimd and TLS +registers. + +Because the whitelisted fields in thread_struct must be contiguous, +this patch groups them together in a nested struct. It is also +necessary to be able to determine the location and size of that +struct, so rather than making the struct anonymous (which would +save on edits elsewhere) or adding an anonymous union containing +named and unnamed instances of the same struct (gross), this patch +gives the struct a name and makes the necessary edits to code that +references it (noisy but simple). + +Care is needed to ensure that the new struct does not contain +padding (which the usercopy hardening would fail to protect). + +For this reason, the presence of tp2_value is made unconditional, +since a padding field would be needed there in any case. This pads +up to the 16-byte alignment required by struct user_fpsimd_state. + +Reported-by: Mark Rutland <mark.rutland@arm.com> +Fixes: 9e8084d3f761 ("arm64: Implement thread_struct whitelist for hardened usercopy") +Signed-off-by: Dave Martin <Dave.Martin@arm.com> +Acked-by: Kees Cook <keescook@chromium.org> +--- + +Changes since v1: + + * Add a BUILD_BUG_ON() check for padding in the whitelist struct. + * Move to using sizeof_field() for assigning *size; get rid of the + dummy pointer that was used previously. + * Delete bogus comment about why no whitelist is (was) needed. +--- + arch/arm64/include/asm/processor.h | 38 +++++++++++++++++++----------- + arch/arm64/kernel/fpsimd.c | 47 +++++++++++++++++++------------------- + arch/arm64/kernel/process.c | 6 ++--- + arch/arm64/kernel/ptrace.c | 30 ++++++++++++------------ + arch/arm64/kernel/signal.c | 3 ++- + arch/arm64/kernel/signal32.c | 3 ++- + arch/arm64/kernel/sys_compat.c | 2 +- + 7 files changed, 72 insertions(+), 57 deletions(-) + +diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h +index 4a04535..224af48 100644 +--- a/arch/arm64/include/asm/processor.h ++++ b/arch/arm64/include/asm/processor.h +@@ -34,6 +34,8 @@ + + #ifdef __KERNEL__ + ++#include <linux/build_bug.h> ++#include <linux/stddef.h> + #include <linux/string.h> + + #include <asm/alternative.h> +@@ -102,11 +104,18 @@ struct cpu_context { + + struct thread_struct { + struct cpu_context cpu_context; /* cpu context */ +- unsigned long tp_value; /* TLS register */ +-#ifdef CONFIG_COMPAT +- unsigned long tp2_value; +-#endif +- struct user_fpsimd_state fpsimd_state; ++ ++ /* ++ * Whitelisted fields for hardened usercopy: ++ * Maintainers must ensure manually that this contains no ++ * implicit padding. ++ */ ++ struct { ++ unsigned long tp_value; /* TLS register */ ++ unsigned long tp2_value; ++ struct user_fpsimd_state fpsimd_state; ++ } uw; ++ + unsigned int fpsimd_cpu; + void *sve_state; /* SVE registers, if any */ + unsigned int sve_vl; /* SVE vector length */ +@@ -116,14 +125,17 @@ struct thread_struct { + struct debug_info debug; /* debugging */ + }; + +-/* +- * Everything usercopied to/from thread_struct is statically-sized, so +- * no hardened usercopy whitelist is needed. +- */ + static inline void arch_thread_struct_whitelist(unsigned long *offset, + unsigned long *size) + { +- *offset = *size = 0; ++ /* Verify that there is no padding among the whitelisted fields: */ ++ BUILD_BUG_ON(sizeof_field(struct thread_struct, uw) != ++ sizeof_field(struct thread_struct, uw.tp_value) + ++ sizeof_field(struct thread_struct, uw.tp2_value) + ++ sizeof_field(struct thread_struct, uw.fpsimd_state)); ++ ++ *offset = offsetof(struct thread_struct, uw); ++ *size = sizeof_field(struct thread_struct, uw); + } + + #ifdef CONFIG_COMPAT +@@ -131,13 +143,13 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset, + ({ \ + unsigned long *__tls; \ + if (is_compat_thread(task_thread_info(t))) \ +- __tls = &(t)->thread.tp2_value; \ ++ __tls = &(t)->thread.uw.tp2_value; \ + else \ +- __tls = &(t)->thread.tp_value; \ ++ __tls = &(t)->thread.uw.tp_value; \ + __tls; \ + }) + #else +-#define task_user_tls(t) (&(t)->thread.tp_value) ++#define task_user_tls(t) (&(t)->thread.uw.tp_value) + #endif + + /* Sync TPIDR_EL0 back to thread_struct for current */ +diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c +index c4be311..7a8ac960b6 100644 +--- a/arch/arm64/kernel/fpsimd.c ++++ b/arch/arm64/kernel/fpsimd.c +@@ -222,7 +222,7 @@ static void sve_user_enable(void) + * sets TIF_SVE. + * + * When stored, FPSIMD registers V0-V31 are encoded in +- * task->fpsimd_state; bits [max : 128] for each of Z0-Z31 are ++ * task->thread.uw.fpsimd_state; bits [max : 128] for each of Z0-Z31 are + * logically zero but not stored anywhere; P0-P15 and FFR are not + * stored and have unspecified values from userspace's point of + * view. For hygiene purposes, the kernel zeroes them on next use, +@@ -231,9 +231,9 @@ static void sve_user_enable(void) + * task->thread.sve_state does not need to be non-NULL, valid or any + * particular size: it must not be dereferenced. + * +- * * FPSR and FPCR are always stored in task->fpsimd_state irrespctive of +- * whether TIF_SVE is clear or set, since these are not vector length +- * dependent. ++ * * FPSR and FPCR are always stored in task->thread.uw.fpsimd_state ++ * irrespective of whether TIF_SVE is clear or set, since these are ++ * not vector length dependent. + */ + + /* +@@ -251,10 +251,10 @@ static void task_fpsimd_load(void) + + if (system_supports_sve() && test_thread_flag(TIF_SVE)) + sve_load_state(sve_pffr(current), +- ¤t->thread.fpsimd_state.fpsr, ++ ¤t->thread.uw.fpsimd_state.fpsr, + sve_vq_from_vl(current->thread.sve_vl) - 1); + else +- fpsimd_load_state(¤t->thread.fpsimd_state); ++ fpsimd_load_state(¤t->thread.uw.fpsimd_state); + + if (system_supports_sve()) { + /* Toggle SVE trapping for userspace if needed */ +@@ -291,9 +291,9 @@ static void task_fpsimd_save(void) + } + + sve_save_state(sve_pffr(current), +- ¤t->thread.fpsimd_state.fpsr); ++ ¤t->thread.uw.fpsimd_state.fpsr); + } else +- fpsimd_save_state(¤t->thread.fpsimd_state); ++ fpsimd_save_state(¤t->thread.uw.fpsimd_state); + } + } + +@@ -404,20 +404,21 @@ static int __init sve_sysctl_init(void) { return 0; } + (SVE_SIG_ZREG_OFFSET(vq, n) - SVE_SIG_REGS_OFFSET)) + + /* +- * Transfer the FPSIMD state in task->thread.fpsimd_state to ++ * Transfer the FPSIMD state in task->thread.uw.fpsimd_state to + * task->thread.sve_state. + * + * Task can be a non-runnable task, or current. In the latter case, + * softirqs (and preemption) must be disabled. + * task->thread.sve_state must point to at least sve_state_size(task) + * bytes of allocated kernel memory. +- * task->thread.fpsimd_state must be up to date before calling this function. ++ * task->thread.uw.fpsimd_state must be up to date before calling this ++ * function. + */ + static void fpsimd_to_sve(struct task_struct *task) + { + unsigned int vq; + void *sst = task->thread.sve_state; +- struct user_fpsimd_state const *fst = &task->thread.fpsimd_state; ++ struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state; + unsigned int i; + + if (!system_supports_sve()) +@@ -431,7 +432,7 @@ static void fpsimd_to_sve(struct task_struct *task) + + /* + * Transfer the SVE state in task->thread.sve_state to +- * task->thread.fpsimd_state. ++ * task->thread.uw.fpsimd_state. + * + * Task can be a non-runnable task, or current. In the latter case, + * softirqs (and preemption) must be disabled. +@@ -443,7 +444,7 @@ static void sve_to_fpsimd(struct task_struct *task) + { + unsigned int vq; + void const *sst = task->thread.sve_state; +- struct user_fpsimd_state *fst = &task->thread.fpsimd_state; ++ struct user_fpsimd_state *fst = &task->thread.uw.fpsimd_state; + unsigned int i; + + if (!system_supports_sve()) +@@ -510,7 +511,7 @@ void fpsimd_sync_to_sve(struct task_struct *task) + } + + /* +- * Ensure that task->thread.fpsimd_state is up to date with respect to ++ * Ensure that task->thread.uw.fpsimd_state is up to date with respect to + * the user task, irrespective of whether SVE is in use or not. + * + * This should only be called by ptrace. task must be non-runnable. +@@ -525,21 +526,21 @@ void sve_sync_to_fpsimd(struct task_struct *task) + + /* + * Ensure that task->thread.sve_state is up to date with respect to +- * the task->thread.fpsimd_state. ++ * the task->thread.uw.fpsimd_state. + * + * This should only be called by ptrace to merge new FPSIMD register + * values into a task for which SVE is currently active. + * task must be non-runnable. + * task->thread.sve_state must point to at least sve_state_size(task) + * bytes of allocated kernel memory. +- * task->thread.fpsimd_state must already have been initialised with ++ * task->thread.uw.fpsimd_state must already have been initialised with + * the new FPSIMD register values to be merged in. + */ + void sve_sync_from_fpsimd_zeropad(struct task_struct *task) + { + unsigned int vq; + void *sst = task->thread.sve_state; +- struct user_fpsimd_state const *fst = &task->thread.fpsimd_state; ++ struct user_fpsimd_state const *fst = &task->thread.uw.fpsimd_state; + unsigned int i; + + if (!test_tsk_thread_flag(task, TIF_SVE)) +@@ -909,7 +910,7 @@ void fpsimd_thread_switch(struct task_struct *next) + * upon the next return to userland. + */ + if (__this_cpu_read(fpsimd_last_state.st) == +- &next->thread.fpsimd_state ++ &next->thread.uw.fpsimd_state + && next->thread.fpsimd_cpu == smp_processor_id()) + clear_tsk_thread_flag(next, TIF_FOREIGN_FPSTATE); + else +@@ -926,8 +927,8 @@ void fpsimd_flush_thread(void) + + local_bh_disable(); + +- memset(¤t->thread.fpsimd_state, 0, +- sizeof current->thread.fpsimd_state); ++ memset(¤t->thread.uw.fpsimd_state, 0, ++ sizeof current->thread.uw.fpsimd_state); + fpsimd_flush_task_state(current); + + if (system_supports_sve()) { +@@ -986,7 +987,7 @@ void fpsimd_preserve_current_state(void) + + /* + * Like fpsimd_preserve_current_state(), but ensure that +- * current->thread.fpsimd_state is updated so that it can be copied to ++ * current->thread.uw.fpsimd_state is updated so that it can be copied to + * the signal frame. + */ + void fpsimd_signal_preserve_current_state(void) +@@ -1005,7 +1006,7 @@ static void fpsimd_bind_to_cpu(void) + struct fpsimd_last_state_struct *last = + this_cpu_ptr(&fpsimd_last_state); + +- last->st = ¤t->thread.fpsimd_state; ++ last->st = ¤t->thread.uw.fpsimd_state; + last->sve_in_use = test_thread_flag(TIF_SVE); + current->thread.fpsimd_cpu = smp_processor_id(); + } +@@ -1042,7 +1043,7 @@ void fpsimd_update_current_state(struct user_fpsimd_state const *state) + + local_bh_disable(); + +- current->thread.fpsimd_state = *state; ++ current->thread.uw.fpsimd_state = *state; + if (system_supports_sve() && test_thread_flag(TIF_SVE)) + fpsimd_to_sve(current); + +diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c +index c0da6ef..f08a2ed 100644 +--- a/arch/arm64/kernel/process.c ++++ b/arch/arm64/kernel/process.c +@@ -257,7 +257,7 @@ static void tls_thread_flush(void) + write_sysreg(0, tpidr_el0); + + if (is_compat_task()) { +- current->thread.tp_value = 0; ++ current->thread.uw.tp_value = 0; + + /* + * We need to ensure ordering between the shadow state and the +@@ -351,7 +351,7 @@ int copy_thread(unsigned long clone_flags, unsigned long stack_start, + * for the new thread. + */ + if (clone_flags & CLONE_SETTLS) +- p->thread.tp_value = childregs->regs[3]; ++ p->thread.uw.tp_value = childregs->regs[3]; + } else { + memset(childregs, 0, sizeof(struct pt_regs)); + childregs->pstate = PSR_MODE_EL1h; +@@ -379,7 +379,7 @@ static void tls_thread_switch(struct task_struct *next) + tls_preserve_current_state(); + + if (is_compat_thread(task_thread_info(next))) +- write_sysreg(next->thread.tp_value, tpidrro_el0); ++ write_sysreg(next->thread.uw.tp_value, tpidrro_el0); + else if (!arm64_kernel_unmapped_at_el0()) + write_sysreg(0, tpidrro_el0); + +diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c +index fdeaba0de..436a132 100644 +--- a/arch/arm64/kernel/ptrace.c ++++ b/arch/arm64/kernel/ptrace.c +@@ -629,7 +629,7 @@ static int __fpr_get(struct task_struct *target, + + sve_sync_to_fpsimd(target); + +- uregs = &target->thread.fpsimd_state; ++ uregs = &target->thread.uw.fpsimd_state; + + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, uregs, + start_pos, start_pos + sizeof(*uregs)); +@@ -655,19 +655,19 @@ static int __fpr_set(struct task_struct *target, + struct user_fpsimd_state newstate; + + /* +- * Ensure target->thread.fpsimd_state is up to date, so that a ++ * Ensure target->thread.uw.fpsimd_state is up to date, so that a + * short copyin can't resurrect stale data. + */ + sve_sync_to_fpsimd(target); + +- newstate = target->thread.fpsimd_state; ++ newstate = target->thread.uw.fpsimd_state; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &newstate, + start_pos, start_pos + sizeof(newstate)); + if (ret) + return ret; + +- target->thread.fpsimd_state = newstate; ++ target->thread.uw.fpsimd_state = newstate; + + return ret; + } +@@ -692,7 +692,7 @@ static int tls_get(struct task_struct *target, const struct user_regset *regset, + unsigned int pos, unsigned int count, + void *kbuf, void __user *ubuf) + { +- unsigned long *tls = &target->thread.tp_value; ++ unsigned long *tls = &target->thread.uw.tp_value; + + if (target == current) + tls_preserve_current_state(); +@@ -705,13 +705,13 @@ static int tls_set(struct task_struct *target, const struct user_regset *regset, + const void *kbuf, const void __user *ubuf) + { + int ret; +- unsigned long tls = target->thread.tp_value; ++ unsigned long tls = target->thread.uw.tp_value; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); + if (ret) + return ret; + +- target->thread.tp_value = tls; ++ target->thread.uw.tp_value = tls; + return ret; + } + +@@ -842,7 +842,7 @@ static int sve_get(struct task_struct *target, + start = end; + end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE; + ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, +- &target->thread.fpsimd_state.fpsr, ++ &target->thread.uw.fpsimd_state.fpsr, + start, end); + if (ret) + return ret; +@@ -941,7 +941,7 @@ static int sve_set(struct task_struct *target, + start = end; + end = SVE_PT_SVE_FPCR_OFFSET(vq) + SVE_PT_SVE_FPCR_SIZE; + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, +- &target->thread.fpsimd_state.fpsr, ++ &target->thread.uw.fpsimd_state.fpsr, + start, end); + + out: +@@ -1169,7 +1169,7 @@ static int compat_vfp_get(struct task_struct *target, + compat_ulong_t fpscr; + int ret, vregs_end_pos; + +- uregs = &target->thread.fpsimd_state; ++ uregs = &target->thread.uw.fpsimd_state; + + if (target == current) + fpsimd_preserve_current_state(); +@@ -1202,7 +1202,7 @@ static int compat_vfp_set(struct task_struct *target, + compat_ulong_t fpscr; + int ret, vregs_end_pos; + +- uregs = &target->thread.fpsimd_state; ++ uregs = &target->thread.uw.fpsimd_state; + + vregs_end_pos = VFP_STATE_SIZE - sizeof(compat_ulong_t); + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, uregs, 0, +@@ -1225,7 +1225,7 @@ static int compat_tls_get(struct task_struct *target, + const struct user_regset *regset, unsigned int pos, + unsigned int count, void *kbuf, void __user *ubuf) + { +- compat_ulong_t tls = (compat_ulong_t)target->thread.tp_value; ++ compat_ulong_t tls = (compat_ulong_t)target->thread.uw.tp_value; + return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); + } + +@@ -1235,13 +1235,13 @@ static int compat_tls_set(struct task_struct *target, + const void __user *ubuf) + { + int ret; +- compat_ulong_t tls = target->thread.tp_value; ++ compat_ulong_t tls = target->thread.uw.tp_value; + + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &tls, 0, -1); + if (ret) + return ret; + +- target->thread.tp_value = tls; ++ target->thread.uw.tp_value = tls; + return ret; + } + +@@ -1538,7 +1538,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, + break; + + case COMPAT_PTRACE_GET_THREAD_AREA: +- ret = put_user((compat_ulong_t)child->thread.tp_value, ++ ret = put_user((compat_ulong_t)child->thread.uw.tp_value, + (compat_ulong_t __user *)datap); + break; + +diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c +index d026615..a0c4138 100644 +--- a/arch/arm64/kernel/signal.c ++++ b/arch/arm64/kernel/signal.c +@@ -178,7 +178,8 @@ static void __user *apply_user_offset( + + static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) + { +- struct user_fpsimd_state const *fpsimd = ¤t->thread.fpsimd_state; ++ struct user_fpsimd_state const *fpsimd = ++ ¤t->thread.uw.fpsimd_state; + int err; + + /* copy the FP and status/control registers */ +diff --git a/arch/arm64/kernel/signal32.c b/arch/arm64/kernel/signal32.c +index 4ea38d3..884177a 100644 +--- a/arch/arm64/kernel/signal32.c ++++ b/arch/arm64/kernel/signal32.c +@@ -148,7 +148,8 @@ union __fpsimd_vreg { + + static int compat_preserve_vfp_context(struct compat_vfp_sigframe __user *frame) + { +- struct user_fpsimd_state const *fpsimd = ¤t->thread.fpsimd_state; ++ struct user_fpsimd_state const *fpsimd = ++ ¤t->thread.uw.fpsimd_state; + compat_ulong_t magic = VFP_MAGIC; + compat_ulong_t size = VFP_STORAGE_SIZE; + compat_ulong_t fpscr, fpexc; +diff --git a/arch/arm64/kernel/sys_compat.c b/arch/arm64/kernel/sys_compat.c +index a382b2a..9155989 100644 +--- a/arch/arm64/kernel/sys_compat.c ++++ b/arch/arm64/kernel/sys_compat.c +@@ -88,7 +88,7 @@ long compat_arm_syscall(struct pt_regs *regs) + return do_compat_cache_op(regs->regs[0], regs->regs[1], regs->regs[2]); + + case __ARM_NR_compat_set_tls: +- current->thread.tp_value = regs->regs[0]; ++ current->thread.uw.tp_value = regs->regs[0]; + + /* + * Protect against register corruption from context switch. diff --git a/baseconfig/arm/CONFIG_ARM64_ERRATUM_1024718 b/baseconfig/arm/CONFIG_ARM64_ERRATUM_1024718 new file mode 100644 index 000000000..1c8f6ffc8 --- /dev/null +++ b/baseconfig/arm/CONFIG_ARM64_ERRATUM_1024718 @@ -0,0 +1 @@ +CONFIG_ARM64_ERRATUM_1024718=y diff --git a/baseconfig/arm/CONFIG_USB_TEGRA_PHY b/baseconfig/arm/CONFIG_USB_TEGRA_PHY new file mode 100644 index 000000000..8f324a3c0 --- /dev/null +++ b/baseconfig/arm/CONFIG_USB_TEGRA_PHY @@ -0,0 +1 @@ +CONFIG_USB_TEGRA_PHY=m diff --git a/baseconfig/arm/aarch64/CONFIG_MV_XOR_V2 b/baseconfig/arm/aarch64/CONFIG_MV_XOR_V2 index a6e590eb8..fdcbbf4c2 100644 --- a/baseconfig/arm/aarch64/CONFIG_MV_XOR_V2 +++ b/baseconfig/arm/aarch64/CONFIG_MV_XOR_V2 @@ -1 +1 @@ -# CONFIG_MV_XOR_V2 is not set +CONFIG_MV_XOR_V2=y diff --git a/kernel-aarch64-debug.config b/kernel-aarch64-debug.config index dcf76bf48..278735ed4 100644 --- a/kernel-aarch64-debug.config +++ b/kernel-aarch64-debug.config @@ -248,6 +248,7 @@ CONFIG_ARCH_ZYNQMP=y CONFIG_ARM64_4K_PAGES=y CONFIG_ARM64_ACPI_PARKING_PROTOCOL=y CONFIG_ARM64_CRYPTO=y +CONFIG_ARM64_ERRATUM_1024718=y CONFIG_ARM64_ERRATUM_819472=y CONFIG_ARM64_ERRATUM_824069=y CONFIG_ARM64_ERRATUM_826319=y @@ -3373,7 +3374,7 @@ CONFIG_MVMDIO=m CONFIG_MVNETA_BM_ENABLE=m CONFIG_MVNETA=m CONFIG_MVPP2=m -# CONFIG_MV_XOR_V2 is not set +CONFIG_MV_XOR_V2=y CONFIG_MV_XOR=y CONFIG_MWAVE=m CONFIG_MWIFIEX=m @@ -6324,6 +6325,7 @@ CONFIG_USB_STORAGE_USBAT=m CONFIG_USB_STV06XX=m CONFIG_USB_SUPPORT=y # CONFIG_USB_SWITCH_FSA9480 is not set +CONFIG_USB_TEGRA_PHY=m # CONFIG_USB_TEST is not set CONFIG_USB_TMC=m CONFIG_USB_TRANCEVIBRATOR=m diff --git a/kernel-aarch64.config b/kernel-aarch64.config index f63520523..19ff06b1c 100644 --- a/kernel-aarch64.config +++ b/kernel-aarch64.config @@ -248,6 +248,7 @@ CONFIG_ARCH_ZYNQMP=y CONFIG_ARM64_4K_PAGES=y CONFIG_ARM64_ACPI_PARKING_PROTOCOL=y CONFIG_ARM64_CRYPTO=y +CONFIG_ARM64_ERRATUM_1024718=y CONFIG_ARM64_ERRATUM_819472=y CONFIG_ARM64_ERRATUM_824069=y CONFIG_ARM64_ERRATUM_826319=y @@ -3351,7 +3352,7 @@ CONFIG_MVMDIO=m CONFIG_MVNETA_BM_ENABLE=m CONFIG_MVNETA=m CONFIG_MVPP2=m -# CONFIG_MV_XOR_V2 is not set +CONFIG_MV_XOR_V2=y CONFIG_MV_XOR=y CONFIG_MWAVE=m CONFIG_MWIFIEX=m @@ -6300,6 +6301,7 @@ CONFIG_USB_STORAGE_USBAT=m CONFIG_USB_STV06XX=m CONFIG_USB_SUPPORT=y # CONFIG_USB_SWITCH_FSA9480 is not set +CONFIG_USB_TEGRA_PHY=m # CONFIG_USB_TEST is not set CONFIG_USB_TMC=m CONFIG_USB_TRANCEVIBRATOR=m diff --git a/kernel-armv7hl-debug.config b/kernel-armv7hl-debug.config index 9154543c1..3d2310882 100644 --- a/kernel-armv7hl-debug.config +++ b/kernel-armv7hl-debug.config @@ -251,6 +251,7 @@ CONFIG_ARCH_VIRT=y # CONFIG_ARCH_ZX is not set CONFIG_ARCH_ZYNQ=y # CONFIG_ARCNET is not set +CONFIG_ARM64_ERRATUM_1024718=y CONFIG_ARM64_ERRATUM_858921=y CONFIG_ARM64_PTDUMP=y CONFIG_ARMADA_THERMAL=m @@ -6832,6 +6833,7 @@ CONFIG_USB_STORAGE_USBAT=m CONFIG_USB_STV06XX=m CONFIG_USB_SUPPORT=y # CONFIG_USB_SWITCH_FSA9480 is not set +CONFIG_USB_TEGRA_PHY=m # CONFIG_USB_TEST is not set CONFIG_USB_TI_CPPI41_DMA=y CONFIG_USB_TMC=m diff --git a/kernel-armv7hl-lpae-debug.config b/kernel-armv7hl-lpae-debug.config index a6a78c269..300cc85f9 100644 --- a/kernel-armv7hl-lpae-debug.config +++ b/kernel-armv7hl-lpae-debug.config @@ -242,6 +242,7 @@ CONFIG_ARCH_VIRT=y # CONFIG_ARCH_ZX is not set # CONFIG_ARCH_ZYNQ is not set # CONFIG_ARCNET is not set +CONFIG_ARM64_ERRATUM_1024718=y CONFIG_ARM64_ERRATUM_858921=y CONFIG_ARM64_PTDUMP=y CONFIG_ARMADA_THERMAL=m @@ -6401,6 +6402,7 @@ CONFIG_USB_STORAGE_USBAT=m CONFIG_USB_STV06XX=m CONFIG_USB_SUPPORT=y # CONFIG_USB_SWITCH_FSA9480 is not set +CONFIG_USB_TEGRA_PHY=m # CONFIG_USB_TEST is not set CONFIG_USB_TMC=m CONFIG_USB_TRANCEVIBRATOR=m diff --git a/kernel-armv7hl-lpae.config b/kernel-armv7hl-lpae.config index 41b9b46b1..a9e4fb88d 100644 --- a/kernel-armv7hl-lpae.config +++ b/kernel-armv7hl-lpae.config @@ -242,6 +242,7 @@ CONFIG_ARCH_VIRT=y # CONFIG_ARCH_ZX is not set # CONFIG_ARCH_ZYNQ is not set # CONFIG_ARCNET is not set +CONFIG_ARM64_ERRATUM_1024718=y CONFIG_ARM64_ERRATUM_858921=y CONFIG_ARMADA_THERMAL=m CONFIG_ARM_AMBA=y @@ -6377,6 +6378,7 @@ CONFIG_USB_STORAGE_USBAT=m CONFIG_USB_STV06XX=m CONFIG_USB_SUPPORT=y # CONFIG_USB_SWITCH_FSA9480 is not set +CONFIG_USB_TEGRA_PHY=m # CONFIG_USB_TEST is not set CONFIG_USB_TMC=m CONFIG_USB_TRANCEVIBRATOR=m diff --git a/kernel-armv7hl.config b/kernel-armv7hl.config index 1567d182d..2cdc55494 100644 --- a/kernel-armv7hl.config +++ b/kernel-armv7hl.config @@ -251,6 +251,7 @@ CONFIG_ARCH_VIRT=y # CONFIG_ARCH_ZX is not set CONFIG_ARCH_ZYNQ=y # CONFIG_ARCNET is not set +CONFIG_ARM64_ERRATUM_1024718=y CONFIG_ARM64_ERRATUM_858921=y CONFIG_ARMADA_THERMAL=m CONFIG_ARM_AMBA=y @@ -6808,6 +6809,7 @@ CONFIG_USB_STORAGE_USBAT=m CONFIG_USB_STV06XX=m CONFIG_USB_SUPPORT=y # CONFIG_USB_SWITCH_FSA9480 is not set +CONFIG_USB_TEGRA_PHY=m # CONFIG_USB_TEST is not set CONFIG_USB_TI_CPPI41_DMA=y CONFIG_USB_TMC=m diff --git a/kernel.spec b/kernel.spec index 6f814c146..1d423ce33 100644 --- a/kernel.spec +++ b/kernel.spec @@ -58,7 +58,7 @@ Summary: The Linux kernel %define stable_rc 0 # Do we have a -stable update to apply? -%define stable_update 7 +%define stable_update 8 # Set rpm version accordingly %if 0%{?stable_update} %define stablerev %{stable_update} @@ -293,8 +293,7 @@ Summary: The Linux kernel %define asmarch s390 %define hdrarch s390 %define all_arch_configs kernel-%{version}-s390x.config -%define make_target image -%define kernel_image arch/s390/boot/image +%define kernel_image arch/s390/boot/bzImage %endif %ifarch %{arm} @@ -636,6 +635,12 @@ Patch320: arm-dts-Add-am335x-pocketbeagle.patch # https://patchwork.kernel.org/patch/10133165/ Patch321: mvebu-a37xx-fixes.patch +# https://www.spinics.net/lists/arm-kernel/msg643991.html +Patch322: arm64-fix-usercopy-whitelist.patch + +# https://www.spinics.net/lists/linux-tegra/msg32920.html +Patch323: arm-tegra-USB-driver-dependency-fix.patch + # Enabling Patches for the RPi3+ Patch330: bcm2837-gpio-expander.patch # http://www.spinics.net/lists/arm-kernel/msg647617.html @@ -643,6 +648,9 @@ Patch331: bcm2837-rpi-initial-3plus-support.patch Patch332: bcm2837-enable-pmu.patch Patch333: bcm2837-lan78xx-fixes.patch +# rhbz 1574718 +Patch340: ACPI-irq-Workaround-firmware-issue-on-X-Gene-based-m400.patch + # 400 - IBM (ppc/s390x) patches # 500 - Temp fixes/CVEs etc @@ -666,6 +674,15 @@ Patch508: Bluetooth-btusb-autosuspend-XPS-13-9360-fixes.patch # rhbz 1572944 Patch509: Revert-the-random-series-for-4.16.4.patch +# CVE-2018-10322 rhbz 1571623 1571624 +Patch510: 0001-xfs-enhance-dinode-verifier.patch + +# CVE-2018-10323 rhbz 1571627 1571630 +Patch511: 0001-xfs-set-format-back-to-extents-if-xfs_bmap_extents_t.patch + +# rhbz 1566258 +Patch512: KVM-vmx-update-sec-exec-controls-for-UMIP-iff-emulating-UMIP.patch + # END OF PATCH DEFINITIONS %endif @@ -1413,6 +1430,9 @@ BuildKernel() { if [ -f arch/$Arch/*lds ]; then cp -a arch/$Arch/*lds $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/arch/%{_arch}/ || : fi + if [ -f arch/%{asmarch}/kernel/module.lds ]; then + cp -a --parents arch/%{asmarch}/kernel/module.lds $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/ + fi rm -f $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/scripts/*.o rm -f $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/scripts/*/*.o %ifarch %{power64} @@ -1422,8 +1442,6 @@ BuildKernel() { cp -a --parents arch/%{asmarch}/include $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/ fi %ifarch aarch64 - # Needed for systemtap - cp -a --parents arch/arm64/kernel/module.lds $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/ # arch/arm64/include/asm/xen references arch/arm cp -a --parents arch/arm/include/asm/xen $RPM_BUILD_ROOT/lib/modules/$KernelVer/build/ # arch/arm64/include/asm/opcodes.h references arch/arm @@ -1941,6 +1959,26 @@ fi # # %changelog +* Wed May 09 2018 Jeremy Cline <jeremy@jcline.org> +- Workaround for m400 uart irq firmware description (rhbz 1574718) + +* Wed May 09 2018 Jeremy Cline <jeremy@jcline.org> - 4.16.8-200 +- Linux v4.16.8 + +* Mon May 07 2018 Jeremy Cline <jeremy@jcline.org> +- Fix issue with KVM on older Core 2 processors (rhbz 1566258) + +* Sat May 5 2018 Peter Robinson <pbrobinson@fedoraproject.org> +- ARM and Raspberry Pi fixes +- Fix USB-2 on Tegra devices + +* Fri May 04 2018 Laura Abbott <labbott@redhat.com> +- Fix for building out of tree modules on powerpc (rhbz 1574604) + +* Fri May 04 2018 Justin M. Forbes <jforbes@fedoraproject.org> +- Fix CVE-2018-10322 (rhbz 1571623 1571624) +- Fix CVE-2018-10323 (rhbz 1571627 1571630) + * Wed May 02 2018 Jeremy Cline <jeremy@jcline.org> - 4.16.7-100 - Linux v4.16.7 - Revert a second patch related to CVE-2018-1108 4.16.4 (rhbz 1572944) @@ -1,2 +1,2 @@ SHA512 (linux-4.16.tar.xz) = ab47849314b177d0eec9dbf261f33972b0d89fb92fb0650130ffa7abc2f36c0fab2d06317dc1683c51a472a9a631573a9b1e7258d6281a2ee189897827f14662 -SHA512 (patch-4.16.7.xz) = 576c2b520d444e11a9ca45ed3ed03822007ab6ff778a1759aa0f65c96946fe3e169e71d48d11e6d3b8627a99cdc20abfb0c84d7b6c9b0d2afa4d5fee9ed3aa41 +SHA512 (patch-4.16.8.xz) = 8bd521f5a14280c6893f6d85f46d12f97ba71abf3e149f1900aa5e1efa3a03a97df674c4b2b46553b8e9df55164894b6fcb510dbba8cab8ce47ee4b0186e27d0 |