Merge tag 'for-linus-20190627' of gitolite.kernel.org:pub/scm/linux/kernel/git/braune...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Jun 2019 00:41:18 +0000 (08:41 +0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 28 Jun 2019 00:41:18 +0000 (08:41 +0800)
Pull pidfd fixes from Christian Brauner:
 "Userspace tools and libraries such as strace or glibc need a cheap and
  reliable way to tell whether CLONE_PIDFD is supported. The easiest way
  is to pass an invalid fd value in the return argument, perform the
  syscall and verify the value in the return argument has been changed
  to a valid fd.

  However, if CLONE_PIDFD is specified we currently check if pidfd == 0
  and return EINVAL if not.

  The check for pidfd == 0 was originally added to enable us to abuse
  the return argument for passing additional flags along with
  CLONE_PIDFD in the future.

  However, extending legacy clone this way would be a terrible idea and
  with clone3 on the horizon and the ability to reuse CLONE_DETACHED
  with CLONE_PIDFD there's no real need for this clutch. So remove the
  pidfd == 0 check and help userspace out.

  Also, accordig to Al, anon_inode_getfd() should only be used past the
  point of no failure and ksys_close() should not be used at all since
  it is far too easy to get wrong. Al's motto being "basically, once
  it's in descriptor table, it's out of your control". So Al's patch
  switches back to what we already had in v1 of the original patchset
  and uses a anon_inode_getfile() + put_user() + fd_install() sequence
  in the success path and a fput() + put_unused_fd() in the failure
  path.

  The other two changes should be trivial"

* tag 'for-linus-20190627' of gitolite.kernel.org:pub/scm/linux/kernel/git/brauner/linux:
  proc: remove useless d_is_dir() check
  copy_process(): don't use ksys_close() on cleanups
  samples: make pidfd-metadata fail gracefully on older kernels
  fork: don't check parent_tidptr with CLONE_PIDFD

69 files changed:
MAINTAINERS
arch/arm/boot/dts/gemini-dlink-dir-685.dts
arch/arm/boot/dts/gemini-dlink-dns-313.dts
arch/arm/boot/dts/imx6ul.dtsi
arch/arm/boot/dts/meson8.dtsi
arch/arm/boot/dts/meson8b.dtsi
arch/arm/mach-omap2/prm3xxx.c
arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
arch/arm64/configs/defconfig
arch/csky/kernel/signal.c
arch/parisc/kernel/module.c
arch/powerpc/mm/book3s64/mmu_context.c
drivers/auxdisplay/cfag12864bfb.c
drivers/auxdisplay/ht16k33.c
drivers/hid/hid-ids.h
drivers/hid/hid-logitech-dj.c
drivers/hid/hid-multitouch.c
drivers/hid/hid-quirks.c
drivers/hid/hid-uclogic-core.c
drivers/hid/hid-uclogic-params.c
drivers/hid/intel-ish-hid/ishtp-fw-loader.c
drivers/hid/intel-ish-hid/ishtp-hid-client.c
drivers/hid/intel-ish-hid/ishtp/bus.c
drivers/mfd/stmfx.c
drivers/mtd/nand/raw/nand_base.c
drivers/mtd/spi-nor/spi-nor.c
drivers/net/bonding/bond_main.c
drivers/net/dsa/microchip/ksz_common.c
drivers/net/ethernet/aquantia/atlantic/aq_filters.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.c
drivers/net/ethernet/aquantia/atlantic/aq_nic.h
drivers/net/ethernet/aquantia/atlantic/hw_atl/hw_atl_b0.c
drivers/net/ethernet/cadence/macb_main.c
drivers/net/ethernet/emulex/benet/be_ethtool.c
drivers/net/ethernet/sis/sis900.c
drivers/net/ethernet/stmicro/stmmac/stmmac_hwtstamp.c
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
drivers/net/ppp/ppp_mppe.c
drivers/net/team/team.c
drivers/net/usb/qmi_wwan.c
drivers/net/vrf.c
fs/afs/callback.c
fs/afs/inode.c
fs/afs/internal.h
fs/afs/volume.c
include/linux/intel-ish-client-if.h
include/linux/mtd/spi-nor.h
include/net/ip6_route.h
include/net/route.h
include/net/tls.h
net/bluetooth/6lowpan.c
net/ipv4/ip_output.c
net/ipv4/raw.c
net/ipv4/route.c
net/ipv6/ip6_output.c
net/ipv6/route.c
net/netfilter/nf_flow_table_ip.c
net/packet/af_packet.c
net/packet/internal.h
net/sched/sch_cbs.c
net/sctp/endpointola.c
net/smc/af_smc.c
net/smc/smc_core.c
net/tipc/core.c
net/tipc/netlink_compat.c
net/tls/tls_main.c
tools/testing/selftests/powerpc/mm/.gitignore
tools/testing/selftests/powerpc/mm/Makefile
tools/testing/selftests/powerpc/mm/large_vm_fork_separation.c [new file with mode: 0644]

index d0ed735994a54fabb37ca9677e861ed261ab621e..3c4d72755127adf4ac80fa4adcd5c35dd4fba690 100644 (file)
@@ -3122,6 +3122,7 @@ F:        arch/arm/mach-bcm/
 BROADCOM BCM2835 ARM ARCHITECTURE
 M:     Eric Anholt <eric@anholt.net>
 M:     Stefan Wahren <wahrenst@gmx.net>
+L:     bcm-kernel-feedback-list@broadcom.com
 L:     linux-rpi-kernel@lists.infradead.org (moderated for non-subscribers)
 L:     linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
 T:     git git://github.com/anholt/linux
@@ -3151,6 +3152,7 @@ F:        arch/arm/boot/dts/bcm953012*
 
 BROADCOM BCM53573 ARM ARCHITECTURE
 M:     RafaÅ‚ MiÅ‚ecki <rafal@milecki.pl>
+L:     bcm-kernel-feedback-list@broadcom.com
 L:     linux-arm-kernel@lists.infradead.org
 S:     Maintained
 F:     arch/arm/boot/dts/bcm53573*
index cfbfbc91a1e1a23ebd9c91f2153ee8f17bea4fdf..3613f05f8a80aad7c2de243333f84dfc3c410a53 100644 (file)
@@ -20,7 +20,7 @@
        };
 
        chosen {
-               bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait";
+               bootargs = "console=ttyS0,19200n8 root=/dev/sda1 rw rootwait consoleblank=300";
                stdout-path = "uart0:19200n8";
        };
 
index b12504e10f0b121904759a1ca2469b3a6b139ff2..360642a02a488c015b05229b01cf18e4c7cd82a2 100644 (file)
@@ -11,7 +11,7 @@
 
 / {
        model = "D-Link DNS-313 1-Bay Network Storage Enclosure";
-       compatible = "dlink,dir-313", "cortina,gemini";
+       compatible = "dlink,dns-313", "cortina,gemini";
        #address-cells = <1>;
        #size-cells = <1>;
 
index bbf010c7333696cd9f6bc5e23dd01cd39268f47b..a7f6d1d58e20dfc66d5c80bd8810369a9fe948f7 100644 (file)
                        pwm1: pwm@2080000 {
                                compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
                                reg = <0x02080000 0x4000>;
-                               interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6UL_CLK_PWM1>,
                                         <&clks IMX6UL_CLK_PWM1>;
                                clock-names = "ipg", "per";
                        pwm2: pwm@2084000 {
                                compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
                                reg = <0x02084000 0x4000>;
-                               interrupts = <GIC_SPI 116 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6UL_CLK_PWM2>,
                                         <&clks IMX6UL_CLK_PWM2>;
                                clock-names = "ipg", "per";
                        pwm3: pwm@2088000 {
                                compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
                                reg = <0x02088000 0x4000>;
-                               interrupts = <GIC_SPI 117 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6UL_CLK_PWM3>,
                                         <&clks IMX6UL_CLK_PWM3>;
                                clock-names = "ipg", "per";
                        pwm4: pwm@208c000 {
                                compatible = "fsl,imx6ul-pwm", "fsl,imx27-pwm";
                                reg = <0x0208c000 0x4000>;
-                               interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>;
+                               interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
                                clocks = <&clks IMX6UL_CLK_PWM4>,
                                         <&clks IMX6UL_CLK_PWM4>;
                                clock-names = "ipg", "per";
index 7ef442462ea474460796b03ebe63462f28e5b65e..40c11b6b217aad3498bd6ea1a9b34774effed87f 100644 (file)
                                     <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
-                                    <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
+                                    <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>,
                                     <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>,
                        clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>;
                        clock-names = "bus", "core";
                        operating-points-v2 = <&gpu_opp_table>;
-                       switch-delay = <0xffff>;
                };
        };
 }; /* end of / */
index 800cd65fc50a4f0e59c2278eee74d49f117aea63..ec67f49116d9cabf9fcc2730d813d7ae3da1aa24 100644 (file)
 
                opp-255000000 {
                        opp-hz = /bits/ 64 <255000000>;
-                       opp-microvolt = <1150000>;
+                       opp-microvolt = <1100000>;
                };
                opp-364300000 {
                        opp-hz = /bits/ 64 <364300000>;
-                       opp-microvolt = <1150000>;
+                       opp-microvolt = <1100000>;
                };
                opp-425000000 {
                        opp-hz = /bits/ 64 <425000000>;
-                       opp-microvolt = <1150000>;
+                       opp-microvolt = <1100000>;
                };
                opp-510000000 {
                        opp-hz = /bits/ 64 <510000000>;
-                       opp-microvolt = <1150000>;
+                       opp-microvolt = <1100000>;
                };
                opp-637500000 {
                        opp-hz = /bits/ 64 <637500000>;
-                       opp-microvolt = <1150000>;
+                       opp-microvolt = <1100000>;
                        turbo-mode;
                };
        };
                        clocks = <&clkc CLKID_CLK81>, <&clkc CLKID_MALI>;
                        clock-names = "bus", "core";
                        operating-points-v2 = <&gpu_opp_table>;
-                       switch-delay = <0xffff>;
                };
        };
 }; /* end of / */
index fd4a3bf27993dc29aa72c685a3f80a5ce98eb486..1b442b1285693cd9d06425d4d066bb596f5af836 100644 (file)
@@ -430,7 +430,7 @@ static void omap3_prm_reconfigure_io_chain(void)
  * registers, and omap3xxx_prm_reconfigure_io_chain() must be called.
  * No return value.
  */
-static void __init omap3xxx_prm_enable_io_wakeup(void)
+static void omap3xxx_prm_enable_io_wakeup(void)
 {
        if (prm_features & PRM_HAS_IO_WAKEUP)
                omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD,
index b04581249f0bca701dfe8134ffc7f65a44a2fbd4..bf7f845447eddb3a3e2d5d9c2fd82b1352c325c8 100644 (file)
@@ -28,7 +28,7 @@
                        enable-method = "psci";
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
-                       cpu-idle-states = <&CPU_PH20>;
+                       cpu-idle-states = <&CPU_PW20>;
                };
 
                cpu1: cpu@1 {
@@ -38,7 +38,7 @@
                        enable-method = "psci";
                        clocks = <&clockgen 1 0>;
                        next-level-cache = <&l2>;
-                       cpu-idle-states = <&CPU_PH20>;
+                       cpu-idle-states = <&CPU_PW20>;
                };
 
                l2: l2-cache {
                 */
                entry-method = "arm,psci";
 
-               CPU_PH20: cpu-ph20 {
-                       compatible = "arm,idle-state";
-                       idle-state-name = "PH20";
-                       arm,psci-suspend-param = <0x00010000>;
-                       entry-latency-us = <1000>;
-                       exit-latency-us = <1000>;
-                       min-residency-us = <3000>;
+               CPU_PW20: cpu-pw20 {
+                         compatible = "arm,idle-state";
+                         idle-state-name = "PW20";
+                         arm,psci-suspend-param = <0x0>;
+                         entry-latency-us = <2000>;
+                         exit-latency-us = <2000>;
+                         min-residency-us = <6000>;
                };
        };
 
index 4d583514258ce57b1edcde391aba9ce0d4211b3e..6bca5b082ea4e6a84430568c89b7532f9e076d62 100644 (file)
@@ -613,6 +613,7 @@ CONFIG_RTC_DRV_TEGRA=y
 CONFIG_RTC_DRV_IMX_SC=m
 CONFIG_RTC_DRV_XGENE=y
 CONFIG_DMADEVICES=y
+CONFIG_FSL_EDMA=y
 CONFIG_DMA_BCM2835=m
 CONFIG_K3_DMA=y
 CONFIG_MV_XOR=y
index 04a43cfd4e09f3babe35685e3dcabcb1085aa6e2..d47a3381aad86f591ed21c2f2792b67504a912d4 100644 (file)
@@ -39,6 +39,11 @@ static int save_fpu_state(struct sigcontext __user *sc)
 #endif
 
 struct rt_sigframe {
+       /*
+        * pad[3] is compatible with the same struct defined in
+        * gcc/libgcc/config/csky/linux-unwind.h
+        */
+       int pad[3];
        struct siginfo info;
        struct ucontext uc;
 };
index f241ded9239b29d45109b72c035dae798352292d..1f0f29a289d360dd6c04d375f17ddf21387390f5 100644 (file)
@@ -786,6 +786,10 @@ int apply_relocate_add(Elf_Shdr *sechdrs,
                        /* 32-bit PC relative address */
                        *loc = val - dot - 8 + addend;
                        break;
+               case R_PARISC_PCREL64:
+                       /* 64-bit PC relative address */
+                       *loc64 = val - dot - 8 + addend;
+                       break;
                case R_PARISC_DIR64:
                        /* 64-bit effective address */
                        *loc64 = val + addend;
index bb70391401f7fd9fe62594c204484e7aa3e83468..794404d50a8503f923ba07bbe5a2ef4169941a1c 100644 (file)
@@ -50,20 +50,52 @@ EXPORT_SYMBOL_GPL(hash__alloc_context_id);
 
 void slb_setup_new_exec(void);
 
+static int realloc_context_ids(mm_context_t *ctx)
+{
+       int i, id;
+
+       /*
+        * id 0 (aka. ctx->id) is special, we always allocate a new one, even if
+        * there wasn't one allocated previously (which happens in the exec
+        * case where ctx is newly allocated).
+        *
+        * We have to be a bit careful here. We must keep the existing ids in
+        * the array, so that we can test if they're non-zero to decide if we
+        * need to allocate a new one. However in case of error we must free the
+        * ids we've allocated but *not* any of the existing ones (or risk a
+        * UAF). That's why we decrement i at the start of the error handling
+        * loop, to skip the id that we just tested but couldn't reallocate.
+        */
+       for (i = 0; i < ARRAY_SIZE(ctx->extended_id); i++) {
+               if (i == 0 || ctx->extended_id[i]) {
+                       id = hash__alloc_context_id();
+                       if (id < 0)
+                               goto error;
+
+                       ctx->extended_id[i] = id;
+               }
+       }
+
+       /* The caller expects us to return id */
+       return ctx->id;
+
+error:
+       for (i--; i >= 0; i--) {
+               if (ctx->extended_id[i])
+                       ida_free(&mmu_context_ida, ctx->extended_id[i]);
+       }
+
+       return id;
+}
+
 static int hash__init_new_context(struct mm_struct *mm)
 {
        int index;
 
-       index = hash__alloc_context_id();
-       if (index < 0)
-               return index;
-
        mm->context.hash_context = kmalloc(sizeof(struct hash_mm_context),
                                           GFP_KERNEL);
-       if (!mm->context.hash_context) {
-               ida_free(&mmu_context_ida, index);
+       if (!mm->context.hash_context)
                return -ENOMEM;
-       }
 
        /*
         * The old code would re-promote on fork, we don't do that when using
@@ -91,13 +123,20 @@ static int hash__init_new_context(struct mm_struct *mm)
                        mm->context.hash_context->spt = kmalloc(sizeof(struct subpage_prot_table),
                                                                GFP_KERNEL);
                        if (!mm->context.hash_context->spt) {
-                               ida_free(&mmu_context_ida, index);
                                kfree(mm->context.hash_context);
                                return -ENOMEM;
                        }
                }
 #endif
+       }
 
+       index = realloc_context_ids(&mm->context);
+       if (index < 0) {
+#ifdef CONFIG_PPC_SUBPAGE_PROT
+               kfree(mm->context.hash_context->spt);
+#endif
+               kfree(mm->context.hash_context);
+               return index;
        }
 
        pkey_mm_init(mm);
index 40c8a552a478e7e7b8818788e22e57f7ba7ec427..4074886b7bc85b9dc9ab438081b82bba134e953c 100644 (file)
@@ -52,8 +52,9 @@ static const struct fb_var_screeninfo cfag12864bfb_var = {
 
 static int cfag12864bfb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
-       return vm_insert_page(vma, vma->vm_start,
-               virt_to_page(cfag12864b_buffer));
+       struct page *pages = virt_to_page(cfag12864b_buffer);
+
+       return vm_map_pages_zero(vma, &pages, 1);
 }
 
 static struct fb_ops cfag12864bfb_ops = {
index 21393ec3b9a4a58fe13037f59be6a3d1466f747e..9c0bb771751d8d986b7f53d1724f1077f9412a1f 100644 (file)
@@ -223,9 +223,9 @@ static const struct backlight_ops ht16k33_bl_ops = {
 static int ht16k33_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
        struct ht16k33_priv *priv = info->par;
+       struct page *pages = virt_to_page(priv->fbdev.buffer);
 
-       return vm_insert_page(vma, vma->vm_start,
-                             virt_to_page(priv->fbdev.buffer));
+       return vm_map_pages_zero(vma, &pages, 1);
 }
 
 static struct fb_ops ht16k33_fb_ops = {
index eac0c54c59701889922adf858fa37295ab0060ad..b032d3899fa35ce412325025c110ad17a677a535 100644 (file)
@@ -80,6 +80,7 @@
 #define HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP    0x1220
 #define HID_DEVICE_ID_ALPS_U1          0x1215
 #define HID_DEVICE_ID_ALPS_T4_BTNLESS  0x120C
+#define HID_DEVICE_ID_ALPS_1222                0x1222
 
 
 #define USB_VENDOR_ID_AMI              0x046b
 #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH      0xb19d
 #define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618
 #define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE 0x1053
+#define USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2        0x0939
 #define USB_DEVICE_ID_CHICONY_WIRELESS2        0x1123
 #define USB_DEVICE_ID_ASUS_AK1D                0x1125
 #define USB_DEVICE_ID_CHICONY_TOSHIBA_WT10A    0x1408
 
 #define USB_VENDOR_ID_HUION            0x256c
 #define USB_DEVICE_ID_HUION_TABLET     0x006e
+#define USB_DEVICE_ID_HUION_HS64       0x006d
 
 #define USB_VENDOR_ID_IBM                                      0x04b3
 #define USB_DEVICE_ID_IBM_SCROLLPOINT_III                      0x3100
index e564bff865159af9c7bf4631f52cef9a209d536d..bfcf2ee58d1495dbfed915ba475a3ce0fecd772b 100644 (file)
@@ -30,6 +30,7 @@
 
 #define REPORT_ID_HIDPP_SHORT                  0x10
 #define REPORT_ID_HIDPP_LONG                   0x11
+#define REPORT_ID_HIDPP_VERY_LONG              0x12
 
 #define HIDPP_REPORT_SHORT_LENGTH              7
 #define HIDPP_REPORT_LONG_LENGTH               20
@@ -1242,7 +1243,8 @@ static int logi_dj_ll_raw_request(struct hid_device *hid,
        int ret;
 
        if ((buf[0] == REPORT_ID_HIDPP_SHORT) ||
-           (buf[0] == REPORT_ID_HIDPP_LONG)) {
+           (buf[0] == REPORT_ID_HIDPP_LONG) ||
+           (buf[0] == REPORT_ID_HIDPP_VERY_LONG)) {
                if (count < 2)
                        return -EINVAL;
 
index 5df5dd56ecc8b67f4e43f09f7d70ead8a0dc49fb..b603c14d043b89c146fc55ff71da16147b157c80 100644 (file)
@@ -1776,6 +1776,10 @@ static const struct hid_device_id mt_devices[] = {
                HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
                        USB_VENDOR_ID_ALPS_JP,
                        HID_DEVICE_ID_ALPS_U1_DUAL_3BTN_PTP) },
+       { .driver_data = MT_CLS_WIN_8_DUAL,
+               HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8,
+                       USB_VENDOR_ID_ALPS_JP,
+                       HID_DEVICE_ID_ALPS_1222) },
 
        /* Lenovo X1 TAB Gen 2 */
        { .driver_data = MT_CLS_WIN_8_DUAL,
index e5ca6fe2ca5708265bc67e37d0e7ab13e91c44e3..671a285724f9d807b9114328e82692bffef2c835 100644 (file)
@@ -42,6 +42,7 @@ static const struct hid_device_id hid_quirks[] = {
        { HID_USB_DEVICE(USB_VENDOR_ID_ATEN, USB_DEVICE_ID_ATEN_UC100KM), HID_QUIRK_NOGET },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH), HID_QUIRK_MULTI_INPUT },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE), HID_QUIRK_ALWAYS_POLL },
+       { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_PIXART_USB_OPTICAL_MOUSE2), HID_QUIRK_ALWAYS_POLL },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS), HID_QUIRK_MULTI_INPUT },
        { HID_USB_DEVICE(USB_VENDOR_ID_CHIC, USB_DEVICE_ID_CHIC_GAMEPAD), HID_QUIRK_BADPAD },
        { HID_USB_DEVICE(USB_VENDOR_ID_CH, USB_DEVICE_ID_CH_3AXIS_5BUTTON_STICK), HID_QUIRK_NOGET },
index 8fe02d81265d0aed8a3e774e415b06d31fded339..914fb527ae7a78e57fdad2dee7e6d50641c2f6cf 100644 (file)
@@ -369,6 +369,8 @@ static const struct hid_device_id uclogic_devices[] = {
                                USB_DEVICE_ID_UCLOGIC_TABLET_TWHA60) },
        { HID_USB_DEVICE(USB_VENDOR_ID_HUION,
                                USB_DEVICE_ID_HUION_TABLET) },
+       { HID_USB_DEVICE(USB_VENDOR_ID_HUION,
+                               USB_DEVICE_ID_HUION_HS64) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
                                USB_DEVICE_ID_HUION_TABLET) },
        { HID_USB_DEVICE(USB_VENDOR_ID_UCLOGIC,
index 0187c9f8fc22c5567e934cc0cc2089877963c56e..273d784fff66df68bb7ab8166599ca343e939813 100644 (file)
@@ -977,6 +977,8 @@ int uclogic_params_init(struct uclogic_params *params,
                /* FALL THROUGH */
        case VID_PID(USB_VENDOR_ID_HUION,
                     USB_DEVICE_ID_HUION_TABLET):
+       case VID_PID(USB_VENDOR_ID_HUION,
+                    USB_DEVICE_ID_HUION_HS64):
        case VID_PID(USB_VENDOR_ID_UCLOGIC,
                     USB_DEVICE_ID_HUION_TABLET):
        case VID_PID(USB_VENDOR_ID_UCLOGIC,
index 22ba2145703504ce1c34af1ef59ddf3eea6d12d7..aa2dbed30fc36aef68c81a7d16b355034f0a677d 100644 (file)
@@ -816,9 +816,9 @@ static int load_fw_from_host(struct ishtp_cl_data *client_data)
                goto end_err_fw_release;
 
        release_firmware(fw);
-       kfree(filename);
        dev_info(cl_data_to_dev(client_data), "ISH firmware %s loaded\n",
                 filename);
+       kfree(filename);
        return 0;
 
 end_err_fw_release:
index c0487b34d2cf1a08c99fb4010560e71e111334c9..6ba944b40fdb4818f764e70b3f9b2a0fd30dc7c2 100644 (file)
@@ -891,7 +891,7 @@ static int hid_ishtp_cl_reset(struct ishtp_cl_device *cl_device)
  */
 static int hid_ishtp_cl_suspend(struct device *device)
 {
-       struct ishtp_cl_device *cl_device = dev_get_drvdata(device);
+       struct ishtp_cl_device *cl_device = ishtp_dev_to_cl_device(device);
        struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
        struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
 
@@ -912,7 +912,7 @@ static int hid_ishtp_cl_suspend(struct device *device)
  */
 static int hid_ishtp_cl_resume(struct device *device)
 {
-       struct ishtp_cl_device *cl_device = dev_get_drvdata(device);
+       struct ishtp_cl_device *cl_device = ishtp_dev_to_cl_device(device);
        struct ishtp_cl *hid_ishtp_cl = ishtp_get_drvdata(cl_device);
        struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
 
index 794e700d65f79dce70edb7aa8683b62479283e01..c47c3328a0f44e842a8ee956bc26057a3d261d6e 100644 (file)
@@ -471,7 +471,6 @@ static struct ishtp_cl_device *ishtp_bus_add_device(struct ishtp_device *dev,
        }
 
        ishtp_device_ready = true;
-       dev_set_drvdata(&device->dev, device);
 
        return device;
 }
@@ -639,6 +638,20 @@ void *ishtp_get_drvdata(struct ishtp_cl_device *cl_device)
 }
 EXPORT_SYMBOL(ishtp_get_drvdata);
 
+/**
+ * ishtp_dev_to_cl_device() - get ishtp_cl_device instance from device instance
+ * @device: device instance
+ *
+ * Get ish_cl_device instance which embeds device instance in it.
+ *
+ * Return: pointer to ishtp_cl_device instance
+ */
+struct ishtp_cl_device *ishtp_dev_to_cl_device(struct device *device)
+{
+       return to_ishtp_cl_device(device);
+}
+EXPORT_SYMBOL(ishtp_dev_to_cl_device);
+
 /**
  * ishtp_bus_new_client() - Create a new client
  * @dev:       ISHTP device instance
index fe8efba2d45f5e568da3b084c98ddf8e74734c52..857991cb3cbb8b5a890514a24d0b3e7d2e0467c0 100644 (file)
@@ -204,12 +204,11 @@ static struct irq_chip stmfx_irq_chip = {
 static irqreturn_t stmfx_irq_handler(int irq, void *data)
 {
        struct stmfx *stmfx = data;
-       unsigned long n, pending;
-       u32 ack;
-       int ret;
+       unsigned long bits;
+       u32 pending, ack;
+       int n, ret;
 
-       ret = regmap_read(stmfx->map, STMFX_REG_IRQ_PENDING,
-                         (u32 *)&pending);
+       ret = regmap_read(stmfx->map, STMFX_REG_IRQ_PENDING, &pending);
        if (ret)
                return IRQ_NONE;
 
@@ -224,7 +223,8 @@ static irqreturn_t stmfx_irq_handler(int irq, void *data)
                        return IRQ_NONE;
        }
 
-       for_each_set_bit(n, &pending, STMFX_REG_IRQ_SRC_MAX)
+       bits = pending;
+       for_each_set_bit(n, &bits, STMFX_REG_IRQ_SRC_MAX)
                handle_nested_irq(irq_find_mapping(stmfx->irq_domain, n));
 
        return IRQ_HANDLED;
index b5b68aa16eb36e06c6d0a8cc34bd87ba1f36840c..6eb131292eb2ce1316fb1c96e32b81e019ee9b27 100644 (file)
@@ -4662,7 +4662,6 @@ static int nand_detect(struct nand_chip *chip, struct nand_flash_dev *type)
        memorg = nanddev_get_memorg(&chip->base);
        memorg->planes_per_lun = 1;
        memorg->luns_per_target = 1;
-       memorg->ntargets = 1;
 
        /*
         * Reset the chip, required by some chips (e.g. Micron MT29FxGxxxxx)
@@ -5027,6 +5026,8 @@ static int nand_scan_ident(struct nand_chip *chip, unsigned int maxchips,
        if (ret)
                return ret;
 
+       memorg->ntargets = maxchips;
+
        /* Read the flash type */
        ret = nand_detect(chip, table);
        if (ret) {
index 73172d7f512bc0f3ef23454dcef9ef44a9869693..0c2ec1c21434c5ea79b36b51c700d7b2cd110081 100644 (file)
@@ -1636,6 +1636,95 @@ static int sr2_bit7_quad_enable(struct spi_nor *nor)
        return 0;
 }
 
+/**
+ * spi_nor_clear_sr_bp() - clear the Status Register Block Protection bits.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_clear_sr_bp(struct spi_nor *nor)
+{
+       int ret;
+       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+
+       ret = read_sr(nor);
+       if (ret < 0) {
+               dev_err(nor->dev, "error while reading status register\n");
+               return ret;
+       }
+
+       write_enable(nor);
+
+       ret = write_sr(nor, ret & ~mask);
+       if (ret) {
+               dev_err(nor->dev, "write to status register failed\n");
+               return ret;
+       }
+
+       ret = spi_nor_wait_till_ready(nor);
+       if (ret)
+               dev_err(nor->dev, "timeout while writing status register\n");
+       return ret;
+}
+
+/**
+ * spi_nor_spansion_clear_sr_bp() - clear the Status Register Block Protection
+ * bits on spansion flashes.
+ * @nor:        pointer to a 'struct spi_nor'
+ *
+ * Read-modify-write function that clears the Block Protection bits from the
+ * Status Register without affecting other bits. The function is tightly
+ * coupled with the spansion_quad_enable() function. Both assume that the Write
+ * Register with 16 bits, together with the Read Configuration Register (35h)
+ * instructions are supported.
+ *
+ * Return: 0 on success, -errno otherwise.
+ */
+static int spi_nor_spansion_clear_sr_bp(struct spi_nor *nor)
+{
+       int ret;
+       u8 mask = SR_BP2 | SR_BP1 | SR_BP0;
+       u8 sr_cr[2] = {0};
+
+       /* Check current Quad Enable bit value. */
+       ret = read_cr(nor);
+       if (ret < 0) {
+               dev_err(nor->dev,
+                       "error while reading configuration register\n");
+               return ret;
+       }
+
+       /*
+        * When the configuration register Quad Enable bit is one, only the
+        * Write Status (01h) command with two data bytes may be used.
+        */
+       if (ret & CR_QUAD_EN_SPAN) {
+               sr_cr[1] = ret;
+
+               ret = read_sr(nor);
+               if (ret < 0) {
+                       dev_err(nor->dev,
+                               "error while reading status register\n");
+                       return ret;
+               }
+               sr_cr[0] = ret & ~mask;
+
+               ret = write_sr_cr(nor, sr_cr);
+               if (ret)
+                       dev_err(nor->dev, "16-bit write register failed\n");
+               return ret;
+       }
+
+       /*
+        * If the Quad Enable bit is zero, use the Write Status (01h) command
+        * with one data byte.
+        */
+       return spi_nor_clear_sr_bp(nor);
+}
+
 /* Used when the "_ext_id" is two bytes at most */
 #define INFO(_jedec_id, _ext_id, _sector_size, _n_sectors, _flags)     \
                .id = {                                                 \
@@ -3660,6 +3749,8 @@ static int spi_nor_init_params(struct spi_nor *nor,
                default:
                        /* Kept only for backward compatibility purpose. */
                        params->quad_enable = spansion_quad_enable;
+                       if (nor->clear_sr_bp)
+                               nor->clear_sr_bp = spi_nor_spansion_clear_sr_bp;
                        break;
                }
 
@@ -3912,17 +4003,13 @@ static int spi_nor_init(struct spi_nor *nor)
 {
        int err;
 
-       /*
-        * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
-        * with the software protection bits set
-        */
-       if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
-           JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
-           JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
-           nor->info->flags & SPI_NOR_HAS_LOCK) {
-               write_enable(nor);
-               write_sr(nor, 0);
-               spi_nor_wait_till_ready(nor);
+       if (nor->clear_sr_bp) {
+               err = nor->clear_sr_bp(nor);
+               if (err) {
+                       dev_err(nor->dev,
+                               "fail to clear block protection bits\n");
+                       return err;
+               }
        }
 
        if (nor->quad_enable) {
@@ -4047,6 +4134,16 @@ int spi_nor_scan(struct spi_nor *nor, const char *name,
        if (info->flags & SPI_S3AN)
                nor->flags |=  SNOR_F_READY_XSR_RDY;
 
+       /*
+        * Atmel, SST, Intel/Numonyx, and others serial NOR tend to power up
+        * with the software protection bits set.
+        */
+       if (JEDEC_MFR(nor->info) == SNOR_MFR_ATMEL ||
+           JEDEC_MFR(nor->info) == SNOR_MFR_INTEL ||
+           JEDEC_MFR(nor->info) == SNOR_MFR_SST ||
+           nor->info->flags & SPI_NOR_HAS_LOCK)
+               nor->clear_sr_bp = spi_nor_clear_sr_bp;
+
        /* Parse the Serial Flash Discoverable Parameters table. */
        ret = spi_nor_init_params(nor, &params);
        if (ret)
index 407f4095a37a9d56a4615dac03c6e5efbd53ffb7..799fc38c5c34e8d167a7a14d01eff54034a1f86a 100644 (file)
@@ -4320,12 +4320,12 @@ void bond_setup(struct net_device *bond_dev)
        bond_dev->features |= NETIF_F_NETNS_LOCAL;
 
        bond_dev->hw_features = BOND_VLAN_FEATURES |
-                               NETIF_F_HW_VLAN_CTAG_TX |
                                NETIF_F_HW_VLAN_CTAG_RX |
                                NETIF_F_HW_VLAN_CTAG_FILTER;
 
        bond_dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
        bond_dev->features |= bond_dev->hw_features;
+       bond_dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
 }
 
 /* Destroy a bonding device.
index f46086fa906462e18913821153a7f1f936aa0799..db91b213eae1c6252fa40910c78fdab6ce04d3cb 100644 (file)
@@ -436,9 +436,9 @@ int ksz_switch_register(struct ksz_device *dev,
                return PTR_ERR(dev->reset_gpio);
 
        if (dev->reset_gpio) {
-               gpiod_set_value(dev->reset_gpio, 1);
+               gpiod_set_value_cansleep(dev->reset_gpio, 1);
                mdelay(10);
-               gpiod_set_value(dev->reset_gpio, 0);
+               gpiod_set_value_cansleep(dev->reset_gpio, 0);
        }
 
        mutex_init(&dev->dev_mutex);
@@ -487,7 +487,7 @@ void ksz_switch_remove(struct ksz_device *dev)
        dsa_unregister_switch(dev->ds);
 
        if (dev->reset_gpio)
-               gpiod_set_value(dev->reset_gpio, 1);
+               gpiod_set_value_cansleep(dev->reset_gpio, 1);
 
 }
 EXPORT_SYMBOL(ksz_switch_remove);
index 18bc035da850eb4d9555602f7422d419859ee3f7..1fff462a4175e87eba57e7d7e63b2bbf9bf0e16a 100644 (file)
@@ -843,9 +843,14 @@ int aq_filters_vlans_update(struct aq_nic_s *aq_nic)
                return err;
 
        if (aq_nic->ndev->features & NETIF_F_HW_VLAN_CTAG_FILTER) {
-               if (hweight < AQ_VLAN_MAX_FILTERS)
-                       err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, true);
+               if (hweight < AQ_VLAN_MAX_FILTERS && hweight > 0) {
+                       err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw,
+                               !(aq_nic->packet_filter & IFF_PROMISC));
+                       aq_nic->aq_nic_cfg.is_vlan_force_promisc = false;
+               } else {
                /* otherwise left in promiscue mode */
+                       aq_nic->aq_nic_cfg.is_vlan_force_promisc = true;
+               }
        }
 
        return err;
@@ -866,6 +871,7 @@ int aq_filters_vlan_offload_off(struct aq_nic_s *aq_nic)
        if (unlikely(!aq_hw_ops->hw_filter_vlan_ctrl))
                return -EOPNOTSUPP;
 
+       aq_nic->aq_nic_cfg.is_vlan_force_promisc = true;
        err = aq_hw_ops->hw_filter_vlan_ctrl(aq_hw, false);
        if (err)
                return err;
index 0da5e161ec5d532d24c3b6556548fca0d23e2640..41172fbebddd3c5cb14307b4e3c691ef044eac9b 100644 (file)
@@ -126,6 +126,7 @@ void aq_nic_cfg_start(struct aq_nic_s *self)
 
        cfg->link_speed_msk &= cfg->aq_hw_caps->link_speed_msk;
        cfg->features = cfg->aq_hw_caps->hw_features;
+       cfg->is_vlan_force_promisc = true;
 }
 
 static int aq_nic_update_link_status(struct aq_nic_s *self)
index eb2e3c7c36f95c94189e23e8d66bdd4e48963d26..0f22f5d5691b30c1ba025b7a9c5eb65339c0f798 100644 (file)
@@ -35,6 +35,7 @@ struct aq_nic_cfg_s {
        u32 flow_control;
        u32 link_speed_msk;
        u32 wol;
+       bool is_vlan_force_promisc;
        u16 is_mc_list_enabled;
        u16 mc_list_count;
        bool is_autoneg;
index 1c7593d54035a44455db81166ef26eec772dc489..13ac2661a473c866d0a53a327e67fd77458738fe 100644 (file)
@@ -778,8 +778,15 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
                                          unsigned int packet_filter)
 {
        unsigned int i = 0U;
+       struct aq_nic_cfg_s *cfg = self->aq_nic_cfg;
+
+       hw_atl_rpfl2promiscuous_mode_en_set(self,
+                                           IS_FILTER_ENABLED(IFF_PROMISC));
+
+       hw_atl_rpf_vlan_prom_mode_en_set(self,
+                                    IS_FILTER_ENABLED(IFF_PROMISC) ||
+                                    cfg->is_vlan_force_promisc);
 
-       hw_atl_rpfl2promiscuous_mode_en_set(self, IS_FILTER_ENABLED(IFF_PROMISC));
        hw_atl_rpfl2multicast_flr_en_set(self,
                                         IS_FILTER_ENABLED(IFF_ALLMULTI), 0);
 
@@ -788,13 +795,13 @@ static int hw_atl_b0_hw_packet_filter_set(struct aq_hw_s *self,
 
        hw_atl_rpfl2broadcast_en_set(self, IS_FILTER_ENABLED(IFF_BROADCAST));
 
-       self->aq_nic_cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST);
+       cfg->is_mc_list_enabled = IS_FILTER_ENABLED(IFF_MULTICAST);
 
        for (i = HW_ATL_B0_MAC_MIN; i < HW_ATL_B0_MAC_MAX; ++i)
                hw_atl_rpfl2_uc_flr_en_set(self,
-                                          (self->aq_nic_cfg->is_mc_list_enabled &&
-                                   (i <= self->aq_nic_cfg->mc_list_count)) ?
-                                   1U : 0U, i);
+                                          (cfg->is_mc_list_enabled &&
+                                           (i <= cfg->mc_list_count)) ?
+                                          1U : 0U, i);
 
        return aq_hw_err_from_flags(self);
 }
@@ -1086,7 +1093,7 @@ static int hw_atl_b0_hw_vlan_set(struct aq_hw_s *self,
 static int hw_atl_b0_hw_vlan_ctrl(struct aq_hw_s *self, bool enable)
 {
        /* set promisc in case of disabing the vland filter */
-       hw_atl_rpf_vlan_prom_mode_en_set(self, !!!enable);
+       hw_atl_rpf_vlan_prom_mode_en_set(self, !enable);
 
        return aq_hw_err_from_flags(self);
 }
index 2375a13bb44690d5dea8108b2195e106936ce92d..262a28ff81fc7338e1408e27861f2c9b6a2bf9fb 100644 (file)
@@ -4180,7 +4180,7 @@ static int macb_probe(struct platform_device *pdev)
        if (PTR_ERR(mac) == -EPROBE_DEFER) {
                err = -EPROBE_DEFER;
                goto err_out_free_netdev;
-       } else if (!IS_ERR(mac)) {
+       } else if (!IS_ERR_OR_NULL(mac)) {
                ether_addr_copy(bp->dev->dev_addr, mac);
        } else {
                macb_get_hwaddr(bp);
index 8a6785173228f3b5892522d6b338abee7a66bb15..492f8769ac12c2339aabfc4a0f718cac19a26a8a 100644 (file)
@@ -891,7 +891,7 @@ static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
                         u64 *data)
 {
        struct be_adapter *adapter = netdev_priv(netdev);
-       int status;
+       int status, cnt;
        u8 link_status = 0;
 
        if (adapter->function_caps & BE_FUNCTION_CAPS_SUPER_NIC) {
@@ -902,6 +902,9 @@ static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
 
        memset(data, 0, sizeof(u64) * ETHTOOL_TESTS_NUM);
 
+       /* check link status before offline tests */
+       link_status = netif_carrier_ok(netdev);
+
        if (test->flags & ETH_TEST_FL_OFFLINE) {
                if (be_loopback_test(adapter, BE_MAC_LOOPBACK, &data[0]) != 0)
                        test->flags |= ETH_TEST_FL_FAILED;
@@ -922,13 +925,26 @@ static void be_self_test(struct net_device *netdev, struct ethtool_test *test,
                test->flags |= ETH_TEST_FL_FAILED;
        }
 
-       status = be_cmd_link_status_query(adapter, NULL, &link_status, 0);
-       if (status) {
-               test->flags |= ETH_TEST_FL_FAILED;
-               data[4] = -1;
-       } else if (!link_status) {
+       /* link status was down prior to test */
+       if (!link_status) {
                test->flags |= ETH_TEST_FL_FAILED;
                data[4] = 1;
+               return;
+       }
+
+       for (cnt = 10; cnt; cnt--) {
+               status = be_cmd_link_status_query(adapter, NULL, &link_status,
+                                                 0);
+               if (status) {
+                       test->flags |= ETH_TEST_FL_FAILED;
+                       data[4] = -1;
+                       break;
+               }
+
+               if (link_status)
+                       break;
+
+               msleep_interruptible(500);
        }
 }
 
index 67f9bb6e941b7ed2467dcfd78a49a0e6c2c8165d..9b036c857b1d4d8b0e350e250e6a909b3de7294b 100644 (file)
@@ -1057,7 +1057,7 @@ sis900_open(struct net_device *net_dev)
        sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
 
        /* Enable all known interrupts by setting the interrupt mask. */
-       sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
+       sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE | TxDESC);
        sw32(cr, RxENA | sr32(cr));
        sw32(ier, IE);
 
@@ -1578,7 +1578,7 @@ static void sis900_tx_timeout(struct net_device *net_dev)
        sw32(txdp, sis_priv->tx_ring_dma);
 
        /* Enable all known interrupts by setting the interrupt mask. */
-       sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
+       sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE | TxDESC);
 }
 
 /**
@@ -1618,7 +1618,7 @@ sis900_start_xmit(struct sk_buff *skb, struct net_device *net_dev)
                        spin_unlock_irqrestore(&sis_priv->lock, flags);
                        return NETDEV_TX_OK;
        }
-       sis_priv->tx_ring[entry].cmdsts = (OWN | skb->len);
+       sis_priv->tx_ring[entry].cmdsts = (OWN | INTR | skb->len);
        sw32(cr, TxENA | sr32(cr));
 
        sis_priv->cur_tx ++;
@@ -1674,7 +1674,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
        do {
                status = sr32(isr);
 
-               if ((status & (HIBERR|TxURN|TxERR|TxIDLE|RxORN|RxERR|RxOK)) == 0)
+               if ((status & (HIBERR|TxURN|TxERR|TxIDLE|TxDESC|RxORN|RxERR|RxOK)) == 0)
                        /* nothing intresting happened */
                        break;
                handled = 1;
@@ -1684,7 +1684,7 @@ static irqreturn_t sis900_interrupt(int irq, void *dev_instance)
                        /* Rx interrupt */
                        sis900_rx(net_dev);
 
-               if (status & (TxURN | TxERR | TxIDLE))
+               if (status & (TxURN | TxERR | TxIDLE | TxDESC))
                        /* Tx interrupt */
                        sis900_finish_xmit(net_dev);
 
@@ -1896,8 +1896,8 @@ static void sis900_finish_xmit (struct net_device *net_dev)
 
                if (tx_status & OWN) {
                        /* The packet is not transmitted yet (owned by hardware) !
-                        * Note: the interrupt is generated only when Tx Machine
-                        * is idle, so this is an almost impossible case */
+                        * Note: this is an almost impossible condition
+                        * in case of TxDESC ('descriptor interrupt') */
                        break;
                }
 
@@ -2473,7 +2473,7 @@ static int sis900_resume(struct pci_dev *pci_dev)
        sis900_set_mode(sis_priv, HW_SPEED_10_MBPS, FDX_CAPABLE_HALF_SELECTED);
 
        /* Enable all known interrupts by setting the interrupt mask. */
-       sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE);
+       sw32(imr, RxSOVR | RxORN | RxERR | RxOK | TxURN | TxERR | TxIDLE | TxDESC);
        sw32(cr, RxENA | sr32(cr));
        sw32(ier, IE);
 
index 2dcdf761d525e7a15728a935f6836004e42ee5c2..0201596225592415b478218718a2212d06f9db6b 100644 (file)
@@ -112,7 +112,7 @@ static int adjust_systime(void __iomem *ioaddr, u32 sec, u32 nsec,
                 * programmed with (2^32 â€“ <new_sec_value>)
                 */
                if (gmac4)
-                       sec = (100000000ULL - sec);
+                       sec = -sec;
 
                value = readl(ioaddr + PTP_TCR);
                if (value & PTP_TCR_TSCTRLSSR)
index 06dd51f47cfd11a9559b6f2e7b2aa7543d2069f8..06358fe5b2456baf8dff0484543281ac7c223865 100644 (file)
@@ -2947,12 +2947,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
 
        /* Manage tx mitigation */
        tx_q->tx_count_frames += nfrags + 1;
-       if (priv->tx_coal_frames <= tx_q->tx_count_frames) {
+       if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
+           !(priv->synopsys_id >= DWMAC_CORE_4_00 &&
+           (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+           priv->hwts_tx_en)) {
+               stmmac_tx_timer_arm(priv, queue);
+       } else {
+               tx_q->tx_count_frames = 0;
                stmmac_set_tx_ic(priv, desc);
                priv->xstats.tx_set_ic_bit++;
-               tx_q->tx_count_frames = 0;
-       } else {
-               stmmac_tx_timer_arm(priv, queue);
        }
 
        skb_tx_timestamp(skb);
@@ -3166,12 +3169,15 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
         * element in case of no SG.
         */
        tx_q->tx_count_frames += nfrags + 1;
-       if (priv->tx_coal_frames <= tx_q->tx_count_frames) {
+       if (likely(priv->tx_coal_frames > tx_q->tx_count_frames) &&
+           !(priv->synopsys_id >= DWMAC_CORE_4_00 &&
+           (skb_shinfo(skb)->tx_flags & SKBTX_HW_TSTAMP) &&
+           priv->hwts_tx_en)) {
+               stmmac_tx_timer_arm(priv, queue);
+       } else {
+               tx_q->tx_count_frames = 0;
                stmmac_set_tx_ic(priv, desc);
                priv->xstats.tx_set_ic_bit++;
-               tx_q->tx_count_frames = 0;
-       } else {
-               stmmac_tx_timer_arm(priv, queue);
        }
 
        skb_tx_timestamp(skb);
index ff61dd8748dea206af81ec419204240511b06d78..66c8e65f68720c5a6b30277b872b88dc342991f7 100644 (file)
@@ -63,6 +63,7 @@ MODULE_AUTHOR("Frank Cusack <fcusack@fcusack.com>");
 MODULE_DESCRIPTION("Point-to-Point Protocol Microsoft Point-to-Point Encryption support");
 MODULE_LICENSE("Dual BSD/GPL");
 MODULE_ALIAS("ppp-compress-" __stringify(CI_MPPE));
+MODULE_SOFTDEP("pre: arc4");
 MODULE_VERSION("1.0.2");
 
 static unsigned int
index b48006e7fa2f381bd2577340ca84dea4188ed30e..36916bf51ee6e64d6c45e60690e444cf168708f2 100644 (file)
@@ -2128,12 +2128,12 @@ static void team_setup(struct net_device *dev)
        dev->features |= NETIF_F_NETNS_LOCAL;
 
        dev->hw_features = TEAM_VLAN_FEATURES |
-                          NETIF_F_HW_VLAN_CTAG_TX |
                           NETIF_F_HW_VLAN_CTAG_RX |
                           NETIF_F_HW_VLAN_CTAG_FILTER;
 
        dev->hw_features |= NETIF_F_GSO_ENCAP_ALL | NETIF_F_GSO_UDP_L4;
        dev->features |= dev->hw_features;
+       dev->features |= NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_STAG_TX;
 }
 
 static int team_newlink(struct net *src_net, struct net_device *dev,
index d080f8048e522d62c2b0481319f28b38f10d867e..8b4ad10cf9402a9e14c1999faa53feeada22cb5b 100644 (file)
@@ -1482,7 +1482,7 @@ static int qmi_wwan_probe(struct usb_interface *intf,
         * different. Ignore the current interface if the number of endpoints
         * equals the number for the diag interface (two).
         */
-       info = (void *)&id->driver_info;
+       info = (void *)id->driver_info;
 
        if (info->data & QMI_WWAN_QUIRK_QUECTEL_DYNCFG) {
                if (desc->bNumEndpoints == 2)
index 11b9525dff277055c693e9b876313d2839513537..311b0cc6eb986ad96107cad57d8202cfedc3c68b 100644 (file)
@@ -350,8 +350,8 @@ static int vrf_finish_output6(struct net *net, struct sock *sk,
 {
        struct dst_entry *dst = skb_dst(skb);
        struct net_device *dev = dst->dev;
+       const struct in6_addr *nexthop;
        struct neighbour *neigh;
-       struct in6_addr *nexthop;
        int ret;
 
        nf_reset(skb);
index d441bef72163289cfcde8ceff2d3271438d2c0f9..915010464572589bfc38b18f28d27598c1c3987e 100644 (file)
@@ -275,9 +275,9 @@ static void afs_break_one_callback(struct afs_server *server,
                        struct afs_super_info *as = AFS_FS_S(cbi->sb);
                        struct afs_volume *volume = as->volume;
 
-                       write_lock(&volume->cb_break_lock);
+                       write_lock(&volume->cb_v_break_lock);
                        volume->cb_v_break++;
-                       write_unlock(&volume->cb_break_lock);
+                       write_unlock(&volume->cb_v_break_lock);
                } else {
                        data.volume = NULL;
                        data.fid = *fid;
index b42d9d09669c863ce51ef463bc695085c072eccd..18a50d4febcffeec5dc014fef3bbb6fa74d113f9 100644 (file)
@@ -55,6 +55,16 @@ static noinline void dump_vnode(struct afs_vnode *vnode, struct afs_vnode *paren
                dump_stack();
 }
 
+/*
+ * Set the file size and block count.  Estimate the number of 512 bytes blocks
+ * used, rounded up to nearest 1K for consistency with other AFS clients.
+ */
+static void afs_set_i_size(struct afs_vnode *vnode, u64 size)
+{
+       i_size_write(&vnode->vfs_inode, size);
+       vnode->vfs_inode.i_blocks = ((size + 1023) >> 10) << 1;
+}
+
 /*
  * Initialise an inode from the vnode status.
  */
@@ -124,12 +134,7 @@ static int afs_inode_init_from_status(struct afs_vnode *vnode, struct key *key,
                return afs_protocol_error(NULL, -EBADMSG, afs_eproto_file_type);
        }
 
-       /*
-        * Estimate 512 bytes  blocks used, rounded up to nearest 1K
-        * for consistency with other AFS clients.
-        */
-       inode->i_blocks         = ((i_size_read(inode) + 1023) >> 10) << 1;
-       i_size_write(&vnode->vfs_inode, status->size);
+       afs_set_i_size(vnode, status->size);
 
        vnode->invalid_before   = status->data_version;
        inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
@@ -207,11 +212,13 @@ static void afs_apply_status(struct afs_fs_cursor *fc,
 
        if (expected_version &&
            *expected_version != status->data_version) {
-               kdebug("vnode modified %llx on {%llx:%llu} [exp %llx] %s",
-                      (unsigned long long) status->data_version,
-                      vnode->fid.vid, vnode->fid.vnode,
-                      (unsigned long long) *expected_version,
-                      fc->type ? fc->type->name : "???");
+               if (test_bit(AFS_VNODE_CB_PROMISED, &vnode->flags))
+                       pr_warn("kAFS: vnode modified {%llx:%llu} %llx->%llx %s\n",
+                               vnode->fid.vid, vnode->fid.vnode,
+                               (unsigned long long)*expected_version,
+                               (unsigned long long)status->data_version,
+                               fc->type ? fc->type->name : "???");
+
                vnode->invalid_before = status->data_version;
                if (vnode->status.type == AFS_FTYPE_DIR) {
                        if (test_and_clear_bit(AFS_VNODE_DIR_VALID, &vnode->flags))
@@ -230,7 +237,7 @@ static void afs_apply_status(struct afs_fs_cursor *fc,
 
        if (data_changed) {
                inode_set_iversion_raw(&vnode->vfs_inode, status->data_version);
-               i_size_write(&vnode->vfs_inode, status->size);
+               afs_set_i_size(vnode, status->size);
        }
 }
 
index 8a67bf7418807b3ebe388c7e0a0fccd0dbcfcd75..7ee63526c6a26f9ad6dcf1db82a61f0f3adce7c7 100644 (file)
@@ -109,10 +109,8 @@ struct afs_call {
        struct rxrpc_call       *rxcall;        /* RxRPC call handle */
        struct key              *key;           /* security for this call */
        struct afs_net          *net;           /* The network namespace */
-       union {
-               struct afs_server       *server;
-               struct afs_vlserver     *vlserver;
-       };
+       struct afs_server       *server;        /* The fileserver record if fs op (pins ref) */
+       struct afs_vlserver     *vlserver;      /* The vlserver record if vl op */
        struct afs_cb_interest  *cbi;           /* Callback interest for server used */
        struct afs_vnode        *lvnode;        /* vnode being locked */
        void                    *request;       /* request data (first part) */
@@ -616,7 +614,7 @@ struct afs_volume {
        unsigned int            servers_seq;    /* Incremented each time ->servers changes */
 
        unsigned                cb_v_break;     /* Break-everything counter. */
-       rwlock_t                cb_break_lock;
+       rwlock_t                cb_v_break_lock;
 
        afs_voltype_t           type;           /* type of volume */
        short                   error;
index 08fdb3951c4952c92ca49cff8acbc6fb8fc3e1c8..1a414300b654514428db4b41ab9cb63504106121 100644 (file)
@@ -43,6 +43,7 @@ static struct afs_volume *afs_alloc_volume(struct afs_fs_context *params,
        atomic_set(&volume->usage, 1);
        INIT_LIST_HEAD(&volume->proc_link);
        rwlock_init(&volume->servers_lock);
+       rwlock_init(&volume->cb_v_break_lock);
        memcpy(volume->name, vldb->name, vldb->name_len + 1);
 
        slist = afs_alloc_server_list(params->cell, params->key, vldb, type_mask);
index 16255c2ca2f4f6e97d8f4464aeac00e148297fa4..0d6b4bc191c5a849437a8c99b61e550c26214c9b 100644 (file)
@@ -103,6 +103,7 @@ void ishtp_put_device(struct ishtp_cl_device *cl_dev);
 void ishtp_get_device(struct ishtp_cl_device *cl_dev);
 void ishtp_set_drvdata(struct ishtp_cl_device *cl_device, void *data);
 void *ishtp_get_drvdata(struct ishtp_cl_device *cl_device);
+struct ishtp_cl_device *ishtp_dev_to_cl_device(struct device *dev);
 int ishtp_register_event_cb(struct ishtp_cl_device *device,
                                void (*read_cb)(struct ishtp_cl_device *));
 struct ishtp_fw_client *ishtp_fw_cl_get_client(struct ishtp_device *dev,
index b3d360b0ee3d79881c45509a17a46fa91e24960e..9f57cdfcc93d8f3c12d844a23169c7746a3974de 100644 (file)
@@ -373,6 +373,8 @@ struct flash_info;
  * @flash_unlock:      [FLASH-SPECIFIC] unlock a region of the SPI NOR
  * @flash_is_locked:   [FLASH-SPECIFIC] check if a region of the SPI NOR is
  * @quad_enable:       [FLASH-SPECIFIC] enables SPI NOR quad mode
+ * @clear_sr_bp:       [FLASH-SPECIFIC] clears the Block Protection Bits from
+ *                     the SPI NOR Status Register.
  *                     completely locked
  * @priv:              the private data
  */
@@ -410,6 +412,7 @@ struct spi_nor {
        int (*flash_unlock)(struct spi_nor *nor, loff_t ofs, uint64_t len);
        int (*flash_is_locked)(struct spi_nor *nor, loff_t ofs, uint64_t len);
        int (*quad_enable)(struct spi_nor *nor);
+       int (*clear_sr_bp)(struct spi_nor *nor);
 
        void *priv;
 };
index 4790beaa86e01e026e279fd397578810392919cf..ee7405e759ba5e6406d3b001ea228668e9f964f7 100644 (file)
@@ -262,8 +262,8 @@ static inline bool ip6_sk_ignore_df(const struct sock *sk)
               inet6_sk(sk)->pmtudisc == IPV6_PMTUDISC_OMIT;
 }
 
-static inline struct in6_addr *rt6_nexthop(struct rt6_info *rt,
-                                          struct in6_addr *daddr)
+static inline const struct in6_addr *rt6_nexthop(const struct rt6_info *rt,
+                                                const struct in6_addr *daddr)
 {
        if (rt->rt6i_flags & RTF_GATEWAY)
                return &rt->rt6i_gateway;
index 065b47754f05fd05efa991fe59bdd449c715cd87..55ff71ffb796acaa3e9e57f73b818dba2305e03d 100644 (file)
@@ -221,6 +221,7 @@ void ip_rt_get_source(u8 *src, struct sk_buff *skb, struct rtable *rt);
 struct rtable *rt_dst_alloc(struct net_device *dev,
                             unsigned int flags, u16 type,
                             bool nopolicy, bool noxfrm, bool will_cache);
+struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt);
 
 struct in_ifaddr;
 void fib_add_ifaddr(struct in_ifaddr *);
index 4a55ce6a303f54ed5bfd79678093aee552eb186f..53d96bca220d0744b9ce46e68dcafef56d9ac864 100644 (file)
@@ -373,21 +373,6 @@ static inline bool tls_is_partially_sent_record(struct tls_context *ctx)
        return !!ctx->partially_sent_record;
 }
 
-static inline int tls_complete_pending_work(struct sock *sk,
-                                           struct tls_context *ctx,
-                                           int flags, long *timeo)
-{
-       int rc = 0;
-
-       if (unlikely(sk->sk_write_pending))
-               rc = wait_on_pending_writer(sk, timeo);
-
-       if (!rc && tls_is_partially_sent_record(ctx))
-               rc = tls_push_partial_record(sk, ctx, flags);
-
-       return rc;
-}
-
 static inline bool tls_is_pending_open_record(struct tls_context *tls_ctx)
 {
        return tls_ctx->pending_open_record_frags;
index 19d27bee285e7201a3518702e6c3aa743a6aa8cd..1555b0c6f7ecf355d8e4e1d22517347a7fee565f 100644 (file)
@@ -160,10 +160,10 @@ static inline struct lowpan_peer *peer_lookup_dst(struct lowpan_btle_dev *dev,
                                                  struct in6_addr *daddr,
                                                  struct sk_buff *skb)
 {
-       struct lowpan_peer *peer;
-       struct in6_addr *nexthop;
        struct rt6_info *rt = (struct rt6_info *)skb_dst(skb);
        int count = atomic_read(&dev->peer_count);
+       const struct in6_addr *nexthop;
+       struct lowpan_peer *peer;
 
        BT_DBG("peers %d addr %pI6c rt %p", count, daddr, rt);
 
index 16f9159234a2014491fdd7f7371d6cb06b978adc..8c2ec35b6512f1486cf2ea01f4a19444c7422642 100644 (file)
@@ -318,6 +318,7 @@ static int ip_finish_output(struct net *net, struct sock *sk, struct sk_buff *sk
 static int ip_mc_finish_output(struct net *net, struct sock *sk,
                               struct sk_buff *skb)
 {
+       struct rtable *new_rt;
        int ret;
 
        ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb);
@@ -326,6 +327,17 @@ static int ip_mc_finish_output(struct net *net, struct sock *sk,
                return ret;
        }
 
+       /* Reset rt_iif so that inet_iif() will return skb->skb_iif. Setting
+        * this to non-zero causes ipi_ifindex in in_pktinfo to be overwritten,
+        * see ipv4_pktinfo_prepare().
+        */
+       new_rt = rt_dst_clone(net->loopback_dev, skb_rtable(skb));
+       if (new_rt) {
+               new_rt->rt_iif = 0;
+               skb_dst_drop(skb);
+               skb_dst_set(skb, &new_rt->dst);
+       }
+
        return dev_loopback_xmit(net, sk, skb);
 }
 
index 0b8e06ca75d6a5d836cdbd442f8a2e38995b19f9..40a6abbc9cf613ed1c180f8bae65a9713736dfdd 100644 (file)
@@ -197,7 +197,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
                }
                sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
                                     iph->saddr, iph->daddr,
-                                    skb->dev->ifindex, sdif);
+                                    dif, sdif);
        }
 out:
        read_unlock(&raw_v4_hashinfo.lock);
index 6cb7cff22db9ca9a08d00fb2ccab732c145b4e9c..8ea0735a67546b745c2ef5ecd7dd0b5d06a22c77 100644 (file)
@@ -1647,6 +1647,39 @@ struct rtable *rt_dst_alloc(struct net_device *dev,
 }
 EXPORT_SYMBOL(rt_dst_alloc);
 
+struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt)
+{
+       struct rtable *new_rt;
+
+       new_rt = dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK,
+                          rt->dst.flags);
+
+       if (new_rt) {
+               new_rt->rt_genid = rt_genid_ipv4(dev_net(dev));
+               new_rt->rt_flags = rt->rt_flags;
+               new_rt->rt_type = rt->rt_type;
+               new_rt->rt_is_input = rt->rt_is_input;
+               new_rt->rt_iif = rt->rt_iif;
+               new_rt->rt_pmtu = rt->rt_pmtu;
+               new_rt->rt_mtu_locked = rt->rt_mtu_locked;
+               new_rt->rt_gw_family = rt->rt_gw_family;
+               if (rt->rt_gw_family == AF_INET)
+                       new_rt->rt_gw4 = rt->rt_gw4;
+               else if (rt->rt_gw_family == AF_INET6)
+                       new_rt->rt_gw6 = rt->rt_gw6;
+               INIT_LIST_HEAD(&new_rt->rt_uncached);
+
+               new_rt->dst.flags |= DST_HOST;
+               new_rt->dst.input = rt->dst.input;
+               new_rt->dst.output = rt->dst.output;
+               new_rt->dst.error = rt->dst.error;
+               new_rt->dst.lastuse = jiffies;
+               new_rt->dst.lwtstate = lwtstate_get(rt->dst.lwtstate);
+       }
+       return new_rt;
+}
+EXPORT_SYMBOL(rt_dst_clone);
+
 /* called in rcu_read_lock() section */
 int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr,
                          u8 tos, struct net_device *dev,
index 834475717110ecc53aa5bd2e3f275f2e8980fb05..21efcd02f33704c8258f3140830d8a91f3b67212 100644 (file)
@@ -59,8 +59,8 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff *
 {
        struct dst_entry *dst = skb_dst(skb);
        struct net_device *dev = dst->dev;
+       const struct in6_addr *nexthop;
        struct neighbour *neigh;
-       struct in6_addr *nexthop;
        int ret;
 
        if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {
index 11ad62effd562bf5a3e77875024323ab30c0cb86..97a843cf164cdee9adb17096e393814180467f31 100644 (file)
@@ -218,7 +218,8 @@ static struct neighbour *ip6_dst_neigh_lookup(const struct dst_entry *dst,
 {
        const struct rt6_info *rt = container_of(dst, struct rt6_info, dst);
 
-       return ip6_neigh_lookup(&rt->rt6i_gateway, dst->dev, skb, daddr);
+       return ip6_neigh_lookup(rt6_nexthop(rt, &in6addr_any),
+                               dst->dev, skb, daddr);
 }
 
 static void ip6_confirm_neigh(const struct dst_entry *dst, const void *daddr)
@@ -5281,7 +5282,7 @@ static struct ctl_table ipv6_route_table_template[] = {
                .data           =       &init_net.ipv6.sysctl.skip_notify_on_dev_down,
                .maxlen         =       sizeof(int),
                .mode           =       0644,
-               .proc_handler   =       proc_dointvec,
+               .proc_handler   =       proc_dointvec_minmax,
                .extra1         =       &zero,
                .extra2         =       &one,
        },
index 241317473114c8c34094a1603ff4bf98b9cd6760..cdfc33517e85b5e0542195b019898bbe8efbcfa8 100644 (file)
@@ -439,9 +439,9 @@ nf_flow_offload_ipv6_hook(void *priv, struct sk_buff *skb,
        struct nf_flowtable *flow_table = priv;
        struct flow_offload_tuple tuple = {};
        enum flow_offload_tuple_dir dir;
+       const struct in6_addr *nexthop;
        struct flow_offload *flow;
        struct net_device *outdev;
-       struct in6_addr *nexthop;
        struct ipv6hdr *ip6h;
        struct rt6_info *rt;
 
index a29d66da7394bb48c4012b29ff2ad3d256cf7bff..5f78df0805732bcff59e52ebce3a2f614d27686b 100644 (file)
@@ -2401,6 +2401,9 @@ static void tpacket_destruct_skb(struct sk_buff *skb)
 
                ts = __packet_set_timestamp(po, ph, skb);
                __packet_set_status(po, ph, TP_STATUS_AVAILABLE | ts);
+
+               if (!packet_read_pending(&po->tx_ring))
+                       complete(&po->skb_completion);
        }
 
        sock_wfree(skb);
@@ -2585,7 +2588,7 @@ static int tpacket_parse_header(struct packet_sock *po, void *frame,
 
 static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
 {
-       struct sk_buff *skb;
+       struct sk_buff *skb = NULL;
        struct net_device *dev;
        struct virtio_net_hdr *vnet_hdr = NULL;
        struct sockcm_cookie sockc;
@@ -2600,6 +2603,7 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
        int len_sum = 0;
        int status = TP_STATUS_AVAILABLE;
        int hlen, tlen, copylen = 0;
+       long timeo = 0;
 
        mutex_lock(&po->pg_vec_lock);
 
@@ -2646,12 +2650,21 @@ static int tpacket_snd(struct packet_sock *po, struct msghdr *msg)
        if ((size_max > dev->mtu + reserve + VLAN_HLEN) && !po->has_vnet_hdr)
                size_max = dev->mtu + reserve + VLAN_HLEN;
 
+       reinit_completion(&po->skb_completion);
+
        do {
                ph = packet_current_frame(po, &po->tx_ring,
                                          TP_STATUS_SEND_REQUEST);
                if (unlikely(ph == NULL)) {
-                       if (need_wait && need_resched())
-                               schedule();
+                       if (need_wait && skb) {
+                               timeo = sock_sndtimeo(&po->sk, msg->msg_flags & MSG_DONTWAIT);
+                               timeo = wait_for_completion_interruptible_timeout(&po->skb_completion, timeo);
+                               if (timeo <= 0) {
+                                       err = !timeo ? -ETIMEDOUT : -ERESTARTSYS;
+                                       goto out_put;
+                               }
+                       }
+                       /* check for additional frames */
                        continue;
                }
 
@@ -3207,6 +3220,7 @@ static int packet_create(struct net *net, struct socket *sock, int protocol,
        sock_init_data(sock, sk);
 
        po = pkt_sk(sk);
+       init_completion(&po->skb_completion);
        sk->sk_family = PF_PACKET;
        po->num = proto;
        po->xmit = dev_queue_xmit;
@@ -4314,7 +4328,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                                    req3->tp_sizeof_priv ||
                                    req3->tp_feature_req_word) {
                                        err = -EINVAL;
-                                       goto out;
+                                       goto out_free_pg_vec;
                                }
                        }
                        break;
@@ -4378,6 +4392,7 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
                        prb_shutdown_retire_blk_timer(po, rb_queue);
        }
 
+out_free_pg_vec:
        if (pg_vec)
                free_pg_vec(pg_vec, order, req->tp_block_nr);
 out:
index 3bb7c5fb3bff2fd5d91c3d973d006d0cdde29a0b..c70a2794456f15559a31de428f6fa6cc8604e090 100644 (file)
@@ -128,6 +128,7 @@ struct packet_sock {
        unsigned int            tp_hdrlen;
        unsigned int            tp_reserve;
        unsigned int            tp_tstamp;
+       struct completion       skb_completion;
        struct net_device __rcu *cached_dev;
        int                     (*xmit)(struct sk_buff *skb);
        struct packet_type      prot_hook ____cacheline_aligned_in_smp;
index e16a3d37d2bcda944c28402eefd4ac9716bbb93b..732e109c305557f4dc365cd65feaacbbb72852eb 100644 (file)
@@ -549,12 +549,17 @@ static struct notifier_block cbs_device_notifier = {
 
 static int __init cbs_module_init(void)
 {
-       int err = register_netdevice_notifier(&cbs_device_notifier);
+       int err;
 
+       err = register_netdevice_notifier(&cbs_device_notifier);
        if (err)
                return err;
 
-       return register_qdisc(&cbs_qdisc_ops);
+       err = register_qdisc(&cbs_qdisc_ops);
+       if (err)
+               unregister_netdevice_notifier(&cbs_device_notifier);
+
+       return err;
 }
 
 static void __exit cbs_module_exit(void)
index e358437ba29ba18403e1d1a5b3a4e19e05da46c1..69cebb2c998bbe0c247df59e2bfb4a408cde08b6 100644 (file)
@@ -118,10 +118,6 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
        /* Initialize the bind addr area */
        sctp_bind_addr_init(&ep->base.bind_addr, 0);
 
-       /* Remember who we are attached to.  */
-       ep->base.sk = sk;
-       sock_hold(ep->base.sk);
-
        /* Create the lists of associations.  */
        INIT_LIST_HEAD(&ep->asocs);
 
@@ -154,6 +150,10 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
        ep->prsctp_enable = net->sctp.prsctp_enable;
        ep->reconf_enable = net->sctp.reconf_enable;
 
+       /* Remember who we are attached to.  */
+       ep->base.sk = sk;
+       sock_hold(ep->base.sk);
+
        return ep;
 
 nomem_shkey:
index 0c874e996f8511ffaa06e84f347329dc2c169b4b..7621ec2f539cf5fe70b6c6edca3b5f0d16a6deee 100644 (file)
@@ -2029,7 +2029,7 @@ static int __init smc_init(void)
 
        rc = smc_pnet_init();
        if (rc)
-               return rc;
+               goto out_pernet_subsys;
 
        rc = smc_llc_init();
        if (rc) {
@@ -2080,6 +2080,9 @@ out_proto:
        proto_unregister(&smc_proto);
 out_pnet:
        smc_pnet_exit();
+out_pernet_subsys:
+       unregister_pernet_subsys(&smc_net_ops);
+
        return rc;
 }
 
index 2d2850adc2a3fa7a6a8667d79add5678beb130ca..4ca50ddf8d1619a78e8a119ef2701d69957a8cd9 100644 (file)
@@ -652,7 +652,10 @@ create:
                rc = smc_lgr_create(smc, ini);
                if (rc)
                        goto out;
+               lgr = conn->lgr;
+               write_lock_bh(&lgr->conns_lock);
                smc_lgr_register_conn(conn); /* add smc conn to lgr */
+               write_unlock_bh(&lgr->conns_lock);
        }
        conn->local_tx_ctrl.common.type = SMC_CDC_MSG_TYPE;
        conn->local_tx_ctrl.len = SMC_WR_TX_SIZE;
index ed536c05252a7e77f2e3b8d19022142973e2e04a..c8370722f0bbccd24d90454e1cdf59a8d203745f 100644 (file)
@@ -134,7 +134,7 @@ static int __init tipc_init(void)
        if (err)
                goto out_sysctl;
 
-       err = register_pernet_subsys(&tipc_net_ops);
+       err = register_pernet_device(&tipc_net_ops);
        if (err)
                goto out_pernet;
 
@@ -142,7 +142,7 @@ static int __init tipc_init(void)
        if (err)
                goto out_socket;
 
-       err = register_pernet_subsys(&tipc_topsrv_net_ops);
+       err = register_pernet_device(&tipc_topsrv_net_ops);
        if (err)
                goto out_pernet_topsrv;
 
@@ -153,11 +153,11 @@ static int __init tipc_init(void)
        pr_info("Started in single node mode\n");
        return 0;
 out_bearer:
-       unregister_pernet_subsys(&tipc_topsrv_net_ops);
+       unregister_pernet_device(&tipc_topsrv_net_ops);
 out_pernet_topsrv:
        tipc_socket_stop();
 out_socket:
-       unregister_pernet_subsys(&tipc_net_ops);
+       unregister_pernet_device(&tipc_net_ops);
 out_pernet:
        tipc_unregister_sysctl();
 out_sysctl:
@@ -172,9 +172,9 @@ out_netlink:
 static void __exit tipc_exit(void)
 {
        tipc_bearer_cleanup();
-       unregister_pernet_subsys(&tipc_topsrv_net_ops);
+       unregister_pernet_device(&tipc_topsrv_net_ops);
        tipc_socket_stop();
-       unregister_pernet_subsys(&tipc_net_ops);
+       unregister_pernet_device(&tipc_net_ops);
        tipc_netlink_stop();
        tipc_netlink_compat_stop();
        tipc_unregister_sysctl();
index c6a04c09d075c92f5f4333f7a7924d384c93a314..cf155061c4724558767f17ecccdfceef23dce937 100644 (file)
@@ -445,7 +445,11 @@ static int tipc_nl_compat_bearer_disable(struct tipc_nl_compat_cmd_doit *cmd,
        if (!bearer)
                return -EMSGSIZE;
 
-       len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_BEARER_NAME);
+       len = TLV_GET_DATA_LEN(msg->req);
+       if (len <= 0)
+               return -EINVAL;
+
+       len = min_t(int, len, TIPC_MAX_BEARER_NAME);
        if (!string_is_valid(name, len))
                return -EINVAL;
 
@@ -539,7 +543,11 @@ static int tipc_nl_compat_link_stat_dump(struct tipc_nl_compat_msg *msg,
 
        name = (char *)TLV_DATA(msg->req);
 
-       len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
+       len = TLV_GET_DATA_LEN(msg->req);
+       if (len <= 0)
+               return -EINVAL;
+
+       len = min_t(int, len, TIPC_MAX_BEARER_NAME);
        if (!string_is_valid(name, len))
                return -EINVAL;
 
@@ -817,7 +825,11 @@ static int tipc_nl_compat_link_reset_stats(struct tipc_nl_compat_cmd_doit *cmd,
        if (!link)
                return -EMSGSIZE;
 
-       len = min_t(int, TLV_GET_DATA_LEN(msg->req), TIPC_MAX_LINK_NAME);
+       len = TLV_GET_DATA_LEN(msg->req);
+       if (len <= 0)
+               return -EINVAL;
+
+       len = min_t(int, len, TIPC_MAX_BEARER_NAME);
        if (!string_is_valid(name, len))
                return -EINVAL;
 
index fc81ae18cc4482b207cab84cc2f87ecef16a8dce..e2b69e805d4640805bd46edca86c6a7930bfe91d 100644 (file)
@@ -279,7 +279,8 @@ static void tls_sk_proto_close(struct sock *sk, long timeout)
                goto skip_tx_cleanup;
        }
 
-       if (!tls_complete_pending_work(sk, ctx, 0, &timeo))
+       if (unlikely(sk->sk_write_pending) &&
+           !wait_on_pending_writer(sk, &timeo))
                tls_handle_open_record(sk, 0);
 
        /* We need these for tls_sw_fallback handling of other packets */
index ba919308fe3052f399162e8f4ca1b165d498c725..d503b8764a8e0908951ef5a7719506d927528a21 100644 (file)
@@ -3,4 +3,5 @@ subpage_prot
 tempfile
 prot_sao
 segv_errors
-wild_bctr
\ No newline at end of file
+wild_bctr
+large_vm_fork_separation
\ No newline at end of file
index 43d68420e363326059e0257f62f8c30e05114ca8..f1fbc15800c4b576e28b4b2798dc891a8a53acef 100644 (file)
@@ -2,7 +2,8 @@
 noarg:
        $(MAKE) -C ../
 
-TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors wild_bctr
+TEST_GEN_PROGS := hugetlb_vs_thp_test subpage_prot prot_sao segv_errors wild_bctr \
+                 large_vm_fork_separation
 TEST_GEN_FILES := tempfile
 
 top_srcdir = ../../../../..
@@ -13,6 +14,7 @@ $(TEST_GEN_PROGS): ../harness.c
 $(OUTPUT)/prot_sao: ../utils.c
 
 $(OUTPUT)/wild_bctr: CFLAGS += -m64
+$(OUTPUT)/large_vm_fork_separation: CFLAGS += -m64
 
 $(OUTPUT)/tempfile:
        dd if=/dev/zero of=$@ bs=64k count=1
diff --git a/tools/testing/selftests/powerpc/mm/large_vm_fork_separation.c b/tools/testing/selftests/powerpc/mm/large_vm_fork_separation.c
new file mode 100644 (file)
index 0000000..2363a7f
--- /dev/null
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: GPL-2.0+
+//
+// Copyright 2019, Michael Ellerman, IBM Corp.
+//
+// Test that allocating memory beyond the memory limit and then forking is
+// handled correctly, ie. the child is able to access the mappings beyond the
+// memory limit and the child's writes are not visible to the parent.
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+#include "utils.h"
+
+
+#ifndef MAP_FIXED_NOREPLACE
+#define MAP_FIXED_NOREPLACE    MAP_FIXED       // "Should be safe" above 512TB
+#endif
+
+
+static int test(void)
+{
+       int p2c[2], c2p[2], rc, status, c, *p;
+       unsigned long page_size;
+       pid_t pid;
+
+       page_size = sysconf(_SC_PAGESIZE);
+       SKIP_IF(page_size != 65536);
+
+       // Create a mapping at 512TB to allocate an extended_id
+       p = mmap((void *)(512ul << 40), page_size, PROT_READ | PROT_WRITE,
+               MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0);
+       if (p == MAP_FAILED) {
+               perror("mmap");
+               printf("Error: couldn't mmap(), confirm kernel has 4TB support?\n");
+               return 1;
+       }
+
+       printf("parent writing %p = 1\n", p);
+       *p = 1;
+
+       FAIL_IF(pipe(p2c) == -1 || pipe(c2p) == -1);
+
+       pid = fork();
+       if (pid == 0) {
+               FAIL_IF(read(p2c[0], &c, 1) != 1);
+
+               pid = getpid();
+               printf("child writing  %p = %d\n", p, pid);
+               *p = pid;
+
+               FAIL_IF(write(c2p[1], &c, 1) != 1);
+               FAIL_IF(read(p2c[0], &c, 1) != 1);
+               exit(0);
+       }
+
+       c = 0;
+       FAIL_IF(write(p2c[1], &c, 1) != 1);
+       FAIL_IF(read(c2p[0], &c, 1) != 1);
+
+       // Prevent compiler optimisation
+       barrier();
+
+       rc = 0;
+       printf("parent reading %p = %d\n", p, *p);
+       if (*p != 1) {
+               printf("Error: BUG! parent saw child's write! *p = %d\n", *p);
+               rc = 1;
+       }
+
+       FAIL_IF(write(p2c[1], &c, 1) != 1);
+       FAIL_IF(waitpid(pid, &status, 0) == -1);
+       FAIL_IF(!WIFEXITED(status) || WEXITSTATUS(status));
+
+       if (rc == 0)
+               printf("success: test completed OK\n");
+
+       return rc;
+}
+
+int main(void)
+{
+       return test_harness(test, "large_vm_fork_separation");
+}