commit:     2f8052d8b0cab6963d9adda65943c18822146475
Author:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
AuthorDate: Mon Jun  6 11:05:43 2022 +0000
Commit:     Mike Pagano <mpagano <AT> gentoo <DOT> org>
CommitDate: Mon Jun  6 11:05:43 2022 +0000
URL:        https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=2f8052d8

Linux patch 4.19.246

Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org>

 0000_README               |   4 +
 1245_linux-4.19.246.patch | 930 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 934 insertions(+)

diff --git a/0000_README b/0000_README
index d527b79c..4389c65a 100644
--- a/0000_README
+++ b/0000_README
@@ -1019,6 +1019,10 @@ Patch:  1244_linux-4.19.245.patch
 From:   https://www.kernel.org
 Desc:   Linux 4.19.245
 
+Patch:  1245_linux-4.19.246.patch
+From:   https://www.kernel.org
+Desc:   Linux 4.19.246
+
 Patch:  1500_XATTR_USER_PREFIX.patch
 From:   https://bugs.gentoo.org/show_bug.cgi?id=470644
 Desc:   Support for namespace user.pax.* on tmpfs.

diff --git a/1245_linux-4.19.246.patch b/1245_linux-4.19.246.patch
new file mode 100644
index 00000000..111b704a
--- /dev/null
+++ b/1245_linux-4.19.246.patch
@@ -0,0 +1,930 @@
+diff --git a/Documentation/process/submitting-patches.rst 
b/Documentation/process/submitting-patches.rst
+index c0917107b90ab..3739c1ce686d4 100644
+--- a/Documentation/process/submitting-patches.rst
++++ b/Documentation/process/submitting-patches.rst
+@@ -133,7 +133,7 @@ as you intend it to.
+ 
+ The maintainer will thank you if you write your patch description in a
+ form which can be easily pulled into Linux's source code management
+-system, ``git``, as a "commit log".  See :ref:`explicit_in_reply_to`.
++system, ``git``, as a "commit log".  See :ref:`the_canonical_patch_format`.
+ 
+ Solve only one problem per patch.  If your description starts to get
+ long, that's a sign that you probably need to split up your patch.
+diff --git a/Makefile b/Makefile
+index 64a64f6ba90d8..e1cbe6e8bcaef 100644
+--- a/Makefile
++++ b/Makefile
+@@ -1,7 +1,7 @@
+ # SPDX-License-Identifier: GPL-2.0
+ VERSION = 4
+ PATCHLEVEL = 19
+-SUBLEVEL = 245
++SUBLEVEL = 246
+ EXTRAVERSION =
+ NAME = "People's Front"
+ 
+diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
+index 22da9bfd8a458..bacf8d988f65f 100644
+--- a/arch/x86/pci/xen.c
++++ b/arch/x86/pci/xen.c
+@@ -441,6 +441,11 @@ void __init xen_msi_init(void)
+ 
+       x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs;
+       x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
++      /*
++       * With XEN PIRQ/Eventchannels in use PCI/MSI[-X] masking is solely
++       * controlled by the hypervisor.
++       */
++      pci_msi_ignore_mask = 1;
+ }
+ #endif
+ 
+diff --git a/block/bio.c b/block/bio.c
+index fe749404ef93b..7858b2d239161 100644
+--- a/block/bio.c
++++ b/block/bio.c
+@@ -1528,7 +1528,7 @@ struct bio *bio_copy_kern(struct request_queue *q, void 
*data, unsigned int len,
+               if (bytes > len)
+                       bytes = len;
+ 
+-              page = alloc_page(q->bounce_gfp | gfp_mask);
++              page = alloc_page(q->bounce_gfp | __GFP_ZERO | gfp_mask);
+               if (!page)
+                       goto cleanup;
+ 
+diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c
+index 39ee0ca636aae..0b6489fd5d0d1 100644
+--- a/drivers/acpi/sysfs.c
++++ b/drivers/acpi/sysfs.c
+@@ -439,18 +439,29 @@ static ssize_t acpi_data_show(struct file *filp, struct 
kobject *kobj,
+ {
+       struct acpi_data_attr *data_attr;
+       void __iomem *base;
+-      ssize_t rc;
++      ssize_t size;
+ 
+       data_attr = container_of(bin_attr, struct acpi_data_attr, attr);
++      size = data_attr->attr.size;
++
++      if (offset < 0)
++              return -EINVAL;
++
++      if (offset >= size)
++              return 0;
+ 
+-      base = acpi_os_map_memory(data_attr->addr, data_attr->attr.size);
++      if (count > size - offset)
++              count = size - offset;
++
++      base = acpi_os_map_iomem(data_attr->addr, size);
+       if (!base)
+               return -ENOMEM;
+-      rc = memory_read_from_buffer(buf, count, &offset, base,
+-                                   data_attr->attr.size);
+-      acpi_os_unmap_memory(base, data_attr->attr.size);
+ 
+-      return rc;
++      memcpy_fromio(buf, base + offset, count);
++
++      acpi_os_unmap_iomem(base, size);
++
++      return count;
+ }
+ 
+ static int acpi_bert_data_init(void *th, struct acpi_data_attr *data_attr)
+diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
+index e71c6b24aed1c..ce497b0691d71 100644
+--- a/drivers/char/tpm/tpm2-cmd.c
++++ b/drivers/char/tpm/tpm2-cmd.c
+@@ -717,7 +717,16 @@ ssize_t tpm2_get_tpm_pt(struct tpm_chip *chip, u32 
property_id,  u32 *value,
+       if (!rc) {
+               out = (struct tpm2_get_cap_out *)
+                       &buf.data[TPM_HEADER_SIZE];
+-              *value = be32_to_cpu(out->value);
++              /*
++               * To prevent failing boot up of some systems, Infineon TPM2.0
++               * returns SUCCESS on TPM2_Startup in field upgrade mode. Also
++               * the TPM2_Getcapability command returns a zero length list
++               * in field upgrade mode.
++               */
++              if (be32_to_cpu(out->property_cnt) > 0)
++                      *value = be32_to_cpu(out->value);
++              else
++                      rc = -ENODATA;
+       }
+       tpm_buf_destroy(&buf);
+       return rc;
+diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c
+index 3ba67bc6baba0..80647eb071fd6 100644
+--- a/drivers/char/tpm/tpm_ibmvtpm.c
++++ b/drivers/char/tpm/tpm_ibmvtpm.c
+@@ -692,6 +692,7 @@ static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev,
+       if (!wait_event_timeout(ibmvtpm->crq_queue.wq,
+                               ibmvtpm->rtce_buf != NULL,
+                               HZ)) {
++              rc = -ENODEV;
+               dev_err(dev, "CRQ response timed out\n");
+               goto init_irq_cleanup;
+       }
+diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
+index 1847faa45d370..af8865281b478 100644
+--- a/drivers/gpu/drm/i915/intel_pm.c
++++ b/drivers/gpu/drm/i915/intel_pm.c
+@@ -2814,7 +2814,7 @@ hsw_compute_linetime_wm(const struct intel_crtc_state 
*cstate)
+ }
+ 
+ static void intel_read_wm_latency(struct drm_i915_private *dev_priv,
+-                                uint16_t wm[8])
++                                uint16_t wm[])
+ {
+       if (INTEL_GEN(dev_priv) >= 9) {
+               uint32_t val;
+diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c
+index c20945ed1dc19..e99286258f62f 100644
+--- a/drivers/hid/hid-multitouch.c
++++ b/drivers/hid/hid-multitouch.c
+@@ -2111,6 +2111,9 @@ static const struct hid_device_id mt_devices[] = {
+       { .driver_data = MT_CLS_GOOGLE,
+               HID_DEVICE(HID_BUS_ANY, HID_GROUP_ANY, USB_VENDOR_ID_GOOGLE,
+                       USB_DEVICE_ID_GOOGLE_TOUCH_ROSE) },
++      { .driver_data = MT_CLS_GOOGLE,
++              HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, 
USB_VENDOR_ID_GOOGLE,
++                      USB_DEVICE_ID_GOOGLE_WHISKERS) },
+ 
+       /* Generic MT device */
+       { HID_DEVICE(HID_BUS_ANY, HID_GROUP_MULTITOUCH, HID_ANY_ID, HID_ANY_ID) 
},
+diff --git a/drivers/i2c/busses/i2c-ismt.c b/drivers/i2c/busses/i2c-ismt.c
+index 0d1c3ec8cb407..80796061102f1 100644
+--- a/drivers/i2c/busses/i2c-ismt.c
++++ b/drivers/i2c/busses/i2c-ismt.c
+@@ -80,6 +80,7 @@
+ 
+ #define ISMT_DESC_ENTRIES     2       /* number of descriptor entries */
+ #define ISMT_MAX_RETRIES      3       /* number of SMBus retries to attempt */
++#define ISMT_LOG_ENTRIES      3       /* number of interrupt cause log 
entries */
+ 
+ /* Hardware Descriptor Constants - Control Field */
+ #define ISMT_DESC_CWRL        0x01    /* Command/Write Length */
+@@ -173,6 +174,8 @@ struct ismt_priv {
+       u8 head;                                /* ring buffer head pointer */
+       struct completion cmp;                  /* interrupt completion */
+       u8 buffer[I2C_SMBUS_BLOCK_MAX + 16];    /* temp R/W data buffer */
++      dma_addr_t log_dma;
++      u32 *log;
+ };
+ 
+ /**
+@@ -406,6 +409,9 @@ static int ismt_access(struct i2c_adapter *adap, u16 addr,
+       memset(desc, 0, sizeof(struct ismt_desc));
+       desc->tgtaddr_rw = ISMT_DESC_ADDR_RW(addr, read_write);
+ 
++      /* Always clear the log entries */
++      memset(priv->log, 0, ISMT_LOG_ENTRIES * sizeof(u32));
++
+       /* Initialize common control bits */
+       if (likely(pci_dev_msi_enabled(priv->pci_dev)))
+               desc->control = ISMT_DESC_INT | ISMT_DESC_FAIR;
+@@ -695,6 +701,8 @@ static void ismt_hw_init(struct ismt_priv *priv)
+       /* initialize the Master Descriptor Base Address (MDBA) */
+       writeq(priv->io_rng_dma, priv->smba + ISMT_MSTR_MDBA);
+ 
++      writeq(priv->log_dma, priv->smba + ISMT_GR_SMTICL);
++
+       /* initialize the Master Control Register (MCTRL) */
+       writel(ISMT_MCTRL_MEIE, priv->smba + ISMT_MSTR_MCTRL);
+ 
+@@ -784,6 +792,12 @@ static int ismt_dev_init(struct ismt_priv *priv)
+       priv->head = 0;
+       init_completion(&priv->cmp);
+ 
++      priv->log = dmam_alloc_coherent(&priv->pci_dev->dev,
++                                      ISMT_LOG_ENTRIES * sizeof(u32),
++                                      &priv->log_dma, GFP_KERNEL);
++      if (!priv->log)
++              return -ENOMEM;
++
+       return 0;
+ }
+ 
+diff --git a/drivers/i2c/busses/i2c-thunderx-pcidrv.c 
b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
+index 19f8eec387172..107aeb8b54da4 100644
+--- a/drivers/i2c/busses/i2c-thunderx-pcidrv.c
++++ b/drivers/i2c/busses/i2c-thunderx-pcidrv.c
+@@ -208,6 +208,7 @@ static int thunder_i2c_probe_pci(struct pci_dev *pdev,
+       i2c->adap.bus_recovery_info = &octeon_i2c_recovery_info;
+       i2c->adap.dev.parent = dev;
+       i2c->adap.dev.of_node = pdev->dev.of_node;
++      i2c->adap.dev.fwnode = dev->fwnode;
+       snprintf(i2c->adap.name, sizeof(i2c->adap.name),
+                "Cavium ThunderX i2c adapter at %s", dev_name(dev));
+       i2c_set_adapdata(&i2c->adap, i2c);
+diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
+index 3441ad140b583..e38c713e882e3 100644
+--- a/drivers/md/dm-crypt.c
++++ b/drivers/md/dm-crypt.c
+@@ -2932,6 +2932,11 @@ static int crypt_map(struct dm_target *ti, struct bio 
*bio)
+       return DM_MAPIO_SUBMITTED;
+ }
+ 
++static char hex2asc(unsigned char c)
++{
++      return c + '0' + ((unsigned)(9 - c) >> 4 & 0x27);
++}
++
+ static void crypt_status(struct dm_target *ti, status_type_t type,
+                        unsigned status_flags, char *result, unsigned maxlen)
+ {
+@@ -2950,9 +2955,12 @@ static void crypt_status(struct dm_target *ti, 
status_type_t type,
+               if (cc->key_size > 0) {
+                       if (cc->key_string)
+                               DMEMIT(":%u:%s", cc->key_size, cc->key_string);
+-                      else
+-                              for (i = 0; i < cc->key_size; i++)
+-                                      DMEMIT("%02x", cc->key[i]);
++                      else {
++                              for (i = 0; i < cc->key_size; i++) {
++                                      DMEMIT("%c%c", hex2asc(cc->key[i] >> 4),
++                                             hex2asc(cc->key[i] & 0xf));
++                              }
++                      }
+               } else
+                       DMEMIT("-");
+ 
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index b0105d53918ab..8456e82409e20 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -3565,8 +3565,6 @@ try_smaller_buffer:
+       }
+ 
+       if (should_write_sb) {
+-              int r;
+-
+               init_journal(ic, 0, ic->journal_sections, 0);
+               r = dm_integrity_failed(ic);
+               if (unlikely(r)) {
+diff --git a/drivers/md/dm-stats.c b/drivers/md/dm-stats.c
+index 21de30b4e2a16..3d59f3e208c50 100644
+--- a/drivers/md/dm-stats.c
++++ b/drivers/md/dm-stats.c
+@@ -224,6 +224,7 @@ void dm_stats_cleanup(struct dm_stats *stats)
+                                      atomic_read(&shared->in_flight[READ]),
+                                      atomic_read(&shared->in_flight[WRITE]));
+                       }
++                      cond_resched();
+               }
+               dm_stat_free(&s->rcu_head);
+       }
+@@ -313,6 +314,7 @@ static int dm_stats_create(struct dm_stats *stats, 
sector_t start, sector_t end,
+       for (ni = 0; ni < n_entries; ni++) {
+               atomic_set(&s->stat_shared[ni].in_flight[READ], 0);
+               atomic_set(&s->stat_shared[ni].in_flight[WRITE], 0);
++              cond_resched();
+       }
+ 
+       if (s->n_histogram_entries) {
+@@ -325,6 +327,7 @@ static int dm_stats_create(struct dm_stats *stats, 
sector_t start, sector_t end,
+               for (ni = 0; ni < n_entries; ni++) {
+                       s->stat_shared[ni].tmp.histogram = hi;
+                       hi += s->n_histogram_entries + 1;
++                      cond_resched();
+               }
+       }
+ 
+@@ -345,6 +348,7 @@ static int dm_stats_create(struct dm_stats *stats, 
sector_t start, sector_t end,
+                       for (ni = 0; ni < n_entries; ni++) {
+                               p[ni].histogram = hi;
+                               hi += s->n_histogram_entries + 1;
++                              cond_resched();
+                       }
+               }
+       }
+@@ -474,6 +478,7 @@ static int dm_stats_list(struct dm_stats *stats, const 
char *program,
+                       }
+                       DMEMIT("\n");
+               }
++              cond_resched();
+       }
+       mutex_unlock(&stats->mutex);
+ 
+@@ -750,6 +755,7 @@ static void __dm_stat_clear(struct dm_stat *s, size_t 
idx_start, size_t idx_end,
+                               local_irq_enable();
+                       }
+               }
++              cond_resched();
+       }
+ }
+ 
+@@ -865,6 +871,8 @@ static int dm_stats_print(struct dm_stats *stats, int id,
+ 
+               if (unlikely(sz + 1 >= maxlen))
+                       goto buffer_overflow;
++
++              cond_resched();
+       }
+ 
+       if (clear)
+diff --git a/drivers/md/dm-verity-target.c b/drivers/md/dm-verity-target.c
+index fa8c201fca778..36945030520a9 100644
+--- a/drivers/md/dm-verity-target.c
++++ b/drivers/md/dm-verity-target.c
+@@ -1176,6 +1176,7 @@ bad:
+ 
+ static struct target_type verity_target = {
+       .name           = "verity",
++      .features       = DM_TARGET_IMMUTABLE,
+       .version        = {1, 4, 0},
+       .module         = THIS_MODULE,
+       .ctr            = verity_ctr,
+diff --git a/drivers/net/ethernet/faraday/ftgmac100.c 
b/drivers/net/ethernet/faraday/ftgmac100.c
+index 964407deca350..23c019d1278cd 100644
+--- a/drivers/net/ethernet/faraday/ftgmac100.c
++++ b/drivers/net/ethernet/faraday/ftgmac100.c
+@@ -1869,6 +1869,11 @@ static int ftgmac100_probe(struct platform_device *pdev)
+       /* AST2400  doesn't have working HW checksum generation */
+       if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac")))
+               netdev->hw_features &= ~NETIF_F_HW_CSUM;
++
++      /* AST2600 tx checksum with NCSI is broken */
++      if (priv->use_ncsi && of_device_is_compatible(np, "aspeed,ast2600-mac"))
++              netdev->hw_features &= ~NETIF_F_HW_CSUM;
++
+       if (np && of_get_property(np, "no-hw-checksum", NULL))
+               netdev->hw_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM);
+       netdev->features |= netdev->hw_features;
+diff --git a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c 
b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+index 466d25ccc4bbc..40d7130a4909b 100644
+--- a/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
++++ b/drivers/staging/rtl8723bs/os_dep/ioctl_linux.c
+@@ -1359,9 +1359,11 @@ static int rtw_wx_set_scan(struct net_device *dev, 
struct iw_request_info *a,
+ 
+                                       sec_len = *(pos++); len-= 1;
+ 
+-                                      if (sec_len>0 && sec_len<=len) {
++                                      if (sec_len > 0 &&
++                                          sec_len <= len &&
++                                          sec_len <= 32) {
+                                               ssid[ssid_index].SsidLength = 
sec_len;
+-                                              memcpy(ssid[ssid_index].Ssid, 
pos, ssid[ssid_index].SsidLength);
++                                              memcpy(ssid[ssid_index].Ssid, 
pos, sec_len);
+                                               /* DBG_871X("%s COMBO_SCAN with 
specific ssid:%s, %d\n", __func__ */
+                                               /*      , 
ssid[ssid_index].Ssid, ssid[ssid_index].SsidLength); */
+                                               ssid_index++;
+diff --git a/fs/exec.c b/fs/exec.c
+index e87e3c020c61e..28e3b5eb2f4a1 100644
+--- a/fs/exec.c
++++ b/fs/exec.c
+@@ -1805,6 +1805,9 @@ static int __do_execve_file(int fd, struct filename 
*filename,
+               goto out_unmark;
+ 
+       bprm->argc = count(argv, MAX_ARG_STRINGS);
++      if (bprm->argc == 0)
++              pr_warn_once("process '%s' launched '%s' with NULL argv: empty 
string added\n",
++                           current->comm, bprm->filename);
+       if ((retval = bprm->argc) < 0)
+               goto out;
+ 
+@@ -1829,6 +1832,20 @@ static int __do_execve_file(int fd, struct filename 
*filename,
+       if (retval < 0)
+               goto out;
+ 
++      /*
++       * When argv is empty, add an empty string ("") as argv[0] to
++       * ensure confused userspace programs that start processing
++       * from argv[1] won't end up walking envp. See also
++       * bprm_stack_limits().
++       */
++      if (bprm->argc == 0) {
++              const char *argv[] = { "", NULL };
++              retval = copy_strings_kernel(1, argv, bprm);
++              if (retval < 0)
++                      goto out;
++              bprm->argc = 1;
++      }
++
+       retval = exec_binprm(bprm);
+       if (retval < 0)
+               goto out;
+diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
+index ed5429d18595c..78191320f8e21 100644
+--- a/fs/nfsd/nfs4state.c
++++ b/fs/nfsd/nfs4state.c
+@@ -6401,16 +6401,12 @@ nfsd4_release_lockowner(struct svc_rqst *rqstp,
+               if (sop->so_is_open_owner || !same_owner_str(sop, owner))
+                       continue;
+ 
+-              /* see if there are still any locks associated with it */
+-              lo = lockowner(sop);
+-              list_for_each_entry(stp, &sop->so_stateids, st_perstateowner) {
+-                      if (check_for_locks(stp->st_stid.sc_file, lo)) {
+-                              status = nfserr_locks_held;
+-                              spin_unlock(&clp->cl_lock);
+-                              return status;
+-                      }
++              if (atomic_read(&sop->so_count) != 1) {
++                      spin_unlock(&clp->cl_lock);
++                      return nfserr_locks_held;
+               }
+ 
++              lo = lockowner(sop);
+               nfs4_get_stateowner(sop);
+               break;
+       }
+diff --git a/include/net/inet_hashtables.h b/include/net/inet_hashtables.h
+index fa5fe23ca6aaa..2d04f3e06de11 100644
+--- a/include/net/inet_hashtables.h
++++ b/include/net/inet_hashtables.h
+@@ -407,7 +407,7 @@ static inline void sk_rcv_saddr_set(struct sock *sk, 
__be32 addr)
+ }
+ 
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+-                      struct sock *sk, u32 port_offset,
++                      struct sock *sk, u64 port_offset,
+                       int (*check_established)(struct inet_timewait_death_row 
*,
+                                                struct sock *, __u16,
+                                                struct inet_timewait_sock **));
+diff --git a/include/net/netfilter/nf_conntrack_core.h 
b/include/net/netfilter/nf_conntrack_core.h
+index 2a3e0974a6af4..4e3fff9f929b1 100644
+--- a/include/net/netfilter/nf_conntrack_core.h
++++ b/include/net/netfilter/nf_conntrack_core.h
+@@ -58,8 +58,13 @@ static inline int nf_conntrack_confirm(struct sk_buff *skb)
+       int ret = NF_ACCEPT;
+ 
+       if (ct) {
+-              if (!nf_ct_is_confirmed(ct))
++              if (!nf_ct_is_confirmed(ct)) {
+                       ret = __nf_conntrack_confirm(skb);
++
++                      if (ret == NF_ACCEPT)
++                              ct = (struct nf_conn *)skb_nfct(skb);
++              }
++
+               if (likely(ret == NF_ACCEPT))
+                       nf_ct_deliver_cached_events(ct);
+       }
+diff --git a/include/net/secure_seq.h b/include/net/secure_seq.h
+index d7d2495f83c27..dac91aa38c5af 100644
+--- a/include/net/secure_seq.h
++++ b/include/net/secure_seq.h
+@@ -4,8 +4,8 @@
+ 
+ #include <linux/types.h>
+ 
+-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
+-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport);
++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
+                              __be16 dport);
+ u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
+                  __be16 sport, __be16 dport);
+diff --git a/lib/assoc_array.c b/lib/assoc_array.c
+index 59875eb278ea5..3b1ff063ceca3 100644
+--- a/lib/assoc_array.c
++++ b/lib/assoc_array.c
+@@ -1465,6 +1465,7 @@ int assoc_array_gc(struct assoc_array *array,
+       struct assoc_array_ptr *cursor, *ptr;
+       struct assoc_array_ptr *new_root, *new_parent, **new_ptr_pp;
+       unsigned long nr_leaves_on_tree;
++      bool retained;
+       int keylen, slot, nr_free, next_slot, i;
+ 
+       pr_devel("-->%s()\n", __func__);
+@@ -1541,6 +1542,7 @@ continue_node:
+               goto descend;
+       }
+ 
++retry_compress:
+       pr_devel("-- compress node %p --\n", new_n);
+ 
+       /* Count up the number of empty slots in this node and work out the
+@@ -1558,6 +1560,7 @@ continue_node:
+       pr_devel("free=%d, leaves=%lu\n", nr_free, new_n->nr_leaves_on_branch);
+ 
+       /* See what we can fold in */
++      retained = false;
+       next_slot = 0;
+       for (slot = 0; slot < ASSOC_ARRAY_FAN_OUT; slot++) {
+               struct assoc_array_shortcut *s;
+@@ -1607,9 +1610,14 @@ continue_node:
+                       pr_devel("[%d] retain node %lu/%d [nx %d]\n",
+                                slot, child->nr_leaves_on_branch, nr_free + 1,
+                                next_slot);
++                      retained = true;
+               }
+       }
+ 
++      if (retained && new_n->nr_leaves_on_branch <= ASSOC_ARRAY_FAN_OUT) {
++              pr_devel("internal nodes remain despite enough space, 
retrying\n");
++              goto retry_compress;
++      }
+       pr_devel("after: %lu\n", new_n->nr_leaves_on_branch);
+ 
+       nr_leaves_on_tree = new_n->nr_leaves_on_branch;
+diff --git a/mm/zsmalloc.c b/mm/zsmalloc.c
+index 11e81b3ff0cf3..4d71356ea66a3 100644
+--- a/mm/zsmalloc.c
++++ b/mm/zsmalloc.c
+@@ -1812,11 +1812,40 @@ static enum fullness_group putback_zspage(struct 
size_class *class,
+  */
+ static void lock_zspage(struct zspage *zspage)
+ {
+-      struct page *page = get_first_page(zspage);
++      struct page *curr_page, *page;
+ 
+-      do {
+-              lock_page(page);
+-      } while ((page = get_next_page(page)) != NULL);
++      /*
++       * Pages we haven't locked yet can be migrated off the list while we're
++       * trying to lock them, so we need to be careful and only attempt to
++       * lock each page under migrate_read_lock(). Otherwise, the page we lock
++       * may no longer belong to the zspage. This means that we may wait for
++       * the wrong page to unlock, so we must take a reference to the page
++       * prior to waiting for it to unlock outside migrate_read_lock().
++       */
++      while (1) {
++              migrate_read_lock(zspage);
++              page = get_first_page(zspage);
++              if (trylock_page(page))
++                      break;
++              get_page(page);
++              migrate_read_unlock(zspage);
++              wait_on_page_locked(page);
++              put_page(page);
++      }
++
++      curr_page = page;
++      while ((page = get_next_page(curr_page))) {
++              if (trylock_page(page)) {
++                      curr_page = page;
++              } else {
++                      get_page(page);
++                      migrate_read_unlock(zspage);
++                      wait_on_page_locked(page);
++                      put_page(page);
++                      migrate_read_lock(zspage);
++              }
++      }
++      migrate_read_unlock(zspage);
+ }
+ 
+ static struct dentry *zs_mount(struct file_system_type *fs_type,
+diff --git a/net/core/filter.c b/net/core/filter.c
+index 7d68c98a00aa8..c1310c9d1b903 100644
+--- a/net/core/filter.c
++++ b/net/core/filter.c
+@@ -1666,7 +1666,7 @@ BPF_CALL_5(bpf_skb_store_bytes, struct sk_buff *, skb, 
u32, offset,
+ 
+       if (unlikely(flags & ~(BPF_F_RECOMPUTE_CSUM | BPF_F_INVALIDATE_HASH)))
+               return -EINVAL;
+-      if (unlikely(offset > 0xffff))
++      if (unlikely(offset > INT_MAX))
+               return -EFAULT;
+       if (unlikely(bpf_try_make_writable(skb, offset + len)))
+               return -EFAULT;
+@@ -1701,7 +1701,7 @@ BPF_CALL_4(bpf_skb_load_bytes, const struct sk_buff *, 
skb, u32, offset,
+ {
+       void *ptr;
+ 
+-      if (unlikely(offset > 0xffff))
++      if (unlikely(offset > INT_MAX))
+               goto err_clear;
+ 
+       ptr = skb_header_pointer(skb, offset, len, to);
+diff --git a/net/core/secure_seq.c b/net/core/secure_seq.c
+index 3a8128341e6ac..6fd25279bee95 100644
+--- a/net/core/secure_seq.c
++++ b/net/core/secure_seq.c
+@@ -96,7 +96,7 @@ u32 secure_tcpv6_seq(const __be32 *saddr, const __be32 
*daddr,
+ }
+ EXPORT_SYMBOL(secure_tcpv6_seq);
+ 
+-u32 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
++u64 secure_ipv6_port_ephemeral(const __be32 *saddr, const __be32 *daddr,
+                              __be16 dport)
+ {
+       const struct {
+@@ -146,7 +146,7 @@ u32 secure_tcp_seq(__be32 saddr, __be32 daddr,
+ }
+ EXPORT_SYMBOL_GPL(secure_tcp_seq);
+ 
+-u32 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
++u64 secure_ipv4_port_ephemeral(__be32 saddr, __be32 daddr, __be16 dport)
+ {
+       net_secret_init();
+       return siphash_4u32((__force u32)saddr, (__force u32)daddr,
+diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
+index c96a5871b49da..0a8aec3f37cc6 100644
+--- a/net/ipv4/inet_hashtables.c
++++ b/net/ipv4/inet_hashtables.c
+@@ -507,7 +507,7 @@ not_unique:
+       return -EADDRNOTAVAIL;
+ }
+ 
+-static u32 inet_sk_port_offset(const struct sock *sk)
++static u64 inet_sk_port_offset(const struct sock *sk)
+ {
+       const struct inet_sock *inet = inet_sk(sk);
+ 
+@@ -714,8 +714,19 @@ unlock:
+ }
+ EXPORT_SYMBOL_GPL(inet_unhash);
+ 
++/* RFC 6056 3.3.4.  Algorithm 4: Double-Hash Port Selection Algorithm
++ * Note that we use 32bit integers (vs RFC 'short integers')
++ * because 2^16 is not a multiple of num_ephemeral and this
++ * property might be used by clever attacker.
++ * RFC claims using TABLE_LENGTH=10 buckets gives an improvement,
++ * we use 256 instead to really give more isolation and
++ * privacy, this only consumes 1 KB of kernel memory.
++ */
++#define INET_TABLE_PERTURB_SHIFT 8
++static u32 table_perturb[1 << INET_TABLE_PERTURB_SHIFT];
++
+ int __inet_hash_connect(struct inet_timewait_death_row *death_row,
+-              struct sock *sk, u32 port_offset,
++              struct sock *sk, u64 port_offset,
+               int (*check_established)(struct inet_timewait_death_row *,
+                       struct sock *, __u16, struct inet_timewait_sock **))
+ {
+@@ -727,7 +738,7 @@ int __inet_hash_connect(struct inet_timewait_death_row 
*death_row,
+       struct inet_bind_bucket *tb;
+       u32 remaining, offset;
+       int ret, i, low, high;
+-      static u32 hint;
++      u32 index;
+ 
+       if (port) {
+               head = &hinfo->bhash[inet_bhashfn(net, port,
+@@ -752,7 +763,12 @@ int __inet_hash_connect(struct inet_timewait_death_row 
*death_row,
+       if (likely(remaining > 1))
+               remaining &= ~1U;
+ 
+-      offset = (hint + port_offset) % remaining;
++      net_get_random_once(table_perturb, sizeof(table_perturb));
++      index = hash_32(port_offset, INET_TABLE_PERTURB_SHIFT);
++
++      offset = READ_ONCE(table_perturb[index]) + port_offset;
++      offset %= remaining;
++
+       /* In first pass we try ports of @low parity.
+        * inet_csk_get_port() does the opposite choice.
+        */
+@@ -805,7 +821,7 @@ next_port:
+       return -EADDRNOTAVAIL;
+ 
+ ok:
+-      hint += i + 2;
++      WRITE_ONCE(table_perturb[index], READ_ONCE(table_perturb[index]) + i + 
2);
+ 
+       /* Head lock still held and bh's disabled */
+       inet_bind_hash(sk, tb, port);
+@@ -828,7 +844,7 @@ ok:
+ int inet_hash_connect(struct inet_timewait_death_row *death_row,
+                     struct sock *sk)
+ {
+-      u32 port_offset = 0;
++      u64 port_offset = 0;
+ 
+       if (!inet_sk(sk)->inet_num)
+               port_offset = inet_sk_port_offset(sk);
+diff --git a/net/ipv6/inet6_hashtables.c b/net/ipv6/inet6_hashtables.c
+index d9e2575dad948..d8391921363ff 100644
+--- a/net/ipv6/inet6_hashtables.c
++++ b/net/ipv6/inet6_hashtables.c
+@@ -311,7 +311,7 @@ not_unique:
+       return -EADDRNOTAVAIL;
+ }
+ 
+-static u32 inet6_sk_port_offset(const struct sock *sk)
++static u64 inet6_sk_port_offset(const struct sock *sk)
+ {
+       const struct inet_sock *inet = inet_sk(sk);
+ 
+@@ -323,7 +323,7 @@ static u32 inet6_sk_port_offset(const struct sock *sk)
+ int inet6_hash_connect(struct inet_timewait_death_row *death_row,
+                      struct sock *sk)
+ {
+-      u32 port_offset = 0;
++      u64 port_offset = 0;
+ 
+       if (!inet_sk(sk)->inet_num)
+               port_offset = inet6_sk_port_offset(sk);
+diff --git a/net/key/af_key.c b/net/key/af_key.c
+index 170960ef7e360..1bbb6ec89ff3d 100644
+--- a/net/key/af_key.c
++++ b/net/key/af_key.c
+@@ -2910,7 +2910,7 @@ static int count_ah_combs(const struct xfrm_tmpl *t)
+                       break;
+               if (!aalg->pfkey_supported)
+                       continue;
+-              if (aalg_tmpl_set(t, aalg))
++              if (aalg_tmpl_set(t, aalg) && aalg->available)
+                       sz += sizeof(struct sadb_comb);
+       }
+       return sz + sizeof(struct sadb_prop);
+@@ -2928,7 +2928,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+               if (!ealg->pfkey_supported)
+                       continue;
+ 
+-              if (!(ealg_tmpl_set(t, ealg)))
++              if (!(ealg_tmpl_set(t, ealg) && ealg->available))
+                       continue;
+ 
+               for (k = 1; ; k++) {
+@@ -2939,7 +2939,7 @@ static int count_esp_combs(const struct xfrm_tmpl *t)
+                       if (!aalg->pfkey_supported)
+                               continue;
+ 
+-                      if (aalg_tmpl_set(t, aalg))
++                      if (aalg_tmpl_set(t, aalg) && aalg->available)
+                               sz += sizeof(struct sadb_comb);
+               }
+       }
+diff --git a/net/wireless/core.c b/net/wireless/core.c
+index 68660781aa51f..7c66f99046ac8 100644
+--- a/net/wireless/core.c
++++ b/net/wireless/core.c
+@@ -4,6 +4,7 @@
+  * Copyright 2006-2010                Johannes Berg 
<[email protected]>
+  * Copyright 2013-2014  Intel Mobile Communications GmbH
+  * Copyright 2015-2017        Intel Deutschland GmbH
++ * Copyright (C) 2018-2021 Intel Corporation
+  */
+ 
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+@@ -835,9 +836,6 @@ int wiphy_register(struct wiphy *wiphy)
+               return res;
+       }
+ 
+-      /* set up regulatory info */
+-      wiphy_regulatory_register(wiphy);
+-
+       list_add_rcu(&rdev->list, &cfg80211_rdev_list);
+       cfg80211_rdev_list_generation++;
+ 
+@@ -851,6 +849,9 @@ int wiphy_register(struct wiphy *wiphy)
+       cfg80211_debugfs_rdev_add(rdev);
+       nl80211_notify_wiphy(rdev, NL80211_CMD_NEW_WIPHY);
+ 
++      /* set up regulatory info */
++      wiphy_regulatory_register(wiphy);
++
+       if (wiphy->regulatory_flags & REGULATORY_CUSTOM_REG) {
+               struct regulatory_request request;
+ 
+diff --git a/net/wireless/reg.c b/net/wireless/reg.c
+index c7825b951f725..dd8503a3ef1e1 100644
+--- a/net/wireless/reg.c
++++ b/net/wireless/reg.c
+@@ -3756,6 +3756,7 @@ void wiphy_regulatory_register(struct wiphy *wiphy)
+ 
+       wiphy_update_regulatory(wiphy, lr->initiator);
+       wiphy_all_share_dfs_chan_state(wiphy);
++      reg_process_self_managed_hints();
+ }
+ 
+ void wiphy_regulatory_deregister(struct wiphy *wiphy)
+diff --git a/tools/lib/traceevent/Makefile b/tools/lib/traceevent/Makefile
+index 05f8a0f27121a..b7f7e4e541d7b 100644
+--- a/tools/lib/traceevent/Makefile
++++ b/tools/lib/traceevent/Makefile
+@@ -263,7 +263,7 @@ define do_generate_dynamic_list_file
+       xargs echo "U w W" | tr 'w ' 'W\n' | sort -u | xargs echo`;\
+       if [ "$$symbol_type" = "U W" ];then                             \
+               (echo '{';                                              \
+-              $(NM) -u -D $1 | awk 'NF>1 {print "\t"$$2";"}' | sort -u;\
++              $(NM) -u -D $1 | awk 'NF>1 {sub("@.*", "", $$2); print 
"\t"$$2";"}' | sort -u;\
+               echo '};';                                              \
+               ) > $2;                                                 \
+       else                                                            \
+diff --git a/tools/perf/bench/bench.h b/tools/perf/bench/bench.h
+index 6c9fcd757f310..b3e418afc21a2 100644
+--- a/tools/perf/bench/bench.h
++++ b/tools/perf/bench/bench.h
+@@ -2,6 +2,10 @@
+ #ifndef BENCH_H
+ #define BENCH_H
+ 
++#include <sys/time.h>
++
++extern struct timeval bench__start, bench__end, bench__runtime;
++
+ /*
+  * The madvise transparent hugepage constants were added in glibc
+  * 2.13. For compatibility with older versions of glibc, define these
+diff --git a/tools/perf/bench/futex-hash.c b/tools/perf/bench/futex-hash.c
+index 9aa3a674829b3..ee9b280651093 100644
+--- a/tools/perf/bench/futex-hash.c
++++ b/tools/perf/bench/futex-hash.c
+@@ -35,7 +35,7 @@ static unsigned int nfutexes = 1024;
+ static bool fshared = false, done = false, silent = false;
+ static int futex_flag = 0;
+ 
+-struct timeval start, end, runtime;
++struct timeval bench__start, bench__end, bench__runtime;
+ static pthread_mutex_t thread_lock;
+ static unsigned int threads_starting;
+ static struct stats throughput_stats;
+@@ -101,8 +101,8 @@ static void toggle_done(int sig __maybe_unused,
+ {
+       /* inform all threads that we're done for the day */
+       done = true;
+-      gettimeofday(&end, NULL);
+-      timersub(&end, &start, &runtime);
++      gettimeofday(&bench__end, NULL);
++      timersub(&bench__end, &bench__start, &bench__runtime);
+ }
+ 
+ static void print_summary(void)
+@@ -112,7 +112,7 @@ static void print_summary(void)
+ 
+       printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
+              !silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg),
+-             (int) runtime.tv_sec);
++             (int)bench__runtime.tv_sec);
+ }
+ 
+ int bench_futex_hash(int argc, const char **argv)
+@@ -159,7 +159,7 @@ int bench_futex_hash(int argc, const char **argv)
+ 
+       threads_starting = nthreads;
+       pthread_attr_init(&thread_attr);
+-      gettimeofday(&start, NULL);
++      gettimeofday(&bench__start, NULL);
+       for (i = 0; i < nthreads; i++) {
+               worker[i].tid = i;
+               worker[i].futex = calloc(nfutexes, sizeof(*worker[i].futex));
+@@ -202,7 +202,7 @@ int bench_futex_hash(int argc, const char **argv)
+       pthread_mutex_destroy(&thread_lock);
+ 
+       for (i = 0; i < nthreads; i++) {
+-              unsigned long t = worker[i].ops/runtime.tv_sec;
++              unsigned long t = worker[i].ops / bench__runtime.tv_sec;
+               update_stats(&throughput_stats, t);
+               if (!silent) {
+                       if (nfutexes == 1)
+diff --git a/tools/perf/bench/futex-lock-pi.c 
b/tools/perf/bench/futex-lock-pi.c
+index 8e9c4753e3040..017609ae35906 100644
+--- a/tools/perf/bench/futex-lock-pi.c
++++ b/tools/perf/bench/futex-lock-pi.c
+@@ -35,7 +35,6 @@ static bool silent = false, multi = false;
+ static bool done = false, fshared = false;
+ static unsigned int nthreads = 0;
+ static int futex_flag = 0;
+-struct timeval start, end, runtime;
+ static pthread_mutex_t thread_lock;
+ static unsigned int threads_starting;
+ static struct stats throughput_stats;
+@@ -62,7 +61,7 @@ static void print_summary(void)
+ 
+       printf("%sAveraged %ld operations/sec (+- %.2f%%), total secs = %d\n",
+              !silent ? "\n" : "", avg, rel_stddev_stats(stddev, avg),
+-             (int) runtime.tv_sec);
++             (int)bench__runtime.tv_sec);
+ }
+ 
+ static void toggle_done(int sig __maybe_unused,
+@@ -71,8 +70,8 @@ static void toggle_done(int sig __maybe_unused,
+ {
+       /* inform all threads that we're done for the day */
+       done = true;
+-      gettimeofday(&end, NULL);
+-      timersub(&end, &start, &runtime);
++      gettimeofday(&bench__end, NULL);
++      timersub(&bench__end, &bench__start, &bench__runtime);
+ }
+ 
+ static void *workerfn(void *arg)
+@@ -183,7 +182,7 @@ int bench_futex_lock_pi(int argc, const char **argv)
+ 
+       threads_starting = nthreads;
+       pthread_attr_init(&thread_attr);
+-      gettimeofday(&start, NULL);
++      gettimeofday(&bench__start, NULL);
+ 
+       create_threads(worker, thread_attr, cpu);
+       pthread_attr_destroy(&thread_attr);
+@@ -209,7 +208,7 @@ int bench_futex_lock_pi(int argc, const char **argv)
+       pthread_mutex_destroy(&thread_lock);
+ 
+       for (i = 0; i < nthreads; i++) {
+-              unsigned long t = worker[i].ops/runtime.tv_sec;
++              unsigned long t = worker[i].ops / bench__runtime.tv_sec;
+ 
+               update_stats(&throughput_stats, t);
+               if (!silent)
+diff --git a/tools/perf/tests/bp_account.c b/tools/perf/tests/bp_account.c
+index a20cbc4454269..624e4ef73d1c0 100644
+--- a/tools/perf/tests/bp_account.c
++++ b/tools/perf/tests/bp_account.c
+@@ -22,7 +22,7 @@
+ #include "perf.h"
+ #include "cloexec.h"
+ 
+-volatile long the_var;
++static volatile long the_var;
+ 
+ static noinline int test_function(void)
+ {

Reply via email to