summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--4.4.5/0000_README6
-rw-r--r--4.4.5/1004_linux-4.4.5.patch3396
-rw-r--r--4.4.5/4420_grsecurity-3.1-4.4.5-201603131305.patch (renamed from 4.4.5/4420_grsecurity-3.1-4.4.5-201603102309.patch)318
3 files changed, 255 insertions, 3465 deletions
diff --git a/4.4.5/0000_README b/4.4.5/0000_README
index e92303f..c02a112 100644
--- a/4.4.5/0000_README
+++ b/4.4.5/0000_README
@@ -2,11 +2,7 @@ README
-----------------------------------------------------------------------------
Individual Patch Descriptions:
-----------------------------------------------------------------------------
-Patch: 1004_linux-4.4.5.patch
-From: https://www.kernel.org/
-Desc: Linux 4.4.5
-
-Patch: 4420_grsecurity-3.1-4.4.5-201603102309.patch
+Patch: 4420_grsecurity-3.1-4.4.5-201603131305.patch
From: http://www.grsecurity.net
Desc: hardened-sources base patch from upstream grsecurity
diff --git a/4.4.5/1004_linux-4.4.5.patch b/4.4.5/1004_linux-4.4.5.patch
deleted file mode 100644
index 82135c4..0000000
--- a/4.4.5/1004_linux-4.4.5.patch
+++ /dev/null
@@ -1,3396 +0,0 @@
-diff --git a/Makefile b/Makefile
-index 344bc6f..d13322a 100644
---- a/Makefile
-+++ b/Makefile
-@@ -1,6 +1,6 @@
- VERSION = 4
- PATCHLEVEL = 4
--SUBLEVEL = 4
-+SUBLEVEL = 5
- EXTRAVERSION =
- NAME = Blurry Fish Butt
-
-diff --git a/arch/arm/kvm/guest.c b/arch/arm/kvm/guest.c
-index 96e935b..3705fc2 100644
---- a/arch/arm/kvm/guest.c
-+++ b/arch/arm/kvm/guest.c
-@@ -155,7 +155,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
- u64 val;
-
- val = kvm_arm_timer_get_reg(vcpu, reg->id);
-- return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id));
-+ return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
- }
-
- static unsigned long num_core_regs(void)
-diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
-index 63f52b5..fc9f7ef 100644
---- a/arch/arm64/include/asm/pgtable.h
-+++ b/arch/arm64/include/asm/pgtable.h
-@@ -34,13 +34,13 @@
- /*
- * VMALLOC and SPARSEMEM_VMEMMAP ranges.
- *
-- * VMEMAP_SIZE: allows the whole VA space to be covered by a struct page array
-+ * VMEMAP_SIZE: allows the whole linear region to be covered by a struct page array
- * (rounded up to PUD_SIZE).
- * VMALLOC_START: beginning of the kernel VA space
- * VMALLOC_END: extends to the available space below vmmemmap, PCI I/O space,
- * fixed mappings and modules
- */
--#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT)) * sizeof(struct page), PUD_SIZE)
-+#define VMEMMAP_SIZE ALIGN((1UL << (VA_BITS - PAGE_SHIFT - 1)) * sizeof(struct page), PUD_SIZE)
-
- #ifndef CONFIG_KASAN
- #define VMALLOC_START (VA_START)
-@@ -51,7 +51,8 @@
-
- #define VMALLOC_END (PAGE_OFFSET - PUD_SIZE - VMEMMAP_SIZE - SZ_64K)
-
--#define vmemmap ((struct page *)(VMALLOC_END + SZ_64K))
-+#define VMEMMAP_START (VMALLOC_END + SZ_64K)
-+#define vmemmap ((struct page *)VMEMMAP_START - (memstart_addr >> PAGE_SHIFT))
-
- #define FIRST_USER_ADDRESS 0UL
-
-diff --git a/arch/arm64/kvm/guest.c b/arch/arm64/kvm/guest.c
-index d250160..3039f08 100644
---- a/arch/arm64/kvm/guest.c
-+++ b/arch/arm64/kvm/guest.c
-@@ -186,7 +186,7 @@ static int get_timer_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg)
- u64 val;
-
- val = kvm_arm_timer_get_reg(vcpu, reg->id);
-- return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id));
-+ return copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id)) ? -EFAULT : 0;
- }
-
- /**
-diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c
-index 17bf39a..4cb98aa 100644
---- a/arch/arm64/mm/init.c
-+++ b/arch/arm64/mm/init.c
-@@ -319,8 +319,8 @@ void __init mem_init(void)
- #endif
- MLG(VMALLOC_START, VMALLOC_END),
- #ifdef CONFIG_SPARSEMEM_VMEMMAP
-- MLG((unsigned long)vmemmap,
-- (unsigned long)vmemmap + VMEMMAP_SIZE),
-+ MLG(VMEMMAP_START,
-+ VMEMMAP_START + VMEMMAP_SIZE),
- MLM((unsigned long)virt_to_page(PAGE_OFFSET),
- (unsigned long)virt_to_page(high_memory)),
- #endif
-diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
-index 886cb19..ca9a810 100644
---- a/arch/mips/kernel/traps.c
-+++ b/arch/mips/kernel/traps.c
-@@ -690,15 +690,15 @@ static int simulate_sync(struct pt_regs *regs, unsigned int opcode)
- asmlinkage void do_ov(struct pt_regs *regs)
- {
- enum ctx_state prev_state;
-- siginfo_t info;
-+ siginfo_t info = {
-+ .si_signo = SIGFPE,
-+ .si_code = FPE_INTOVF,
-+ .si_addr = (void __user *)regs->cp0_epc,
-+ };
-
- prev_state = exception_enter();
- die_if_kernel("Integer overflow", regs);
-
-- info.si_code = FPE_INTOVF;
-- info.si_signo = SIGFPE;
-- info.si_errno = 0;
-- info.si_addr = (void __user *) regs->cp0_epc;
- force_sig_info(SIGFPE, &info, current);
- exception_exit(prev_state);
- }
-@@ -874,7 +874,7 @@ out:
- void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
- const char *str)
- {
-- siginfo_t info;
-+ siginfo_t info = { 0 };
- char b[40];
-
- #ifdef CONFIG_KGDB_LOW_LEVEL_TRAP
-@@ -903,7 +903,6 @@ void do_trap_or_bp(struct pt_regs *regs, unsigned int code,
- else
- info.si_code = FPE_INTOVF;
- info.si_signo = SIGFPE;
-- info.si_errno = 0;
- info.si_addr = (void __user *) regs->cp0_epc;
- force_sig_info(SIGFPE, &info, current);
- break;
-diff --git a/arch/mips/kvm/mips.c b/arch/mips/kvm/mips.c
-index b9b803f..2683d04 100644
---- a/arch/mips/kvm/mips.c
-+++ b/arch/mips/kvm/mips.c
-@@ -702,7 +702,7 @@ static int kvm_mips_get_reg(struct kvm_vcpu *vcpu,
- } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) {
- void __user *uaddr = (void __user *)(long)reg->addr;
-
-- return copy_to_user(uaddr, vs, 16);
-+ return copy_to_user(uaddr, vs, 16) ? -EFAULT : 0;
- } else {
- return -EINVAL;
- }
-@@ -732,7 +732,7 @@ static int kvm_mips_set_reg(struct kvm_vcpu *vcpu,
- } else if ((reg->id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U128) {
- void __user *uaddr = (void __user *)(long)reg->addr;
-
-- return copy_from_user(vs, uaddr, 16);
-+ return copy_from_user(vs, uaddr, 16) ? -EFAULT : 0;
- } else {
- return -EINVAL;
- }
-diff --git a/arch/mips/mm/sc-mips.c b/arch/mips/mm/sc-mips.c
-index 3bd0597..ddb8154 100644
---- a/arch/mips/mm/sc-mips.c
-+++ b/arch/mips/mm/sc-mips.c
-@@ -164,11 +164,13 @@ static int __init mips_sc_probe_cm3(void)
-
- sets = cfg & CM_GCR_L2_CONFIG_SET_SIZE_MSK;
- sets >>= CM_GCR_L2_CONFIG_SET_SIZE_SHF;
-- c->scache.sets = 64 << sets;
-+ if (sets)
-+ c->scache.sets = 64 << sets;
-
- line_sz = cfg & CM_GCR_L2_CONFIG_LINE_SIZE_MSK;
- line_sz >>= CM_GCR_L2_CONFIG_LINE_SIZE_SHF;
-- c->scache.linesz = 2 << line_sz;
-+ if (line_sz)
-+ c->scache.linesz = 2 << line_sz;
-
- assoc = cfg & CM_GCR_L2_CONFIG_ASSOC_MSK;
- assoc >>= CM_GCR_L2_CONFIG_ASSOC_SHF;
-@@ -176,9 +178,12 @@ static int __init mips_sc_probe_cm3(void)
- c->scache.waysize = c->scache.sets * c->scache.linesz;
- c->scache.waybit = __ffs(c->scache.waysize);
-
-- c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
-+ if (c->scache.linesz) {
-+ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
-+ return 1;
-+ }
-
-- return 1;
-+ return 0;
- }
-
- void __weak platform_early_l2_init(void)
-diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
-index 9585c81..ce0b2b4 100644
---- a/arch/parisc/kernel/ptrace.c
-+++ b/arch/parisc/kernel/ptrace.c
-@@ -269,14 +269,19 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
-
- long do_syscall_trace_enter(struct pt_regs *regs)
- {
-- long ret = 0;
--
- /* Do the secure computing check first. */
- secure_computing_strict(regs->gr[20]);
-
- if (test_thread_flag(TIF_SYSCALL_TRACE) &&
-- tracehook_report_syscall_entry(regs))
-- ret = -1L;
-+ tracehook_report_syscall_entry(regs)) {
-+ /*
-+ * Tracing decided this syscall should not happen or the
-+ * debugger stored an invalid system call number. Skip
-+ * the system call and the system call restart handling.
-+ */
-+ regs->gr[20] = -1UL;
-+ goto out;
-+ }
-
- #ifdef CONFIG_64BIT
- if (!is_compat_task())
-@@ -290,7 +295,8 @@ long do_syscall_trace_enter(struct pt_regs *regs)
- regs->gr[24] & 0xffffffff,
- regs->gr[23] & 0xffffffff);
-
-- return ret ? : regs->gr[20];
-+out:
-+ return regs->gr[20];
- }
-
- void do_syscall_trace_exit(struct pt_regs *regs)
-diff --git a/arch/parisc/kernel/syscall.S b/arch/parisc/kernel/syscall.S
-index 3fbd725..fbafa0d 100644
---- a/arch/parisc/kernel/syscall.S
-+++ b/arch/parisc/kernel/syscall.S
-@@ -343,7 +343,7 @@ tracesys_next:
- #endif
-
- comiclr,>>= __NR_Linux_syscalls, %r20, %r0
-- b,n .Lsyscall_nosys
-+ b,n .Ltracesys_nosys
-
- LDREGX %r20(%r19), %r19
-
-@@ -359,6 +359,9 @@ tracesys_next:
- be 0(%sr7,%r19)
- ldo R%tracesys_exit(%r2),%r2
-
-+.Ltracesys_nosys:
-+ ldo -ENOSYS(%r0),%r28 /* set errno */
-+
- /* Do *not* call this function on the gateway page, because it
- makes a direct call to syscall_trace. */
-
-diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
-index d1daead..adb3eaf 100644
---- a/arch/x86/kernel/acpi/sleep.c
-+++ b/arch/x86/kernel/acpi/sleep.c
-@@ -16,6 +16,7 @@
- #include <asm/cacheflush.h>
- #include <asm/realmode.h>
-
-+#include <linux/ftrace.h>
- #include "../../realmode/rm/wakeup.h"
- #include "sleep.h"
-
-@@ -107,7 +108,13 @@ int x86_acpi_suspend_lowlevel(void)
- saved_magic = 0x123456789abcdef0L;
- #endif /* CONFIG_64BIT */
-
-+ /*
-+ * Pause/unpause graph tracing around do_suspend_lowlevel as it has
-+ * inconsistent call/return info after it jumps to the wakeup vector.
-+ */
-+ pause_graph_tracing();
- do_suspend_lowlevel();
-+ unpause_graph_tracing();
- return 0;
- }
-
-diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
-index 10e7693..5fd846c 100644
---- a/arch/x86/kvm/vmx.c
-+++ b/arch/x86/kvm/vmx.c
-@@ -595,6 +595,8 @@ struct vcpu_vmx {
- /* Support for PML */
- #define PML_ENTITY_NUM 512
- struct page *pml_pg;
-+
-+ u64 current_tsc_ratio;
- };
-
- enum segment_cache_field {
-@@ -2062,14 +2064,16 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
- rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
- vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
-
-- /* Setup TSC multiplier */
-- if (cpu_has_vmx_tsc_scaling())
-- vmcs_write64(TSC_MULTIPLIER,
-- vcpu->arch.tsc_scaling_ratio);
--
- vmx->loaded_vmcs->cpu = cpu;
- }
-
-+ /* Setup TSC multiplier */
-+ if (kvm_has_tsc_control &&
-+ vmx->current_tsc_ratio != vcpu->arch.tsc_scaling_ratio) {
-+ vmx->current_tsc_ratio = vcpu->arch.tsc_scaling_ratio;
-+ vmcs_write64(TSC_MULTIPLIER, vmx->current_tsc_ratio);
-+ }
-+
- vmx_vcpu_pi_load(vcpu, cpu);
- }
-
-diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
-index 6ef3856..d294502 100644
---- a/arch/x86/kvm/x86.c
-+++ b/arch/x86/kvm/x86.c
-@@ -2736,7 +2736,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
- }
-
- kvm_make_request(KVM_REQ_STEAL_UPDATE, vcpu);
-- vcpu->arch.switch_db_regs |= KVM_DEBUGREG_RELOAD;
- }
-
- void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
-@@ -6545,12 +6544,12 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu)
- * KVM_DEBUGREG_WONT_EXIT again.
- */
- if (unlikely(vcpu->arch.switch_db_regs & KVM_DEBUGREG_WONT_EXIT)) {
-- int i;
--
- WARN_ON(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP);
- kvm_x86_ops->sync_dirty_debug_regs(vcpu);
-- for (i = 0; i < KVM_NR_DB_REGS; i++)
-- vcpu->arch.eff_db[i] = vcpu->arch.db[i];
-+ kvm_update_dr0123(vcpu);
-+ kvm_update_dr6(vcpu);
-+ kvm_update_dr7(vcpu);
-+ vcpu->arch.switch_db_regs &= ~KVM_DEBUGREG_RELOAD;
- }
-
- /*
-diff --git a/block/blk-settings.c b/block/blk-settings.c
-index dd49735..c7bb666 100644
---- a/block/blk-settings.c
-+++ b/block/blk-settings.c
-@@ -91,8 +91,8 @@ void blk_set_default_limits(struct queue_limits *lim)
- lim->seg_boundary_mask = BLK_SEG_BOUNDARY_MASK;
- lim->virt_boundary_mask = 0;
- lim->max_segment_size = BLK_MAX_SEGMENT_SIZE;
-- lim->max_sectors = lim->max_dev_sectors = lim->max_hw_sectors =
-- BLK_SAFE_MAX_SECTORS;
-+ lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS;
-+ lim->max_dev_sectors = 0;
- lim->chunk_sectors = 0;
- lim->max_write_same_sectors = 0;
- lim->max_discard_sectors = 0;
-diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
-index 99921aa..60a1583 100644
---- a/drivers/ata/ahci.c
-+++ b/drivers/ata/ahci.c
-@@ -367,15 +367,21 @@ static const struct pci_device_id ahci_pci_tbl[] = {
- { PCI_VDEVICE(INTEL, 0xa107), board_ahci }, /* Sunrise Point-H RAID */
- { PCI_VDEVICE(INTEL, 0xa10f), board_ahci }, /* Sunrise Point-H RAID */
- { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* Lewisburg RAID*/
-+ { PCI_VDEVICE(INTEL, 0x2823), board_ahci }, /* Lewisburg AHCI*/
- { PCI_VDEVICE(INTEL, 0x2826), board_ahci }, /* Lewisburg RAID*/
-+ { PCI_VDEVICE(INTEL, 0x2827), board_ahci }, /* Lewisburg RAID*/
- { PCI_VDEVICE(INTEL, 0xa182), board_ahci }, /* Lewisburg AHCI*/
- { PCI_VDEVICE(INTEL, 0xa184), board_ahci }, /* Lewisburg RAID*/
- { PCI_VDEVICE(INTEL, 0xa186), board_ahci }, /* Lewisburg RAID*/
- { PCI_VDEVICE(INTEL, 0xa18e), board_ahci }, /* Lewisburg RAID*/
-+ { PCI_VDEVICE(INTEL, 0xa1d2), board_ahci }, /* Lewisburg RAID*/
-+ { PCI_VDEVICE(INTEL, 0xa1d6), board_ahci }, /* Lewisburg RAID*/
- { PCI_VDEVICE(INTEL, 0xa202), board_ahci }, /* Lewisburg AHCI*/
- { PCI_VDEVICE(INTEL, 0xa204), board_ahci }, /* Lewisburg RAID*/
- { PCI_VDEVICE(INTEL, 0xa206), board_ahci }, /* Lewisburg RAID*/
- { PCI_VDEVICE(INTEL, 0xa20e), board_ahci }, /* Lewisburg RAID*/
-+ { PCI_VDEVICE(INTEL, 0xa252), board_ahci }, /* Lewisburg RAID*/
-+ { PCI_VDEVICE(INTEL, 0xa256), board_ahci }, /* Lewisburg RAID*/
-
- /* JMicron 360/1/3/5/6, match class to avoid IDE function */
- { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
-diff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c
-index 1f225cc..998c6a8 100644
---- a/drivers/ata/libahci.c
-+++ b/drivers/ata/libahci.c
-@@ -1142,8 +1142,7 @@ static void ahci_port_init(struct device *dev, struct ata_port *ap,
-
- /* mark esata ports */
- tmp = readl(port_mmio + PORT_CMD);
-- if ((tmp & PORT_CMD_HPCP) ||
-- ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS)))
-+ if ((tmp & PORT_CMD_ESP) && (hpriv->cap & HOST_CAP_SXS))
- ap->pflags |= ATA_PFLAG_EXTERNAL;
- }
-
-diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
-index 7e959f9..e417e1a 100644
---- a/drivers/ata/libata-scsi.c
-+++ b/drivers/ata/libata-scsi.c
-@@ -675,19 +675,18 @@ static int ata_ioc32(struct ata_port *ap)
- int ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev,
- int cmd, void __user *arg)
- {
-- int val = -EINVAL, rc = -EINVAL;
-+ unsigned long val;
-+ int rc = -EINVAL;
- unsigned long flags;
-
- switch (cmd) {
-- case ATA_IOC_GET_IO32:
-+ case HDIO_GET_32BIT:
- spin_lock_irqsave(ap->lock, flags);
- val = ata_ioc32(ap);
- spin_unlock_irqrestore(ap->lock, flags);
-- if (copy_to_user(arg, &val, 1))
-- return -EFAULT;
-- return 0;
-+ return put_user(val, (unsigned long __user *)arg);
-
-- case ATA_IOC_SET_IO32:
-+ case HDIO_SET_32BIT:
- val = (unsigned long) arg;
- rc = 0;
- spin_lock_irqsave(ap->lock, flags);
-diff --git a/drivers/ata/pata_rb532_cf.c b/drivers/ata/pata_rb532_cf.c
-index 12fe0f3..c8b6a78 100644
---- a/drivers/ata/pata_rb532_cf.c
-+++ b/drivers/ata/pata_rb532_cf.c
-@@ -32,6 +32,8 @@
- #include <linux/libata.h>
- #include <scsi/scsi_host.h>
-
-+#include <asm/mach-rc32434/rb.h>
-+
- #define DRV_NAME "pata-rb532-cf"
- #define DRV_VERSION "0.1.0"
- #define DRV_DESC "PATA driver for RouterBOARD 532 Compact Flash"
-@@ -107,6 +109,7 @@ static int rb532_pata_driver_probe(struct platform_device *pdev)
- int gpio;
- struct resource *res;
- struct ata_host *ah;
-+ struct cf_device *pdata;
- struct rb532_cf_info *info;
- int ret;
-
-@@ -122,7 +125,13 @@ static int rb532_pata_driver_probe(struct platform_device *pdev)
- return -ENOENT;
- }
-
-- gpio = irq_to_gpio(irq);
-+ pdata = dev_get_platdata(&pdev->dev);
-+ if (!pdata) {
-+ dev_err(&pdev->dev, "no platform data specified\n");
-+ return -EINVAL;
-+ }
-+
-+ gpio = pdata->gpio_pin;
- if (gpio < 0) {
- dev_err(&pdev->dev, "no GPIO found for irq%d\n", irq);
- return -ENOENT;
-diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c
-index fc4156a..a59061e 100644
---- a/drivers/dma/pxa_dma.c
-+++ b/drivers/dma/pxa_dma.c
-@@ -583,6 +583,8 @@ static void set_updater_desc(struct pxad_desc_sw *sw_desc,
- (PXA_DCMD_LENGTH & sizeof(u32));
- if (flags & DMA_PREP_INTERRUPT)
- updater->dcmd |= PXA_DCMD_ENDIRQEN;
-+ if (sw_desc->cyclic)
-+ sw_desc->hw_desc[sw_desc->nb_desc - 2]->ddadr = sw_desc->first;
- }
-
- static bool is_desc_completed(struct virt_dma_desc *vd)
-@@ -673,6 +675,10 @@ static irqreturn_t pxad_chan_handler(int irq, void *dev_id)
- dev_dbg(&chan->vc.chan.dev->device,
- "%s(): checking txd %p[%x]: completed=%d\n",
- __func__, vd, vd->tx.cookie, is_desc_completed(vd));
-+ if (to_pxad_sw_desc(vd)->cyclic) {
-+ vchan_cyclic_callback(vd);
-+ break;
-+ }
- if (is_desc_completed(vd)) {
- list_del(&vd->node);
- vchan_cookie_complete(vd);
-@@ -1080,7 +1086,7 @@ pxad_prep_dma_cyclic(struct dma_chan *dchan,
- return NULL;
-
- pxad_get_config(chan, dir, &dcmd, &dsadr, &dtadr);
-- dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH | period_len);
-+ dcmd |= PXA_DCMD_ENDIRQEN | (PXA_DCMD_LENGTH & period_len);
- dev_dbg(&chan->vc.chan.dev->device,
- "%s(): buf_addr=0x%lx len=%zu period=%zu dir=%d flags=%lx\n",
- __func__, (unsigned long)buf_addr, len, period_len, dir, flags);
-diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
-index 89c3dd6..119cdc2 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
-@@ -77,7 +77,7 @@ void amdgpu_connector_hotplug(struct drm_connector *connector)
- } else if (amdgpu_atombios_dp_needs_link_train(amdgpu_connector)) {
- /* Don't try to start link training before we
- * have the dpcd */
-- if (!amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
-+ if (amdgpu_atombios_dp_get_dpcd(amdgpu_connector))
- return;
-
- /* set it to OFF so that drm_helper_connector_dpms()
-diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
-index a2a16ac..b8fbbd7 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_object.c
-@@ -33,6 +33,7 @@
- #include <linux/slab.h>
- #include <drm/drmP.h>
- #include <drm/amdgpu_drm.h>
-+#include <drm/drm_cache.h>
- #include "amdgpu.h"
- #include "amdgpu_trace.h"
-
-@@ -261,6 +262,13 @@ int amdgpu_bo_create_restricted(struct amdgpu_device *adev,
- AMDGPU_GEM_DOMAIN_OA);
-
- bo->flags = flags;
-+
-+ /* For architectures that don't support WC memory,
-+ * mask out the WC flag from the BO
-+ */
-+ if (!drm_arch_can_wc_memory())
-+ bo->flags &= ~AMDGPU_GEM_CREATE_CPU_GTT_USWC;
-+
- amdgpu_fill_placement_to_bo(bo, placement);
- /* Kernel allocation are uninterruptible */
- r = ttm_bo_init(&adev->mman.bdev, &bo->tbo, size, type,
-diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
-index 03fe251..7ae15fa 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_pm.c
-@@ -596,9 +596,6 @@ force:
- /* update display watermarks based on new power state */
- amdgpu_display_bandwidth_update(adev);
-
-- adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
-- adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
--
- /* wait for the rings to drain */
- for (i = 0; i < AMDGPU_MAX_RINGS; i++) {
- struct amdgpu_ring *ring = adev->rings[i];
-@@ -617,6 +614,9 @@ force:
- /* update displays */
- amdgpu_dpm_display_configuration_changed(adev);
-
-+ adev->pm.dpm.current_active_crtcs = adev->pm.dpm.new_active_crtcs;
-+ adev->pm.dpm.current_active_crtc_count = adev->pm.dpm.new_active_crtc_count;
-+
- if (adev->pm.funcs->force_performance_level) {
- if (adev->pm.dpm.thermal_active) {
- enum amdgpu_dpm_forced_level level = adev->pm.dpm.forced_level;
-diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
-index 39adbb6..8c5ec15 100644
---- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
-+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c
-@@ -1248,7 +1248,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
- {
- const unsigned align = min(AMDGPU_VM_PTB_ALIGN_SIZE,
- AMDGPU_VM_PTE_COUNT * 8);
-- unsigned pd_size, pd_entries, pts_size;
-+ unsigned pd_size, pd_entries;
- int i, r;
-
- for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
-@@ -1266,8 +1266,7 @@ int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm)
- pd_entries = amdgpu_vm_num_pdes(adev);
-
- /* allocate page table array */
-- pts_size = pd_entries * sizeof(struct amdgpu_vm_pt);
-- vm->page_tables = kzalloc(pts_size, GFP_KERNEL);
-+ vm->page_tables = drm_calloc_large(pd_entries, sizeof(struct amdgpu_vm_pt));
- if (vm->page_tables == NULL) {
- DRM_ERROR("Cannot allocate memory for page table array\n");
- return -ENOMEM;
-@@ -1327,7 +1326,7 @@ void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm)
-
- for (i = 0; i < amdgpu_vm_num_pdes(adev); i++)
- amdgpu_bo_unref(&vm->page_tables[i].bo);
-- kfree(vm->page_tables);
-+ drm_free_large(vm->page_tables);
-
- amdgpu_bo_unref(&vm->page_directory);
- fence_put(vm->page_directory_fence);
-diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
-index 72793f9..aa49154 100644
---- a/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
-+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v7_0.c
-@@ -3628,6 +3628,19 @@ static void gfx_v7_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
- unsigned vm_id, uint64_t pd_addr)
- {
- int usepfp = (ring->type == AMDGPU_RING_TYPE_GFX);
-+ uint32_t seq = ring->fence_drv.sync_seq;
-+ uint64_t addr = ring->fence_drv.gpu_addr;
-+
-+ amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
-+ amdgpu_ring_write(ring, (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
-+ WAIT_REG_MEM_FUNCTION(3) | /* equal */
-+ WAIT_REG_MEM_ENGINE(usepfp))); /* pfp or me */
-+ amdgpu_ring_write(ring, addr & 0xfffffffc);
-+ amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
-+ amdgpu_ring_write(ring, seq);
-+ amdgpu_ring_write(ring, 0xffffffff);
-+ amdgpu_ring_write(ring, 4); /* poll interval */
-+
- if (usepfp) {
- /* synce CE with ME to prevent CE fetch CEIB before context switch done */
- amdgpu_ring_write(ring, PACKET3(PACKET3_SWITCH_BUFFER, 0));
-diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
-index 4cb45f4..d105403 100644
---- a/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
-+++ b/drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
-@@ -4681,7 +4681,8 @@ static void gfx_v8_0_ring_emit_vm_flush(struct amdgpu_ring *ring,
-
- amdgpu_ring_write(ring, PACKET3(PACKET3_WAIT_REG_MEM, 5));
- amdgpu_ring_write(ring, (WAIT_REG_MEM_MEM_SPACE(1) | /* memory */
-- WAIT_REG_MEM_FUNCTION(3))); /* equal */
-+ WAIT_REG_MEM_FUNCTION(3) | /* equal */
-+ WAIT_REG_MEM_ENGINE(usepfp))); /* pfp or me */
- amdgpu_ring_write(ring, addr & 0xfffffffc);
- amdgpu_ring_write(ring, upper_32_bits(addr) & 0xffffffff);
- amdgpu_ring_write(ring, seq);
-diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c
-index 7628eb4..3e9cbe3 100644
---- a/drivers/gpu/drm/amd/amdgpu/vi.c
-+++ b/drivers/gpu/drm/amd/amdgpu/vi.c
-@@ -1082,10 +1082,10 @@ static const struct amdgpu_ip_block_version topaz_ip_blocks[] =
- },
- {
- .type = AMD_IP_BLOCK_TYPE_GMC,
-- .major = 8,
-- .minor = 0,
-+ .major = 7,
-+ .minor = 4,
- .rev = 0,
-- .funcs = &gmc_v8_0_ip_funcs,
-+ .funcs = &gmc_v7_0_ip_funcs,
- },
- {
- .type = AMD_IP_BLOCK_TYPE_IH,
-@@ -1129,10 +1129,10 @@ static const struct amdgpu_ip_block_version tonga_ip_blocks[] =
- },
- {
- .type = AMD_IP_BLOCK_TYPE_GMC,
-- .major = 7,
-- .minor = 4,
-+ .major = 8,
-+ .minor = 0,
- .rev = 0,
-- .funcs = &gmc_v7_0_ip_funcs,
-+ .funcs = &gmc_v8_0_ip_funcs,
- },
- {
- .type = AMD_IP_BLOCK_TYPE_IH,
-diff --git a/drivers/gpu/drm/ast/ast_main.c b/drivers/gpu/drm/ast/ast_main.c
-index 541a610..e0b4586 100644
---- a/drivers/gpu/drm/ast/ast_main.c
-+++ b/drivers/gpu/drm/ast/ast_main.c
-@@ -227,7 +227,7 @@ static int ast_get_dram_info(struct drm_device *dev)
- } while (ast_read32(ast, 0x10000) != 0x01);
- data = ast_read32(ast, 0x10004);
-
-- if (data & 0x400)
-+ if (data & 0x40)
- ast->dram_bus_width = 16;
- else
- ast->dram_bus_width = 32;
-diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
-index 760e0ce..a6ad938 100644
---- a/drivers/gpu/drm/i915/i915_drv.c
-+++ b/drivers/gpu/drm/i915/i915_drv.c
-@@ -531,7 +531,10 @@ void intel_detect_pch(struct drm_device *dev)
- dev_priv->pch_type = PCH_SPT;
- DRM_DEBUG_KMS("Found SunrisePoint LP PCH\n");
- WARN_ON(!IS_SKYLAKE(dev));
-- } else if (id == INTEL_PCH_P2X_DEVICE_ID_TYPE) {
-+ } else if ((id == INTEL_PCH_P2X_DEVICE_ID_TYPE) ||
-+ ((id == INTEL_PCH_QEMU_DEVICE_ID_TYPE) &&
-+ pch->subsystem_vendor == 0x1af4 &&
-+ pch->subsystem_device == 0x1100)) {
- dev_priv->pch_type = intel_virt_detect_pch(dev);
- } else
- continue;
-diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
-index f4af19a..d3ce4da 100644
---- a/drivers/gpu/drm/i915/i915_drv.h
-+++ b/drivers/gpu/drm/i915/i915_drv.h
-@@ -2614,6 +2614,7 @@ struct drm_i915_cmd_table {
- #define INTEL_PCH_SPT_DEVICE_ID_TYPE 0xA100
- #define INTEL_PCH_SPT_LP_DEVICE_ID_TYPE 0x9D00
- #define INTEL_PCH_P2X_DEVICE_ID_TYPE 0x7100
-+#define INTEL_PCH_QEMU_DEVICE_ID_TYPE 0x2900 /* qemu q35 has 2918 */
-
- #define INTEL_PCH_TYPE(dev) (__I915__(dev)->pch_type)
- #define HAS_PCH_SPT(dev) (INTEL_PCH_TYPE(dev) == PCH_SPT)
-diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
-index 2081a60..1fa8121 100644
---- a/drivers/gpu/drm/radeon/radeon_pm.c
-+++ b/drivers/gpu/drm/radeon/radeon_pm.c
-@@ -1076,10 +1076,6 @@ force:
- /* update display watermarks based on new power state */
- radeon_bandwidth_update(rdev);
-
-- rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
-- rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
-- rdev->pm.dpm.single_display = single_display;
--
- /* wait for the rings to drain */
- for (i = 0; i < RADEON_NUM_RINGS; i++) {
- struct radeon_ring *ring = &rdev->ring[i];
-@@ -1098,6 +1094,10 @@ force:
- /* update displays */
- radeon_dpm_display_configuration_changed(rdev);
-
-+ rdev->pm.dpm.current_active_crtcs = rdev->pm.dpm.new_active_crtcs;
-+ rdev->pm.dpm.current_active_crtc_count = rdev->pm.dpm.new_active_crtc_count;
-+ rdev->pm.dpm.single_display = single_display;
-+
- if (rdev->asic->dpm.force_performance_level) {
- if (rdev->pm.dpm.thermal_active) {
- enum radeon_dpm_forced_level level = rdev->pm.dpm.forced_level;
-diff --git a/drivers/i2c/busses/i2c-brcmstb.c b/drivers/i2c/busses/i2c-brcmstb.c
-index 8e9637e..81115ab 100644
---- a/drivers/i2c/busses/i2c-brcmstb.c
-+++ b/drivers/i2c/busses/i2c-brcmstb.c
-@@ -562,8 +562,7 @@ static int brcmstb_i2c_probe(struct platform_device *pdev)
- if (!dev)
- return -ENOMEM;
-
-- dev->bsc_regmap = devm_kzalloc(&pdev->dev, sizeof(struct bsc_regs *),
-- GFP_KERNEL);
-+ dev->bsc_regmap = devm_kzalloc(&pdev->dev, sizeof(*dev->bsc_regmap), GFP_KERNEL);
- if (!dev->bsc_regmap)
- return -ENOMEM;
-
-diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c
-index 013bdff..bf4959f 100644
---- a/drivers/iommu/amd_iommu_init.c
-+++ b/drivers/iommu/amd_iommu_init.c
-@@ -228,6 +228,10 @@ static int amd_iommu_enable_interrupts(void);
- static int __init iommu_go_to_state(enum iommu_init_state state);
- static void init_device_table_dma(void);
-
-+static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu,
-+ u8 bank, u8 cntr, u8 fxn,
-+ u64 *value, bool is_write);
-+
- static inline void update_last_devid(u16 devid)
- {
- if (devid > amd_iommu_last_bdf)
-@@ -1016,6 +1020,34 @@ static void amd_iommu_erratum_746_workaround(struct amd_iommu *iommu)
- }
-
- /*
-+ * Family15h Model 30h-3fh (IOMMU Mishandles ATS Write Permission)
-+ * Workaround:
-+ * BIOS should enable ATS write permission check by setting
-+ * L2_DEBUG_3[AtsIgnoreIWDis](D0F2xF4_x47[0]) = 1b
-+ */
-+static void amd_iommu_ats_write_check_workaround(struct amd_iommu *iommu)
-+{
-+ u32 value;
-+
-+ if ((boot_cpu_data.x86 != 0x15) ||
-+ (boot_cpu_data.x86_model < 0x30) ||
-+ (boot_cpu_data.x86_model > 0x3f))
-+ return;
-+
-+ /* Test L2_DEBUG_3[AtsIgnoreIWDis] == 1 */
-+ value = iommu_read_l2(iommu, 0x47);
-+
-+ if (value & BIT(0))
-+ return;
-+
-+ /* Set L2_DEBUG_3[AtsIgnoreIWDis] = 1 */
-+ iommu_write_l2(iommu, 0x47, value | BIT(0));
-+
-+ pr_info("AMD-Vi: Applying ATS write check workaround for IOMMU at %s\n",
-+ dev_name(&iommu->dev->dev));
-+}
-+
-+/*
- * This function clues the initialization function for one IOMMU
- * together and also allocates the command buffer and programs the
- * hardware. It does NOT enable the IOMMU. This is done afterwards.
-@@ -1142,8 +1174,8 @@ static void init_iommu_perf_ctr(struct amd_iommu *iommu)
- amd_iommu_pc_present = true;
-
- /* Check if the performance counters can be written to */
-- if ((0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val, true)) ||
-- (0 != amd_iommu_pc_get_set_reg_val(0, 0, 0, 0, &val2, false)) ||
-+ if ((0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val, true)) ||
-+ (0 != iommu_pc_get_set_reg_val(iommu, 0, 0, 0, &val2, false)) ||
- (val != val2)) {
- pr_err("AMD-Vi: Unable to write to IOMMU perf counter.\n");
- amd_iommu_pc_present = false;
-@@ -1284,6 +1316,7 @@ static int iommu_init_pci(struct amd_iommu *iommu)
- }
-
- amd_iommu_erratum_746_workaround(iommu);
-+ amd_iommu_ats_write_check_workaround(iommu);
-
- iommu->iommu_dev = iommu_device_create(&iommu->dev->dev, iommu,
- amd_iommu_groups, "ivhd%d",
-@@ -2283,22 +2316,15 @@ u8 amd_iommu_pc_get_max_counters(u16 devid)
- }
- EXPORT_SYMBOL(amd_iommu_pc_get_max_counters);
-
--int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
-+static int iommu_pc_get_set_reg_val(struct amd_iommu *iommu,
-+ u8 bank, u8 cntr, u8 fxn,
- u64 *value, bool is_write)
- {
-- struct amd_iommu *iommu;
- u32 offset;
- u32 max_offset_lim;
-
-- /* Make sure the IOMMU PC resource is available */
-- if (!amd_iommu_pc_present)
-- return -ENODEV;
--
-- /* Locate the iommu associated with the device ID */
-- iommu = amd_iommu_rlookup_table[devid];
--
- /* Check for valid iommu and pc register indexing */
-- if (WARN_ON((iommu == NULL) || (fxn > 0x28) || (fxn & 7)))
-+ if (WARN_ON((fxn > 0x28) || (fxn & 7)))
- return -ENODEV;
-
- offset = (u32)(((0x40|bank) << 12) | (cntr << 8) | fxn);
-@@ -2322,3 +2348,16 @@ int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
- return 0;
- }
- EXPORT_SYMBOL(amd_iommu_pc_get_set_reg_val);
-+
-+int amd_iommu_pc_get_set_reg_val(u16 devid, u8 bank, u8 cntr, u8 fxn,
-+ u64 *value, bool is_write)
-+{
-+ struct amd_iommu *iommu = amd_iommu_rlookup_table[devid];
-+
-+ /* Make sure the IOMMU PC resource is available */
-+ if (!amd_iommu_pc_present || iommu == NULL)
-+ return -ENODEV;
-+
-+ return iommu_pc_get_set_reg_val(iommu, bank, cntr, fxn,
-+ value, is_write);
-+}
-diff --git a/drivers/iommu/dmar.c b/drivers/iommu/dmar.c
-index 55a19e4..3821c47 100644
---- a/drivers/iommu/dmar.c
-+++ b/drivers/iommu/dmar.c
-@@ -329,7 +329,8 @@ static int dmar_pci_bus_notifier(struct notifier_block *nb,
- /* Only care about add/remove events for physical functions */
- if (pdev->is_virtfn)
- return NOTIFY_DONE;
-- if (action != BUS_NOTIFY_ADD_DEVICE && action != BUS_NOTIFY_DEL_DEVICE)
-+ if (action != BUS_NOTIFY_ADD_DEVICE &&
-+ action != BUS_NOTIFY_REMOVED_DEVICE)
- return NOTIFY_DONE;
-
- info = dmar_alloc_pci_notify_info(pdev, action);
-@@ -339,7 +340,7 @@ static int dmar_pci_bus_notifier(struct notifier_block *nb,
- down_write(&dmar_global_lock);
- if (action == BUS_NOTIFY_ADD_DEVICE)
- dmar_pci_bus_add_dev(info);
-- else if (action == BUS_NOTIFY_DEL_DEVICE)
-+ else if (action == BUS_NOTIFY_REMOVED_DEVICE)
- dmar_pci_bus_del_dev(info);
- up_write(&dmar_global_lock);
-
-diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
-index 986a53e..a2e1b7f 100644
---- a/drivers/iommu/intel-iommu.c
-+++ b/drivers/iommu/intel-iommu.c
-@@ -4367,7 +4367,7 @@ int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
- rmrru->devices_cnt);
- if(ret < 0)
- return ret;
-- } else if (info->event == BUS_NOTIFY_DEL_DEVICE) {
-+ } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
- dmar_remove_dev_scope(info, rmrr->segment,
- rmrru->devices, rmrru->devices_cnt);
- }
-@@ -4387,7 +4387,7 @@ int dmar_iommu_notify_scope_dev(struct dmar_pci_notify_info *info)
- break;
- else if(ret < 0)
- return ret;
-- } else if (info->event == BUS_NOTIFY_DEL_DEVICE) {
-+ } else if (info->event == BUS_NOTIFY_REMOVED_DEVICE) {
- if (dmar_remove_dev_scope(info, atsr->segment,
- atsru->devices, atsru->devices_cnt))
- break;
-diff --git a/drivers/media/i2c/adv7604.c b/drivers/media/i2c/adv7604.c
-index 5631ec0..01adcdc 100644
---- a/drivers/media/i2c/adv7604.c
-+++ b/drivers/media/i2c/adv7604.c
-@@ -1960,10 +1960,9 @@ static int adv76xx_isr(struct v4l2_subdev *sd, u32 status, bool *handled)
- }
-
- /* tx 5v detect */
-- tx_5v = io_read(sd, 0x70) & info->cable_det_mask;
-+ tx_5v = irq_reg_0x70 & info->cable_det_mask;
- if (tx_5v) {
- v4l2_dbg(1, debug, sd, "%s: tx_5v: 0x%x\n", __func__, tx_5v);
-- io_write(sd, 0x71, tx_5v);
- adv76xx_s_detect_tx_5v_ctrl(sd);
- if (handled)
- *handled = true;
-diff --git a/drivers/misc/cxl/pci.c b/drivers/misc/cxl/pci.c
-index 85761d7..be2c8e24 100644
---- a/drivers/misc/cxl/pci.c
-+++ b/drivers/misc/cxl/pci.c
-@@ -414,7 +414,7 @@ static int cxl_setup_psl_timebase(struct cxl *adapter, struct pci_dev *dev)
- delta = mftb() - psl_tb;
- if (delta < 0)
- delta = -delta;
-- } while (cputime_to_usecs(delta) > 16);
-+ } while (tb_to_ns(delta) > 16000);
-
- return 0;
- }
-diff --git a/drivers/mtd/ubi/upd.c b/drivers/mtd/ubi/upd.c
-index 2a1b6e0..0134ba3 100644
---- a/drivers/mtd/ubi/upd.c
-+++ b/drivers/mtd/ubi/upd.c
-@@ -193,7 +193,7 @@ int ubi_start_leb_change(struct ubi_device *ubi, struct ubi_volume *vol,
- vol->changing_leb = 1;
- vol->ch_lnum = req->lnum;
-
-- vol->upd_buf = vmalloc(req->bytes);
-+ vol->upd_buf = vmalloc(ALIGN((int)req->bytes, ubi->min_io_size));
- if (!vol->upd_buf)
- return -ENOMEM;
-
-diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
-index ed34c95..6153853 100644
---- a/drivers/pci/host/pci-keystone-dw.c
-+++ b/drivers/pci/host/pci-keystone-dw.c
-@@ -58,11 +58,6 @@
-
- #define to_keystone_pcie(x) container_of(x, struct keystone_pcie, pp)
-
--static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
--{
-- return sys->private_data;
--}
--
- static inline void update_reg_offset_bit_pos(u32 offset, u32 *reg_offset,
- u32 *bit_pos)
- {
-@@ -108,7 +103,7 @@ static void ks_dw_pcie_msi_irq_ack(struct irq_data *d)
- struct pcie_port *pp;
-
- msi = irq_data_get_msi_desc(d);
-- pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
-+ pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
- ks_pcie = to_keystone_pcie(pp);
- offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
- update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
-@@ -146,7 +141,7 @@ static void ks_dw_pcie_msi_irq_mask(struct irq_data *d)
- u32 offset;
-
- msi = irq_data_get_msi_desc(d);
-- pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
-+ pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
- ks_pcie = to_keystone_pcie(pp);
- offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
-
-@@ -167,7 +162,7 @@ static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d)
- u32 offset;
-
- msi = irq_data_get_msi_desc(d);
-- pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
-+ pp = (struct pcie_port *) msi_desc_to_pci_sysdata(msi);
- ks_pcie = to_keystone_pcie(pp);
- offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
-
-diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c
-index 91a00301..a9bac3b 100644
---- a/drivers/sh/pm_runtime.c
-+++ b/drivers/sh/pm_runtime.c
-@@ -34,7 +34,7 @@ static struct pm_clk_notifier_block platform_bus_notifier = {
-
- static int __init sh_pm_runtime_init(void)
- {
-- if (IS_ENABLED(CONFIG_ARCH_SHMOBILE)) {
-+ if (IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_ARCH_SHMOBILE)) {
- if (!of_find_compatible_node(NULL, NULL,
- "renesas,cpg-mstp-clocks"))
- return 0;
-diff --git a/drivers/target/target_core_device.c b/drivers/target/target_core_device.c
-index 88ea4e4..3436a83 100644
---- a/drivers/target/target_core_device.c
-+++ b/drivers/target/target_core_device.c
-@@ -826,6 +826,49 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name)
- return dev;
- }
-
-+/*
-+ * Check if the underlying struct block_device request_queue supports
-+ * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
-+ * in ATA and we need to set TPE=1
-+ */
-+bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib,
-+ struct request_queue *q, int block_size)
-+{
-+ if (!blk_queue_discard(q))
-+ return false;
-+
-+ attrib->max_unmap_lba_count = (q->limits.max_discard_sectors << 9) /
-+ block_size;
-+ /*
-+ * Currently hardcoded to 1 in Linux/SCSI code..
-+ */
-+ attrib->max_unmap_block_desc_count = 1;
-+ attrib->unmap_granularity = q->limits.discard_granularity / block_size;
-+ attrib->unmap_granularity_alignment = q->limits.discard_alignment /
-+ block_size;
-+ return true;
-+}
-+EXPORT_SYMBOL(target_configure_unmap_from_queue);
-+
-+/*
-+ * Convert from blocksize advertised to the initiator to the 512 byte
-+ * units unconditionally used by the Linux block layer.
-+ */
-+sector_t target_to_linux_sector(struct se_device *dev, sector_t lb)
-+{
-+ switch (dev->dev_attrib.block_size) {
-+ case 4096:
-+ return lb << 3;
-+ case 2048:
-+ return lb << 2;
-+ case 1024:
-+ return lb << 1;
-+ default:
-+ return lb;
-+ }
-+}
-+EXPORT_SYMBOL(target_to_linux_sector);
-+
- int target_configure_device(struct se_device *dev)
- {
- struct se_hba *hba = dev->se_hba;
-diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c
-index e319570..75f0f08 100644
---- a/drivers/target/target_core_file.c
-+++ b/drivers/target/target_core_file.c
-@@ -160,25 +160,11 @@ static int fd_configure_device(struct se_device *dev)
- " block_device blocks: %llu logical_block_size: %d\n",
- dev_size, div_u64(dev_size, fd_dev->fd_block_size),
- fd_dev->fd_block_size);
-- /*
-- * Check if the underlying struct block_device request_queue supports
-- * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
-- * in ATA and we need to set TPE=1
-- */
-- if (blk_queue_discard(q)) {
-- dev->dev_attrib.max_unmap_lba_count =
-- q->limits.max_discard_sectors;
-- /*
-- * Currently hardcoded to 1 in Linux/SCSI code..
-- */
-- dev->dev_attrib.max_unmap_block_desc_count = 1;
-- dev->dev_attrib.unmap_granularity =
-- q->limits.discard_granularity >> 9;
-- dev->dev_attrib.unmap_granularity_alignment =
-- q->limits.discard_alignment;
-+
-+ if (target_configure_unmap_from_queue(&dev->dev_attrib, q,
-+ fd_dev->fd_block_size))
- pr_debug("IFILE: BLOCK Discard support available,"
-- " disabled by default\n");
-- }
-+ " disabled by default\n");
- /*
- * Enable write same emulation for IBLOCK and use 0xFFFF as
- * the smaller WRITE_SAME(10) only has a two-byte block count.
-@@ -490,9 +476,12 @@ fd_execute_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb)
- if (S_ISBLK(inode->i_mode)) {
- /* The backend is block device, use discard */
- struct block_device *bdev = inode->i_bdev;
-+ struct se_device *dev = cmd->se_dev;
-
-- ret = blkdev_issue_discard(bdev, lba,
-- nolb, GFP_KERNEL, 0);
-+ ret = blkdev_issue_discard(bdev,
-+ target_to_linux_sector(dev, lba),
-+ target_to_linux_sector(dev, nolb),
-+ GFP_KERNEL, 0);
- if (ret < 0) {
- pr_warn("FILEIO: blkdev_issue_discard() failed: %d\n",
- ret);
-diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
-index f29c691..2c53dce 100644
---- a/drivers/target/target_core_iblock.c
-+++ b/drivers/target/target_core_iblock.c
-@@ -121,27 +121,11 @@ static int iblock_configure_device(struct se_device *dev)
- dev->dev_attrib.hw_max_sectors = queue_max_hw_sectors(q);
- dev->dev_attrib.hw_queue_depth = q->nr_requests;
-
-- /*
-- * Check if the underlying struct block_device request_queue supports
-- * the QUEUE_FLAG_DISCARD bit for UNMAP/WRITE_SAME in SCSI + TRIM
-- * in ATA and we need to set TPE=1
-- */
-- if (blk_queue_discard(q)) {
-- dev->dev_attrib.max_unmap_lba_count =
-- q->limits.max_discard_sectors;
--
-- /*
-- * Currently hardcoded to 1 in Linux/SCSI code..
-- */
-- dev->dev_attrib.max_unmap_block_desc_count = 1;
-- dev->dev_attrib.unmap_granularity =
-- q->limits.discard_granularity >> 9;
-- dev->dev_attrib.unmap_granularity_alignment =
-- q->limits.discard_alignment;
--
-+ if (target_configure_unmap_from_queue(&dev->dev_attrib, q,
-+ dev->dev_attrib.hw_block_size))
- pr_debug("IBLOCK: BLOCK Discard support available,"
-- " disabled by default\n");
-- }
-+ " disabled by default\n");
-+
- /*
- * Enable write same emulation for IBLOCK and use 0xFFFF as
- * the smaller WRITE_SAME(10) only has a two-byte block count.
-@@ -413,9 +397,13 @@ static sense_reason_t
- iblock_execute_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb)
- {
- struct block_device *bdev = IBLOCK_DEV(cmd->se_dev)->ibd_bd;
-+ struct se_device *dev = cmd->se_dev;
- int ret;
-
-- ret = blkdev_issue_discard(bdev, lba, nolb, GFP_KERNEL, 0);
-+ ret = blkdev_issue_discard(bdev,
-+ target_to_linux_sector(dev, lba),
-+ target_to_linux_sector(dev, nolb),
-+ GFP_KERNEL, 0);
- if (ret < 0) {
- pr_err("blkdev_issue_discard() failed: %d\n", ret);
- return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-@@ -431,8 +419,10 @@ iblock_execute_write_same(struct se_cmd *cmd)
- struct scatterlist *sg;
- struct bio *bio;
- struct bio_list list;
-- sector_t block_lba = cmd->t_task_lba;
-- sector_t sectors = sbc_get_write_same_sectors(cmd);
-+ struct se_device *dev = cmd->se_dev;
-+ sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
-+ sector_t sectors = target_to_linux_sector(dev,
-+ sbc_get_write_same_sectors(cmd));
-
- if (cmd->prot_op) {
- pr_err("WRITE_SAME: Protection information with IBLOCK"
-@@ -646,12 +636,12 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
- enum dma_data_direction data_direction)
- {
- struct se_device *dev = cmd->se_dev;
-+ sector_t block_lba = target_to_linux_sector(dev, cmd->t_task_lba);
- struct iblock_req *ibr;
- struct bio *bio, *bio_start;
- struct bio_list list;
- struct scatterlist *sg;
- u32 sg_num = sgl_nents;
-- sector_t block_lba;
- unsigned bio_cnt;
- int rw = 0;
- int i;
-@@ -677,24 +667,6 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
- rw = READ;
- }
-
-- /*
-- * Convert the blocksize advertised to the initiator to the 512 byte
-- * units unconditionally used by the Linux block layer.
-- */
-- if (dev->dev_attrib.block_size == 4096)
-- block_lba = (cmd->t_task_lba << 3);
-- else if (dev->dev_attrib.block_size == 2048)
-- block_lba = (cmd->t_task_lba << 2);
-- else if (dev->dev_attrib.block_size == 1024)
-- block_lba = (cmd->t_task_lba << 1);
-- else if (dev->dev_attrib.block_size == 512)
-- block_lba = cmd->t_task_lba;
-- else {
-- pr_err("Unsupported SCSI -> BLOCK LBA conversion:"
-- " %u\n", dev->dev_attrib.block_size);
-- return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
-- }
--
- ibr = kzalloc(sizeof(struct iblock_req), GFP_KERNEL);
- if (!ibr)
- goto fail;
-diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c
-index e3fbc5a..6ceac4f 100644
---- a/drivers/thermal/cpu_cooling.c
-+++ b/drivers/thermal/cpu_cooling.c
-@@ -377,26 +377,28 @@ static u32 cpu_power_to_freq(struct cpufreq_cooling_device *cpufreq_device,
- * get_load() - get load for a cpu since last updated
- * @cpufreq_device: &struct cpufreq_cooling_device for this cpu
- * @cpu: cpu number
-+ * @cpu_idx: index of the cpu in cpufreq_device->allowed_cpus
- *
- * Return: The average load of cpu @cpu in percentage since this
- * function was last called.
- */
--static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu)
-+static u32 get_load(struct cpufreq_cooling_device *cpufreq_device, int cpu,
-+ int cpu_idx)
- {
- u32 load;
- u64 now, now_idle, delta_time, delta_idle;
-
- now_idle = get_cpu_idle_time(cpu, &now, 0);
-- delta_idle = now_idle - cpufreq_device->time_in_idle[cpu];
-- delta_time = now - cpufreq_device->time_in_idle_timestamp[cpu];
-+ delta_idle = now_idle - cpufreq_device->time_in_idle[cpu_idx];
-+ delta_time = now - cpufreq_device->time_in_idle_timestamp[cpu_idx];
-
- if (delta_time <= delta_idle)
- load = 0;
- else
- load = div64_u64(100 * (delta_time - delta_idle), delta_time);
-
-- cpufreq_device->time_in_idle[cpu] = now_idle;
-- cpufreq_device->time_in_idle_timestamp[cpu] = now;
-+ cpufreq_device->time_in_idle[cpu_idx] = now_idle;
-+ cpufreq_device->time_in_idle_timestamp[cpu_idx] = now;
-
- return load;
- }
-@@ -598,7 +600,7 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev,
- u32 load;
-
- if (cpu_online(cpu))
-- load = get_load(cpufreq_device, cpu);
-+ load = get_load(cpufreq_device, cpu, i);
- else
- load = 0;
-
-diff --git a/drivers/usb/chipidea/otg.c b/drivers/usb/chipidea/otg.c
-index 45f86da..03b6743 100644
---- a/drivers/usb/chipidea/otg.c
-+++ b/drivers/usb/chipidea/otg.c
-@@ -158,7 +158,7 @@ static void ci_otg_work(struct work_struct *work)
- int ci_hdrc_otg_init(struct ci_hdrc *ci)
- {
- INIT_WORK(&ci->work, ci_otg_work);
-- ci->wq = create_singlethread_workqueue("ci_otg");
-+ ci->wq = create_freezable_workqueue("ci_otg");
- if (!ci->wq) {
- dev_err(ci->dev, "can't create workqueue\n");
- return -ENODEV;
-diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
-index a7caf53..7a76fe4 100644
---- a/drivers/usb/serial/cp210x.c
-+++ b/drivers/usb/serial/cp210x.c
-@@ -164,6 +164,7 @@ static const struct usb_device_id id_table[] = {
- { USB_DEVICE(0x18EF, 0xE025) }, /* ELV Marble Sound Board 1 */
- { USB_DEVICE(0x1901, 0x0190) }, /* GE B850 CP2105 Recorder interface */
- { USB_DEVICE(0x1901, 0x0193) }, /* GE B650 CP2104 PMC interface */
-+ { USB_DEVICE(0x19CF, 0x3000) }, /* Parrot NMEA GPS Flight Recorder */
- { USB_DEVICE(0x1ADB, 0x0001) }, /* Schweitzer Engineering C662 Cable */
- { USB_DEVICE(0x1B1C, 0x1C00) }, /* Corsair USB Dongle */
- { USB_DEVICE(0x1BA4, 0x0002) }, /* Silicon Labs 358x factory default */
-diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
-index 8849439a..348e198 100644
---- a/drivers/usb/serial/option.c
-+++ b/drivers/usb/serial/option.c
-@@ -270,6 +270,7 @@ static void option_instat_callback(struct urb *urb);
- #define TELIT_PRODUCT_UE910_V2 0x1012
- #define TELIT_PRODUCT_LE922_USBCFG0 0x1042
- #define TELIT_PRODUCT_LE922_USBCFG3 0x1043
-+#define TELIT_PRODUCT_LE922_USBCFG5 0x1045
- #define TELIT_PRODUCT_LE920 0x1200
- #define TELIT_PRODUCT_LE910 0x1201
-
-@@ -1132,6 +1133,8 @@ static const struct usb_device_id option_ids[] = {
- { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x6613)}, /* Onda H600/ZTE MF330 */
- { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x0023)}, /* ONYX 3G device */
- { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9000)}, /* SIMCom SIM5218 */
-+ { USB_DEVICE(QUALCOMM_VENDOR_ID, 0x9003), /* Quectel UC20 */
-+ .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
- { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6001) },
- { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_CMU_300) },
- { USB_DEVICE(CMOTECH_VENDOR_ID, CMOTECH_PRODUCT_6003),
-@@ -1183,6 +1186,8 @@ static const struct usb_device_id option_ids[] = {
- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
- { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG3),
- .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg3 },
-+ { USB_DEVICE_INTERFACE_CLASS(TELIT_VENDOR_ID, TELIT_PRODUCT_LE922_USBCFG5, 0xff),
-+ .driver_info = (kernel_ulong_t)&telit_le922_blacklist_usbcfg0 },
- { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE910),
- .driver_info = (kernel_ulong_t)&telit_le910_blacklist },
- { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
-diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c
-index 9919d2a..1bc6089 100644
---- a/drivers/usb/serial/qcserial.c
-+++ b/drivers/usb/serial/qcserial.c
-@@ -157,14 +157,17 @@ static const struct usb_device_id id_table[] = {
- {DEVICE_SWI(0x1199, 0x9056)}, /* Sierra Wireless Modem */
- {DEVICE_SWI(0x1199, 0x9060)}, /* Sierra Wireless Modem */
- {DEVICE_SWI(0x1199, 0x9061)}, /* Sierra Wireless Modem */
-- {DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx/EM74xx */
-- {DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx/EM74xx */
-+ {DEVICE_SWI(0x1199, 0x9070)}, /* Sierra Wireless MC74xx */
-+ {DEVICE_SWI(0x1199, 0x9071)}, /* Sierra Wireless MC74xx */
-+ {DEVICE_SWI(0x1199, 0x9078)}, /* Sierra Wireless EM74xx */
-+ {DEVICE_SWI(0x1199, 0x9079)}, /* Sierra Wireless EM74xx */
- {DEVICE_SWI(0x413c, 0x81a2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */
- {DEVICE_SWI(0x413c, 0x81a3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */
- {DEVICE_SWI(0x413c, 0x81a4)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */
- {DEVICE_SWI(0x413c, 0x81a8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */
- {DEVICE_SWI(0x413c, 0x81a9)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */
- {DEVICE_SWI(0x413c, 0x81b1)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card */
-+ {DEVICE_SWI(0x413c, 0x81b3)}, /* Dell Wireless 5809e Gobi(TM) 4G LTE Mobile Broadband Card (rev3) */
-
- /* Huawei devices */
- {DEVICE_HWI(0x03f0, 0x581d)}, /* HP lt4112 LTE/HSPA+ Gobi 4G Modem (Huawei me906e) */
-diff --git a/drivers/vfio/pci/vfio_pci.c b/drivers/vfio/pci/vfio_pci.c
-index 56bf6db..9982cb1 100644
---- a/drivers/vfio/pci/vfio_pci.c
-+++ b/drivers/vfio/pci/vfio_pci.c
-@@ -446,7 +446,8 @@ static long vfio_pci_ioctl(void *device_data,
- info.num_regions = VFIO_PCI_NUM_REGIONS;
- info.num_irqs = VFIO_PCI_NUM_IRQS;
-
-- return copy_to_user((void __user *)arg, &info, minsz);
-+ return copy_to_user((void __user *)arg, &info, minsz) ?
-+ -EFAULT : 0;
-
- } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) {
- struct pci_dev *pdev = vdev->pdev;
-@@ -520,7 +521,8 @@ static long vfio_pci_ioctl(void *device_data,
- return -EINVAL;
- }
-
-- return copy_to_user((void __user *)arg, &info, minsz);
-+ return copy_to_user((void __user *)arg, &info, minsz) ?
-+ -EFAULT : 0;
-
- } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
- struct vfio_irq_info info;
-@@ -555,7 +557,8 @@ static long vfio_pci_ioctl(void *device_data,
- else
- info.flags |= VFIO_IRQ_INFO_NORESIZE;
-
-- return copy_to_user((void __user *)arg, &info, minsz);
-+ return copy_to_user((void __user *)arg, &info, minsz) ?
-+ -EFAULT : 0;
-
- } else if (cmd == VFIO_DEVICE_SET_IRQS) {
- struct vfio_irq_set hdr;
-diff --git a/drivers/vfio/platform/vfio_platform_common.c b/drivers/vfio/platform/vfio_platform_common.c
-index 418cdd9..e65b142 100644
---- a/drivers/vfio/platform/vfio_platform_common.c
-+++ b/drivers/vfio/platform/vfio_platform_common.c
-@@ -219,7 +219,8 @@ static long vfio_platform_ioctl(void *device_data,
- info.num_regions = vdev->num_regions;
- info.num_irqs = vdev->num_irqs;
-
-- return copy_to_user((void __user *)arg, &info, minsz);
-+ return copy_to_user((void __user *)arg, &info, minsz) ?
-+ -EFAULT : 0;
-
- } else if (cmd == VFIO_DEVICE_GET_REGION_INFO) {
- struct vfio_region_info info;
-@@ -240,7 +241,8 @@ static long vfio_platform_ioctl(void *device_data,
- info.size = vdev->regions[info.index].size;
- info.flags = vdev->regions[info.index].flags;
-
-- return copy_to_user((void __user *)arg, &info, minsz);
-+ return copy_to_user((void __user *)arg, &info, minsz) ?
-+ -EFAULT : 0;
-
- } else if (cmd == VFIO_DEVICE_GET_IRQ_INFO) {
- struct vfio_irq_info info;
-@@ -259,7 +261,8 @@ static long vfio_platform_ioctl(void *device_data,
- info.flags = vdev->irqs[info.index].flags;
- info.count = vdev->irqs[info.index].count;
-
-- return copy_to_user((void __user *)arg, &info, minsz);
-+ return copy_to_user((void __user *)arg, &info, minsz) ?
-+ -EFAULT : 0;
-
- } else if (cmd == VFIO_DEVICE_SET_IRQS) {
- struct vfio_irq_set hdr;
-diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c
-index 59d47cb..ecb826e 100644
---- a/drivers/vfio/vfio_iommu_type1.c
-+++ b/drivers/vfio/vfio_iommu_type1.c
-@@ -999,7 +999,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
-
- info.iova_pgsizes = vfio_pgsize_bitmap(iommu);
-
-- return copy_to_user((void __user *)arg, &info, minsz);
-+ return copy_to_user((void __user *)arg, &info, minsz) ?
-+ -EFAULT : 0;
-
- } else if (cmd == VFIO_IOMMU_MAP_DMA) {
- struct vfio_iommu_type1_dma_map map;
-@@ -1032,7 +1033,8 @@ static long vfio_iommu_type1_ioctl(void *iommu_data,
- if (ret)
- return ret;
-
-- return copy_to_user((void __user *)arg, &unmap, minsz);
-+ return copy_to_user((void __user *)arg, &unmap, minsz) ?
-+ -EFAULT : 0;
- }
-
- return -ENOTTY;
-diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
-index 92f3949..6e92917 100644
---- a/drivers/video/console/fbcon.c
-+++ b/drivers/video/console/fbcon.c
-@@ -709,6 +709,7 @@ static int con2fb_acquire_newinfo(struct vc_data *vc, struct fb_info *info,
- }
-
- if (!err) {
-+ ops->cur_blink_jiffies = HZ / 5;
- info->fbcon_par = ops;
-
- if (vc)
-@@ -956,6 +957,7 @@ static const char *fbcon_startup(void)
- ops->currcon = -1;
- ops->graphics = 1;
- ops->cur_rotate = -1;
-+ ops->cur_blink_jiffies = HZ / 5;
- info->fbcon_par = ops;
- p->con_rotate = initial_rotation;
- set_blitting_type(vc, info);
-diff --git a/fs/btrfs/async-thread.c b/fs/btrfs/async-thread.c
-index 3e36e4a..9aba42b 100644
---- a/fs/btrfs/async-thread.c
-+++ b/fs/btrfs/async-thread.c
-@@ -328,8 +328,8 @@ static inline void __btrfs_queue_work(struct __btrfs_workqueue *wq,
- list_add_tail(&work->ordered_list, &wq->ordered_list);
- spin_unlock_irqrestore(&wq->list_lock, flags);
- }
-- queue_work(wq->normal_wq, &work->normal_work);
- trace_btrfs_work_queued(work);
-+ queue_work(wq->normal_wq, &work->normal_work);
- }
-
- void btrfs_queue_work(struct btrfs_workqueue *wq,
-diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
-index 35489e7..385b449 100644
---- a/fs/btrfs/ctree.h
-+++ b/fs/btrfs/ctree.h
-@@ -1572,7 +1572,7 @@ struct btrfs_fs_info {
-
- spinlock_t delayed_iput_lock;
- struct list_head delayed_iputs;
-- struct rw_semaphore delayed_iput_sem;
-+ struct mutex cleaner_delayed_iput_mutex;
-
- /* this protects tree_mod_seq_list */
- spinlock_t tree_mod_seq_lock;
-diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
-index 4958360..41fb431 100644
---- a/fs/btrfs/disk-io.c
-+++ b/fs/btrfs/disk-io.c
-@@ -1796,7 +1796,10 @@ static int cleaner_kthread(void *arg)
- goto sleep;
- }
-
-+ mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex);
- btrfs_run_delayed_iputs(root);
-+ mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex);
-+
- again = btrfs_clean_one_deleted_snapshot(root);
- mutex_unlock(&root->fs_info->cleaner_mutex);
-
-@@ -2556,8 +2559,8 @@ int open_ctree(struct super_block *sb,
- mutex_init(&fs_info->delete_unused_bgs_mutex);
- mutex_init(&fs_info->reloc_mutex);
- mutex_init(&fs_info->delalloc_root_mutex);
-+ mutex_init(&fs_info->cleaner_delayed_iput_mutex);
- seqlock_init(&fs_info->profiles_lock);
-- init_rwsem(&fs_info->delayed_iput_sem);
-
- INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
- INIT_LIST_HEAD(&fs_info->space_info);
-diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
-index c4661db..2368cac 100644
---- a/fs/btrfs/extent-tree.c
-+++ b/fs/btrfs/extent-tree.c
-@@ -4086,8 +4086,10 @@ commit_trans:
- !atomic_read(&root->fs_info->open_ioctl_trans)) {
- need_commit--;
-
-- if (need_commit > 0)
-+ if (need_commit > 0) {
-+ btrfs_start_delalloc_roots(fs_info, 0, -1);
- btrfs_wait_ordered_roots(fs_info, -1);
-+ }
-
- trans = btrfs_join_transaction(root);
- if (IS_ERR(trans))
-@@ -4100,11 +4102,12 @@ commit_trans:
- if (ret)
- return ret;
- /*
-- * make sure that all running delayed iput are
-- * done
-+ * The cleaner kthread might still be doing iput
-+ * operations. Wait for it to finish so that
-+ * more space is released.
- */
-- down_write(&root->fs_info->delayed_iput_sem);
-- up_write(&root->fs_info->delayed_iput_sem);
-+ mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex);
-+ mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex);
- goto again;
- } else {
- btrfs_end_transaction(trans, root);
-diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
-index 52fc1b5..4bc9dbf 100644
---- a/fs/btrfs/inode.c
-+++ b/fs/btrfs/inode.c
-@@ -3142,8 +3142,6 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root)
- if (empty)
- return;
-
-- down_read(&fs_info->delayed_iput_sem);
--
- spin_lock(&fs_info->delayed_iput_lock);
- list_splice_init(&fs_info->delayed_iputs, &list);
- spin_unlock(&fs_info->delayed_iput_lock);
-@@ -3154,8 +3152,6 @@ void btrfs_run_delayed_iputs(struct btrfs_root *root)
- iput(delayed->inode);
- kfree(delayed);
- }
--
-- up_read(&root->fs_info->delayed_iput_sem);
- }
-
- /*
-diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c
-index 7cf8509..2c849b0 100644
---- a/fs/btrfs/root-tree.c
-+++ b/fs/btrfs/root-tree.c
-@@ -310,8 +310,16 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root)
- set_bit(BTRFS_ROOT_ORPHAN_ITEM_INSERTED, &root->state);
-
- err = btrfs_insert_fs_root(root->fs_info, root);
-+ /*
-+ * The root might have been inserted already, as before we look
-+ * for orphan roots, log replay might have happened, which
-+ * triggers a transaction commit and qgroup accounting, which
-+ * in turn reads and inserts fs roots while doing backref
-+ * walking.
-+ */
-+ if (err == -EEXIST)
-+ err = 0;
- if (err) {
-- BUG_ON(err == -EEXIST);
- btrfs_free_fs_root(root);
- break;
- }
-diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
-index c3cc160..44b3d42 100644
---- a/fs/cifs/cifsfs.h
-+++ b/fs/cifs/cifsfs.h
-@@ -31,19 +31,15 @@
- * so that it will fit. We use hash_64 to convert the value to 31 bits, and
- * then add 1, to ensure that we don't end up with a 0 as the value.
- */
--#if BITS_PER_LONG == 64
- static inline ino_t
- cifs_uniqueid_to_ino_t(u64 fileid)
- {
-+ if ((sizeof(ino_t)) < (sizeof(u64)))
-+ return (ino_t)hash_64(fileid, (sizeof(ino_t) * 8) - 1) + 1;
-+
- return (ino_t)fileid;
-+
- }
--#else
--static inline ino_t
--cifs_uniqueid_to_ino_t(u64 fileid)
--{
-- return (ino_t)hash_64(fileid, (sizeof(ino_t) * 8) - 1) + 1;
--}
--#endif
-
- extern struct file_system_type cifs_fs_type;
- extern const struct address_space_operations cifs_addr_ops;
-diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
-index 90b4f9f..76fcb50 100644
---- a/fs/cifs/cifssmb.c
-+++ b/fs/cifs/cifssmb.c
-@@ -1396,11 +1396,10 @@ openRetry:
- * current bigbuf.
- */
- static int
--cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
-+discard_remaining_data(struct TCP_Server_Info *server)
- {
- unsigned int rfclen = get_rfc1002_length(server->smallbuf);
- int remaining = rfclen + 4 - server->total_read;
-- struct cifs_readdata *rdata = mid->callback_data;
-
- while (remaining > 0) {
- int length;
-@@ -1414,10 +1413,20 @@ cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
- remaining -= length;
- }
-
-- dequeue_mid(mid, rdata->result);
- return 0;
- }
-
-+static int
-+cifs_readv_discard(struct TCP_Server_Info *server, struct mid_q_entry *mid)
-+{
-+ int length;
-+ struct cifs_readdata *rdata = mid->callback_data;
-+
-+ length = discard_remaining_data(server);
-+ dequeue_mid(mid, rdata->result);
-+ return length;
-+}
-+
- int
- cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
- {
-@@ -1446,6 +1455,12 @@ cifs_readv_receive(struct TCP_Server_Info *server, struct mid_q_entry *mid)
- return length;
- server->total_read += length;
-
-+ if (server->ops->is_status_pending &&
-+ server->ops->is_status_pending(buf, server, 0)) {
-+ discard_remaining_data(server);
-+ return -1;
-+ }
-+
- /* Was the SMB read successful? */
- rdata->result = server->ops->map_error(buf, false);
- if (rdata->result != 0) {
-diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
-index 7675555..373b5cd 100644
---- a/fs/cifs/smb2pdu.c
-+++ b/fs/cifs/smb2pdu.c
-@@ -1109,21 +1109,25 @@ parse_lease_state(struct TCP_Server_Info *server, struct smb2_create_rsp *rsp,
- {
- char *data_offset;
- struct create_context *cc;
-- unsigned int next = 0;
-+ unsigned int next;
-+ unsigned int remaining;
- char *name;
-
- data_offset = (char *)rsp + 4 + le32_to_cpu(rsp->CreateContextsOffset);
-+ remaining = le32_to_cpu(rsp->CreateContextsLength);
- cc = (struct create_context *)data_offset;
-- do {
-- cc = (struct create_context *)((char *)cc + next);
-+ while (remaining >= sizeof(struct create_context)) {
- name = le16_to_cpu(cc->NameOffset) + (char *)cc;
-- if (le16_to_cpu(cc->NameLength) != 4 ||
-- strncmp(name, "RqLs", 4)) {
-- next = le32_to_cpu(cc->Next);
-- continue;
-- }
-- return server->ops->parse_lease_buf(cc, epoch);
-- } while (next != 0);
-+ if (le16_to_cpu(cc->NameLength) == 4 &&
-+ strncmp(name, "RqLs", 4) == 0)
-+ return server->ops->parse_lease_buf(cc, epoch);
-+
-+ next = le32_to_cpu(cc->Next);
-+ if (!next)
-+ break;
-+ remaining -= next;
-+ cc = (struct create_context *)((char *)cc + next);
-+ }
-
- return 0;
- }
-diff --git a/fs/dcache.c b/fs/dcache.c
-index 5c33aeb..877bcbb 100644
---- a/fs/dcache.c
-+++ b/fs/dcache.c
-@@ -269,9 +269,6 @@ static inline int dname_external(const struct dentry *dentry)
- return dentry->d_name.name != dentry->d_iname;
- }
-
--/*
-- * Make sure other CPUs see the inode attached before the type is set.
-- */
- static inline void __d_set_inode_and_type(struct dentry *dentry,
- struct inode *inode,
- unsigned type_flags)
-@@ -279,28 +276,18 @@ static inline void __d_set_inode_and_type(struct dentry *dentry,
- unsigned flags;
-
- dentry->d_inode = inode;
-- smp_wmb();
- flags = READ_ONCE(dentry->d_flags);
- flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU);
- flags |= type_flags;
- WRITE_ONCE(dentry->d_flags, flags);
- }
-
--/*
-- * Ideally, we want to make sure that other CPUs see the flags cleared before
-- * the inode is detached, but this is really a violation of RCU principles
-- * since the ordering suggests we should always set inode before flags.
-- *
-- * We should instead replace or discard the entire dentry - but that sucks
-- * performancewise on mass deletion/rename.
-- */
- static inline void __d_clear_type_and_inode(struct dentry *dentry)
- {
- unsigned flags = READ_ONCE(dentry->d_flags);
-
- flags &= ~(DCACHE_ENTRY_TYPE | DCACHE_FALLTHRU);
- WRITE_ONCE(dentry->d_flags, flags);
-- smp_wmb();
- dentry->d_inode = NULL;
- }
-
-@@ -370,9 +357,11 @@ static void dentry_unlink_inode(struct dentry * dentry)
- __releases(dentry->d_inode->i_lock)
- {
- struct inode *inode = dentry->d_inode;
-+
-+ raw_write_seqcount_begin(&dentry->d_seq);
- __d_clear_type_and_inode(dentry);
- hlist_del_init(&dentry->d_u.d_alias);
-- dentry_rcuwalk_invalidate(dentry);
-+ raw_write_seqcount_end(&dentry->d_seq);
- spin_unlock(&dentry->d_lock);
- spin_unlock(&inode->i_lock);
- if (!inode->i_nlink)
-@@ -1757,8 +1746,9 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode)
- spin_lock(&dentry->d_lock);
- if (inode)
- hlist_add_head(&dentry->d_u.d_alias, &inode->i_dentry);
-+ raw_write_seqcount_begin(&dentry->d_seq);
- __d_set_inode_and_type(dentry, inode, add_flags);
-- dentry_rcuwalk_invalidate(dentry);
-+ raw_write_seqcount_end(&dentry->d_seq);
- spin_unlock(&dentry->d_lock);
- fsnotify_d_instantiate(dentry, inode);
- }
-diff --git a/fs/fs-writeback.c b/fs/fs-writeback.c
-index e5232bb..7a8ea13 100644
---- a/fs/fs-writeback.c
-+++ b/fs/fs-writeback.c
-@@ -223,6 +223,9 @@ static void wb_wait_for_completion(struct backing_dev_info *bdi,
- #define WB_FRN_HIST_MAX_SLOTS (WB_FRN_HIST_THR_SLOTS / 2 + 1)
- /* one round can affect upto 5 slots */
-
-+static atomic_t isw_nr_in_flight = ATOMIC_INIT(0);
-+static struct workqueue_struct *isw_wq;
-+
- void __inode_attach_wb(struct inode *inode, struct page *page)
- {
- struct backing_dev_info *bdi = inode_to_bdi(inode);
-@@ -317,7 +320,6 @@ static void inode_switch_wbs_work_fn(struct work_struct *work)
- struct inode_switch_wbs_context *isw =
- container_of(work, struct inode_switch_wbs_context, work);
- struct inode *inode = isw->inode;
-- struct super_block *sb = inode->i_sb;
- struct address_space *mapping = inode->i_mapping;
- struct bdi_writeback *old_wb = inode->i_wb;
- struct bdi_writeback *new_wb = isw->new_wb;
-@@ -424,8 +426,9 @@ skip_switch:
- wb_put(new_wb);
-
- iput(inode);
-- deactivate_super(sb);
- kfree(isw);
-+
-+ atomic_dec(&isw_nr_in_flight);
- }
-
- static void inode_switch_wbs_rcu_fn(struct rcu_head *rcu_head)
-@@ -435,7 +438,7 @@ static void inode_switch_wbs_rcu_fn(struct rcu_head *rcu_head)
-
- /* needs to grab bh-unsafe locks, bounce to work item */
- INIT_WORK(&isw->work, inode_switch_wbs_work_fn);
-- schedule_work(&isw->work);
-+ queue_work(isw_wq, &isw->work);
- }
-
- /**
-@@ -471,20 +474,20 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
-
- /* while holding I_WB_SWITCH, no one else can update the association */
- spin_lock(&inode->i_lock);
--
-- if (inode->i_state & (I_WB_SWITCH | I_FREEING) ||
-- inode_to_wb(inode) == isw->new_wb)
-- goto out_unlock;
--
-- if (!atomic_inc_not_zero(&inode->i_sb->s_active))
-- goto out_unlock;
--
-+ if (!(inode->i_sb->s_flags & MS_ACTIVE) ||
-+ inode->i_state & (I_WB_SWITCH | I_FREEING) ||
-+ inode_to_wb(inode) == isw->new_wb) {
-+ spin_unlock(&inode->i_lock);
-+ goto out_free;
-+ }
- inode->i_state |= I_WB_SWITCH;
- spin_unlock(&inode->i_lock);
-
- ihold(inode);
- isw->inode = inode;
-
-+ atomic_inc(&isw_nr_in_flight);
-+
- /*
- * In addition to synchronizing among switchers, I_WB_SWITCH tells
- * the RCU protected stat update paths to grab the mapping's
-@@ -494,8 +497,6 @@ static void inode_switch_wbs(struct inode *inode, int new_wb_id)
- call_rcu(&isw->rcu_head, inode_switch_wbs_rcu_fn);
- return;
-
--out_unlock:
-- spin_unlock(&inode->i_lock);
- out_free:
- if (isw->new_wb)
- wb_put(isw->new_wb);
-@@ -849,6 +850,33 @@ restart:
- wb_put(last_wb);
- }
-
-+/**
-+ * cgroup_writeback_umount - flush inode wb switches for umount
-+ *
-+ * This function is called when a super_block is about to be destroyed and
-+ * flushes in-flight inode wb switches. An inode wb switch goes through
-+ * RCU and then workqueue, so the two need to be flushed in order to ensure
-+ * that all previously scheduled switches are finished. As wb switches are
-+ * rare occurrences and synchronize_rcu() can take a while, perform
-+ * flushing iff wb switches are in flight.
-+ */
-+void cgroup_writeback_umount(void)
-+{
-+ if (atomic_read(&isw_nr_in_flight)) {
-+ synchronize_rcu();
-+ flush_workqueue(isw_wq);
-+ }
-+}
-+
-+static int __init cgroup_writeback_init(void)
-+{
-+ isw_wq = alloc_workqueue("inode_switch_wbs", 0, 0);
-+ if (!isw_wq)
-+ return -ENOMEM;
-+ return 0;
-+}
-+fs_initcall(cgroup_writeback_init);
-+
- #else /* CONFIG_CGROUP_WRITEBACK */
-
- static struct bdi_writeback *
-diff --git a/fs/jffs2/README.Locking b/fs/jffs2/README.Locking
-index 3ea3655..8918ac9 100644
---- a/fs/jffs2/README.Locking
-+++ b/fs/jffs2/README.Locking
-@@ -2,10 +2,6 @@
- JFFS2 LOCKING DOCUMENTATION
- ---------------------------
-
--At least theoretically, JFFS2 does not require the Big Kernel Lock
--(BKL), which was always helpfully obtained for it by Linux 2.4 VFS
--code. It has its own locking, as described below.
--
- This document attempts to describe the existing locking rules for
- JFFS2. It is not expected to remain perfectly up to date, but ought to
- be fairly close.
-@@ -69,6 +65,7 @@ Ordering constraints:
- any f->sem held.
- 2. Never attempt to lock two file mutexes in one thread.
- No ordering rules have been made for doing so.
-+ 3. Never lock a page cache page with f->sem held.
-
-
- erase_completion_lock spinlock
-diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c
-index a3750f9..c1f0494 100644
---- a/fs/jffs2/build.c
-+++ b/fs/jffs2/build.c
-@@ -49,7 +49,8 @@ next_inode(int *i, struct jffs2_inode_cache *ic, struct jffs2_sb_info *c)
-
-
- static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
-- struct jffs2_inode_cache *ic)
-+ struct jffs2_inode_cache *ic,
-+ int *dir_hardlinks)
- {
- struct jffs2_full_dirent *fd;
-
-@@ -68,19 +69,21 @@ static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
- dbg_fsbuild("child \"%s\" (ino #%u) of dir ino #%u doesn't exist!\n",
- fd->name, fd->ino, ic->ino);
- jffs2_mark_node_obsolete(c, fd->raw);
-+ /* Clear the ic/raw union so it doesn't cause problems later. */
-+ fd->ic = NULL;
- continue;
- }
-
-+ /* From this point, fd->raw is no longer used so we can set fd->ic */
-+ fd->ic = child_ic;
-+ child_ic->pino_nlink++;
-+ /* If we appear (at this stage) to have hard-linked directories,
-+ * set a flag to trigger a scan later */
- if (fd->type == DT_DIR) {
-- if (child_ic->pino_nlink) {
-- JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u appears to be a hard link\n",
-- fd->name, fd->ino, ic->ino);
-- /* TODO: What do we do about it? */
-- } else {
-- child_ic->pino_nlink = ic->ino;
-- }
-- } else
-- child_ic->pino_nlink++;
-+ child_ic->flags |= INO_FLAGS_IS_DIR;
-+ if (child_ic->pino_nlink > 1)
-+ *dir_hardlinks = 1;
-+ }
-
- dbg_fsbuild("increased nlink for child \"%s\" (ino #%u)\n", fd->name, fd->ino);
- /* Can't free scan_dents so far. We might need them in pass 2 */
-@@ -94,8 +97,7 @@ static void jffs2_build_inode_pass1(struct jffs2_sb_info *c,
- */
- static int jffs2_build_filesystem(struct jffs2_sb_info *c)
- {
-- int ret;
-- int i;
-+ int ret, i, dir_hardlinks = 0;
- struct jffs2_inode_cache *ic;
- struct jffs2_full_dirent *fd;
- struct jffs2_full_dirent *dead_fds = NULL;
-@@ -119,7 +121,7 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
- /* Now scan the directory tree, increasing nlink according to every dirent found. */
- for_each_inode(i, c, ic) {
- if (ic->scan_dents) {
-- jffs2_build_inode_pass1(c, ic);
-+ jffs2_build_inode_pass1(c, ic, &dir_hardlinks);
- cond_resched();
- }
- }
-@@ -155,6 +157,20 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
- }
-
- dbg_fsbuild("pass 2a complete\n");
-+
-+ if (dir_hardlinks) {
-+ /* If we detected directory hardlinks earlier, *hopefully*
-+ * they are gone now because some of the links were from
-+ * dead directories which still had some old dirents lying
-+ * around and not yet garbage-collected, but which have
-+ * been discarded above. So clear the pino_nlink field
-+ * in each directory, so that the final scan below can
-+ * print appropriate warnings. */
-+ for_each_inode(i, c, ic) {
-+ if (ic->flags & INO_FLAGS_IS_DIR)
-+ ic->pino_nlink = 0;
-+ }
-+ }
- dbg_fsbuild("freeing temporary data structures\n");
-
- /* Finally, we can scan again and free the dirent structs */
-@@ -162,6 +178,33 @@ static int jffs2_build_filesystem(struct jffs2_sb_info *c)
- while(ic->scan_dents) {
- fd = ic->scan_dents;
- ic->scan_dents = fd->next;
-+ /* We do use the pino_nlink field to count nlink of
-+ * directories during fs build, so set it to the
-+ * parent ino# now. Now that there's hopefully only
-+ * one. */
-+ if (fd->type == DT_DIR) {
-+ if (!fd->ic) {
-+ /* We'll have complained about it and marked the coresponding
-+ raw node obsolete already. Just skip it. */
-+ continue;
-+ }
-+
-+ /* We *have* to have set this in jffs2_build_inode_pass1() */
-+ BUG_ON(!(fd->ic->flags & INO_FLAGS_IS_DIR));
-+
-+ /* We clear ic->pino_nlink ∀ directories' ic *only* if dir_hardlinks
-+ * is set. Otherwise, we know this should never trigger anyway, so
-+ * we don't do the check. And ic->pino_nlink still contains the nlink
-+ * value (which is 1). */
-+ if (dir_hardlinks && fd->ic->pino_nlink) {
-+ JFFS2_ERROR("child dir \"%s\" (ino #%u) of dir ino #%u is also hard linked from dir ino #%u\n",
-+ fd->name, fd->ino, ic->ino, fd->ic->pino_nlink);
-+ /* Should we unlink it from its previous parent? */
-+ }
-+
-+ /* For directories, ic->pino_nlink holds that parent inode # */
-+ fd->ic->pino_nlink = ic->ino;
-+ }
- jffs2_free_full_dirent(fd);
- }
- ic->scan_dents = NULL;
-@@ -240,11 +283,7 @@ static void jffs2_build_remove_unlinked_inode(struct jffs2_sb_info *c,
-
- /* Reduce nlink of the child. If it's now zero, stick it on the
- dead_fds list to be cleaned up later. Else just free the fd */
--
-- if (fd->type == DT_DIR)
-- child_ic->pino_nlink = 0;
-- else
-- child_ic->pino_nlink--;
-+ child_ic->pino_nlink--;
-
- if (!child_ic->pino_nlink) {
- dbg_fsbuild("inode #%u (\"%s\") now has no links; adding to dead_fds list.\n",
-diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
-index f509f62..3361979 100644
---- a/fs/jffs2/file.c
-+++ b/fs/jffs2/file.c
-@@ -137,39 +137,33 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
- struct page *pg;
- struct inode *inode = mapping->host;
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
-- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-- struct jffs2_raw_inode ri;
-- uint32_t alloc_len = 0;
- pgoff_t index = pos >> PAGE_CACHE_SHIFT;
- uint32_t pageofs = index << PAGE_CACHE_SHIFT;
- int ret = 0;
-
-- jffs2_dbg(1, "%s()\n", __func__);
--
-- if (pageofs > inode->i_size) {
-- ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-- ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-- if (ret)
-- return ret;
-- }
--
-- mutex_lock(&f->sem);
- pg = grab_cache_page_write_begin(mapping, index, flags);
-- if (!pg) {
-- if (alloc_len)
-- jffs2_complete_reservation(c);
-- mutex_unlock(&f->sem);
-+ if (!pg)
- return -ENOMEM;
-- }
- *pagep = pg;
-
-- if (alloc_len) {
-+ jffs2_dbg(1, "%s()\n", __func__);
-+
-+ if (pageofs > inode->i_size) {
- /* Make new hole frag from old EOF to new page */
-+ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
-+ struct jffs2_raw_inode ri;
- struct jffs2_full_dnode *fn;
-+ uint32_t alloc_len;
-
- jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
- (unsigned int)inode->i_size, pageofs);
-
-+ ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
-+ ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
-+ if (ret)
-+ goto out_page;
-+
-+ mutex_lock(&f->sem);
- memset(&ri, 0, sizeof(ri));
-
- ri.magic = cpu_to_je16(JFFS2_MAGIC_BITMASK);
-@@ -196,6 +190,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
- if (IS_ERR(fn)) {
- ret = PTR_ERR(fn);
- jffs2_complete_reservation(c);
-+ mutex_unlock(&f->sem);
- goto out_page;
- }
- ret = jffs2_add_full_dnode_to_inode(c, f, fn);
-@@ -210,10 +205,12 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
- jffs2_mark_node_obsolete(c, fn->raw);
- jffs2_free_full_dnode(fn);
- jffs2_complete_reservation(c);
-+ mutex_unlock(&f->sem);
- goto out_page;
- }
- jffs2_complete_reservation(c);
- inode->i_size = pageofs;
-+ mutex_unlock(&f->sem);
- }
-
- /*
-@@ -222,18 +219,18 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
- * case of a short-copy.
- */
- if (!PageUptodate(pg)) {
-+ mutex_lock(&f->sem);
- ret = jffs2_do_readpage_nolock(inode, pg);
-+ mutex_unlock(&f->sem);
- if (ret)
- goto out_page;
- }
-- mutex_unlock(&f->sem);
- jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags);
- return ret;
-
- out_page:
- unlock_page(pg);
- page_cache_release(pg);
-- mutex_unlock(&f->sem);
- return ret;
- }
-
-diff --git a/fs/jffs2/gc.c b/fs/jffs2/gc.c
-index 5a2dec2..95d5880 100644
---- a/fs/jffs2/gc.c
-+++ b/fs/jffs2/gc.c
-@@ -1296,14 +1296,17 @@ static int jffs2_garbage_collect_dnode(struct jffs2_sb_info *c, struct jffs2_era
- BUG_ON(start > orig_start);
- }
-
-- /* First, use readpage() to read the appropriate page into the page cache */
-- /* Q: What happens if we actually try to GC the _same_ page for which commit_write()
-- * triggered garbage collection in the first place?
-- * A: I _think_ it's OK. read_cache_page shouldn't deadlock, we'll write out the
-- * page OK. We'll actually write it out again in commit_write, which is a little
-- * suboptimal, but at least we're correct.
-- */
-+ /* The rules state that we must obtain the page lock *before* f->sem, so
-+ * drop f->sem temporarily. Since we also hold c->alloc_sem, nothing's
-+ * actually going to *change* so we're safe; we only allow reading.
-+ *
-+ * It is important to note that jffs2_write_begin() will ensure that its
-+ * page is marked Uptodate before allocating space. That means that if we
-+ * end up here trying to GC the *same* page that jffs2_write_begin() is
-+ * trying to write out, read_cache_page() will not deadlock. */
-+ mutex_unlock(&f->sem);
- pg_ptr = jffs2_gc_fetch_page(c, f, start, &pg);
-+ mutex_lock(&f->sem);
-
- if (IS_ERR(pg_ptr)) {
- pr_warn("read_cache_page() returned error: %ld\n",
-diff --git a/fs/jffs2/nodelist.h b/fs/jffs2/nodelist.h
-index fa35ff7..0637271 100644
---- a/fs/jffs2/nodelist.h
-+++ b/fs/jffs2/nodelist.h
-@@ -194,6 +194,7 @@ struct jffs2_inode_cache {
- #define INO_STATE_CLEARING 6 /* In clear_inode() */
-
- #define INO_FLAGS_XATTR_CHECKED 0x01 /* has no duplicate xattr_ref */
-+#define INO_FLAGS_IS_DIR 0x02 /* is a directory */
-
- #define RAWNODE_CLASS_INODE_CACHE 0
- #define RAWNODE_CLASS_XATTR_DATUM 1
-@@ -249,7 +250,10 @@ struct jffs2_readinode_info
-
- struct jffs2_full_dirent
- {
-- struct jffs2_raw_node_ref *raw;
-+ union {
-+ struct jffs2_raw_node_ref *raw;
-+ struct jffs2_inode_cache *ic; /* Just during part of build */
-+ };
- struct jffs2_full_dirent *next;
- uint32_t version;
- uint32_t ino; /* == zero for unlink */
-diff --git a/fs/super.c b/fs/super.c
-index 954aeb8..f5f4b32 100644
---- a/fs/super.c
-+++ b/fs/super.c
-@@ -415,6 +415,7 @@ void generic_shutdown_super(struct super_block *sb)
- sb->s_flags &= ~MS_ACTIVE;
-
- fsnotify_unmount_inodes(sb);
-+ cgroup_writeback_umount();
-
- evict_inodes(sb);
-
-diff --git a/include/linux/ata.h b/include/linux/ata.h
-index d2992bf..c1a2f34 100644
---- a/include/linux/ata.h
-+++ b/include/linux/ata.h
-@@ -487,8 +487,8 @@ enum ata_tf_protocols {
- };
-
- enum ata_ioctls {
-- ATA_IOC_GET_IO32 = 0x309,
-- ATA_IOC_SET_IO32 = 0x324,
-+ ATA_IOC_GET_IO32 = 0x309, /* HDIO_GET_32BIT */
-+ ATA_IOC_SET_IO32 = 0x324, /* HDIO_SET_32BIT */
- };
-
- /* core structures */
-diff --git a/include/linux/bio.h b/include/linux/bio.h
-index b9b6e04..79cfaee 100644
---- a/include/linux/bio.h
-+++ b/include/linux/bio.h
-@@ -310,6 +310,43 @@ static inline void bio_clear_flag(struct bio *bio, unsigned int bit)
- bio->bi_flags &= ~(1U << bit);
- }
-
-+static inline void bio_get_first_bvec(struct bio *bio, struct bio_vec *bv)
-+{
-+ *bv = bio_iovec(bio);
-+}
-+
-+static inline void bio_get_last_bvec(struct bio *bio, struct bio_vec *bv)
-+{
-+ struct bvec_iter iter = bio->bi_iter;
-+ int idx;
-+
-+ if (!bio_flagged(bio, BIO_CLONED)) {
-+ *bv = bio->bi_io_vec[bio->bi_vcnt - 1];
-+ return;
-+ }
-+
-+ if (unlikely(!bio_multiple_segments(bio))) {
-+ *bv = bio_iovec(bio);
-+ return;
-+ }
-+
-+ bio_advance_iter(bio, &iter, iter.bi_size);
-+
-+ if (!iter.bi_bvec_done)
-+ idx = iter.bi_idx - 1;
-+ else /* in the middle of bvec */
-+ idx = iter.bi_idx;
-+
-+ *bv = bio->bi_io_vec[idx];
-+
-+ /*
-+ * iter.bi_bvec_done records actual length of the last bvec
-+ * if this bio ends in the middle of one io vector
-+ */
-+ if (iter.bi_bvec_done)
-+ bv->bv_len = iter.bi_bvec_done;
-+}
-+
- enum bip_flags {
- BIP_BLOCK_INTEGRITY = 1 << 0, /* block layer owns integrity data */
- BIP_MAPPED_INTEGRITY = 1 << 1, /* ref tag has been remapped */
-diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
-index c70e358..1687557 100644
---- a/include/linux/blkdev.h
-+++ b/include/linux/blkdev.h
-@@ -1367,6 +1367,13 @@ static inline void put_dev_sector(Sector p)
- page_cache_release(p.v);
- }
-
-+static inline bool __bvec_gap_to_prev(struct request_queue *q,
-+ struct bio_vec *bprv, unsigned int offset)
-+{
-+ return offset ||
-+ ((bprv->bv_offset + bprv->bv_len) & queue_virt_boundary(q));
-+}
-+
- /*
- * Check if adding a bio_vec after bprv with offset would create a gap in
- * the SG list. Most drivers don't care about this, but some do.
-@@ -1376,18 +1383,22 @@ static inline bool bvec_gap_to_prev(struct request_queue *q,
- {
- if (!queue_virt_boundary(q))
- return false;
-- return offset ||
-- ((bprv->bv_offset + bprv->bv_len) & queue_virt_boundary(q));
-+ return __bvec_gap_to_prev(q, bprv, offset);
- }
-
- static inline bool bio_will_gap(struct request_queue *q, struct bio *prev,
- struct bio *next)
- {
-- if (!bio_has_data(prev))
-- return false;
-+ if (bio_has_data(prev) && queue_virt_boundary(q)) {
-+ struct bio_vec pb, nb;
-+
-+ bio_get_last_bvec(prev, &pb);
-+ bio_get_first_bvec(next, &nb);
-
-- return bvec_gap_to_prev(q, &prev->bi_io_vec[prev->bi_vcnt - 1],
-- next->bi_io_vec[0].bv_offset);
-+ return __bvec_gap_to_prev(q, &pb, nb.bv_offset);
-+ }
-+
-+ return false;
- }
-
- static inline bool req_gap_back_merge(struct request *req, struct bio *bio)
-diff --git a/include/linux/dcache.h b/include/linux/dcache.h
-index d67ae11..8a2e009 100644
---- a/include/linux/dcache.h
-+++ b/include/linux/dcache.h
-@@ -409,9 +409,7 @@ static inline bool d_mountpoint(const struct dentry *dentry)
- */
- static inline unsigned __d_entry_type(const struct dentry *dentry)
- {
-- unsigned type = READ_ONCE(dentry->d_flags);
-- smp_rmb();
-- return type & DCACHE_ENTRY_TYPE;
-+ return dentry->d_flags & DCACHE_ENTRY_TYPE;
- }
-
- static inline bool d_is_miss(const struct dentry *dentry)
-diff --git a/include/linux/libata.h b/include/linux/libata.h
-index 600c1e0..b20a275 100644
---- a/include/linux/libata.h
-+++ b/include/linux/libata.h
-@@ -718,7 +718,7 @@ struct ata_device {
- union {
- u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
- u32 gscr[SATA_PMP_GSCR_DWORDS]; /* PMP GSCR block */
-- };
-+ } ____cacheline_aligned;
-
- /* DEVSLP Timing Variables from Identify Device Data Log */
- u8 devslp_timing[ATA_LOG_DEVSLP_SIZE];
-diff --git a/include/linux/module.h b/include/linux/module.h
-index 3a19c79..b229a99 100644
---- a/include/linux/module.h
-+++ b/include/linux/module.h
-@@ -302,6 +302,12 @@ struct mod_tree_node {
- struct latch_tree_node node;
- };
-
-+struct mod_kallsyms {
-+ Elf_Sym *symtab;
-+ unsigned int num_symtab;
-+ char *strtab;
-+};
-+
- struct module {
- enum module_state state;
-
-@@ -411,14 +417,9 @@ struct module {
- #endif
-
- #ifdef CONFIG_KALLSYMS
-- /*
-- * We keep the symbol and string tables for kallsyms.
-- * The core_* fields below are temporary, loader-only (they
-- * could really be discarded after module init).
-- */
-- Elf_Sym *symtab, *core_symtab;
-- unsigned int num_symtab, core_num_syms;
-- char *strtab, *core_strtab;
-+ /* Protected by RCU and/or module_mutex: use rcu_dereference() */
-+ struct mod_kallsyms *kallsyms;
-+ struct mod_kallsyms core_kallsyms;
-
- /* Section attributes */
- struct module_sect_attrs *sect_attrs;
-diff --git a/include/linux/trace_events.h b/include/linux/trace_events.h
-index 429fdfc..925730b 100644
---- a/include/linux/trace_events.h
-+++ b/include/linux/trace_events.h
-@@ -568,6 +568,8 @@ enum {
- FILTER_DYN_STRING,
- FILTER_PTR_STRING,
- FILTER_TRACE_FN,
-+ FILTER_COMM,
-+ FILTER_CPU,
- };
-
- extern int trace_event_raw_init(struct trace_event_call *call);
-diff --git a/include/linux/writeback.h b/include/linux/writeback.h
-index b333c94..d0b5ca5 100644
---- a/include/linux/writeback.h
-+++ b/include/linux/writeback.h
-@@ -198,6 +198,7 @@ void wbc_attach_and_unlock_inode(struct writeback_control *wbc,
- void wbc_detach_inode(struct writeback_control *wbc);
- void wbc_account_io(struct writeback_control *wbc, struct page *page,
- size_t bytes);
-+void cgroup_writeback_umount(void);
-
- /**
- * inode_attach_wb - associate an inode with its wb
-@@ -301,6 +302,10 @@ static inline void wbc_account_io(struct writeback_control *wbc,
- {
- }
-
-+static inline void cgroup_writeback_umount(void)
-+{
-+}
-+
- #endif /* CONFIG_CGROUP_WRITEBACK */
-
- /*
-diff --git a/include/target/target_core_backend.h b/include/target/target_core_backend.h
-index 56cf8e4..28ee5c2 100644
---- a/include/target/target_core_backend.h
-+++ b/include/target/target_core_backend.h
-@@ -94,5 +94,8 @@ sense_reason_t passthrough_parse_cdb(struct se_cmd *cmd,
- sense_reason_t (*exec_cmd)(struct se_cmd *cmd));
-
- bool target_sense_desc_format(struct se_device *dev);
-+sector_t target_to_linux_sector(struct se_device *dev, sector_t lb);
-+bool target_configure_unmap_from_queue(struct se_dev_attrib *attrib,
-+ struct request_queue *q, int block_size);
-
- #endif /* TARGET_CORE_BACKEND_H */
-diff --git a/kernel/module.c b/kernel/module.c
-index 14833e6..0e5c711 100644
---- a/kernel/module.c
-+++ b/kernel/module.c
-@@ -327,6 +327,9 @@ struct load_info {
- struct _ddebug *debug;
- unsigned int num_debug;
- bool sig_ok;
-+#ifdef CONFIG_KALLSYMS
-+ unsigned long mod_kallsyms_init_off;
-+#endif
- struct {
- unsigned int sym, str, mod, vers, info, pcpu;
- } index;
-@@ -2492,10 +2495,21 @@ static void layout_symtab(struct module *mod, struct load_info *info)
- strsect->sh_flags |= SHF_ALLOC;
- strsect->sh_entsize = get_offset(mod, &mod->init_size, strsect,
- info->index.str) | INIT_OFFSET_MASK;
-- mod->init_size = debug_align(mod->init_size);
- pr_debug("\t%s\n", info->secstrings + strsect->sh_name);
-+
-+ /* We'll tack temporary mod_kallsyms on the end. */
-+ mod->init_size = ALIGN(mod->init_size,
-+ __alignof__(struct mod_kallsyms));
-+ info->mod_kallsyms_init_off = mod->init_size;
-+ mod->init_size += sizeof(struct mod_kallsyms);
-+ mod->init_size = debug_align(mod->init_size);
- }
-
-+/*
-+ * We use the full symtab and strtab which layout_symtab arranged to
-+ * be appended to the init section. Later we switch to the cut-down
-+ * core-only ones.
-+ */
- static void add_kallsyms(struct module *mod, const struct load_info *info)
- {
- unsigned int i, ndst;
-@@ -2504,28 +2518,33 @@ static void add_kallsyms(struct module *mod, const struct load_info *info)
- char *s;
- Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
-
-- mod->symtab = (void *)symsec->sh_addr;
-- mod->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
-+ /* Set up to point into init section. */
-+ mod->kallsyms = mod->module_init + info->mod_kallsyms_init_off;
-+
-+ mod->kallsyms->symtab = (void *)symsec->sh_addr;
-+ mod->kallsyms->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
- /* Make sure we get permanent strtab: don't use info->strtab. */
-- mod->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
-+ mod->kallsyms->strtab = (void *)info->sechdrs[info->index.str].sh_addr;
-
- /* Set types up while we still have access to sections. */
-- for (i = 0; i < mod->num_symtab; i++)
-- mod->symtab[i].st_info = elf_type(&mod->symtab[i], info);
--
-- mod->core_symtab = dst = mod->module_core + info->symoffs;
-- mod->core_strtab = s = mod->module_core + info->stroffs;
-- src = mod->symtab;
-- for (ndst = i = 0; i < mod->num_symtab; i++) {
-+ for (i = 0; i < mod->kallsyms->num_symtab; i++)
-+ mod->kallsyms->symtab[i].st_info
-+ = elf_type(&mod->kallsyms->symtab[i], info);
-+
-+ /* Now populate the cut down core kallsyms for after init. */
-+ mod->core_kallsyms.symtab = dst = mod->module_core + info->symoffs;
-+ mod->core_kallsyms.strtab = s = mod->module_core + info->stroffs;
-+ src = mod->kallsyms->symtab;
-+ for (ndst = i = 0; i < mod->kallsyms->num_symtab; i++) {
- if (i == 0 ||
- is_core_symbol(src+i, info->sechdrs, info->hdr->e_shnum)) {
- dst[ndst] = src[i];
-- dst[ndst++].st_name = s - mod->core_strtab;
-- s += strlcpy(s, &mod->strtab[src[i].st_name],
-+ dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
-+ s += strlcpy(s, &mod->kallsyms->strtab[src[i].st_name],
- KSYM_NAME_LEN) + 1;
- }
- }
-- mod->core_num_syms = ndst;
-+ mod->core_kallsyms.num_symtab = ndst;
- }
- #else
- static inline void layout_symtab(struct module *mod, struct load_info *info)
-@@ -3274,9 +3293,8 @@ static noinline int do_init_module(struct module *mod)
- module_put(mod);
- trim_init_extable(mod);
- #ifdef CONFIG_KALLSYMS
-- mod->num_symtab = mod->core_num_syms;
-- mod->symtab = mod->core_symtab;
-- mod->strtab = mod->core_strtab;
-+ /* Switch to core kallsyms now init is done: kallsyms may be walking! */
-+ rcu_assign_pointer(mod->kallsyms, &mod->core_kallsyms);
- #endif
- mod_tree_remove_init(mod);
- unset_module_init_ro_nx(mod);
-@@ -3646,9 +3664,9 @@ static inline int is_arm_mapping_symbol(const char *str)
- && (str[2] == '\0' || str[2] == '.');
- }
-
--static const char *symname(struct module *mod, unsigned int symnum)
-+static const char *symname(struct mod_kallsyms *kallsyms, unsigned int symnum)
- {
-- return mod->strtab + mod->symtab[symnum].st_name;
-+ return kallsyms->strtab + kallsyms->symtab[symnum].st_name;
- }
-
- static const char *get_ksymbol(struct module *mod,
-@@ -3658,6 +3676,7 @@ static const char *get_ksymbol(struct module *mod,
- {
- unsigned int i, best = 0;
- unsigned long nextval;
-+ struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
-
- /* At worse, next value is at end of module */
- if (within_module_init(addr, mod))
-@@ -3667,32 +3686,32 @@ static const char *get_ksymbol(struct module *mod,
-
- /* Scan for closest preceding symbol, and next symbol. (ELF
- starts real symbols at 1). */
-- for (i = 1; i < mod->num_symtab; i++) {
-- if (mod->symtab[i].st_shndx == SHN_UNDEF)
-+ for (i = 1; i < kallsyms->num_symtab; i++) {
-+ if (kallsyms->symtab[i].st_shndx == SHN_UNDEF)
- continue;
-
- /* We ignore unnamed symbols: they're uninformative
- * and inserted at a whim. */
-- if (*symname(mod, i) == '\0'
-- || is_arm_mapping_symbol(symname(mod, i)))
-+ if (*symname(kallsyms, i) == '\0'
-+ || is_arm_mapping_symbol(symname(kallsyms, i)))
- continue;
-
-- if (mod->symtab[i].st_value <= addr
-- && mod->symtab[i].st_value > mod->symtab[best].st_value)
-+ if (kallsyms->symtab[i].st_value <= addr
-+ && kallsyms->symtab[i].st_value > kallsyms->symtab[best].st_value)
- best = i;
-- if (mod->symtab[i].st_value > addr
-- && mod->symtab[i].st_value < nextval)
-- nextval = mod->symtab[i].st_value;
-+ if (kallsyms->symtab[i].st_value > addr
-+ && kallsyms->symtab[i].st_value < nextval)
-+ nextval = kallsyms->symtab[i].st_value;
- }
-
- if (!best)
- return NULL;
-
- if (size)
-- *size = nextval - mod->symtab[best].st_value;
-+ *size = nextval - kallsyms->symtab[best].st_value;
- if (offset)
-- *offset = addr - mod->symtab[best].st_value;
-- return symname(mod, best);
-+ *offset = addr - kallsyms->symtab[best].st_value;
-+ return symname(kallsyms, best);
- }
-
- /* For kallsyms to ask for address resolution. NULL means not found. Careful
-@@ -3782,18 +3801,21 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
-
- preempt_disable();
- list_for_each_entry_rcu(mod, &modules, list) {
-+ struct mod_kallsyms *kallsyms;
-+
- if (mod->state == MODULE_STATE_UNFORMED)
- continue;
-- if (symnum < mod->num_symtab) {
-- *value = mod->symtab[symnum].st_value;
-- *type = mod->symtab[symnum].st_info;
-- strlcpy(name, symname(mod, symnum), KSYM_NAME_LEN);
-+ kallsyms = rcu_dereference_sched(mod->kallsyms);
-+ if (symnum < kallsyms->num_symtab) {
-+ *value = kallsyms->symtab[symnum].st_value;
-+ *type = kallsyms->symtab[symnum].st_info;
-+ strlcpy(name, symname(kallsyms, symnum), KSYM_NAME_LEN);
- strlcpy(module_name, mod->name, MODULE_NAME_LEN);
- *exported = is_exported(name, *value, mod);
- preempt_enable();
- return 0;
- }
-- symnum -= mod->num_symtab;
-+ symnum -= kallsyms->num_symtab;
- }
- preempt_enable();
- return -ERANGE;
-@@ -3802,11 +3824,12 @@ int module_get_kallsym(unsigned int symnum, unsigned long *value, char *type,
- static unsigned long mod_find_symname(struct module *mod, const char *name)
- {
- unsigned int i;
-+ struct mod_kallsyms *kallsyms = rcu_dereference_sched(mod->kallsyms);
-
-- for (i = 0; i < mod->num_symtab; i++)
-- if (strcmp(name, symname(mod, i)) == 0 &&
-- mod->symtab[i].st_info != 'U')
-- return mod->symtab[i].st_value;
-+ for (i = 0; i < kallsyms->num_symtab; i++)
-+ if (strcmp(name, symname(kallsyms, i)) == 0 &&
-+ kallsyms->symtab[i].st_info != 'U')
-+ return kallsyms->symtab[i].st_value;
- return 0;
- }
-
-@@ -3845,11 +3868,14 @@ int module_kallsyms_on_each_symbol(int (*fn)(void *, const char *,
- module_assert_mutex();
-
- list_for_each_entry(mod, &modules, list) {
-+ /* We hold module_mutex: no need for rcu_dereference_sched */
-+ struct mod_kallsyms *kallsyms = mod->kallsyms;
-+
- if (mod->state == MODULE_STATE_UNFORMED)
- continue;
-- for (i = 0; i < mod->num_symtab; i++) {
-- ret = fn(data, symname(mod, i),
-- mod, mod->symtab[i].st_value);
-+ for (i = 0; i < kallsyms->num_symtab; i++) {
-+ ret = fn(data, symname(kallsyms, i),
-+ mod, kallsyms->symtab[i].st_value);
- if (ret != 0)
- return ret;
- }
-diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
-index debf6e8..d202d99 100644
---- a/kernel/trace/trace_events.c
-+++ b/kernel/trace/trace_events.c
-@@ -97,16 +97,16 @@ trace_find_event_field(struct trace_event_call *call, char *name)
- struct ftrace_event_field *field;
- struct list_head *head;
-
-- field = __find_event_field(&ftrace_generic_fields, name);
-+ head = trace_get_fields(call);
-+ field = __find_event_field(head, name);
- if (field)
- return field;
-
-- field = __find_event_field(&ftrace_common_fields, name);
-+ field = __find_event_field(&ftrace_generic_fields, name);
- if (field)
- return field;
-
-- head = trace_get_fields(call);
-- return __find_event_field(head, name);
-+ return __find_event_field(&ftrace_common_fields, name);
- }
-
- static int __trace_define_field(struct list_head *head, const char *type,
-@@ -171,8 +171,10 @@ static int trace_define_generic_fields(void)
- {
- int ret;
-
-- __generic_field(int, cpu, FILTER_OTHER);
-- __generic_field(char *, comm, FILTER_PTR_STRING);
-+ __generic_field(int, CPU, FILTER_CPU);
-+ __generic_field(int, cpu, FILTER_CPU);
-+ __generic_field(char *, COMM, FILTER_COMM);
-+ __generic_field(char *, comm, FILTER_COMM);
-
- return ret;
- }
-diff --git a/kernel/trace/trace_events_filter.c b/kernel/trace/trace_events_filter.c
-index f93a219..6816302 100644
---- a/kernel/trace/trace_events_filter.c
-+++ b/kernel/trace/trace_events_filter.c
-@@ -1043,13 +1043,14 @@ static int init_pred(struct filter_parse_state *ps,
- return -EINVAL;
- }
-
-- if (is_string_field(field)) {
-+ if (field->filter_type == FILTER_COMM) {
-+ filter_build_regex(pred);
-+ fn = filter_pred_comm;
-+ pred->regex.field_len = TASK_COMM_LEN;
-+ } else if (is_string_field(field)) {
- filter_build_regex(pred);
-
-- if (!strcmp(field->name, "comm")) {
-- fn = filter_pred_comm;
-- pred->regex.field_len = TASK_COMM_LEN;
-- } else if (field->filter_type == FILTER_STATIC_STRING) {
-+ if (field->filter_type == FILTER_STATIC_STRING) {
- fn = filter_pred_string;
- pred->regex.field_len = field->size;
- } else if (field->filter_type == FILTER_DYN_STRING)
-@@ -1072,7 +1073,7 @@ static int init_pred(struct filter_parse_state *ps,
- }
- pred->val = val;
-
-- if (!strcmp(field->name, "cpu"))
-+ if (field->filter_type == FILTER_CPU)
- fn = filter_pred_cpu;
- else
- fn = select_comparison_fn(pred->op, field->size,
-diff --git a/sound/core/control_compat.c b/sound/core/control_compat.c
-index b9c0910..0608f21 100644
---- a/sound/core/control_compat.c
-+++ b/sound/core/control_compat.c
-@@ -170,6 +170,19 @@ struct snd_ctl_elem_value32 {
- unsigned char reserved[128];
- };
-
-+#ifdef CONFIG_X86_X32
-+/* x32 has a different alignment for 64bit values from ia32 */
-+struct snd_ctl_elem_value_x32 {
-+ struct snd_ctl_elem_id id;
-+ unsigned int indirect; /* bit-field causes misalignment */
-+ union {
-+ s32 integer[128];
-+ unsigned char data[512];
-+ s64 integer64[64];
-+ } value;
-+ unsigned char reserved[128];
-+};
-+#endif /* CONFIG_X86_X32 */
-
- /* get the value type and count of the control */
- static int get_ctl_type(struct snd_card *card, struct snd_ctl_elem_id *id,
-@@ -219,9 +232,11 @@ static int get_elem_size(int type, int count)
-
- static int copy_ctl_value_from_user(struct snd_card *card,
- struct snd_ctl_elem_value *data,
-- struct snd_ctl_elem_value32 __user *data32,
-+ void __user *userdata,
-+ void __user *valuep,
- int *typep, int *countp)
- {
-+ struct snd_ctl_elem_value32 __user *data32 = userdata;
- int i, type, size;
- int uninitialized_var(count);
- unsigned int indirect;
-@@ -239,8 +254,9 @@ static int copy_ctl_value_from_user(struct snd_card *card,
- if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
- type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
- for (i = 0; i < count; i++) {
-+ s32 __user *intp = valuep;
- int val;
-- if (get_user(val, &data32->value.integer[i]))
-+ if (get_user(val, &intp[i]))
- return -EFAULT;
- data->value.integer.value[i] = val;
- }
-@@ -250,8 +266,7 @@ static int copy_ctl_value_from_user(struct snd_card *card,
- dev_err(card->dev, "snd_ioctl32_ctl_elem_value: unknown type %d\n", type);
- return -EINVAL;
- }
-- if (copy_from_user(data->value.bytes.data,
-- data32->value.data, size))
-+ if (copy_from_user(data->value.bytes.data, valuep, size))
- return -EFAULT;
- }
-
-@@ -261,7 +276,8 @@ static int copy_ctl_value_from_user(struct snd_card *card,
- }
-
- /* restore the value to 32bit */
--static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
-+static int copy_ctl_value_to_user(void __user *userdata,
-+ void __user *valuep,
- struct snd_ctl_elem_value *data,
- int type, int count)
- {
-@@ -270,22 +286,22 @@ static int copy_ctl_value_to_user(struct snd_ctl_elem_value32 __user *data32,
- if (type == SNDRV_CTL_ELEM_TYPE_BOOLEAN ||
- type == SNDRV_CTL_ELEM_TYPE_INTEGER) {
- for (i = 0; i < count; i++) {
-+ s32 __user *intp = valuep;
- int val;
- val = data->value.integer.value[i];
-- if (put_user(val, &data32->value.integer[i]))
-+ if (put_user(val, &intp[i]))
- return -EFAULT;
- }
- } else {
- size = get_elem_size(type, count);
-- if (copy_to_user(data32->value.data,
-- data->value.bytes.data, size))
-+ if (copy_to_user(valuep, data->value.bytes.data, size))
- return -EFAULT;
- }
- return 0;
- }
-
--static int snd_ctl_elem_read_user_compat(struct snd_card *card,
-- struct snd_ctl_elem_value32 __user *data32)
-+static int ctl_elem_read_user(struct snd_card *card,
-+ void __user *userdata, void __user *valuep)
- {
- struct snd_ctl_elem_value *data;
- int err, type, count;
-@@ -294,7 +310,9 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
- if (data == NULL)
- return -ENOMEM;
-
-- if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
-+ err = copy_ctl_value_from_user(card, data, userdata, valuep,
-+ &type, &count);
-+ if (err < 0)
- goto error;
-
- snd_power_lock(card);
-@@ -303,14 +321,15 @@ static int snd_ctl_elem_read_user_compat(struct snd_card *card,
- err = snd_ctl_elem_read(card, data);
- snd_power_unlock(card);
- if (err >= 0)
-- err = copy_ctl_value_to_user(data32, data, type, count);
-+ err = copy_ctl_value_to_user(userdata, valuep, data,
-+ type, count);
- error:
- kfree(data);
- return err;
- }
-
--static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
-- struct snd_ctl_elem_value32 __user *data32)
-+static int ctl_elem_write_user(struct snd_ctl_file *file,
-+ void __user *userdata, void __user *valuep)
- {
- struct snd_ctl_elem_value *data;
- struct snd_card *card = file->card;
-@@ -320,7 +339,9 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
- if (data == NULL)
- return -ENOMEM;
-
-- if ((err = copy_ctl_value_from_user(card, data, data32, &type, &count)) < 0)
-+ err = copy_ctl_value_from_user(card, data, userdata, valuep,
-+ &type, &count);
-+ if (err < 0)
- goto error;
-
- snd_power_lock(card);
-@@ -329,12 +350,39 @@ static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
- err = snd_ctl_elem_write(card, file, data);
- snd_power_unlock(card);
- if (err >= 0)
-- err = copy_ctl_value_to_user(data32, data, type, count);
-+ err = copy_ctl_value_to_user(userdata, valuep, data,
-+ type, count);
- error:
- kfree(data);
- return err;
- }
-
-+static int snd_ctl_elem_read_user_compat(struct snd_card *card,
-+ struct snd_ctl_elem_value32 __user *data32)
-+{
-+ return ctl_elem_read_user(card, data32, &data32->value);
-+}
-+
-+static int snd_ctl_elem_write_user_compat(struct snd_ctl_file *file,
-+ struct snd_ctl_elem_value32 __user *data32)
-+{
-+ return ctl_elem_write_user(file, data32, &data32->value);
-+}
-+
-+#ifdef CONFIG_X86_X32
-+static int snd_ctl_elem_read_user_x32(struct snd_card *card,
-+ struct snd_ctl_elem_value_x32 __user *data32)
-+{
-+ return ctl_elem_read_user(card, data32, &data32->value);
-+}
-+
-+static int snd_ctl_elem_write_user_x32(struct snd_ctl_file *file,
-+ struct snd_ctl_elem_value_x32 __user *data32)
-+{
-+ return ctl_elem_write_user(file, data32, &data32->value);
-+}
-+#endif /* CONFIG_X86_X32 */
-+
- /* add or replace a user control */
- static int snd_ctl_elem_add_compat(struct snd_ctl_file *file,
- struct snd_ctl_elem_info32 __user *data32,
-@@ -393,6 +441,10 @@ enum {
- SNDRV_CTL_IOCTL_ELEM_WRITE32 = _IOWR('U', 0x13, struct snd_ctl_elem_value32),
- SNDRV_CTL_IOCTL_ELEM_ADD32 = _IOWR('U', 0x17, struct snd_ctl_elem_info32),
- SNDRV_CTL_IOCTL_ELEM_REPLACE32 = _IOWR('U', 0x18, struct snd_ctl_elem_info32),
-+#ifdef CONFIG_X86_X32
-+ SNDRV_CTL_IOCTL_ELEM_READ_X32 = _IOWR('U', 0x12, struct snd_ctl_elem_value_x32),
-+ SNDRV_CTL_IOCTL_ELEM_WRITE_X32 = _IOWR('U', 0x13, struct snd_ctl_elem_value_x32),
-+#endif /* CONFIG_X86_X32 */
- };
-
- static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
-@@ -431,6 +483,12 @@ static inline long snd_ctl_ioctl_compat(struct file *file, unsigned int cmd, uns
- return snd_ctl_elem_add_compat(ctl, argp, 0);
- case SNDRV_CTL_IOCTL_ELEM_REPLACE32:
- return snd_ctl_elem_add_compat(ctl, argp, 1);
-+#ifdef CONFIG_X86_X32
-+ case SNDRV_CTL_IOCTL_ELEM_READ_X32:
-+ return snd_ctl_elem_read_user_x32(ctl->card, argp);
-+ case SNDRV_CTL_IOCTL_ELEM_WRITE_X32:
-+ return snd_ctl_elem_write_user_x32(ctl, argp);
-+#endif /* CONFIG_X86_X32 */
- }
-
- down_read(&snd_ioctl_rwsem);
-diff --git a/sound/core/pcm_compat.c b/sound/core/pcm_compat.c
-index 9630e9f..1f64ab0 100644
---- a/sound/core/pcm_compat.c
-+++ b/sound/core/pcm_compat.c
-@@ -183,6 +183,14 @@ static int snd_pcm_ioctl_channel_info_compat(struct snd_pcm_substream *substream
- return err;
- }
-
-+#ifdef CONFIG_X86_X32
-+/* X32 ABI has the same struct as x86-64 for snd_pcm_channel_info */
-+static int snd_pcm_channel_info_user(struct snd_pcm_substream *substream,
-+ struct snd_pcm_channel_info __user *src);
-+#define snd_pcm_ioctl_channel_info_x32(s, p) \
-+ snd_pcm_channel_info_user(s, p)
-+#endif /* CONFIG_X86_X32 */
-+
- struct snd_pcm_status32 {
- s32 state;
- struct compat_timespec trigger_tstamp;
-@@ -243,6 +251,71 @@ static int snd_pcm_status_user_compat(struct snd_pcm_substream *substream,
- return err;
- }
-
-+#ifdef CONFIG_X86_X32
-+/* X32 ABI has 64bit timespec and 64bit alignment */
-+struct snd_pcm_status_x32 {
-+ s32 state;
-+ u32 rsvd; /* alignment */
-+ struct timespec trigger_tstamp;
-+ struct timespec tstamp;
-+ u32 appl_ptr;
-+ u32 hw_ptr;
-+ s32 delay;
-+ u32 avail;
-+ u32 avail_max;
-+ u32 overrange;
-+ s32 suspended_state;
-+ u32 audio_tstamp_data;
-+ struct timespec audio_tstamp;
-+ struct timespec driver_tstamp;
-+ u32 audio_tstamp_accuracy;
-+ unsigned char reserved[52-2*sizeof(struct timespec)];
-+} __packed;
-+
-+#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
-+
-+static int snd_pcm_status_user_x32(struct snd_pcm_substream *substream,
-+ struct snd_pcm_status_x32 __user *src,
-+ bool ext)
-+{
-+ struct snd_pcm_status status;
-+ int err;
-+
-+ memset(&status, 0, sizeof(status));
-+ /*
-+ * with extension, parameters are read/write,
-+ * get audio_tstamp_data from user,
-+ * ignore rest of status structure
-+ */
-+ if (ext && get_user(status.audio_tstamp_data,
-+ (u32 __user *)(&src->audio_tstamp_data)))
-+ return -EFAULT;
-+ err = snd_pcm_status(substream, &status);
-+ if (err < 0)
-+ return err;
-+
-+ if (clear_user(src, sizeof(*src)))
-+ return -EFAULT;
-+ if (put_user(status.state, &src->state) ||
-+ put_timespec(&status.trigger_tstamp, &src->trigger_tstamp) ||
-+ put_timespec(&status.tstamp, &src->tstamp) ||
-+ put_user(status.appl_ptr, &src->appl_ptr) ||
-+ put_user(status.hw_ptr, &src->hw_ptr) ||
-+ put_user(status.delay, &src->delay) ||
-+ put_user(status.avail, &src->avail) ||
-+ put_user(status.avail_max, &src->avail_max) ||
-+ put_user(status.overrange, &src->overrange) ||
-+ put_user(status.suspended_state, &src->suspended_state) ||
-+ put_user(status.audio_tstamp_data, &src->audio_tstamp_data) ||
-+ put_timespec(&status.audio_tstamp, &src->audio_tstamp) ||
-+ put_timespec(&status.driver_tstamp, &src->driver_tstamp) ||
-+ put_user(status.audio_tstamp_accuracy, &src->audio_tstamp_accuracy))
-+ return -EFAULT;
-+
-+ return err;
-+}
-+#endif /* CONFIG_X86_X32 */
-+
- /* both for HW_PARAMS and HW_REFINE */
- static int snd_pcm_ioctl_hw_params_compat(struct snd_pcm_substream *substream,
- int refine,
-@@ -469,6 +542,93 @@ static int snd_pcm_ioctl_sync_ptr_compat(struct snd_pcm_substream *substream,
- return 0;
- }
-
-+#ifdef CONFIG_X86_X32
-+/* X32 ABI has 64bit timespec and 64bit alignment */
-+struct snd_pcm_mmap_status_x32 {
-+ s32 state;
-+ s32 pad1;
-+ u32 hw_ptr;
-+ u32 pad2; /* alignment */
-+ struct timespec tstamp;
-+ s32 suspended_state;
-+ struct timespec audio_tstamp;
-+} __packed;
-+
-+struct snd_pcm_mmap_control_x32 {
-+ u32 appl_ptr;
-+ u32 avail_min;
-+};
-+
-+struct snd_pcm_sync_ptr_x32 {
-+ u32 flags;
-+ u32 rsvd; /* alignment */
-+ union {
-+ struct snd_pcm_mmap_status_x32 status;
-+ unsigned char reserved[64];
-+ } s;
-+ union {
-+ struct snd_pcm_mmap_control_x32 control;
-+ unsigned char reserved[64];
-+ } c;
-+} __packed;
-+
-+static int snd_pcm_ioctl_sync_ptr_x32(struct snd_pcm_substream *substream,
-+ struct snd_pcm_sync_ptr_x32 __user *src)
-+{
-+ struct snd_pcm_runtime *runtime = substream->runtime;
-+ volatile struct snd_pcm_mmap_status *status;
-+ volatile struct snd_pcm_mmap_control *control;
-+ u32 sflags;
-+ struct snd_pcm_mmap_control scontrol;
-+ struct snd_pcm_mmap_status sstatus;
-+ snd_pcm_uframes_t boundary;
-+ int err;
-+
-+ if (snd_BUG_ON(!runtime))
-+ return -EINVAL;
-+
-+ if (get_user(sflags, &src->flags) ||
-+ get_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
-+ get_user(scontrol.avail_min, &src->c.control.avail_min))
-+ return -EFAULT;
-+ if (sflags & SNDRV_PCM_SYNC_PTR_HWSYNC) {
-+ err = snd_pcm_hwsync(substream);
-+ if (err < 0)
-+ return err;
-+ }
-+ status = runtime->status;
-+ control = runtime->control;
-+ boundary = recalculate_boundary(runtime);
-+ if (!boundary)
-+ boundary = 0x7fffffff;
-+ snd_pcm_stream_lock_irq(substream);
-+ /* FIXME: we should consider the boundary for the sync from app */
-+ if (!(sflags & SNDRV_PCM_SYNC_PTR_APPL))
-+ control->appl_ptr = scontrol.appl_ptr;
-+ else
-+ scontrol.appl_ptr = control->appl_ptr % boundary;
-+ if (!(sflags & SNDRV_PCM_SYNC_PTR_AVAIL_MIN))
-+ control->avail_min = scontrol.avail_min;
-+ else
-+ scontrol.avail_min = control->avail_min;
-+ sstatus.state = status->state;
-+ sstatus.hw_ptr = status->hw_ptr % boundary;
-+ sstatus.tstamp = status->tstamp;
-+ sstatus.suspended_state = status->suspended_state;
-+ sstatus.audio_tstamp = status->audio_tstamp;
-+ snd_pcm_stream_unlock_irq(substream);
-+ if (put_user(sstatus.state, &src->s.status.state) ||
-+ put_user(sstatus.hw_ptr, &src->s.status.hw_ptr) ||
-+ put_timespec(&sstatus.tstamp, &src->s.status.tstamp) ||
-+ put_user(sstatus.suspended_state, &src->s.status.suspended_state) ||
-+ put_timespec(&sstatus.audio_tstamp, &src->s.status.audio_tstamp) ||
-+ put_user(scontrol.appl_ptr, &src->c.control.appl_ptr) ||
-+ put_user(scontrol.avail_min, &src->c.control.avail_min))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+#endif /* CONFIG_X86_X32 */
-
- /*
- */
-@@ -487,7 +647,12 @@ enum {
- SNDRV_PCM_IOCTL_WRITEN_FRAMES32 = _IOW('A', 0x52, struct snd_xfern32),
- SNDRV_PCM_IOCTL_READN_FRAMES32 = _IOR('A', 0x53, struct snd_xfern32),
- SNDRV_PCM_IOCTL_SYNC_PTR32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr32),
--
-+#ifdef CONFIG_X86_X32
-+ SNDRV_PCM_IOCTL_CHANNEL_INFO_X32 = _IOR('A', 0x32, struct snd_pcm_channel_info),
-+ SNDRV_PCM_IOCTL_STATUS_X32 = _IOR('A', 0x20, struct snd_pcm_status_x32),
-+ SNDRV_PCM_IOCTL_STATUS_EXT_X32 = _IOWR('A', 0x24, struct snd_pcm_status_x32),
-+ SNDRV_PCM_IOCTL_SYNC_PTR_X32 = _IOWR('A', 0x23, struct snd_pcm_sync_ptr_x32),
-+#endif /* CONFIG_X86_X32 */
- };
-
- static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
-@@ -559,6 +724,16 @@ static long snd_pcm_ioctl_compat(struct file *file, unsigned int cmd, unsigned l
- return snd_pcm_ioctl_rewind_compat(substream, argp);
- case SNDRV_PCM_IOCTL_FORWARD32:
- return snd_pcm_ioctl_forward_compat(substream, argp);
-+#ifdef CONFIG_X86_X32
-+ case SNDRV_PCM_IOCTL_STATUS_X32:
-+ return snd_pcm_status_user_x32(substream, argp, false);
-+ case SNDRV_PCM_IOCTL_STATUS_EXT_X32:
-+ return snd_pcm_status_user_x32(substream, argp, true);
-+ case SNDRV_PCM_IOCTL_SYNC_PTR_X32:
-+ return snd_pcm_ioctl_sync_ptr_x32(substream, argp);
-+ case SNDRV_PCM_IOCTL_CHANNEL_INFO_X32:
-+ return snd_pcm_ioctl_channel_info_x32(substream, argp);
-+#endif /* CONFIG_X86_X32 */
- }
-
- return -ENOIOCTLCMD;
-diff --git a/sound/core/rawmidi_compat.c b/sound/core/rawmidi_compat.c
-index 5268c1f..09a8909 100644
---- a/sound/core/rawmidi_compat.c
-+++ b/sound/core/rawmidi_compat.c
-@@ -94,9 +94,58 @@ static int snd_rawmidi_ioctl_status_compat(struct snd_rawmidi_file *rfile,
- return 0;
- }
-
-+#ifdef CONFIG_X86_X32
-+/* X32 ABI has 64bit timespec and 64bit alignment */
-+struct snd_rawmidi_status_x32 {
-+ s32 stream;
-+ u32 rsvd; /* alignment */
-+ struct timespec tstamp;
-+ u32 avail;
-+ u32 xruns;
-+ unsigned char reserved[16];
-+} __attribute__((packed));
-+
-+#define put_timespec(src, dst) copy_to_user(dst, src, sizeof(*dst))
-+
-+static int snd_rawmidi_ioctl_status_x32(struct snd_rawmidi_file *rfile,
-+ struct snd_rawmidi_status_x32 __user *src)
-+{
-+ int err;
-+ struct snd_rawmidi_status status;
-+
-+ if (rfile->output == NULL)
-+ return -EINVAL;
-+ if (get_user(status.stream, &src->stream))
-+ return -EFAULT;
-+
-+ switch (status.stream) {
-+ case SNDRV_RAWMIDI_STREAM_OUTPUT:
-+ err = snd_rawmidi_output_status(rfile->output, &status);
-+ break;
-+ case SNDRV_RAWMIDI_STREAM_INPUT:
-+ err = snd_rawmidi_input_status(rfile->input, &status);
-+ break;
-+ default:
-+ return -EINVAL;
-+ }
-+ if (err < 0)
-+ return err;
-+
-+ if (put_timespec(&status.tstamp, &src->tstamp) ||
-+ put_user(status.avail, &src->avail) ||
-+ put_user(status.xruns, &src->xruns))
-+ return -EFAULT;
-+
-+ return 0;
-+}
-+#endif /* CONFIG_X86_X32 */
-+
- enum {
- SNDRV_RAWMIDI_IOCTL_PARAMS32 = _IOWR('W', 0x10, struct snd_rawmidi_params32),
- SNDRV_RAWMIDI_IOCTL_STATUS32 = _IOWR('W', 0x20, struct snd_rawmidi_status32),
-+#ifdef CONFIG_X86_X32
-+ SNDRV_RAWMIDI_IOCTL_STATUS_X32 = _IOWR('W', 0x20, struct snd_rawmidi_status_x32),
-+#endif /* CONFIG_X86_X32 */
- };
-
- static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
-@@ -115,6 +164,10 @@ static long snd_rawmidi_ioctl_compat(struct file *file, unsigned int cmd, unsign
- return snd_rawmidi_ioctl_params_compat(rfile, argp);
- case SNDRV_RAWMIDI_IOCTL_STATUS32:
- return snd_rawmidi_ioctl_status_compat(rfile, argp);
-+#ifdef CONFIG_X86_X32
-+ case SNDRV_RAWMIDI_IOCTL_STATUS_X32:
-+ return snd_rawmidi_ioctl_status_x32(rfile, argp);
-+#endif /* CONFIG_X86_X32 */
- }
- return -ENOIOCTLCMD;
- }
-diff --git a/sound/core/seq/oss/seq_oss.c b/sound/core/seq/oss/seq_oss.c
-index 7354b8b..cb23899 100644
---- a/sound/core/seq/oss/seq_oss.c
-+++ b/sound/core/seq/oss/seq_oss.c
-@@ -148,8 +148,6 @@ odev_release(struct inode *inode, struct file *file)
- if ((dp = file->private_data) == NULL)
- return 0;
-
-- snd_seq_oss_drain_write(dp);
--
- mutex_lock(&register_mutex);
- snd_seq_oss_release(dp);
- mutex_unlock(&register_mutex);
-diff --git a/sound/core/seq/oss/seq_oss_device.h b/sound/core/seq/oss/seq_oss_device.h
-index b439243..d7b4d01 100644
---- a/sound/core/seq/oss/seq_oss_device.h
-+++ b/sound/core/seq/oss/seq_oss_device.h
-@@ -127,7 +127,6 @@ int snd_seq_oss_write(struct seq_oss_devinfo *dp, const char __user *buf, int co
- unsigned int snd_seq_oss_poll(struct seq_oss_devinfo *dp, struct file *file, poll_table * wait);
-
- void snd_seq_oss_reset(struct seq_oss_devinfo *dp);
--void snd_seq_oss_drain_write(struct seq_oss_devinfo *dp);
-
- /* */
- void snd_seq_oss_process_queue(struct seq_oss_devinfo *dp, abstime_t time);
-diff --git a/sound/core/seq/oss/seq_oss_init.c b/sound/core/seq/oss/seq_oss_init.c
-index 6779e82b..92c96a9 100644
---- a/sound/core/seq/oss/seq_oss_init.c
-+++ b/sound/core/seq/oss/seq_oss_init.c
-@@ -436,22 +436,6 @@ snd_seq_oss_release(struct seq_oss_devinfo *dp)
-
-
- /*
-- * Wait until the queue is empty (if we don't have nonblock)
-- */
--void
--snd_seq_oss_drain_write(struct seq_oss_devinfo *dp)
--{
-- if (! dp->timer->running)
-- return;
-- if (is_write_mode(dp->file_mode) && !is_nonblock_mode(dp->file_mode) &&
-- dp->writeq) {
-- while (snd_seq_oss_writeq_sync(dp->writeq))
-- ;
-- }
--}
--
--
--/*
- * reset sequencer devices
- */
- void
-diff --git a/sound/core/timer_compat.c b/sound/core/timer_compat.c
-index e05802a..2e90822 100644
---- a/sound/core/timer_compat.c
-+++ b/sound/core/timer_compat.c
-@@ -70,13 +70,14 @@ static int snd_timer_user_status_compat(struct file *file,
- struct snd_timer_status32 __user *_status)
- {
- struct snd_timer_user *tu;
-- struct snd_timer_status status;
-+ struct snd_timer_status32 status;
-
- tu = file->private_data;
- if (snd_BUG_ON(!tu->timeri))
- return -ENXIO;
- memset(&status, 0, sizeof(status));
-- status.tstamp = tu->tstamp;
-+ status.tstamp.tv_sec = tu->tstamp.tv_sec;
-+ status.tstamp.tv_nsec = tu->tstamp.tv_nsec;
- status.resolution = snd_timer_resolution(tu->timeri);
- status.lost = tu->timeri->lost;
- status.overrun = tu->overrun;
-@@ -88,12 +89,21 @@ static int snd_timer_user_status_compat(struct file *file,
- return 0;
- }
-
-+#ifdef CONFIG_X86_X32
-+/* X32 ABI has the same struct as x86-64 */
-+#define snd_timer_user_status_x32(file, s) \
-+ snd_timer_user_status(file, s)
-+#endif /* CONFIG_X86_X32 */
-+
- /*
- */
-
- enum {
- SNDRV_TIMER_IOCTL_INFO32 = _IOR('T', 0x11, struct snd_timer_info32),
- SNDRV_TIMER_IOCTL_STATUS32 = _IOW('T', 0x14, struct snd_timer_status32),
-+#ifdef CONFIG_X86_X32
-+ SNDRV_TIMER_IOCTL_STATUS_X32 = _IOW('T', 0x14, struct snd_timer_status),
-+#endif /* CONFIG_X86_X32 */
- };
-
- static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, unsigned long arg)
-@@ -122,6 +132,10 @@ static long snd_timer_user_ioctl_compat(struct file *file, unsigned int cmd, uns
- return snd_timer_user_info_compat(file, argp);
- case SNDRV_TIMER_IOCTL_STATUS32:
- return snd_timer_user_status_compat(file, argp);
-+#ifdef CONFIG_X86_X32
-+ case SNDRV_TIMER_IOCTL_STATUS_X32:
-+ return snd_timer_user_status_x32(file, argp);
-+#endif /* CONFIG_X86_X32 */
- }
- return -ENOIOCTLCMD;
- }
-diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
-index 72fa58d..c2430b3 100644
---- a/sound/pci/hda/patch_realtek.c
-+++ b/sound/pci/hda/patch_realtek.c
-@@ -5386,6 +5386,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
- SND_PCI_QUIRK(0x1025, 0x080d, "Acer Aspire V5-122P", ALC269_FIXUP_ASPIRE_HEADSET_MIC),
- SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
- SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
-+ SND_PCI_QUIRK(0x1025, 0x0762, "Acer Aspire E1-472", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
- SND_PCI_QUIRK(0x1025, 0x0775, "Acer Aspire E1-572", ALC271_FIXUP_HP_GATE_MIC_JACK_E1_572),
- SND_PCI_QUIRK(0x1025, 0x079b, "Acer Aspire V5-573G", ALC282_FIXUP_ASPIRE_V5_PINS),
- SND_PCI_QUIRK(0x1025, 0x106d, "Acer Cloudbook 14", ALC283_FIXUP_CHROME_BOOK),
-diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c
-index 2875b4f..7c8941b 100644
---- a/sound/pci/rme9652/hdsp.c
-+++ b/sound/pci/rme9652/hdsp.c
-@@ -2879,7 +2879,7 @@ static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl
- {
- struct hdsp *hdsp = snd_kcontrol_chip(kcontrol);
-
-- ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp);
-+ ucontrol->value.integer.value[0] = hdsp_dds_offset(hdsp);
- return 0;
- }
-
-@@ -2891,7 +2891,7 @@ static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl
-
- if (!snd_hdsp_use_is_exclusive(hdsp))
- return -EBUSY;
-- val = ucontrol->value.enumerated.item[0];
-+ val = ucontrol->value.integer.value[0];
- spin_lock_irq(&hdsp->lock);
- if (val != hdsp_dds_offset(hdsp))
- change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0;
-diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
-index 8bc8016..a4a999a 100644
---- a/sound/pci/rme9652/hdspm.c
-+++ b/sound/pci/rme9652/hdspm.c
-@@ -1601,6 +1601,9 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate)
- {
- u64 n;
-
-+ if (snd_BUG_ON(rate <= 0))
-+ return;
-+
- if (rate >= 112000)
- rate /= 4;
- else if (rate >= 56000)
-@@ -2215,6 +2218,8 @@ static int hdspm_get_system_sample_rate(struct hdspm *hdspm)
- } else {
- /* slave mode, return external sample rate */
- rate = hdspm_external_sample_rate(hdspm);
-+ if (!rate)
-+ rate = hdspm->system_sample_rate;
- }
- }
-
-@@ -2260,8 +2265,11 @@ static int snd_hdspm_put_system_sample_rate(struct snd_kcontrol *kcontrol,
- ucontrol)
- {
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-+ int rate = ucontrol->value.integer.value[0];
-
-- hdspm_set_dds_value(hdspm, ucontrol->value.enumerated.item[0]);
-+ if (rate < 27000 || rate > 207000)
-+ return -EINVAL;
-+ hdspm_set_dds_value(hdspm, ucontrol->value.integer.value[0]);
- return 0;
- }
-
-@@ -4449,7 +4457,7 @@ static int snd_hdspm_get_tco_word_term(struct snd_kcontrol *kcontrol,
- {
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
-- ucontrol->value.enumerated.item[0] = hdspm->tco->term;
-+ ucontrol->value.integer.value[0] = hdspm->tco->term;
-
- return 0;
- }
-@@ -4460,8 +4468,8 @@ static int snd_hdspm_put_tco_word_term(struct snd_kcontrol *kcontrol,
- {
- struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
-
-- if (hdspm->tco->term != ucontrol->value.enumerated.item[0]) {
-- hdspm->tco->term = ucontrol->value.enumerated.item[0];
-+ if (hdspm->tco->term != ucontrol->value.integer.value[0]) {
-+ hdspm->tco->term = ucontrol->value.integer.value[0];
-
- hdspm_tco_write(hdspm);
-
-diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c
-index 4f6ce1c..c458d60 100644
---- a/sound/usb/quirks.c
-+++ b/sound/usb/quirks.c
-@@ -1124,6 +1124,7 @@ bool snd_usb_get_sample_rate_quirk(struct snd_usb_audio *chip)
- case USB_ID(0x045E, 0x076F): /* MS Lifecam HD-6000 */
- case USB_ID(0x045E, 0x0772): /* MS Lifecam Studio */
- case USB_ID(0x045E, 0x0779): /* MS Lifecam HD-3000 */
-+ case USB_ID(0x047F, 0xAA05): /* Plantronics DA45 */
- case USB_ID(0x04D8, 0xFEEA): /* Benchmark DAC1 Pre */
- case USB_ID(0x074D, 0x3553): /* Outlaw RR2150 (Micronas UAC3553B) */
- case USB_ID(0x21B4, 0x0081): /* AudioQuest DragonFly */
diff --git a/4.4.5/4420_grsecurity-3.1-4.4.5-201603102309.patch b/4.4.5/4420_grsecurity-3.1-4.4.5-201603131305.patch
index 13412c8..c5fcaad 100644
--- a/4.4.5/4420_grsecurity-3.1-4.4.5-201603102309.patch
+++ b/4.4.5/4420_grsecurity-3.1-4.4.5-201603131305.patch
@@ -448,6 +448,20 @@ index af70d15..ccd3786 100644
modules_disabled:
A toggle value indicating if modules are allowed to be loaded
+diff --git a/Documentation/virtual/kvm/mmu.txt b/Documentation/virtual/kvm/mmu.txt
+index 3a4d681..b653641 100644
+--- a/Documentation/virtual/kvm/mmu.txt
++++ b/Documentation/virtual/kvm/mmu.txt
+@@ -358,7 +358,8 @@ In the first case there are two additional complications:
+ - if CR4.SMEP is enabled: since we've turned the page into a kernel page,
+ the kernel may now execute it. We handle this by also setting spte.nx.
+ If we get a user fetch or read fault, we'll change spte.u=1 and
+- spte.nx=gpte.nx back.
++ spte.nx=gpte.nx back. For this to work, KVM forces EFER.NX to 1 when
++ shadow paging is in use.
+ - if CR4.SMAP is disabled: since the page has been changed to a kernel
+ page, it can not be reused when CR4.SMAP is enabled. We set
+ CR4.SMAP && !CR0.WP into shadow page's role to avoid this case. Note,
diff --git a/Makefile b/Makefile
index d13322a..6eaab55 100644
--- a/Makefile
@@ -24713,7 +24727,7 @@ index 4d38416..ec7cc4e 100644
unlock_done:
mutex_unlock(&espfix_init_mutex);
diff --git a/arch/x86/kernel/fpu/core.c b/arch/x86/kernel/fpu/core.c
-index d25097c..e2df353 100644
+index d25097c..4c36ff6 100644
--- a/arch/x86/kernel/fpu/core.c
+++ b/arch/x86/kernel/fpu/core.c
@@ -127,7 +127,7 @@ void __kernel_fpu_end(void)
@@ -24779,7 +24793,19 @@ index d25097c..e2df353 100644
fpu->counter++;
kernel_fpu_enable();
}
-@@ -442,25 +442,25 @@ void fpu__clear(struct fpu *fpu)
+@@ -409,8 +409,10 @@ static inline void copy_init_fpstate_to_fpregs(void)
+ {
+ if (use_xsave())
+ copy_kernel_to_xregs(&init_fpstate.xsave, -1);
+- else
++ else if (static_cpu_has(X86_FEATURE_FXSR))
+ copy_kernel_to_fxregs(&init_fpstate.fxsave);
++ else
++ copy_kernel_to_fregs(&init_fpstate.fsave);
+ }
+
+ /*
+@@ -442,25 +444,25 @@ void fpu__clear(struct fpu *fpu)
static inline unsigned short get_fpu_cwd(struct fpu *fpu)
{
if (cpu_has_fxsr) {
@@ -24811,7 +24837,7 @@ index d25097c..e2df353 100644
return MXCSR_DEFAULT;
}
diff --git a/arch/x86/kernel/fpu/init.c b/arch/x86/kernel/fpu/init.c
-index be39b5f..b76c3b1 100644
+index be39b5f..1095798 100644
--- a/arch/x86/kernel/fpu/init.c
+++ b/arch/x86/kernel/fpu/init.c
@@ -42,7 +42,7 @@ static void fpu__init_cpu_generic(void)
@@ -24823,6 +24849,15 @@ index be39b5f..b76c3b1 100644
else
#endif
asm volatile ("fninit");
+@@ -129,7 +129,7 @@ static void __init fpu__init_system_generic(void)
+ * Set up the legacy init FPU context. (xstate init might overwrite this
+ * with a more modern format, if the CPU supports it.)
+ */
+- fpstate_init_fxstate(&init_fpstate.fxsave);
++ fpstate_init(&init_fpstate);
+
+ fpu__init_system_mxcsr();
+ }
@@ -143,42 +143,7 @@ static void __init fpu__init_system_generic(void)
unsigned int xstate_size;
EXPORT_SYMBOL_GPL(xstate_size);
@@ -29594,6 +29629,27 @@ index 4d30b86..94115f0 100644
#define APIC_LVT_NUM 6
/* 14 is the version for Xeon and Pentium 8.4.8*/
+diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c
+index e7c2c14..8eb8a93 100644
+--- a/arch/x86/kvm/mmu.c
++++ b/arch/x86/kvm/mmu.c
+@@ -3754,13 +3754,15 @@ static void reset_rsvds_bits_mask_ept(struct kvm_vcpu *vcpu,
+ void
+ reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context)
+ {
++ bool uses_nx = context->nx || context->base_role.smep_andnot_wp;
++
+ /*
+ * Passing "true" to the last argument is okay; it adds a check
+ * on bit 8 of the SPTEs which KVM doesn't use anyway.
+ */
+ __reset_rsvds_bits_mask(vcpu, &context->shadow_zero_check,
+ boot_cpu_data.x86_phys_bits,
+- context->shadow_root_level, context->nx,
++ context->shadow_root_level, uses_nx,
+ guest_cpuid_has_gbpages(vcpu), is_pse(vcpu),
+ true);
+ }
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h
index 7be8a25..7d71250 100644
--- a/arch/x86/kvm/paging_tmpl.h
@@ -29644,7 +29700,7 @@ index 899c40f..a114588 100644
.disabled_by_bios = is_disabled,
.hardware_setup = svm_hardware_setup,
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
-index 5fd846c..cdf2fca 100644
+index 5fd846c..405597f 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -1514,12 +1514,12 @@ static void vmcs_write64(unsigned long field, u64 value)
@@ -29662,7 +29718,7 @@ index 5fd846c..cdf2fca 100644
{
vmcs_writel(field, vmcs_readl(field) | mask);
}
-@@ -1779,7 +1779,11 @@ static void reload_tss(void)
+@@ -1779,32 +1779,41 @@ static void reload_tss(void)
struct desc_struct *descs;
descs = (void *)gdt->address;
@@ -29674,7 +29730,72 @@ index 5fd846c..cdf2fca 100644
load_TR_desc();
}
-@@ -2061,6 +2065,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
+ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
+ {
+- u64 guest_efer;
+- u64 ignore_bits;
++ u64 guest_efer = vmx->vcpu.arch.efer;
++ u64 ignore_bits = 0;
+
+- guest_efer = vmx->vcpu.arch.efer;
++ if (!enable_ept) {
++ /*
++ * NX is needed to handle CR0.WP=1, CR4.SMEP=1. Testing
++ * host CPUID is more efficient than testing guest CPUID
++ * or CR4. Host SMEP is anyway a requirement for guest SMEP.
++ */
++ if (boot_cpu_has(X86_FEATURE_SMEP))
++ guest_efer |= EFER_NX;
++ else if (!(guest_efer & EFER_NX))
++ ignore_bits |= EFER_NX;
++ }
+
+ /*
+- * NX is emulated; LMA and LME handled by hardware; SCE meaningless
+- * outside long mode
++ * LMA and LME handled by hardware; SCE meaningless outside long mode.
+ */
+- ignore_bits = EFER_NX | EFER_SCE;
++ ignore_bits |= EFER_SCE;
+ #ifdef CONFIG_X86_64
+ ignore_bits |= EFER_LMA | EFER_LME;
+ /* SCE is meaningful only in long mode on Intel */
+ if (guest_efer & EFER_LMA)
+ ignore_bits &= ~(u64)EFER_SCE;
+ #endif
+- guest_efer &= ~ignore_bits;
+- guest_efer |= host_efer & ignore_bits;
+- vmx->guest_msrs[efer_offset].data = guest_efer;
+- vmx->guest_msrs[efer_offset].mask = ~ignore_bits;
+
+ clear_atomic_switch_msr(vmx, MSR_EFER);
+
+@@ -1815,16 +1824,21 @@ static bool update_transition_efer(struct vcpu_vmx *vmx, int efer_offset)
+ */
+ if (cpu_has_load_ia32_efer ||
+ (enable_ept && ((vmx->vcpu.arch.efer ^ host_efer) & EFER_NX))) {
+- guest_efer = vmx->vcpu.arch.efer;
+ if (!(guest_efer & EFER_LMA))
+ guest_efer &= ~EFER_LME;
+ if (guest_efer != host_efer)
+ add_atomic_switch_msr(vmx, MSR_EFER,
+ guest_efer, host_efer);
+ return false;
++ } else {
++ guest_efer &= ~ignore_bits;
++ guest_efer |= host_efer & ignore_bits;
++
++ vmx->guest_msrs[efer_offset].data = guest_efer;
++ vmx->guest_msrs[efer_offset].mask = ~ignore_bits;
++
++ return true;
+ }
+-
+- return true;
+ }
+
+ static unsigned long segment_base(u16 selector)
+@@ -2061,6 +2075,10 @@ static void vmx_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
vmcs_writel(HOST_TR_BASE, kvm_read_tr_base()); /* 22.2.4 */
vmcs_writel(HOST_GDTR_BASE, gdt->address); /* 22.2.4 */
@@ -29685,7 +29806,7 @@ index 5fd846c..cdf2fca 100644
rdmsrl(MSR_IA32_SYSENTER_ESP, sysenter_esp);
vmcs_writel(HOST_IA32_SYSENTER_ESP, sysenter_esp); /* 22.2.3 */
-@@ -2378,7 +2386,7 @@ static void setup_msrs(struct vcpu_vmx *vmx)
+@@ -2378,7 +2396,7 @@ static void setup_msrs(struct vcpu_vmx *vmx)
* guest_tsc = (host_tsc * tsc multiplier) >> 48 + tsc_offset
* -- Intel TSC Scaling for Virtualization White Paper, sec 1.3
*/
@@ -29694,7 +29815,7 @@ index 5fd846c..cdf2fca 100644
{
u64 host_tsc, tsc_offset;
-@@ -4609,7 +4617,10 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
+@@ -4609,7 +4627,10 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
unsigned long cr4;
vmcs_writel(HOST_CR0, read_cr0() & ~X86_CR0_TS); /* 22.2.3 */
@@ -29705,7 +29826,7 @@ index 5fd846c..cdf2fca 100644
/* Save the most likely value for this task's CR4 in the VMCS. */
cr4 = cr4_read_shadow();
-@@ -4636,7 +4647,7 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
+@@ -4636,7 +4657,7 @@ static void vmx_set_constant_host_state(struct vcpu_vmx *vmx)
vmcs_writel(HOST_IDTR_BASE, dt.address); /* 22.2.4 */
vmx->host_idt_base = dt.address;
@@ -29714,7 +29835,7 @@ index 5fd846c..cdf2fca 100644
rdmsr(MSR_IA32_SYSENTER_CS, low32, high32);
vmcs_write32(HOST_IA32_SYSENTER_CS, low32);
-@@ -6186,11 +6197,17 @@ static __init int hardware_setup(void)
+@@ -6186,11 +6207,17 @@ static __init int hardware_setup(void)
* page upon invalidation. No need to do anything if not
* using the APIC_ACCESS_ADDR VMCS field.
*/
@@ -29734,7 +29855,7 @@ index 5fd846c..cdf2fca 100644
if (enable_ept && !cpu_has_vmx_ept_2m_page())
kvm_disable_largepages();
-@@ -6207,6 +6224,7 @@ static __init int hardware_setup(void)
+@@ -6207,6 +6234,7 @@ static __init int hardware_setup(void)
kvm_tsc_scaling_ratio_frac_bits = 48;
}
@@ -29742,7 +29863,7 @@ index 5fd846c..cdf2fca 100644
if (enable_apicv)
kvm_x86_ops->update_cr8_intercept = NULL;
else {
-@@ -6215,6 +6233,7 @@ static __init int hardware_setup(void)
+@@ -6215,6 +6243,7 @@ static __init int hardware_setup(void)
kvm_x86_ops->deliver_posted_interrupt = NULL;
kvm_x86_ops->sync_pir_to_irr = vmx_sync_pir_to_irr_dummy;
}
@@ -29750,7 +29871,7 @@ index 5fd846c..cdf2fca 100644
vmx_disable_intercept_for_msr(MSR_FS_BASE, false);
vmx_disable_intercept_for_msr(MSR_GS_BASE, false);
-@@ -6269,10 +6288,12 @@ static __init int hardware_setup(void)
+@@ -6269,10 +6298,12 @@ static __init int hardware_setup(void)
enable_pml = 0;
if (!enable_pml) {
@@ -29763,7 +29884,7 @@ index 5fd846c..cdf2fca 100644
}
kvm_set_posted_intr_wakeup_handler(wakeup_handler);
-@@ -8584,6 +8605,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+@@ -8584,6 +8615,12 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
"jmp 2f \n\t"
"1: " __ex(ASM_VMX_VMRESUME) "\n\t"
"2: "
@@ -29776,7 +29897,7 @@ index 5fd846c..cdf2fca 100644
/* Save guest registers, load host registers, keep flags */
"mov %0, %c[wordsize](%%" _ASM_SP ") \n\t"
"pop %0 \n\t"
-@@ -8636,6 +8663,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+@@ -8636,6 +8673,11 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
#endif
[cr2]"i"(offsetof(struct vcpu_vmx, vcpu.arch.cr2)),
[wordsize]"i"(sizeof(ulong))
@@ -29788,7 +29909,7 @@ index 5fd846c..cdf2fca 100644
: "cc", "memory"
#ifdef CONFIG_X86_64
, "rax", "rbx", "rdi", "rsi"
-@@ -8649,7 +8681,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+@@ -8649,7 +8691,7 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
if (debugctlmsr)
update_debugctlmsr(debugctlmsr);
@@ -29797,7 +29918,7 @@ index 5fd846c..cdf2fca 100644
/*
* The sysexit path does not restore ds/es, so we must set them to
* a reasonable value ourselves.
-@@ -8658,8 +8690,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
+@@ -8658,8 +8700,18 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu)
* may be executed in interrupt context, which saves and restore segments
* around it, nullifying its effect.
*/
@@ -29818,7 +29939,7 @@ index 5fd846c..cdf2fca 100644
#endif
vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP)
-@@ -10741,7 +10783,7 @@ out:
+@@ -10741,7 +10793,7 @@ out:
return ret;
}
@@ -83375,7 +83496,7 @@ index 14db05d..687f6d8 100644
#define MNT_NS_INTERNAL ERR_PTR(-EINVAL) /* distinct from any mnt_namespace */
diff --git a/fs/namei.c b/fs/namei.c
-index d8ee4da..47a7c9c 100644
+index d8ee4da..dc6d6b5 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -336,17 +336,32 @@ int generic_permission(struct inode *inode, int mask)
@@ -83699,7 +83820,23 @@ index d8ee4da..47a7c9c 100644
audit_inode(nd->name, nd->path.dentry, 0);
if (unlikely(d_is_symlink(nd->path.dentry)) && !(open_flag & O_PATH)) {
error = -ELOOP;
-@@ -3440,9 +3587,11 @@ static struct dentry *filename_create(int dfd, struct filename *name,
+@@ -3351,6 +3498,15 @@ out2:
+ error = -ESTALE;
+ }
+ file = ERR_PTR(error);
++ } else {
++ error = gr_chroot_pathat(nd->dfd, file->f_path.dentry, file->f_path.mnt, flags);
++ if (error == -ECHILD) {
++ fput(file);
++ file = ERR_PTR(error);
++ } else if (!error) {
++ fput(file);
++ file = ERR_PTR(-ENOENT);
++ }
+ }
+ return file;
+ }
+@@ -3440,9 +3596,11 @@ static struct dentry *filename_create(int dfd, struct filename *name,
goto unlock;
error = -EEXIST;
@@ -83713,7 +83850,7 @@ index d8ee4da..47a7c9c 100644
/*
* Special case - lookup gave negative, but... we had foo/bar/
* From the vfs_mknod() POV we just have a negative dentry -
-@@ -3496,6 +3645,20 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname,
+@@ -3496,6 +3654,20 @@ inline struct dentry *user_path_create(int dfd, const char __user *pathname,
}
EXPORT_SYMBOL(user_path_create);
@@ -83734,7 +83871,7 @@ index d8ee4da..47a7c9c 100644
int vfs_mknod(struct inode *dir, struct dentry *dentry, umode_t mode, dev_t dev)
{
int error = may_create(dir, dentry);
-@@ -3559,6 +3722,17 @@ retry:
+@@ -3559,6 +3731,17 @@ retry:
if (!IS_POSIXACL(path.dentry->d_inode))
mode &= ~current_umask();
@@ -83752,7 +83889,7 @@ index d8ee4da..47a7c9c 100644
error = security_path_mknod(&path, dentry, mode, dev);
if (error)
goto out;
-@@ -3574,6 +3748,8 @@ retry:
+@@ -3574,6 +3757,8 @@ retry:
error = vfs_mknod(path.dentry->d_inode,dentry,mode,0);
break;
}
@@ -83761,7 +83898,7 @@ index d8ee4da..47a7c9c 100644
out:
done_path_create(&path, dentry);
if (retry_estale(error, lookup_flags)) {
-@@ -3628,9 +3804,16 @@ retry:
+@@ -3628,9 +3813,16 @@ retry:
if (!IS_POSIXACL(path.dentry->d_inode))
mode &= ~current_umask();
@@ -83778,7 +83915,7 @@ index d8ee4da..47a7c9c 100644
done_path_create(&path, dentry);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
-@@ -3663,7 +3846,7 @@ void dentry_unhash(struct dentry *dentry)
+@@ -3663,7 +3855,7 @@ void dentry_unhash(struct dentry *dentry)
{
shrink_dcache_parent(dentry);
spin_lock(&dentry->d_lock);
@@ -83787,7 +83924,7 @@ index d8ee4da..47a7c9c 100644
__d_drop(dentry);
spin_unlock(&dentry->d_lock);
}
-@@ -3716,6 +3899,8 @@ static long do_rmdir(int dfd, const char __user *pathname)
+@@ -3716,6 +3908,8 @@ static long do_rmdir(int dfd, const char __user *pathname)
struct path path;
struct qstr last;
int type;
@@ -83796,7 +83933,7 @@ index d8ee4da..47a7c9c 100644
unsigned int lookup_flags = 0;
retry:
name = user_path_parent(dfd, pathname,
-@@ -3748,10 +3933,20 @@ retry:
+@@ -3748,10 +3942,20 @@ retry:
error = -ENOENT;
goto exit3;
}
@@ -83817,7 +83954,7 @@ index d8ee4da..47a7c9c 100644
exit3:
dput(dentry);
exit2:
-@@ -3846,6 +4041,8 @@ static long do_unlinkat(int dfd, const char __user *pathname)
+@@ -3846,6 +4050,8 @@ static long do_unlinkat(int dfd, const char __user *pathname)
int type;
struct inode *inode = NULL;
struct inode *delegated_inode = NULL;
@@ -83826,7 +83963,7 @@ index d8ee4da..47a7c9c 100644
unsigned int lookup_flags = 0;
retry:
name = user_path_parent(dfd, pathname,
-@@ -3872,10 +4069,21 @@ retry_deleg:
+@@ -3872,10 +4078,21 @@ retry_deleg:
if (d_is_negative(dentry))
goto slashes;
ihold(inode);
@@ -83848,7 +83985,7 @@ index d8ee4da..47a7c9c 100644
exit2:
dput(dentry);
}
-@@ -3964,9 +4172,17 @@ retry:
+@@ -3964,9 +4181,17 @@ retry:
if (IS_ERR(dentry))
goto out_putname;
@@ -83866,7 +84003,7 @@ index d8ee4da..47a7c9c 100644
done_path_create(&path, dentry);
if (retry_estale(error, lookup_flags)) {
lookup_flags |= LOOKUP_REVAL;
-@@ -4070,6 +4286,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
+@@ -4070,6 +4295,7 @@ SYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
struct dentry *new_dentry;
struct path old_path, new_path;
struct inode *delegated_inode = NULL;
@@ -83874,7 +84011,7 @@ index d8ee4da..47a7c9c 100644
int how = 0;
int error;
-@@ -4093,7 +4310,7 @@ retry:
+@@ -4093,7 +4319,7 @@ retry:
if (error)
return error;
@@ -83883,7 +84020,7 @@ index d8ee4da..47a7c9c 100644
(how & LOOKUP_REVAL));
error = PTR_ERR(new_dentry);
if (IS_ERR(new_dentry))
-@@ -4105,11 +4322,26 @@ retry:
+@@ -4105,11 +4331,26 @@ retry:
error = may_linkat(&old_path);
if (unlikely(error))
goto out_dput;
@@ -83910,7 +84047,7 @@ index d8ee4da..47a7c9c 100644
done_path_create(&new_path, new_dentry);
if (delegated_inode) {
error = break_deleg_wait(&delegated_inode);
-@@ -4424,6 +4656,20 @@ retry_deleg:
+@@ -4424,6 +4665,20 @@ retry_deleg:
if (new_dentry == trap)
goto exit5;
@@ -83931,7 +84068,7 @@ index d8ee4da..47a7c9c 100644
error = security_path_rename(&old_path, old_dentry,
&new_path, new_dentry, flags);
if (error)
-@@ -4431,6 +4677,9 @@ retry_deleg:
+@@ -4431,6 +4686,9 @@ retry_deleg:
error = vfs_rename(old_path.dentry->d_inode, old_dentry,
new_path.dentry->d_inode, new_dentry,
&delegated_inode, flags);
@@ -83941,7 +84078,7 @@ index d8ee4da..47a7c9c 100644
exit5:
dput(new_dentry);
exit4:
-@@ -4487,14 +4736,24 @@ EXPORT_SYMBOL(vfs_whiteout);
+@@ -4487,14 +4745,24 @@ EXPORT_SYMBOL(vfs_whiteout);
int readlink_copy(char __user *buffer, int buflen, const char *link)
{
@@ -87895,7 +88032,7 @@ index 119c242..a02e8da 100644
/*
diff --git a/fs/xfs/libxfs/xfs_da_btree.c b/fs/xfs/libxfs/xfs_da_btree.c
-index e89a0f8..3165b4a 100644
+index e89a0f8f..3165b4a 100644
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -2011,6 +2011,7 @@ xfs_da_grow_inode_int(
@@ -87971,10 +88108,10 @@ index ec0e239..ab85b22 100644
diff --git a/grsecurity/Kconfig b/grsecurity/Kconfig
new file mode 100644
-index 0000000..354c5a3
+index 0000000..f172760
--- /dev/null
+++ b/grsecurity/Kconfig
-@@ -0,0 +1,1203 @@
+@@ -0,0 +1,1205 @@
+#
+# grecurity configuration
+#
@@ -88543,10 +88680,12 @@ index 0000000..354c5a3
+ help
+ If you say Y here, a well-known method of breaking chroots by fchdir'ing
+ to a file descriptor of the chrooting process that points to a directory
-+ outside the filesystem will be stopped. Additionally, this option prevents
-+ use of the recently-created syscall for opening files by a guessable "file
-+ handle" inside a chroot. If the sysctl option is enabled, a sysctl option
-+ with name "chroot_deny_fchdir" is created.
++ outside the filesystem will be stopped. This option also prevents use of
++ the recently-created syscall for opening files by a guessable "file handle"
++ inside a chroot, as well as accessing relative paths outside of a
++ directory passed in via file descriptor with openat and similar syscalls.
++ If the sysctl option is enabled, a sysctl option with name "chroot_deny_fchdir"
++ is created.
+
+config GRKERNSEC_CHROOT_MKNOD
+ bool "Deny mknod"
@@ -95815,10 +95954,10 @@ index 0000000..bc0be01
+}
diff --git a/grsecurity/grsec_chroot.c b/grsecurity/grsec_chroot.c
new file mode 100644
-index 0000000..652ab45
+index 0000000..aa6fed5
--- /dev/null
+++ b/grsecurity/grsec_chroot.c
-@@ -0,0 +1,467 @@
+@@ -0,0 +1,506 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/sched.h>
@@ -95826,6 +95965,7 @@ index 0000000..652ab45
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/types.h>
++#include <linux/namei.h>
+#include "../fs/mount.h"
+#include <linux/grsecurity.h>
+#include <linux/grinternal.h>
@@ -96075,6 +96215,44 @@ index 0000000..652ab45
+}
+
+int
++gr_chroot_pathat(int dfd, struct dentry *u_dentry, struct vfsmount *u_mnt, unsigned flags)
++{
++#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
++ struct fd f;
++ struct path fd_path;
++ struct path file_path;
++
++ if (!grsec_enable_chroot_fchdir)
++ return 1;
++
++ if (!proc_is_chrooted(current) || dfd == -1 || dfd == AT_FDCWD)
++ return 1;
++
++ if (flags & LOOKUP_RCU)
++ return -ECHILD;
++
++ f = fdget_raw(dfd);
++ if (!f.file)
++ return 1;
++
++ fd_path = f.file->f_path;
++ path_get(&fd_path);
++ fdput(f);
++
++ file_path.dentry = u_dentry;
++ file_path.mnt = u_mnt;
++
++ if (!gr_is_outside_chroot(u_dentry, u_mnt) && !path_is_under(&file_path, &fd_path)) {
++ path_put(&fd_path);
++ gr_log_fs_generic(GR_DONT_AUDIT, GR_CHROOT_PATHAT_MSG, u_dentry, u_mnt);
++ return 0;
++ }
++ path_put(&fd_path);
++#endif
++ return 1;
++}
++
++int
+gr_chroot_fhandle(void)
+{
+#ifdef CONFIG_GRKERNSEC_CHROOT_FCHDIR
@@ -100175,6 +100353,22 @@ index 576e463..28fd926 100644
extern void __register_binfmt(struct linux_binfmt *fmt, int insert);
+diff --git a/include/linux/bio.h b/include/linux/bio.h
+index 79cfaee..fbe47bc 100644
+--- a/include/linux/bio.h
++++ b/include/linux/bio.h
+@@ -320,11 +320,6 @@ static inline void bio_get_last_bvec(struct bio *bio, struct bio_vec *bv)
+ struct bvec_iter iter = bio->bi_iter;
+ int idx;
+
+- if (!bio_flagged(bio, BIO_CLONED)) {
+- *bv = bio->bi_io_vec[bio->bi_vcnt - 1];
+- return;
+- }
+-
+ if (unlikely(!bio_multiple_segments(bio))) {
+ *bv = bio_iovec(bio);
+ return;
diff --git a/include/linux/bitmap.h b/include/linux/bitmap.h
index 9653fdb..b3d3a17 100644
--- a/include/linux/bitmap.h
@@ -102425,10 +102619,10 @@ index 0000000..1dbf9c8
+#endif
diff --git a/include/linux/grmsg.h b/include/linux/grmsg.h
new file mode 100644
-index 0000000..12028ce
+index 0000000..94ac4d2
--- /dev/null
+++ b/include/linux/grmsg.h
-@@ -0,0 +1,119 @@
+@@ -0,0 +1,120 @@
+#define DEFAULTSECMSG "%.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u, parent %.256s[%.16s:%d] uid/euid:%u/%u gid/egid:%u/%u"
+#define GR_ACL_PROCACCT_MSG "%.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u run time:[%ud %uh %um %us] cpu time:[%ud %uh %um %us] %s with exit code %ld, parent %.256s[%.16s:%d] IP:%pI4 TTY:%.64s uid/euid:%u/%u gid/egid:%u/%u"
+#define GR_PTRACE_ACL_MSG "denied ptrace of %.950s(%.16s:%d) by "
@@ -102476,6 +102670,7 @@ index 0000000..12028ce
+#define GR_CHMOD_CHROOT_MSG "denied chmod +s of %.950s by "
+#define GR_CHMOD_ACL_MSG "%s chmod of %.950s by "
+#define GR_CHROOT_FCHDIR_MSG "denied fchdir outside of chroot to %.950s by "
++#define GR_CHROOT_PATHAT_MSG "denied relative path access outside of chroot to %.950s by "
+#define GR_CHROOT_FHANDLE_MSG "denied use of file handles inside chroot by "
+#define GR_CHOWN_ACL_MSG "%s chown of %.950s by "
+#define GR_SETXATTR_ACL_MSG "%s setting extended attribute of %.950s by "
@@ -102550,10 +102745,10 @@ index 0000000..12028ce
+#define GR_MSRWRITE_MSG "denied write to CPU MSR by "
diff --git a/include/linux/grsecurity.h b/include/linux/grsecurity.h
new file mode 100644
-index 0000000..0166061
+index 0000000..4d5dae0
--- /dev/null
+++ b/include/linux/grsecurity.h
-@@ -0,0 +1,258 @@
+@@ -0,0 +1,259 @@
+#ifndef GR_SECURITY_H
+#define GR_SECURITY_H
+#include <linux/fs.h>
@@ -102611,6 +102806,7 @@ index 0000000..0166061
+int gr_handle_chroot_setpriority(struct task_struct *p,
+ const int niceval);
+int gr_chroot_fchdir(struct dentry *u_dentry, struct vfsmount *u_mnt);
++int gr_chroot_pathat(int dfd, struct dentry *u_dentry, struct vfsmount *u_mnt, unsigned flags);
+int gr_chroot_fhandle(void);
+int gr_handle_chroot_chroot(const struct dentry *dentry,
+ const struct vfsmount *mnt);
@@ -131307,10 +131503,10 @@ index 2628890..1c2f5c6 100755
# Find all available archs
find_all_archs()
diff --git a/security/Kconfig b/security/Kconfig
-index e452378..16eb80f 100644
+index e452378..d8f5de9 100644
--- a/security/Kconfig
+++ b/security/Kconfig
-@@ -4,6 +4,980 @@
+@@ -4,6 +4,974 @@
menu "Security options"
@@ -131825,21 +132021,15 @@ index e452378..16eb80f 100644
+
+config PAX_MPROTECT_COMPAT
+ bool "Use legacy/compat protection demoting (read help)"
-+ default y if (GRKERNSEC_CONFIG_AUTO && GRKERNSEC_CONFIG_DESKTOP)
+ depends on PAX_MPROTECT
++ default n
+ help
+ The current implementation of PAX_MPROTECT denies RWX allocations/mprotects
-+ by sending the proper error code to the application. For some broken
-+ userland, this can cause problems with Python or other applications. The
-+ current implementation however allows for applications like clamav to
-+ detect if JIT compilation/execution is allowed and to fall back gracefully
-+ to an interpreter-based mode if it does not. While we encourage everyone
-+ to use the current implementation as-is and push upstream to fix broken
-+ userland (note that the RWX logging option can assist with this), in some
-+ environments this may not be possible. Having to disable MPROTECT
-+ completely on certain binaries reduces the security benefit of PaX,
-+ so this option is provided for those environments to revert to the old
-+ behavior.
++ by sending the proper error code to the application. For some older
++ userland, this can cause problems with applications that assume such
++ allocations will not be prevented by PaX or SELinux and other access
++ control systems and have no fallback mechanisms. For modern distros,
++ this option should generally be set to 'N'.
+
+config PAX_ELFRELOCS
+ bool "Allow ELF text relocations (read help)"
@@ -132291,7 +132481,7 @@ index e452378..16eb80f 100644
source security/keys/Kconfig
config SECURITY_DMESG_RESTRICT
-@@ -104,7 +1078,7 @@ config INTEL_TXT
+@@ -104,7 +1072,7 @@ config INTEL_TXT
config LSM_MMAP_MIN_ADDR
int "Low address space for LSM to protect from user allocation"
depends on SECURITY && SECURITY_SELINUX