Merge tag 'pinctrl-v4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw...
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 19 Oct 2016 16:17:29 +0000 (09:17 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 19 Oct 2016 16:17:29 +0000 (09:17 -0700)
Pull first round of pin control fixes from Linus Walleij:

 - a bunch of barnsjukdomar/kinderkrankheiten/maladie infantile in the
   Aspeed driver. (Why doesn't English have a word for this?)

   [ Maybe "teething problems" is the closest English idiom? - Linus T ]

 - fix a lockdep bug on the Intel BayTrail.

 - fix a few special laptop issues on the Intel pin controller solving
   suspend issues.

* tag 'pinctrl-v4.9-2' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl:
  pinctrl: intel: Only restore pins that are used by the driver
  pinctrl: baytrail: Fix lockdep
  pinctrl: aspeed-g5: Fix pin association of SPI1 function
  pinctrl: aspeed-g5: Fix GPIOE1 typo
  pinctrl: aspeed-g5: Fix names of GPID2 pins
  pinctrl: aspeed: "Not enabled" is a significant mux state

122 files changed:
arch/alpha/kernel/ptrace.c
arch/arm64/kernel/sleep.S
arch/blackfin/kernel/ptrace.c
arch/cris/arch-v32/drivers/cryptocop.c
arch/cris/arch-v32/kernel/ptrace.c
arch/ia64/kernel/err_inject.c
arch/ia64/kernel/ptrace.c
arch/m32r/kernel/ptrace.c
arch/mips/kernel/ptrace32.c
arch/mips/mm/gup.c
arch/powerpc/kernel/ptrace32.c
arch/s390/mm/gup.c
arch/score/kernel/ptrace.c
arch/sh/mm/gup.c
arch/sparc/kernel/ptrace_64.c
arch/sparc/mm/gup.c
arch/x86/entry/syscalls/syscall_32.tbl
arch/x86/entry/syscalls/syscall_64.tbl
arch/x86/events/intel/core.c
arch/x86/events/intel/lbr.c
arch/x86/events/intel/rapl.c
arch/x86/events/intel/uncore.c
arch/x86/include/asm/intel-family.h
arch/x86/include/asm/msr-index.h
arch/x86/include/asm/rwsem.h
arch/x86/kernel/e820.c
arch/x86/kernel/kprobes/core.c
arch/x86/kernel/smp.c
arch/x86/kernel/step.c
arch/x86/mm/gup.c
arch/x86/mm/mpx.c
arch/x86/um/ptrace_32.c
arch/x86/um/ptrace_64.c
drivers/firewire/nosy.c
drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
drivers/gpu/drm/amd/amdgpu/amdgpu_dpm.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
drivers/gpu/drm/amd/amdgpu/cz_dpm.c
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
drivers/gpu/drm/amd/amdgpu/gfx_v8_0.c
drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c
drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c
drivers/gpu/drm/amd/amdgpu/si_dpm.c
drivers/gpu/drm/amd/amdgpu/tonga_ih.c
drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c
drivers/gpu/drm/amd/amdgpu/vce_v3_0.c
drivers/gpu/drm/amd/include/amd_shared.h
drivers/gpu/drm/amd/powerplay/eventmgr/eventactionchains.c
drivers/gpu/drm/amd/powerplay/hwmgr/cz_hwmgr.c
drivers/gpu/drm/amd/powerplay/hwmgr/smu7_hwmgr.c
drivers/gpu/drm/amd/powerplay/smumgr/iceland_smc.c
drivers/gpu/drm/drm_info.c
drivers/gpu/drm/etnaviv/etnaviv_gem.c
drivers/gpu/drm/exynos/exynos_drm_g2d.c
drivers/gpu/drm/i915/i915_gem_userptr.c
drivers/gpu/drm/radeon/r600_dpm.c
drivers/gpu/drm/radeon/radeon_connectors.c
drivers/gpu/drm/radeon/radeon_display.c
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_i2c.c
drivers/gpu/drm/radeon/radeon_ttm.c
drivers/gpu/drm/radeon/si.c
drivers/gpu/drm/radeon/sid.h
drivers/gpu/drm/via/via_dmablit.c
drivers/infiniband/core/umem.c
drivers/infiniband/core/umem_odp.c
drivers/infiniband/hw/mthca/mthca_memfree.c
drivers/infiniband/hw/qib/qib_user_pages.c
drivers/infiniband/hw/usnic/usnic_uiom.c
drivers/irqchip/irq-eznps.c
drivers/irqchip/irq-gic-v3.c
drivers/irqchip/irq-jcore-aic.c
drivers/media/pci/ivtv/ivtv-udma.c
drivers/media/pci/ivtv/ivtv-yuv.c
drivers/media/platform/omap/omap_vout.c
drivers/media/v4l2-core/videobuf-dma-sg.c
drivers/media/v4l2-core/videobuf2-memops.c
drivers/misc/mic/scif/scif_rma.c
drivers/misc/sgi-gru/grufault.c
drivers/platform/goldfish/goldfish_pipe.c
drivers/rapidio/devices/rio_mport_cdev.c
drivers/scsi/st.c
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_2835_arm.c
drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c
drivers/video/fbdev/pvr2fb.c
drivers/virt/fsl_hypervisor.c
fs/btrfs/compression.c
fs/exec.c
fs/f2fs/gc.c
fs/locks.c
fs/proc/base.c
include/linux/kasan.h
include/linux/mm.h
include/linux/syscalls.h
include/uapi/asm-generic/unistd.h
kernel/cpu.c
kernel/events/uprobes.c
kernel/printk/printk.c
kernel/ptrace.c
kernel/sched/fair.c
kernel/time/alarmtimer.c
mm/frame_vector.c
mm/gup.c
mm/kasan/kasan.c
mm/memory.c
mm/mempolicy.c
mm/nommu.c
mm/process_vm_access.c
mm/util.c
net/ceph/pagevec.c
security/tomoyo/domain.c
tools/objtool/arch/x86/decode.c
tools/objtool/builtin-check.c
tools/perf/jvmti/Makefile
tools/perf/ui/browsers/hists.c
tools/perf/util/header.c
tools/perf/util/parse-events.l
virt/kvm/async_pf.c
virt/kvm/kvm_main.c

index d9ee817..940dfb4 100644 (file)
@@ -157,14 +157,16 @@ put_reg(struct task_struct *task, unsigned long regno, unsigned long data)
 static inline int
 read_int(struct task_struct *task, unsigned long addr, int * data)
 {
-       int copied = access_process_vm(task, addr, data, sizeof(int), 0);
+       int copied = access_process_vm(task, addr, data, sizeof(int),
+                       FOLL_FORCE);
        return (copied == sizeof(int)) ? 0 : -EIO;
 }
 
 static inline int
 write_int(struct task_struct *task, unsigned long addr, int data)
 {
-       int copied = access_process_vm(task, addr, &data, sizeof(int), 1);
+       int copied = access_process_vm(task, addr, &data, sizeof(int),
+                       FOLL_FORCE | FOLL_WRITE);
        return (copied == sizeof(int)) ? 0 : -EIO;
 }
 
@@ -281,7 +283,8 @@ long arch_ptrace(struct task_struct *child, long request,
        /* When I and D space are separate, these will need to be fixed.  */
        case PTRACE_PEEKTEXT: /* read word at location addr. */
        case PTRACE_PEEKDATA:
-               copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+               copied = access_process_vm(child, addr, &tmp, sizeof(tmp),
+                               FOLL_FORCE);
                ret = -EIO;
                if (copied != sizeof(tmp))
                        break;
index b8799e7..1bec41b 100644 (file)
@@ -135,7 +135,7 @@ ENTRY(_cpu_resume)
 
 #ifdef CONFIG_KASAN
        mov     x0, sp
-       bl      kasan_unpoison_remaining_stack
+       bl      kasan_unpoison_task_stack_below
 #endif
 
        ldp     x19, x20, [x29, #16]
index 8b8fe67..8d79286 100644 (file)
@@ -271,7 +271,7 @@ long arch_ptrace(struct task_struct *child, long request,
                        case BFIN_MEM_ACCESS_CORE:
                        case BFIN_MEM_ACCESS_CORE_ONLY:
                                copied = access_process_vm(child, addr, &tmp,
-                                                          to_copy, 0);
+                                                          to_copy, FOLL_FORCE);
                                if (copied)
                                        break;
 
@@ -324,7 +324,8 @@ long arch_ptrace(struct task_struct *child, long request,
                        case BFIN_MEM_ACCESS_CORE:
                        case BFIN_MEM_ACCESS_CORE_ONLY:
                                copied = access_process_vm(child, addr, &data,
-                                                          to_copy, 1);
+                                                          to_copy,
+                                                          FOLL_FORCE | FOLL_WRITE);
                                break;
                        case BFIN_MEM_ACCESS_DMA:
                                if (safe_dma_memcpy(paddr, &data, to_copy))
index b5698c8..099e170 100644 (file)
@@ -2722,7 +2722,6 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig
        err = get_user_pages((unsigned long int)(oper.indata + prev_ix),
                             noinpages,
                             0,  /* read access only for in data */
-                            0, /* no force */
                             inpages,
                             NULL);
 
@@ -2736,8 +2735,7 @@ static int cryptocop_ioctl_process(struct inode *inode, struct file *filp, unsig
        if (oper.do_cipher){
                err = get_user_pages((unsigned long int)oper.cipher_outdata,
                                     nooutpages,
-                                    1, /* write access for out data */
-                                    0, /* no force */
+                                    FOLL_WRITE, /* write access for out data */
                                     outpages,
                                     NULL);
                up_read(&current->mm->mmap_sem);
index f085229..f0df654 100644 (file)
@@ -147,7 +147,7 @@ long arch_ptrace(struct task_struct *child, long request,
                                /* The trampoline page is globally mapped, no page table to traverse.*/
                                tmp = *(unsigned long*)addr;
                        } else {
-                               copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0);
+                               copied = access_process_vm(child, addr, &tmp, sizeof(tmp), FOLL_FORCE);
 
                                if (copied != sizeof(tmp))
                                        break;
@@ -279,7 +279,7 @@ static int insn_size(struct task_struct *child, unsigned long pc)
   int opsize = 0;
 
   /* Read the opcode at pc (do what PTRACE_PEEKTEXT would do). */
-  copied = access_process_vm(child, pc, &opcode, sizeof(opcode), 0);
+  copied = access_process_vm(child, pc, &opcode, sizeof(opcode), FOLL_FORCE);
   if (copied != sizeof(opcode))
     return 0;
 
index 09f8457..5ed0ea9 100644 (file)
@@ -142,7 +142,7 @@ store_virtual_to_phys(struct device *dev, struct device_attribute *attr,
        u64 virt_addr=simple_strtoull(buf, NULL, 16);
        int ret;
 
-       ret = get_user_pages(virt_addr, 1, VM_READ, 0, NULL, NULL);
+       ret = get_user_pages(virt_addr, 1, FOLL_WRITE, NULL, NULL);
        if (ret<=0) {
 #ifdef ERR_INJ_DEBUG
                printk("Virtual address %lx is not existing.\n",virt_addr);
index 6f54d51..31aa8c0 100644 (file)
@@ -453,7 +453,7 @@ ia64_peek (struct task_struct *child, struct switch_stack *child_stack,
                        return 0;
                }
        }
-       copied = access_process_vm(child, addr, &ret, sizeof(ret), 0);
+       copied = access_process_vm(child, addr, &ret, sizeof(ret), FOLL_FORCE);
        if (copied != sizeof(ret))
                return -EIO;
        *val = ret;
@@ -489,7 +489,8 @@ ia64_poke (struct task_struct *child, struct switch_stack *child_stack,
                                *ia64_rse_skip_regs(krbs, regnum) = val;
                        }
                }
-       } else if (access_process_vm(child, addr, &val, sizeof(val), 1)
+       } else if (access_process_vm(child, addr, &val, sizeof(val),
+                               FOLL_FORCE | FOLL_WRITE)
                   != sizeof(val))
                return -EIO;
        return 0;
@@ -543,7 +544,8 @@ ia64_sync_user_rbs (struct task_struct *child, struct switch_stack *sw,
                ret = ia64_peek(child, sw, user_rbs_end, addr, &val);
                if (ret < 0)
                        return ret;
-               if (access_process_vm(child, addr, &val, sizeof(val), 1)
+               if (access_process_vm(child, addr, &val, sizeof(val),
+                               FOLL_FORCE | FOLL_WRITE)
                    != sizeof(val))
                        return -EIO;
        }
@@ -559,7 +561,8 @@ ia64_sync_kernel_rbs (struct task_struct *child, struct switch_stack *sw,
 
        /* now copy word for word from user rbs to kernel rbs: */
        for (addr = user_rbs_start; addr < user_rbs_end; addr += 8) {
-               if (access_process_vm(child, addr, &val, sizeof(val), 0)
+               if (access_process_vm(child, addr, &val, sizeof(val),
+                               FOLL_FORCE)
                                != sizeof(val))
                        return -EIO;
 
@@ -1156,7 +1159,8 @@ arch_ptrace (struct task_struct *child, long request,
        case PTRACE_PEEKTEXT:
        case PTRACE_PEEKDATA:
                /* read word at location addr */
-               if (access_process_vm(child, addr, &data, sizeof(data), 0)
+               if (access_process_vm(child, addr, &data, sizeof(data),
+                               FOLL_FORCE)
                    != sizeof(data))
                        return -EIO;
                /* ensure return value is not mistaken for error code */
index 51f5e9a..c145605 100644 (file)
@@ -493,7 +493,8 @@ unregister_all_debug_traps(struct task_struct *child)
        int i;
 
        for (i = 0; i < p->nr_trap; i++)
-               access_process_vm(child, p->addr[i], &p->insn[i], sizeof(p->insn[i]), 1);
+               access_process_vm(child, p->addr[i], &p->insn[i], sizeof(p->insn[i]),
+                               FOLL_FORCE | FOLL_WRITE);
        p->nr_trap = 0;
 }
 
@@ -537,7 +538,8 @@ embed_debug_trap(struct task_struct *child, unsigned long next_pc)
        unsigned long next_insn, code;
        unsigned long addr = next_pc & ~3;
 
-       if (access_process_vm(child, addr, &next_insn, sizeof(next_insn), 0)
+       if (access_process_vm(child, addr, &next_insn, sizeof(next_insn),
+                       FOLL_FORCE)
            != sizeof(next_insn)) {
                return -1; /* error */
        }
@@ -546,7 +548,8 @@ embed_debug_trap(struct task_struct *child, unsigned long next_pc)
        if (register_debug_trap(child, next_pc, next_insn, &code)) {
                return -1; /* error */
        }
-       if (access_process_vm(child, addr, &code, sizeof(code), 1)
+       if (access_process_vm(child, addr, &code, sizeof(code),
+                       FOLL_FORCE | FOLL_WRITE)
            != sizeof(code)) {
                return -1; /* error */
        }
@@ -562,7 +565,8 @@ withdraw_debug_trap(struct pt_regs *regs)
        addr = (regs->bpc - 2) & ~3;
        regs->bpc -= 2;
        if (unregister_debug_trap(current, addr, &code)) {
-           access_process_vm(current, addr, &code, sizeof(code), 1);
+           access_process_vm(current, addr, &code, sizeof(code),
+                   FOLL_FORCE | FOLL_WRITE);
            invalidate_cache();
        }
 }
@@ -589,7 +593,8 @@ void user_enable_single_step(struct task_struct *child)
        /* Compute next pc.  */
        pc = get_stack_long(child, PT_BPC);
 
-       if (access_process_vm(child, pc&~3, &insn, sizeof(insn), 0)
+       if (access_process_vm(child, pc&~3, &insn, sizeof(insn),
+                       FOLL_FORCE)
            != sizeof(insn))
                return;
 
index 283b5a1..7e71a4e 100644 (file)
@@ -70,7 +70,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        break;
 
                copied = access_process_vm(child, (u64)addrOthers, &tmp,
-                               sizeof(tmp), 0);
+                               sizeof(tmp), FOLL_FORCE);
                if (copied != sizeof(tmp))
                        break;
                ret = put_user(tmp, (u32 __user *) (unsigned long) data);
@@ -179,7 +179,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        break;
                ret = 0;
                if (access_process_vm(child, (u64)addrOthers, &data,
-                                       sizeof(data), 1) == sizeof(data))
+                                       sizeof(data),
+                                       FOLL_FORCE | FOLL_WRITE) == sizeof(data))
                        break;
                ret = -EIO;
                break;
index 42d124f..d8c3c15 100644 (file)
@@ -287,7 +287,7 @@ slow_irqon:
        pages += nr;
 
        ret = get_user_pages_unlocked(start, (end - start) >> PAGE_SHIFT,
-                                     write, 0, pages);
+                                     pages, write ? FOLL_WRITE : 0);
 
        /* Have to be a bit careful with return values */
        if (nr > 0) {
index f52b7db..010b7b3 100644 (file)
@@ -74,7 +74,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        break;
 
                copied = access_process_vm(child, (u64)addrOthers, &tmp,
-                               sizeof(tmp), 0);
+                               sizeof(tmp), FOLL_FORCE);
                if (copied != sizeof(tmp))
                        break;
                ret = put_user(tmp, (u32 __user *)data);
@@ -179,7 +179,8 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
                        break;
                ret = 0;
                if (access_process_vm(child, (u64)addrOthers, &tmp,
-                                       sizeof(tmp), 1) == sizeof(tmp))
+                                       sizeof(tmp),
+                                       FOLL_FORCE | FOLL_WRITE) == sizeof(tmp))
                        break;
                ret = -EIO;
                break;
index adb0c34..18d4107 100644 (file)
@@ -266,7 +266,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
        /* Try to get the remaining pages with get_user_pages */
        start += nr << PAGE_SHIFT;
        pages += nr;
-       ret = get_user_pages_unlocked(start, nr_pages - nr, write, 0, pages);
+       ret = get_user_pages_unlocked(start, nr_pages - nr, pages,
+                                     write ? FOLL_WRITE : 0);
        /* Have to be a bit careful with return values */
        if (nr > 0)
                ret = (ret < 0) ? nr : ret + nr;
index 5583618..4f7314d 100644 (file)
@@ -131,7 +131,7 @@ read_tsk_long(struct task_struct *child,
 {
        int copied;
 
-       copied = access_process_vm(child, addr, res, sizeof(*res), 0);
+       copied = access_process_vm(child, addr, res, sizeof(*res), FOLL_FORCE);
 
        return copied != sizeof(*res) ? -EIO : 0;
 }
@@ -142,7 +142,7 @@ read_tsk_short(struct task_struct *child,
 {
        int copied;
 
-       copied = access_process_vm(child, addr, res, sizeof(*res), 0);
+       copied = access_process_vm(child, addr, res, sizeof(*res), FOLL_FORCE);
 
        return copied != sizeof(*res) ? -EIO : 0;
 }
@@ -153,7 +153,8 @@ write_tsk_short(struct task_struct *child,
 {
        int copied;
 
-       copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+       copied = access_process_vm(child, addr, &val, sizeof(val),
+                       FOLL_FORCE | FOLL_WRITE);
 
        return copied != sizeof(val) ? -EIO : 0;
 }
@@ -164,7 +165,8 @@ write_tsk_long(struct task_struct *child,
 {
        int copied;
 
-       copied = access_process_vm(child, addr, &val, sizeof(val), 1);
+       copied = access_process_vm(child, addr, &val, sizeof(val),
+                       FOLL_FORCE | FOLL_WRITE);
 
        return copied != sizeof(val) ? -EIO : 0;
 }
index 40fa6c8..063c298 100644 (file)
@@ -258,7 +258,8 @@ slow_irqon:
                pages += nr;
 
                ret = get_user_pages_unlocked(start,
-                       (end - start) >> PAGE_SHIFT, write, 0, pages);
+                       (end - start) >> PAGE_SHIFT, pages,
+                       write ? FOLL_WRITE : 0);
 
                /* Have to be a bit careful with return values */
                if (nr > 0) {
index 9ddc492..ac082dd 100644 (file)
@@ -127,7 +127,8 @@ static int get_from_target(struct task_struct *target, unsigned long uaddr,
                if (copy_from_user(kbuf, (void __user *) uaddr, len))
                        return -EFAULT;
        } else {
-               int len2 = access_process_vm(target, uaddr, kbuf, len, 0);
+               int len2 = access_process_vm(target, uaddr, kbuf, len,
+                               FOLL_FORCE);
                if (len2 != len)
                        return -EFAULT;
        }
@@ -141,7 +142,8 @@ static int set_to_target(struct task_struct *target, unsigned long uaddr,
                if (copy_to_user((void __user *) uaddr, kbuf, len))
                        return -EFAULT;
        } else {
-               int len2 = access_process_vm(target, uaddr, kbuf, len, 1);
+               int len2 = access_process_vm(target, uaddr, kbuf, len,
+                               FOLL_FORCE | FOLL_WRITE);
                if (len2 != len)
                        return -EFAULT;
        }
@@ -505,7 +507,8 @@ static int genregs32_get(struct task_struct *target,
                                if (access_process_vm(target,
                                                      (unsigned long)
                                                      &reg_window[pos],
-                                                     k, sizeof(*k), 0)
+                                                     k, sizeof(*k),
+                                                     FOLL_FORCE)
                                    != sizeof(*k))
                                        return -EFAULT;
                                k++;
@@ -531,12 +534,14 @@ static int genregs32_get(struct task_struct *target,
                                if (access_process_vm(target,
                                                      (unsigned long)
                                                      &reg_window[pos],
-                                                     &reg, sizeof(reg), 0)
+                                                     &reg, sizeof(reg),
+                                                     FOLL_FORCE)
                                    != sizeof(reg))
                                        return -EFAULT;
                                if (access_process_vm(target,
                                                      (unsigned long) u,
-                                                     &reg, sizeof(reg), 1)
+                                                     &reg, sizeof(reg),
+                                                     FOLL_FORCE | FOLL_WRITE)
                                    != sizeof(reg))
                                        return -EFAULT;
                                pos++;
@@ -615,7 +620,8 @@ static int genregs32_set(struct task_struct *target,
                                                      (unsigned long)
                                                      &reg_window[pos],
                                                      (void *) k,
-                                                     sizeof(*k), 1)
+                                                     sizeof(*k),
+                                                     FOLL_FORCE | FOLL_WRITE)
                                    != sizeof(*k))
                                        return -EFAULT;
                                k++;
@@ -642,13 +648,15 @@ static int genregs32_set(struct task_struct *target,
                                if (access_process_vm(target,
                                                      (unsigned long)
                                                      u,
-                                                     &reg, sizeof(reg), 0)
+                                                     &reg, sizeof(reg),
+                                                     FOLL_FORCE)
                                    != sizeof(reg))
                                        return -EFAULT;
                                if (access_process_vm(target,
                                                      (unsigned long)
                                                      &reg_window[pos],
-                                                     &reg, sizeof(reg), 1)
+                                                     &reg, sizeof(reg),
+                                                     FOLL_FORCE | FOLL_WRITE)
                                    != sizeof(reg))
                                        return -EFAULT;
                                pos++;
index 4e06750..cd0e32b 100644 (file)
@@ -238,7 +238,8 @@ slow:
                pages += nr;
 
                ret = get_user_pages_unlocked(start,
-                       (end - start) >> PAGE_SHIFT, write, 0, pages);
+                       (end - start) >> PAGE_SHIFT, pages,
+                       write ? FOLL_WRITE : 0);
 
                /* Have to be a bit careful with return values */
                if (nr > 0) {
index ff6ef7b..2b36185 100644 (file)
 380    i386    pkey_mprotect           sys_pkey_mprotect
 381    i386    pkey_alloc              sys_pkey_alloc
 382    i386    pkey_free               sys_pkey_free
-#383   i386    pkey_get                sys_pkey_get
-#384   i386    pkey_set                sys_pkey_set
index 2f024d0..e93ef0b 100644 (file)
 329    common  pkey_mprotect           sys_pkey_mprotect
 330    common  pkey_alloc              sys_pkey_alloc
 331    common  pkey_free               sys_pkey_free
-#332   common  pkey_get                sys_pkey_get
-#333   common  pkey_set                sys_pkey_set
 
 #
 # x32-specific system call numbers start at 512 to avoid cache impact
index a3a9eb8..eab0915 100644 (file)
@@ -3898,6 +3898,7 @@ __init int intel_pmu_init(void)
                break;
 
        case INTEL_FAM6_XEON_PHI_KNL:
+       case INTEL_FAM6_XEON_PHI_KNM:
                memcpy(hw_cache_event_ids,
                       slm_hw_cache_event_ids, sizeof(hw_cache_event_ids));
                memcpy(hw_cache_extra_regs,
@@ -3912,7 +3913,7 @@ __init int intel_pmu_init(void)
                x86_pmu.flags |= PMU_FL_HAS_RSP_1;
                x86_pmu.flags |= PMU_FL_NO_HT_SHARING;
 
-               pr_cont("Knights Landing events, ");
+               pr_cont("Knights Landing/Mill events, ");
                break;
 
        case INTEL_FAM6_SKYLAKE_MOBILE:
index fc6cf21..81b321a 100644 (file)
@@ -458,8 +458,8 @@ void intel_pmu_lbr_del(struct perf_event *event)
        if (!x86_pmu.lbr_nr)
                return;
 
-       if (branch_user_callstack(cpuc->br_sel) && event->ctx &&
-                                       event->ctx->task_ctx_data) {
+       if (branch_user_callstack(cpuc->br_sel) &&
+           event->ctx->task_ctx_data) {
                task_ctx = event->ctx->task_ctx_data;
                task_ctx->lbr_callstack_users--;
        }
index b0f0e83..0a535ce 100644 (file)
@@ -763,6 +763,7 @@ static const struct x86_cpu_id rapl_cpu_match[] __initconst = {
        X86_RAPL_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, hsw_rapl_init),
 
        X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL, knl_rapl_init),
+       X86_RAPL_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM, knl_rapl_init),
 
        X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE,  skl_rapl_init),
        X86_RAPL_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP, skl_rapl_init),
index d9844cc..efca268 100644 (file)
@@ -1349,6 +1349,7 @@ static const struct x86_cpu_id intel_uncore_match[] __initconst = {
        X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_X,    bdx_uncore_init),
        X86_UNCORE_MODEL_MATCH(INTEL_FAM6_BROADWELL_XEON_D, bdx_uncore_init),
        X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNL,   knl_uncore_init),
+       X86_UNCORE_MODEL_MATCH(INTEL_FAM6_XEON_PHI_KNM,   knl_uncore_init),
        X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_DESKTOP,skl_uncore_init),
        X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_MOBILE, skl_uncore_init),
        X86_UNCORE_MODEL_MATCH(INTEL_FAM6_SKYLAKE_X,      skx_uncore_init),
index 9ae5ab8..34a46dc 100644 (file)
@@ -64,5 +64,6 @@
 /* Xeon Phi */
 
 #define INTEL_FAM6_XEON_PHI_KNL                0x57 /* Knights Landing */
+#define INTEL_FAM6_XEON_PHI_KNM                0x85 /* Knights Mill */
 
 #endif /* _ASM_X86_INTEL_FAMILY_H */
index 56f4c66..78f3760 100644 (file)
@@ -88,7 +88,6 @@
 
 #define MSR_IA32_RTIT_CTL              0x00000570
 #define MSR_IA32_RTIT_STATUS           0x00000571
-#define MSR_IA32_RTIT_STATUS           0x00000571
 #define MSR_IA32_RTIT_ADDR0_A          0x00000580
 #define MSR_IA32_RTIT_ADDR0_B          0x00000581
 #define MSR_IA32_RTIT_ADDR1_A          0x00000582
index 3d33a71..a34e0d4 100644 (file)
@@ -103,8 +103,10 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem)
 ({                                                     \
        long tmp;                                       \
        struct rw_semaphore* ret;                       \
+       register void *__sp asm(_ASM_SP);               \
+                                                       \
        asm volatile("# beginning down_write\n\t"       \
-                    LOCK_PREFIX "  xadd      %1,(%3)\n\t"      \
+                    LOCK_PREFIX "  xadd      %1,(%4)\n\t"      \
                     /* adds 0xffff0001, returns the old value */ \
                     "  test " __ASM_SEL(%w1,%k1) "," __ASM_SEL(%w1,%k1) "\n\t" \
                     /* was the active mask 0 before? */\
@@ -112,7 +114,7 @@ static inline bool __down_read_trylock(struct rw_semaphore *sem)
                     "  call " slow_path "\n"           \
                     "1:\n"                             \
                     "# ending down_write"              \
-                    : "+m" (sem->count), "=d" (tmp), "=a" (ret)        \
+                    : "+m" (sem->count), "=d" (tmp), "=a" (ret), "+r" (__sp) \
                     : "a" (sem), "1" (RWSEM_ACTIVE_WRITE_BIAS) \
                     : "memory", "cc");                 \
        ret;                                            \
index b85fe5f..90e8dde 100644 (file)
@@ -350,7 +350,7 @@ int __init sanitize_e820_map(struct e820entry *biosmap, int max_nr_map,
                 * continue building up new bios map based on this
                 * information
                 */
-               if (current_type != last_type) {
+               if (current_type != last_type || current_type == E820_PRAM) {
                        if (last_type != 0)      {
                                new_bios[new_bios_entry].size =
                                        change_point[chgidx]->addr - last_addr;
index 28cee01..d9d8d16 100644 (file)
@@ -50,6 +50,7 @@
 #include <linux/kallsyms.h>
 #include <linux/ftrace.h>
 #include <linux/frame.h>
+#include <linux/kasan.h>
 
 #include <asm/text-patching.h>
 #include <asm/cacheflush.h>
@@ -1057,9 +1058,10 @@ int setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs)
         * tailcall optimization. So, to be absolutely safe
         * we also save and restore enough stack bytes to cover
         * the argument area.
+        * Use __memcpy() to avoid KASAN stack out-of-bounds reports as we copy
+        * raw stack chunk with redzones:
         */
-       memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr,
-              MIN_STACK_SIZE(addr));
+       __memcpy(kcb->jprobes_stack, (kprobe_opcode_t *)addr, MIN_STACK_SIZE(addr));
        regs->flags &= ~X86_EFLAGS_IF;
        trace_hardirqs_off();
        regs->ip = (unsigned long)(jp->entry);
@@ -1080,6 +1082,9 @@ void jprobe_return(void)
 {
        struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
 
+       /* Unpoison stack redzones in the frames we are going to jump over. */
+       kasan_unpoison_stack_above_sp_to(kcb->jprobe_saved_sp);
+
        asm volatile (
 #ifdef CONFIG_X86_64
                        "       xchg   %%rbx,%%rsp      \n"
@@ -1118,7 +1123,7 @@ int longjmp_break_handler(struct kprobe *p, struct pt_regs *regs)
                /* It's OK to start function graph tracing again */
                unpause_graph_tracing();
                *regs = kcb->jprobe_saved_regs;
-               memcpy(saved_sp, kcb->jprobes_stack, MIN_STACK_SIZE(saved_sp));
+               __memcpy(saved_sp, kcb->jprobes_stack, MIN_STACK_SIZE(saved_sp));
                preempt_enable_no_resched();
                return 1;
        }
index 68f8cc2..c00cb64 100644 (file)
@@ -261,8 +261,10 @@ static inline void __smp_reschedule_interrupt(void)
 
 __visible void smp_reschedule_interrupt(struct pt_regs *regs)
 {
+       irq_enter();
        ack_APIC_irq();
        __smp_reschedule_interrupt();
+       irq_exit();
        /*
         * KVM uses this interrupt to force a cpu out of guest mode
         */
index c9a0738..a23ce84 100644 (file)
@@ -57,7 +57,8 @@ static int is_setting_trap_flag(struct task_struct *child, struct pt_regs *regs)
        unsigned char opcode[15];
        unsigned long addr = convert_ip_to_linear(child, regs);
 
-       copied = access_process_vm(child, addr, opcode, sizeof(opcode), 0);
+       copied = access_process_vm(child, addr, opcode, sizeof(opcode),
+                       FOLL_FORCE);
        for (i = 0; i < copied; i++) {
                switch (opcode[i]) {
                /* popf and iret */
index b8b6a60..0d4fb3e 100644 (file)
@@ -435,7 +435,7 @@ slow_irqon:
 
                ret = get_user_pages_unlocked(start,
                                              (end - start) >> PAGE_SHIFT,
-                                             write, 0, pages);
+                                             pages, write ? FOLL_WRITE : 0);
 
                /* Have to be a bit careful with return values */
                if (nr > 0) {
index 8047687..e4f8009 100644 (file)
@@ -544,10 +544,9 @@ static int mpx_resolve_fault(long __user *addr, int write)
 {
        long gup_ret;
        int nr_pages = 1;
-       int force = 0;
 
-       gup_ret = get_user_pages((unsigned long)addr, nr_pages, write,
-                       force, NULL, NULL);
+       gup_ret = get_user_pages((unsigned long)addr, nr_pages,
+                       write ? FOLL_WRITE : 0, NULL, NULL);
        /*
         * get_user_pages() returns number of pages gotten.
         * 0 means we failed to fault in and get anything,
index 5766ead..60a5a5a 100644 (file)
@@ -36,7 +36,8 @@ int is_syscall(unsigned long addr)
                 * slow, but that doesn't matter, since it will be called only
                 * in case of singlestepping, if copy_from_user failed.
                 */
-               n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
+               n = access_process_vm(current, addr, &instr, sizeof(instr),
+                               FOLL_FORCE);
                if (n != sizeof(instr)) {
                        printk(KERN_ERR "is_syscall : failed to read "
                               "instruction from 0x%lx\n", addr);
index 0b5c184..e30202b 100644 (file)
@@ -212,7 +212,8 @@ int is_syscall(unsigned long addr)
                 * slow, but that doesn't matter, since it will be called only
                 * in case of singlestepping, if copy_from_user failed.
                 */
-               n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
+               n = access_process_vm(current, addr, &instr, sizeof(instr),
+                               FOLL_FORCE);
                if (n != sizeof(instr)) {
                        printk("is_syscall : failed to read instruction from "
                               "0x%lx\n", addr);
index 631c977..180f0a9 100644 (file)
@@ -566,6 +566,11 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused)
 
        lynx->registers = ioremap_nocache(pci_resource_start(dev, 0),
                                          PCILYNX_MAX_REGISTER);
+       if (lynx->registers == NULL) {
+               dev_err(&dev->dev, "Failed to map registers\n");
+               ret = -ENOMEM;
+               goto fail_deallocate_lynx;
+       }
 
        lynx->rcv_start_pcl = pci_alloc_consistent(lynx->pci_device,
                                sizeof(struct pcl), &lynx->rcv_start_pcl_bus);
@@ -578,7 +583,7 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused)
            lynx->rcv_buffer == NULL) {
                dev_err(&dev->dev, "Failed to allocate receive buffer\n");
                ret = -ENOMEM;
-               goto fail_deallocate;
+               goto fail_deallocate_buffers;
        }
        lynx->rcv_start_pcl->next       = cpu_to_le32(lynx->rcv_pcl_bus);
        lynx->rcv_pcl->next             = cpu_to_le32(PCL_NEXT_INVALID);
@@ -641,7 +646,7 @@ add_card(struct pci_dev *dev, const struct pci_device_id *unused)
                dev_err(&dev->dev,
                        "Failed to allocate shared interrupt %d\n", dev->irq);
                ret = -EIO;
-               goto fail_deallocate;
+               goto fail_deallocate_buffers;
        }
 
        lynx->misc.parent = &dev->dev;
@@ -668,7 +673,7 @@ fail_free_irq:
        reg_write(lynx, PCI_INT_ENABLE, 0);
        free_irq(lynx->pci_device->irq, lynx);
 
-fail_deallocate:
+fail_deallocate_buffers:
        if (lynx->rcv_start_pcl)
                pci_free_consistent(lynx->pci_device, sizeof(struct pcl),
                                lynx->rcv_start_pcl, lynx->rcv_start_pcl_bus);
@@ -679,6 +684,8 @@ fail_deallocate:
                pci_free_consistent(lynx->pci_device, PAGE_SIZE,
                                lynx->rcv_buffer, lynx->rcv_buffer_bus);
        iounmap(lynx->registers);
+
+fail_deallocate_lynx:
        kfree(lynx);
 
 fail_disable:
index 2e3a054..e3281d4 100644 (file)
@@ -765,7 +765,7 @@ amdgpu_connector_lvds_detect(struct drm_connector *connector, bool force)
        return ret;
 }
 
-static void amdgpu_connector_destroy(struct drm_connector *connector)
+static void amdgpu_connector_unregister(struct drm_connector *connector)
 {
        struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
 
@@ -773,6 +773,12 @@ static void amdgpu_connector_destroy(struct drm_connector *connector)
                drm_dp_aux_unregister(&amdgpu_connector->ddc_bus->aux);
                amdgpu_connector->ddc_bus->has_aux = false;
        }
+}
+
+static void amdgpu_connector_destroy(struct drm_connector *connector)
+{
+       struct amdgpu_connector *amdgpu_connector = to_amdgpu_connector(connector);
+
        amdgpu_connector_free_edid(connector);
        kfree(amdgpu_connector->con_priv);
        drm_connector_unregister(connector);
@@ -826,6 +832,7 @@ static const struct drm_connector_funcs amdgpu_connector_lvds_funcs = {
        .dpms = drm_helper_connector_dpms,
        .detect = amdgpu_connector_lvds_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
+       .early_unregister = amdgpu_connector_unregister,
        .destroy = amdgpu_connector_destroy,
        .set_property = amdgpu_connector_set_lcd_property,
 };
@@ -936,6 +943,7 @@ static const struct drm_connector_funcs amdgpu_connector_vga_funcs = {
        .dpms = drm_helper_connector_dpms,
        .detect = amdgpu_connector_vga_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
+       .early_unregister = amdgpu_connector_unregister,
        .destroy = amdgpu_connector_destroy,
        .set_property = amdgpu_connector_set_property,
 };
@@ -1203,6 +1211,7 @@ static const struct drm_connector_funcs amdgpu_connector_dvi_funcs = {
        .detect = amdgpu_connector_dvi_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = amdgpu_connector_set_property,
+       .early_unregister = amdgpu_connector_unregister,
        .destroy = amdgpu_connector_destroy,
        .force = amdgpu_connector_dvi_force,
 };
@@ -1493,6 +1502,7 @@ static const struct drm_connector_funcs amdgpu_connector_dp_funcs = {
        .detect = amdgpu_connector_dp_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = amdgpu_connector_set_property,
+       .early_unregister = amdgpu_connector_unregister,
        .destroy = amdgpu_connector_destroy,
        .force = amdgpu_connector_dvi_force,
 };
@@ -1502,6 +1512,7 @@ static const struct drm_connector_funcs amdgpu_connector_edp_funcs = {
        .detect = amdgpu_connector_dp_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = amdgpu_connector_set_lcd_property,
+       .early_unregister = amdgpu_connector_unregister,
        .destroy = amdgpu_connector_destroy,
        .force = amdgpu_connector_dvi_force,
 };
index e203e55..a5e2fcb 100644 (file)
@@ -43,6 +43,9 @@ static int amdgpu_ctx_init(struct amdgpu_device *adev, struct amdgpu_ctx *ctx)
                ctx->rings[i].sequence = 1;
                ctx->rings[i].fences = &ctx->fences[amdgpu_sched_jobs * i];
        }
+
+       ctx->reset_counter = atomic_read(&adev->gpu_reset_counter);
+
        /* create context entity for each ring */
        for (i = 0; i < adev->num_rings; i++) {
                struct amdgpu_ring *ring = adev->rings[i];
index 7dbe85d..b4f4a92 100644 (file)
@@ -1408,16 +1408,6 @@ static int amdgpu_late_init(struct amdgpu_device *adev)
        for (i = 0; i < adev->num_ip_blocks; i++) {
                if (!adev->ip_block_status[i].valid)
                        continue;
-               if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_UVD ||
-                       adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_VCE)
-                       continue;
-               /* enable clockgating to save power */
-               r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
-                                                                   AMD_CG_STATE_GATE);
-               if (r) {
-                       DRM_ERROR("set_clockgating_state(gate) of IP block <%s> failed %d\n", adev->ip_blocks[i].funcs->name, r);
-                       return r;
-               }
                if (adev->ip_blocks[i].funcs->late_init) {
                        r = adev->ip_blocks[i].funcs->late_init((void *)adev);
                        if (r) {
@@ -1426,6 +1416,18 @@ static int amdgpu_late_init(struct amdgpu_device *adev)
                        }
                        adev->ip_block_status[i].late_initialized = true;
                }
+               /* skip CG for VCE/UVD, it's handled specially */
+               if (adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_UVD &&
+                   adev->ip_blocks[i].type != AMD_IP_BLOCK_TYPE_VCE) {
+                       /* enable clockgating to save power */
+                       r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
+                                                                           AMD_CG_STATE_GATE);
+                       if (r) {
+                               DRM_ERROR("set_clockgating_state(gate) of IP block <%s> failed %d\n",
+                                         adev->ip_blocks[i].funcs->name, r);
+                               return r;
+                       }
+               }
        }
 
        return 0;
@@ -1435,6 +1437,30 @@ static int amdgpu_fini(struct amdgpu_device *adev)
 {
        int i, r;
 
+       /* need to disable SMC first */
+       for (i = 0; i < adev->num_ip_blocks; i++) {
+               if (!adev->ip_block_status[i].hw)
+                       continue;
+               if (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) {
+                       /* ungate blocks before hw fini so that we can shutdown the blocks safely */
+                       r = adev->ip_blocks[i].funcs->set_clockgating_state((void *)adev,
+                                                                           AMD_CG_STATE_UNGATE);
+                       if (r) {
+                               DRM_ERROR("set_clockgating_state(ungate) of IP block <%s> failed %d\n",
+                                         adev->ip_blocks[i].funcs->name, r);
+                               return r;
+                       }
+                       r = adev->ip_blocks[i].funcs->hw_fini((void *)adev);
+                       /* XXX handle errors */
+                       if (r) {
+                               DRM_DEBUG("hw_fini of IP block <%s> failed %d\n",
+                                         adev->ip_blocks[i].funcs->name, r);
+                       }
+                       adev->ip_block_status[i].hw = false;
+                       break;
+               }
+       }
+
        for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
                if (!adev->ip_block_status[i].hw)
                        continue;
@@ -2073,7 +2099,8 @@ static bool amdgpu_check_soft_reset(struct amdgpu_device *adev)
                if (!adev->ip_block_status[i].valid)
                        continue;
                if (adev->ip_blocks[i].funcs->check_soft_reset)
-                       adev->ip_blocks[i].funcs->check_soft_reset(adev);
+                       adev->ip_block_status[i].hang =
+                               adev->ip_blocks[i].funcs->check_soft_reset(adev);
                if (adev->ip_block_status[i].hang) {
                        DRM_INFO("IP block:%d is hang!\n", i);
                        asic_hang = true;
@@ -2102,12 +2129,20 @@ static int amdgpu_pre_soft_reset(struct amdgpu_device *adev)
 
 static bool amdgpu_need_full_reset(struct amdgpu_device *adev)
 {
-       if (adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang ||
-           adev->ip_block_status[AMD_IP_BLOCK_TYPE_SMC].hang ||
-           adev->ip_block_status[AMD_IP_BLOCK_TYPE_ACP].hang ||
-           adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang) {
-               DRM_INFO("Some block need full reset!\n");
-               return true;
+       int i;
+
+       for (i = 0; i < adev->num_ip_blocks; i++) {
+               if (!adev->ip_block_status[i].valid)
+                       continue;
+               if ((adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_GMC) ||
+                   (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_SMC) ||
+                   (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_ACP) ||
+                   (adev->ip_blocks[i].type == AMD_IP_BLOCK_TYPE_DCE)) {
+                       if (adev->ip_block_status[i].hang) {
+                               DRM_INFO("Some block need full reset!\n");
+                               return true;
+                       }
+               }
        }
        return false;
 }
index fe36caf..14f57d9 100644 (file)
@@ -113,24 +113,26 @@ void amdgpu_dpm_print_ps_status(struct amdgpu_device *adev,
        printk("\n");
 }
 
+
 u32 amdgpu_dpm_get_vblank_time(struct amdgpu_device *adev)
 {
        struct drm_device *dev = adev->ddev;
        struct drm_crtc *crtc;
        struct amdgpu_crtc *amdgpu_crtc;
-       u32 line_time_us, vblank_lines;
+       u32 vblank_in_pixels;
        u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
 
        if (adev->mode_info.num_crtc && adev->mode_info.mode_config_initialized) {
                list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                        amdgpu_crtc = to_amdgpu_crtc(crtc);
                        if (crtc->enabled && amdgpu_crtc->enabled && amdgpu_crtc->hw_mode.clock) {
-                               line_time_us = (amdgpu_crtc->hw_mode.crtc_htotal * 1000) /
-                                       amdgpu_crtc->hw_mode.clock;
-                               vblank_lines = amdgpu_crtc->hw_mode.crtc_vblank_end -
+                               vblank_in_pixels =
+                                       amdgpu_crtc->hw_mode.crtc_htotal *
+                                       (amdgpu_crtc->hw_mode.crtc_vblank_end -
                                        amdgpu_crtc->hw_mode.crtc_vdisplay +
-                                       (amdgpu_crtc->v_border * 2);
-                               vblank_time_us = vblank_lines * line_time_us;
+                                       (amdgpu_crtc->v_border * 2));
+
+                               vblank_time_us = vblank_in_pixels * 1000 / amdgpu_crtc->hw_mode.clock;
                                break;
                        }
                }
index e1fa873..3cb5e90 100644 (file)
@@ -345,8 +345,8 @@ static int amdgpu_debugfs_ring_init(struct amdgpu_device *adev,
        ent = debugfs_create_file(name,
                                  S_IFREG | S_IRUGO, root,
                                  ring, &amdgpu_debugfs_ring_fops);
-       if (IS_ERR(ent))
-               return PTR_ERR(ent);
+       if (!ent)
+               return -ENOMEM;
 
        i_size_write(ent->d_inode, ring->ring_size + 12);
        ring->ent = ent;
index 887483b..dcaf691 100644 (file)
@@ -555,10 +555,13 @@ struct amdgpu_ttm_tt {
 int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
 {
        struct amdgpu_ttm_tt *gtt = (void *)ttm;
-       int write = !(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY);
+       unsigned int flags = 0;
        unsigned pinned = 0;
        int r;
 
+       if (!(gtt->userflags & AMDGPU_GEM_USERPTR_READONLY))
+               flags |= FOLL_WRITE;
+
        if (gtt->userflags & AMDGPU_GEM_USERPTR_ANONONLY) {
                /* check that we only use anonymous memory
                   to prevent problems with writeback */
@@ -581,7 +584,7 @@ int amdgpu_ttm_tt_get_user_pages(struct ttm_tt *ttm, struct page **pages)
                list_add(&guptask.list, &gtt->guptasks);
                spin_unlock(&gtt->guptasklock);
 
-               r = get_user_pages(userptr, num_pages, write, 0, p, NULL);
+               r = get_user_pages(userptr, num_pages, flags, p, NULL);
 
                spin_lock(&gtt->guptasklock);
                list_del(&guptask.list);
index f80a083..3c082e1 100644 (file)
@@ -1514,14 +1514,16 @@ static int cz_dpm_set_powergating_state(void *handle,
        return 0;
 }
 
-/* borrowed from KV, need future unify */
 static int cz_dpm_get_temperature(struct amdgpu_device *adev)
 {
        int actual_temp = 0;
-       uint32_t temp = RREG32_SMC(0xC0300E0C);
+       uint32_t val = RREG32_SMC(ixTHM_TCON_CUR_TMP);
+       uint32_t temp = REG_GET_FIELD(val, THM_TCON_CUR_TMP, CUR_TEMP);
 
-       if (temp)
+       if (REG_GET_FIELD(val, THM_TCON_CUR_TMP, CUR_TEMP_RANGE_SEL))
                actual_temp = 1000 * ((temp / 8) - 49);
+       else
+               actual_temp = 1000 * (temp / 8);
 
        return actual_temp;
 }
index 613ebb7..4108c68 100644 (file)
@@ -3188,16 +3188,11 @@ static int dce_v10_0_wait_for_idle(void *handle)
        return 0;
 }
 
-static int dce_v10_0_check_soft_reset(void *handle)
+static bool dce_v10_0_check_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (dce_v10_0_is_display_hung(adev))
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = true;
-       else
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang = false;
-
-       return 0;
+       return dce_v10_0_is_display_hung(adev);
 }
 
 static int dce_v10_0_soft_reset(void *handle)
@@ -3205,9 +3200,6 @@ static int dce_v10_0_soft_reset(void *handle)
        u32 srbm_soft_reset = 0, tmp;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_DCE].hang)
-               return 0;
-
        if (dce_v10_0_is_display_hung(adev))
                srbm_soft_reset |= SRBM_SOFT_RESET__SOFT_RESET_DC_MASK;
 
index 6c6ff57..ee6a48a 100644 (file)
@@ -4087,14 +4087,21 @@ static int gfx_v8_0_rlc_load_microcode(struct amdgpu_device *adev)
 static int gfx_v8_0_rlc_resume(struct amdgpu_device *adev)
 {
        int r;
+       u32 tmp;
 
        gfx_v8_0_rlc_stop(adev);
 
        /* disable CG */
-       WREG32(mmRLC_CGCG_CGLS_CTRL, 0);
+       tmp = RREG32(mmRLC_CGCG_CGLS_CTRL);
+       tmp &= ~(RLC_CGCG_CGLS_CTRL__CGCG_EN_MASK |
+                RLC_CGCG_CGLS_CTRL__CGLS_EN_MASK);
+       WREG32(mmRLC_CGCG_CGLS_CTRL, tmp);
        if (adev->asic_type == CHIP_POLARIS11 ||
-           adev->asic_type == CHIP_POLARIS10)
-               WREG32(mmRLC_CGCG_CGLS_CTRL_3D, 0);
+           adev->asic_type == CHIP_POLARIS10) {
+               tmp = RREG32(mmRLC_CGCG_CGLS_CTRL_3D);
+               tmp &= ~0x3;
+               WREG32(mmRLC_CGCG_CGLS_CTRL_3D, tmp);
+       }
 
        /* disable PG */
        WREG32(mmRLC_PG_CNTL, 0);
@@ -5137,7 +5144,7 @@ static int gfx_v8_0_wait_for_idle(void *handle)
        return -ETIMEDOUT;
 }
 
-static int gfx_v8_0_check_soft_reset(void *handle)
+static bool gfx_v8_0_check_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
@@ -5189,16 +5196,14 @@ static int gfx_v8_0_check_soft_reset(void *handle)
                                                SRBM_SOFT_RESET, SOFT_RESET_SEM, 1);
 
        if (grbm_soft_reset || srbm_soft_reset) {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = true;
                adev->gfx.grbm_soft_reset = grbm_soft_reset;
                adev->gfx.srbm_soft_reset = srbm_soft_reset;
+               return true;
        } else {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang = false;
                adev->gfx.grbm_soft_reset = 0;
                adev->gfx.srbm_soft_reset = 0;
+               return false;
        }
-
-       return 0;
 }
 
 static void gfx_v8_0_inactive_hqd(struct amdgpu_device *adev,
@@ -5226,7 +5231,8 @@ static int gfx_v8_0_pre_soft_reset(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
+       if ((!adev->gfx.grbm_soft_reset) &&
+           (!adev->gfx.srbm_soft_reset))
                return 0;
 
        grbm_soft_reset = adev->gfx.grbm_soft_reset;
@@ -5264,7 +5270,8 @@ static int gfx_v8_0_soft_reset(void *handle)
        u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
        u32 tmp;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
+       if ((!adev->gfx.grbm_soft_reset) &&
+           (!adev->gfx.srbm_soft_reset))
                return 0;
 
        grbm_soft_reset = adev->gfx.grbm_soft_reset;
@@ -5334,7 +5341,8 @@ static int gfx_v8_0_post_soft_reset(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GFX].hang)
+       if ((!adev->gfx.grbm_soft_reset) &&
+           (!adev->gfx.srbm_soft_reset))
                return 0;
 
        grbm_soft_reset = adev->gfx.grbm_soft_reset;
index 1b319f5..c22ef14 100644 (file)
@@ -1099,7 +1099,7 @@ static int gmc_v8_0_wait_for_idle(void *handle)
 
 }
 
-static int gmc_v8_0_check_soft_reset(void *handle)
+static bool gmc_v8_0_check_soft_reset(void *handle)
 {
        u32 srbm_soft_reset = 0;
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
@@ -1116,20 +1116,19 @@ static int gmc_v8_0_check_soft_reset(void *handle)
                                                        SRBM_SOFT_RESET, SOFT_RESET_MC, 1);
        }
        if (srbm_soft_reset) {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = true;
                adev->mc.srbm_soft_reset = srbm_soft_reset;
+               return true;
        } else {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang = false;
                adev->mc.srbm_soft_reset = 0;
+               return false;
        }
-       return 0;
 }
 
 static int gmc_v8_0_pre_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
+       if (!adev->mc.srbm_soft_reset)
                return 0;
 
        gmc_v8_0_mc_stop(adev, &adev->mc.save);
@@ -1145,7 +1144,7 @@ static int gmc_v8_0_soft_reset(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
+       if (!adev->mc.srbm_soft_reset)
                return 0;
        srbm_soft_reset = adev->mc.srbm_soft_reset;
 
@@ -1175,7 +1174,7 @@ static int gmc_v8_0_post_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_GMC].hang)
+       if (!adev->mc.srbm_soft_reset)
                return 0;
 
        gmc_v8_0_mc_resume(adev, &adev->mc.save);
index f325fd8..a9d1094 100644 (file)
@@ -1268,7 +1268,7 @@ static int sdma_v3_0_wait_for_idle(void *handle)
        return -ETIMEDOUT;
 }
 
-static int sdma_v3_0_check_soft_reset(void *handle)
+static bool sdma_v3_0_check_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset = 0;
@@ -1281,14 +1281,12 @@ static int sdma_v3_0_check_soft_reset(void *handle)
        }
 
        if (srbm_soft_reset) {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = true;
                adev->sdma.srbm_soft_reset = srbm_soft_reset;
+               return true;
        } else {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang = false;
                adev->sdma.srbm_soft_reset = 0;
+               return false;
        }
-
-       return 0;
 }
 
 static int sdma_v3_0_pre_soft_reset(void *handle)
@@ -1296,7 +1294,7 @@ static int sdma_v3_0_pre_soft_reset(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset = 0;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang)
+       if (!adev->sdma.srbm_soft_reset)
                return 0;
 
        srbm_soft_reset = adev->sdma.srbm_soft_reset;
@@ -1315,7 +1313,7 @@ static int sdma_v3_0_post_soft_reset(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset = 0;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang)
+       if (!adev->sdma.srbm_soft_reset)
                return 0;
 
        srbm_soft_reset = adev->sdma.srbm_soft_reset;
@@ -1335,7 +1333,7 @@ static int sdma_v3_0_soft_reset(void *handle)
        u32 srbm_soft_reset = 0;
        u32 tmp;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_SDMA].hang)
+       if (!adev->sdma.srbm_soft_reset)
                return 0;
 
        srbm_soft_reset = adev->sdma.srbm_soft_reset;
index 8bd0892..3de7bca 100644 (file)
@@ -3499,6 +3499,12 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev,
                max_sclk = 75000;
                max_mclk = 80000;
        }
+       /* Limit clocks for some HD8600 parts */
+       if (adev->pdev->device == 0x6660 &&
+           adev->pdev->revision == 0x83) {
+               max_sclk = 75000;
+               max_mclk = 80000;
+       }
 
        if (rps->vce_active) {
                rps->evclk = adev->pm.dpm.vce_states[adev->pm.dpm.vce_level].evclk;
index d127d59..b4ea229 100644 (file)
@@ -373,7 +373,7 @@ static int tonga_ih_wait_for_idle(void *handle)
        return -ETIMEDOUT;
 }
 
-static int tonga_ih_check_soft_reset(void *handle)
+static bool tonga_ih_check_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset = 0;
@@ -384,21 +384,19 @@ static int tonga_ih_check_soft_reset(void *handle)
                                                SOFT_RESET_IH, 1);
 
        if (srbm_soft_reset) {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang = true;
                adev->irq.srbm_soft_reset = srbm_soft_reset;
+               return true;
        } else {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang = false;
                adev->irq.srbm_soft_reset = 0;
+               return false;
        }
-
-       return 0;
 }
 
 static int tonga_ih_pre_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang)
+       if (!adev->irq.srbm_soft_reset)
                return 0;
 
        return tonga_ih_hw_fini(adev);
@@ -408,7 +406,7 @@ static int tonga_ih_post_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang)
+       if (!adev->irq.srbm_soft_reset)
                return 0;
 
        return tonga_ih_hw_init(adev);
@@ -419,7 +417,7 @@ static int tonga_ih_soft_reset(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_IH].hang)
+       if (!adev->irq.srbm_soft_reset)
                return 0;
        srbm_soft_reset = adev->irq.srbm_soft_reset;
 
index e0fd9f2..ab3df6d 100644 (file)
@@ -770,7 +770,7 @@ static int uvd_v6_0_wait_for_idle(void *handle)
 }
 
 #define AMDGPU_UVD_STATUS_BUSY_MASK    0xfd
-static int uvd_v6_0_check_soft_reset(void *handle)
+static bool uvd_v6_0_check_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset = 0;
@@ -782,19 +782,19 @@ static int uvd_v6_0_check_soft_reset(void *handle)
                srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_UVD, 1);
 
        if (srbm_soft_reset) {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang = true;
                adev->uvd.srbm_soft_reset = srbm_soft_reset;
+               return true;
        } else {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang = false;
                adev->uvd.srbm_soft_reset = 0;
+               return false;
        }
-       return 0;
 }
+
 static int uvd_v6_0_pre_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang)
+       if (!adev->uvd.srbm_soft_reset)
                return 0;
 
        uvd_v6_0_stop(adev);
@@ -806,7 +806,7 @@ static int uvd_v6_0_soft_reset(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang)
+       if (!adev->uvd.srbm_soft_reset)
                return 0;
        srbm_soft_reset = adev->uvd.srbm_soft_reset;
 
@@ -836,7 +836,7 @@ static int uvd_v6_0_post_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_UVD].hang)
+       if (!adev->uvd.srbm_soft_reset)
                return 0;
 
        mdelay(5);
index 3f6db4e..8533269 100644 (file)
@@ -561,7 +561,7 @@ static int vce_v3_0_wait_for_idle(void *handle)
 #define  AMDGPU_VCE_STATUS_BUSY_MASK (VCE_STATUS_VCPU_REPORT_AUTO_BUSY_MASK | \
                                      VCE_STATUS_VCPU_REPORT_RB0_BUSY_MASK)
 
-static int vce_v3_0_check_soft_reset(void *handle)
+static bool vce_v3_0_check_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset = 0;
@@ -591,16 +591,15 @@ static int vce_v3_0_check_soft_reset(void *handle)
                srbm_soft_reset = REG_SET_FIELD(srbm_soft_reset, SRBM_SOFT_RESET, SOFT_RESET_VCE1, 1);
        }
        WREG32_FIELD(GRBM_GFX_INDEX, INSTANCE_INDEX, 0);
+       mutex_unlock(&adev->grbm_idx_mutex);
 
        if (srbm_soft_reset) {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang = true;
                adev->vce.srbm_soft_reset = srbm_soft_reset;
+               return true;
        } else {
-               adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang = false;
                adev->vce.srbm_soft_reset = 0;
+               return false;
        }
-       mutex_unlock(&adev->grbm_idx_mutex);
-       return 0;
 }
 
 static int vce_v3_0_soft_reset(void *handle)
@@ -608,7 +607,7 @@ static int vce_v3_0_soft_reset(void *handle)
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
        u32 srbm_soft_reset;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang)
+       if (!adev->vce.srbm_soft_reset)
                return 0;
        srbm_soft_reset = adev->vce.srbm_soft_reset;
 
@@ -638,7 +637,7 @@ static int vce_v3_0_pre_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang)
+       if (!adev->vce.srbm_soft_reset)
                return 0;
 
        mdelay(5);
@@ -651,7 +650,7 @@ static int vce_v3_0_post_soft_reset(void *handle)
 {
        struct amdgpu_device *adev = (struct amdgpu_device *)handle;
 
-       if (!adev->ip_block_status[AMD_IP_BLOCK_TYPE_VCE].hang)
+       if (!adev->vce.srbm_soft_reset)
                return 0;
 
        mdelay(5);
index c934b78..bec8125 100644 (file)
@@ -165,7 +165,7 @@ struct amd_ip_funcs {
        /* poll for idle */
        int (*wait_for_idle)(void *handle);
        /* check soft reset the IP block */
-       int (*check_soft_reset)(void *handle);
+       bool (*check_soft_reset)(void *handle);
        /* pre soft reset the IP block */
        int (*pre_soft_reset)(void *handle);
        /* soft reset the IP block */
index 92b1178..8cee4e0 100644 (file)
@@ -49,6 +49,7 @@ static const pem_event_action * const uninitialize_event[] = {
        uninitialize_display_phy_access_tasks,
        disable_gfx_voltage_island_power_gating_tasks,
        disable_gfx_clock_gating_tasks,
+       uninitialize_thermal_controller_tasks,
        set_boot_state_tasks,
        adjust_power_state_tasks,
        disable_dynamic_state_management_tasks,
index 7e4fcbb..9604249 100644 (file)
@@ -1785,6 +1785,21 @@ static int cz_get_max_high_clocks(struct pp_hwmgr *hwmgr, struct amd_pp_simple_c
        return 0;
 }
 
+static int cz_thermal_get_temperature(struct pp_hwmgr *hwmgr)
+{
+       int actual_temp = 0;
+       uint32_t val = cgs_read_ind_register(hwmgr->device,
+                                            CGS_IND_REG__SMC, ixTHM_TCON_CUR_TMP);
+       uint32_t temp = PHM_GET_FIELD(val, THM_TCON_CUR_TMP, CUR_TEMP);
+
+       if (PHM_GET_FIELD(val, THM_TCON_CUR_TMP, CUR_TEMP_RANGE_SEL))
+               actual_temp = ((temp / 8) - 49) * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+       else
+               actual_temp = (temp / 8) * PP_TEMPERATURE_UNITS_PER_CENTIGRADES;
+
+       return actual_temp;
+}
+
 static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx, int32_t *value)
 {
        struct cz_hwmgr *cz_hwmgr = (struct cz_hwmgr *)(hwmgr->backend);
@@ -1881,6 +1896,9 @@ static int cz_read_sensor(struct pp_hwmgr *hwmgr, int idx, int32_t *value)
        case AMDGPU_PP_SENSOR_VCE_POWER:
                *value = cz_hwmgr->vce_power_gated ? 0 : 1;
                return 0;
+       case AMDGPU_PP_SENSOR_GPU_TEMP:
+               *value = cz_thermal_get_temperature(hwmgr);
+               return 0;
        default:
                return -EINVAL;
        }
index 508245d..609996c 100644 (file)
@@ -1030,20 +1030,19 @@ static int smu7_disable_sclk_mclk_dpm(struct pp_hwmgr *hwmgr)
        struct smu7_hwmgr *data = (struct smu7_hwmgr *)(hwmgr->backend);
 
        /* disable SCLK dpm */
-       if (!data->sclk_dpm_key_disabled)
-               PP_ASSERT_WITH_CODE(
-                               (smum_send_msg_to_smc(hwmgr->smumgr,
-                                               PPSMC_MSG_DPM_Disable) == 0),
-                               "Failed to disable SCLK DPM!",
-                               return -EINVAL);
+       if (!data->sclk_dpm_key_disabled) {
+               PP_ASSERT_WITH_CODE(true == smum_is_dpm_running(hwmgr),
+                               "Trying to disable SCLK DPM when DPM is disabled",
+                               return 0);
+               smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_DPM_Disable);
+       }
 
        /* disable MCLK dpm */
        if (!data->mclk_dpm_key_disabled) {
-               PP_ASSERT_WITH_CODE(
-                               (smum_send_msg_to_smc(hwmgr->smumgr,
-                                               PPSMC_MSG_MCLKDPM_Disable) == 0),
-                               "Failed to disable MCLK DPM!",
-                               return -EINVAL);
+               PP_ASSERT_WITH_CODE(true == smum_is_dpm_running(hwmgr),
+                               "Trying to disable MCLK DPM when DPM is disabled",
+                               return 0);
+               smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_MCLKDPM_Disable);
        }
 
        return 0;
@@ -1069,10 +1068,13 @@ static int smu7_stop_dpm(struct pp_hwmgr *hwmgr)
                                return -EINVAL);
        }
 
-       if (smu7_disable_sclk_mclk_dpm(hwmgr)) {
-               printk(KERN_ERR "Failed to disable Sclk DPM and Mclk DPM!");
-               return -EINVAL;
-       }
+       smu7_disable_sclk_mclk_dpm(hwmgr);
+
+       PP_ASSERT_WITH_CODE(true == smum_is_dpm_running(hwmgr),
+                       "Trying to disable voltage DPM when DPM is disabled",
+                       return 0);
+
+       smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_Voltage_Cntl_Disable);
 
        return 0;
 }
@@ -1226,7 +1228,7 @@ int smu7_enable_dpm_tasks(struct pp_hwmgr *hwmgr)
        PP_ASSERT_WITH_CODE((0 == tmp_result),
                        "Failed to enable VR hot GPIO interrupt!", result = tmp_result);
 
-       smum_send_msg_to_smc(hwmgr->smumgr, (PPSMC_Msg)PPSMC_HasDisplay);
+       smum_send_msg_to_smc(hwmgr->smumgr, (PPSMC_Msg)PPSMC_NoDisplay);
 
        tmp_result = smu7_enable_sclk_control(hwmgr);
        PP_ASSERT_WITH_CODE((0 == tmp_result),
@@ -1306,6 +1308,12 @@ int smu7_disable_dpm_tasks(struct pp_hwmgr *hwmgr)
        PP_ASSERT_WITH_CODE((tmp_result == 0),
                        "Failed to disable thermal auto throttle!", result = tmp_result);
 
+       if (1 == PHM_READ_VFPF_INDIRECT_FIELD(hwmgr->device, CGS_IND_REG__SMC, FEATURE_STATUS, AVS_ON)) {
+               PP_ASSERT_WITH_CODE((0 == smum_send_msg_to_smc(hwmgr->smumgr, PPSMC_MSG_DisableAvfs)),
+                                       "Failed to disable AVFS!",
+                                       return -EINVAL);
+       }
+
        tmp_result = smu7_stop_dpm(hwmgr);
        PP_ASSERT_WITH_CODE((tmp_result == 0),
                        "Failed to stop DPM!", result = tmp_result);
@@ -1452,8 +1460,10 @@ static int smu7_get_evv_voltages(struct pp_hwmgr *hwmgr)
        struct phm_ppt_v1_clock_voltage_dependency_table *sclk_table = NULL;
 
 
-       if (table_info != NULL)
-               sclk_table = table_info->vdd_dep_on_sclk;
+       if (table_info == NULL)
+               return -EINVAL;
+
+       sclk_table = table_info->vdd_dep_on_sclk;
 
        for (i = 0; i < SMU7_MAX_LEAKAGE_COUNT; i++) {
                vv_id = ATOM_VIRTUAL_VOLTAGE_ID0 + i;
@@ -3802,13 +3812,15 @@ static inline bool smu7_are_power_levels_equal(const struct smu7_performance_lev
 
 int smu7_check_states_equal(struct pp_hwmgr *hwmgr, const struct pp_hw_power_state *pstate1, const struct pp_hw_power_state *pstate2, bool *equal)
 {
-       const struct smu7_power_state *psa = cast_const_phw_smu7_power_state(pstate1);
-       const struct smu7_power_state *psb = cast_const_phw_smu7_power_state(pstate2);
+       const struct smu7_power_state *psa;
+       const struct smu7_power_state *psb;
        int i;
 
        if (pstate1 == NULL || pstate2 == NULL || equal == NULL)
                return -EINVAL;
 
+       psa = cast_const_phw_smu7_power_state(pstate1);
+       psb = cast_const_phw_smu7_power_state(pstate2);
        /* If the two states don't even have the same number of performance levels they cannot be the same state. */
        if (psa->performance_level_count != psb->performance_level_count) {
                *equal = false;
@@ -4324,6 +4336,7 @@ static const struct pp_hwmgr_func smu7_hwmgr_funcs = {
        .set_mclk_od = smu7_set_mclk_od,
        .get_clock_by_type = smu7_get_clock_by_type,
        .read_sensor = smu7_read_sensor,
+       .dynamic_state_management_disable = smu7_disable_dpm_tasks,
 };
 
 uint8_t smu7_get_sleep_divider_id_from_clock(uint32_t clock,
index eda802b..8c889ca 100644 (file)
@@ -2458,7 +2458,7 @@ static int iceland_set_mc_special_registers(struct pp_hwmgr *hwmgr,
                        PP_ASSERT_WITH_CODE((j <= SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE),
                                "Invalid VramInfo table.", return -EINVAL);
 
-                       if (!data->is_memory_gddr5) {
+                       if (!data->is_memory_gddr5 && j < SMU71_DISCRETE_MC_REGISTER_ARRAY_SIZE) {
                                table->mc_reg_address[j].s1 = mmMC_PMG_AUTO_CMD;
                                table->mc_reg_address[j].s0 = mmMC_PMG_AUTO_CMD;
                                for (k = 0; k < table->num_entries; k++) {
index 1df2d33..ffb2ab3 100644 (file)
@@ -54,9 +54,6 @@ int drm_name_info(struct seq_file *m, void *data)
 
        mutex_lock(&dev->master_mutex);
        master = dev->master;
-       if (!master)
-               goto out_unlock;
-
        seq_printf(m, "%s", dev->driver->name);
        if (dev->dev)
                seq_printf(m, " dev=%s", dev_name(dev->dev));
@@ -65,7 +62,6 @@ int drm_name_info(struct seq_file *m, void *data)
        if (dev->unique)
                seq_printf(m, " unique=%s", dev->unique);
        seq_printf(m, "\n");
-out_unlock:
        mutex_unlock(&dev->master_mutex);
 
        return 0;
index 5ce3603..0370b84 100644 (file)
@@ -748,19 +748,22 @@ static struct page **etnaviv_gem_userptr_do_get_pages(
        int ret = 0, pinned, npages = etnaviv_obj->base.size >> PAGE_SHIFT;
        struct page **pvec;
        uintptr_t ptr;
+       unsigned int flags = 0;
 
        pvec = drm_malloc_ab(npages, sizeof(struct page *));
        if (!pvec)
                return ERR_PTR(-ENOMEM);
 
+       if (!etnaviv_obj->userptr.ro)
+               flags |= FOLL_WRITE;
+
        pinned = 0;
        ptr = etnaviv_obj->userptr.ptr;
 
        down_read(&mm->mmap_sem);
        while (pinned < npages) {
                ret = get_user_pages_remote(task, mm, ptr, npages - pinned,
-                                           !etnaviv_obj->userptr.ro, 0,
-                                           pvec + pinned, NULL);
+                                           flags, pvec + pinned, NULL);
                if (ret < 0)
                        break;
 
index aa92dec..fbd13fa 100644 (file)
@@ -488,7 +488,8 @@ static dma_addr_t *g2d_userptr_get_dma_addr(struct drm_device *drm_dev,
                goto err_free;
        }
 
-       ret = get_vaddr_frames(start, npages, true, true, g2d_userptr->vec);
+       ret = get_vaddr_frames(start, npages, FOLL_FORCE | FOLL_WRITE,
+               g2d_userptr->vec);
        if (ret != npages) {
                DRM_ERROR("failed to get user pages from userptr.\n");
                if (ret < 0)
index e537930..c6f780f 100644 (file)
@@ -508,6 +508,10 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
        pvec = drm_malloc_gfp(npages, sizeof(struct page *), GFP_TEMPORARY);
        if (pvec != NULL) {
                struct mm_struct *mm = obj->userptr.mm->mm;
+               unsigned int flags = 0;
+
+               if (!obj->userptr.read_only)
+                       flags |= FOLL_WRITE;
 
                ret = -EFAULT;
                if (atomic_inc_not_zero(&mm->mm_users)) {
@@ -517,7 +521,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work)
                                        (work->task, mm,
                                         obj->userptr.ptr + pinned * PAGE_SIZE,
                                         npages - pinned,
-                                        !obj->userptr.read_only, 0,
+                                        flags,
                                         pvec + pinned, NULL);
                                if (ret < 0)
                                        break;
index 6a4b020..5a26eb4 100644 (file)
@@ -156,19 +156,20 @@ u32 r600_dpm_get_vblank_time(struct radeon_device *rdev)
        struct drm_device *dev = rdev->ddev;
        struct drm_crtc *crtc;
        struct radeon_crtc *radeon_crtc;
-       u32 line_time_us, vblank_lines;
+       u32 vblank_in_pixels;
        u32 vblank_time_us = 0xffffffff; /* if the displays are off, vblank time is max */
 
        if (rdev->num_crtc && rdev->mode_info.mode_config_initialized) {
                list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                        radeon_crtc = to_radeon_crtc(crtc);
                        if (crtc->enabled && radeon_crtc->enabled && radeon_crtc->hw_mode.clock) {
-                               line_time_us = (radeon_crtc->hw_mode.crtc_htotal * 1000) /
-                                       radeon_crtc->hw_mode.clock;
-                               vblank_lines = radeon_crtc->hw_mode.crtc_vblank_end -
-                                       radeon_crtc->hw_mode.crtc_vdisplay +
-                                       (radeon_crtc->v_border * 2);
-                               vblank_time_us = vblank_lines * line_time_us;
+                               vblank_in_pixels =
+                                       radeon_crtc->hw_mode.crtc_htotal *
+                                       (radeon_crtc->hw_mode.crtc_vblank_end -
+                                        radeon_crtc->hw_mode.crtc_vdisplay +
+                                        (radeon_crtc->v_border * 2));
+
+                               vblank_time_us = vblank_in_pixels * 1000 / radeon_crtc->hw_mode.clock;
                                break;
                        }
                }
index 50e96d2..e18839d 100644 (file)
@@ -927,6 +927,16 @@ radeon_lvds_detect(struct drm_connector *connector, bool force)
        return ret;
 }
 
+static void radeon_connector_unregister(struct drm_connector *connector)
+{
+       struct radeon_connector *radeon_connector = to_radeon_connector(connector);
+
+       if (radeon_connector->ddc_bus->has_aux) {
+               drm_dp_aux_unregister(&radeon_connector->ddc_bus->aux);
+               radeon_connector->ddc_bus->has_aux = false;
+       }
+}
+
 static void radeon_connector_destroy(struct drm_connector *connector)
 {
        struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -984,6 +994,7 @@ static const struct drm_connector_funcs radeon_lvds_connector_funcs = {
        .dpms = drm_helper_connector_dpms,
        .detect = radeon_lvds_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
+       .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .set_property = radeon_lvds_set_property,
 };
@@ -1111,6 +1122,7 @@ static const struct drm_connector_funcs radeon_vga_connector_funcs = {
        .dpms = drm_helper_connector_dpms,
        .detect = radeon_vga_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
+       .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .set_property = radeon_connector_set_property,
 };
@@ -1188,6 +1200,7 @@ static const struct drm_connector_funcs radeon_tv_connector_funcs = {
        .dpms = drm_helper_connector_dpms,
        .detect = radeon_tv_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
+       .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .set_property = radeon_connector_set_property,
 };
@@ -1519,6 +1532,7 @@ static const struct drm_connector_funcs radeon_dvi_connector_funcs = {
        .detect = radeon_dvi_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = radeon_connector_set_property,
+       .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .force = radeon_dvi_force,
 };
@@ -1832,6 +1846,7 @@ static const struct drm_connector_funcs radeon_dp_connector_funcs = {
        .detect = radeon_dp_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = radeon_connector_set_property,
+       .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .force = radeon_dvi_force,
 };
@@ -1841,6 +1856,7 @@ static const struct drm_connector_funcs radeon_edp_connector_funcs = {
        .detect = radeon_dp_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = radeon_lvds_set_property,
+       .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .force = radeon_dvi_force,
 };
@@ -1850,6 +1866,7 @@ static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = {
        .detect = radeon_dp_detect,
        .fill_modes = drm_helper_probe_single_connector_modes,
        .set_property = radeon_lvds_set_property,
+       .early_unregister = radeon_connector_unregister,
        .destroy = radeon_connector_destroy,
        .force = radeon_dvi_force,
 };
index b8ab30a..cdb8cb5 100644 (file)
@@ -1675,20 +1675,20 @@ int radeon_modeset_init(struct radeon_device *rdev)
 
 void radeon_modeset_fini(struct radeon_device *rdev)
 {
-       radeon_fbdev_fini(rdev);
-       kfree(rdev->mode_info.bios_hardcoded_edid);
-
-       /* free i2c buses */
-       radeon_i2c_fini(rdev);
-
        if (rdev->mode_info.mode_config_initialized) {
-               radeon_afmt_fini(rdev);
                drm_kms_helper_poll_fini(rdev->ddev);
                radeon_hpd_fini(rdev);
                drm_crtc_force_disable_all(rdev->ddev);
+               radeon_fbdev_fini(rdev);
+               radeon_afmt_fini(rdev);
                drm_mode_config_cleanup(rdev->ddev);
                rdev->mode_info.mode_config_initialized = false;
        }
+
+       kfree(rdev->mode_info.bios_hardcoded_edid);
+
+       /* free i2c buses */
+       radeon_i2c_fini(rdev);
 }
 
 static bool is_hdtv_mode(const struct drm_display_mode *mode)
index 91c8f43..00ea000 100644 (file)
  *   2.45.0 - Allow setting shader registers using DMA/COPY packet3 on SI
  *   2.46.0 - Add PFP_SYNC_ME support on evergreen
  *   2.47.0 - Add UVD_NO_OP register support
+ *   2.48.0 - TA_CS_BC_BASE_ADDR allowed on SI
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       47
+#define KMS_DRIVER_MINOR       48
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);
index 021aa00..29f7817 100644 (file)
@@ -982,9 +982,8 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
 {
        if (!i2c)
                return;
+       WARN_ON(i2c->has_aux);
        i2c_del_adapter(&i2c->adapter);
-       if (i2c->has_aux)
-               drm_dp_aux_unregister(&i2c->aux);
        kfree(i2c);
 }
 
index 4552682..3de5e6e 100644 (file)
@@ -566,7 +566,8 @@ static int radeon_ttm_tt_pin_userptr(struct ttm_tt *ttm)
                uint64_t userptr = gtt->userptr + pinned * PAGE_SIZE;
                struct page **pages = ttm->pages + pinned;
 
-               r = get_user_pages(userptr, num_pages, write, 0, pages, NULL);
+               r = get_user_pages(userptr, num_pages, write ? FOLL_WRITE : 0,
+                                  pages, NULL);
                if (r < 0)
                        goto release_pages;
 
index 7ee9aaf..e402be8 100644 (file)
@@ -4431,6 +4431,7 @@ static bool si_vm_reg_valid(u32 reg)
        case SPI_CONFIG_CNTL:
        case SPI_CONFIG_CNTL_1:
        case TA_CNTL_AUX:
+       case TA_CS_BC_BASE_ADDR:
                return true;
        default:
                DRM_ERROR("Invalid register 0x%x in CS\n", reg);
index eb220ee..65a911d 100644 (file)
 #define        SPI_LB_CU_MASK                                  0x9354
 
 #define        TA_CNTL_AUX                                     0x9508
+#define        TA_CS_BC_BASE_ADDR                              0x950C
 
 #define CC_RB_BACKEND_DISABLE                          0x98F4
 #define                BACKEND_DISABLE(x)                      ((x) << 16)
index 7e2a12c..1a3ad76 100644 (file)
@@ -241,8 +241,8 @@ via_lock_all_dma_pages(drm_via_sg_info_t *vsg,  drm_via_dmablit_t *xfer)
        down_read(&current->mm->mmap_sem);
        ret = get_user_pages((unsigned long)xfer->mem_addr,
                             vsg->num_pages,
-                            (vsg->direction == DMA_FROM_DEVICE),
-                            0, vsg->pages, NULL);
+                            (vsg->direction == DMA_FROM_DEVICE) ? FOLL_WRITE : 0,
+                            vsg->pages, NULL);
 
        up_read(&current->mm->mmap_sem);
        if (ret != vsg->num_pages) {
index c68746c..224ad27 100644 (file)
@@ -94,6 +94,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
        unsigned long dma_attrs = 0;
        struct scatterlist *sg, *sg_list_start;
        int need_release = 0;
+       unsigned int gup_flags = FOLL_WRITE;
 
        if (dmasync)
                dma_attrs |= DMA_ATTR_WRITE_BARRIER;
@@ -183,6 +184,9 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
        if (ret)
                goto out;
 
+       if (!umem->writable)
+               gup_flags |= FOLL_FORCE;
+
        need_release = 1;
        sg_list_start = umem->sg_head.sgl;
 
@@ -190,7 +194,7 @@ struct ib_umem *ib_umem_get(struct ib_ucontext *context, unsigned long addr,
                ret = get_user_pages(cur_base,
                                     min_t(unsigned long, npages,
                                           PAGE_SIZE / sizeof (struct page *)),
-                                    1, !umem->writable, page_list, vma_list);
+                                    gup_flags, page_list, vma_list);
 
                if (ret < 0)
                        goto out;
index 75077a0..1f0fe32 100644 (file)
@@ -527,6 +527,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
        u64 off;
        int j, k, ret = 0, start_idx, npages = 0;
        u64 base_virt_addr;
+       unsigned int flags = 0;
 
        if (access_mask == 0)
                return -EINVAL;
@@ -556,6 +557,9 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
                goto out_put_task;
        }
 
+       if (access_mask & ODP_WRITE_ALLOWED_BIT)
+               flags |= FOLL_WRITE;
+
        start_idx = (user_virt - ib_umem_start(umem)) >> PAGE_SHIFT;
        k = start_idx;
 
@@ -574,8 +578,7 @@ int ib_umem_odp_map_dma_pages(struct ib_umem *umem, u64 user_virt, u64 bcnt,
                 */
                npages = get_user_pages_remote(owning_process, owning_mm,
                                user_virt, gup_num_pages,
-                               access_mask & ODP_WRITE_ALLOWED_BIT,
-                               0, local_page_list, NULL);
+                               flags, local_page_list, NULL);
                up_read(&owning_mm->mmap_sem);
 
                if (npages < 0)
index 6c00d04..c6fe89d 100644 (file)
@@ -472,7 +472,7 @@ int mthca_map_user_db(struct mthca_dev *dev, struct mthca_uar *uar,
                goto out;
        }
 
-       ret = get_user_pages(uaddr & PAGE_MASK, 1, 1, 0, pages, NULL);
+       ret = get_user_pages(uaddr & PAGE_MASK, 1, FOLL_WRITE, pages, NULL);
        if (ret < 0)
                goto out;
 
index 2d2b94f..75f0862 100644 (file)
@@ -67,7 +67,8 @@ static int __qib_get_user_pages(unsigned long start_page, size_t num_pages,
 
        for (got = 0; got < num_pages; got += ret) {
                ret = get_user_pages(start_page + got * PAGE_SIZE,
-                                    num_pages - got, 1, 1,
+                                    num_pages - got,
+                                    FOLL_WRITE | FOLL_FORCE,
                                     p + got, NULL);
                if (ret < 0)
                        goto bail_release;
index a0b6ebe..1ccee6e 100644 (file)
@@ -111,6 +111,7 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
        int i;
        int flags;
        dma_addr_t pa;
+       unsigned int gup_flags;
 
        if (!can_do_mlock())
                return -EPERM;
@@ -135,6 +136,8 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
 
        flags = IOMMU_READ | IOMMU_CACHE;
        flags |= (writable) ? IOMMU_WRITE : 0;
+       gup_flags = FOLL_WRITE;
+       gup_flags |= (writable) ? 0 : FOLL_FORCE;
        cur_base = addr & PAGE_MASK;
        ret = 0;
 
@@ -142,7 +145,7 @@ static int usnic_uiom_get_pages(unsigned long addr, size_t size, int writable,
                ret = get_user_pages(cur_base,
                                        min_t(unsigned long, npages,
                                        PAGE_SIZE / sizeof(struct page *)),
-                                       1, !writable, page_list, NULL);
+                                       gup_flags, page_list, NULL);
 
                if (ret < 0)
                        goto out;
index efbf0e4..ebc2b0b 100644 (file)
@@ -85,7 +85,7 @@ static void nps400_irq_eoi_global(struct irq_data *irqd)
        nps_ack_gic();
 }
 
-static void nps400_irq_eoi(struct irq_data *irqd)
+static void nps400_irq_ack(struct irq_data *irqd)
 {
        unsigned int __maybe_unused irq = irqd_to_hwirq(irqd);
 
@@ -103,7 +103,7 @@ static struct irq_chip nps400_irq_chip_percpu = {
        .name           = "NPS400 IC",
        .irq_mask       = nps400_irq_mask,
        .irq_unmask     = nps400_irq_unmask,
-       .irq_eoi        = nps400_irq_eoi,
+       .irq_ack        = nps400_irq_ack,
 };
 
 static int nps400_irq_map(struct irq_domain *d, unsigned int virq,
index 9b81bd8..19d642e 100644 (file)
@@ -153,7 +153,7 @@ static void gic_enable_redist(bool enable)
                        return; /* No PM support in this redistributor */
        }
 
-       while (count--) {
+       while (--count) {
                val = readl_relaxed(rbase + GICR_WAKER);
                if (enable ^ (bool)(val & GICR_WAKER_ChildrenAsleep))
                        break;
index 84b01de..033bccb 100644 (file)
 
 static struct irq_chip jcore_aic;
 
+/*
+ * The J-Core AIC1 and AIC2 are cpu-local interrupt controllers and do
+ * not distinguish or use distinct irq number ranges for per-cpu event
+ * interrupts (timer, IPI). Since information to determine whether a
+ * particular irq number should be treated as per-cpu is not available
+ * at mapping time, we use a wrapper handler function which chooses
+ * the right handler at runtime based on whether IRQF_PERCPU was used
+ * when requesting the irq.
+ */
+
+static void handle_jcore_irq(struct irq_desc *desc)
+{
+       if (irqd_is_per_cpu(irq_desc_get_irq_data(desc)))
+               handle_percpu_irq(desc);
+       else
+               handle_simple_irq(desc);
+}
+
 static int jcore_aic_irqdomain_map(struct irq_domain *d, unsigned int irq,
                                   irq_hw_number_t hwirq)
 {
        struct irq_chip *aic = d->host_data;
 
-       irq_set_chip_and_handler(irq, aic, handle_simple_irq);
+       irq_set_chip_and_handler(irq, aic, handle_jcore_irq);
 
        return 0;
 }
index 4769469..2c9232e 100644 (file)
@@ -124,8 +124,8 @@ int ivtv_udma_setup(struct ivtv *itv, unsigned long ivtv_dest_addr,
        }
 
        /* Get user pages for DMA Xfer */
-       err = get_user_pages_unlocked(user_dma.uaddr, user_dma.page_count, 0,
-                       1, dma->map);
+       err = get_user_pages_unlocked(user_dma.uaddr, user_dma.page_count,
+                       dma->map, FOLL_FORCE);
 
        if (user_dma.page_count != err) {
                IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n",
index b094054..f7299d3 100644 (file)
@@ -76,11 +76,12 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
 
        /* Get user pages for DMA Xfer */
        y_pages = get_user_pages_unlocked(y_dma.uaddr,
-                       y_dma.page_count, 0, 1, &dma->map[0]);
+                       y_dma.page_count, &dma->map[0], FOLL_FORCE);
        uv_pages = 0; /* silence gcc. value is set and consumed only if: */
        if (y_pages == y_dma.page_count) {
                uv_pages = get_user_pages_unlocked(uv_dma.uaddr,
-                               uv_dma.page_count, 0, 1, &dma->map[y_pages]);
+                               uv_dma.page_count, &dma->map[y_pages],
+                               FOLL_FORCE);
        }
 
        if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
index e668dde..a31b95c 100644 (file)
@@ -214,7 +214,7 @@ static int omap_vout_get_userptr(struct videobuf_buffer *vb, u32 virtp,
        if (!vec)
                return -ENOMEM;
 
-       ret = get_vaddr_frames(virtp, 1, true, false, vec);
+       ret = get_vaddr_frames(virtp, 1, FOLL_WRITE, vec);
        if (ret != 1) {
                frame_vector_destroy(vec);
                return -EINVAL;
index f300f06..1db0af6 100644 (file)
@@ -156,6 +156,7 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
 {
        unsigned long first, last;
        int err, rw = 0;
+       unsigned int flags = FOLL_FORCE;
 
        dma->direction = direction;
        switch (dma->direction) {
@@ -178,12 +179,14 @@ static int videobuf_dma_init_user_locked(struct videobuf_dmabuf *dma,
        if (NULL == dma->pages)
                return -ENOMEM;
 
+       if (rw == READ)
+               flags |= FOLL_WRITE;
+
        dprintk(1, "init user [0x%lx+0x%lx => %d pages]\n",
                data, size, dma->nr_pages);
 
        err = get_user_pages(data & PAGE_MASK, dma->nr_pages,
-                            rw == READ, 1, /* force */
-                            dma->pages, NULL);
+                            flags, dma->pages, NULL);
 
        if (err != dma->nr_pages) {
                dma->nr_pages = (err >= 0) ? err : 0;
index 3c3b517..1cd322e 100644 (file)
@@ -42,6 +42,10 @@ struct frame_vector *vb2_create_framevec(unsigned long start,
        unsigned long first, last;
        unsigned long nr;
        struct frame_vector *vec;
+       unsigned int flags = FOLL_FORCE;
+
+       if (write)
+               flags |= FOLL_WRITE;
 
        first = start >> PAGE_SHIFT;
        last = (start + length - 1) >> PAGE_SHIFT;
@@ -49,7 +53,7 @@ struct frame_vector *vb2_create_framevec(unsigned long start,
        vec = frame_vector_create(nr);
        if (!vec)
                return ERR_PTR(-ENOMEM);
-       ret = get_vaddr_frames(start & PAGE_MASK, nr, write, true, vec);
+       ret = get_vaddr_frames(start & PAGE_MASK, nr, flags, vec);
        if (ret < 0)
                goto out_destroy;
        /* We accept only complete set of PFNs */
index e0203b1..f806a44 100644 (file)
@@ -1396,8 +1396,7 @@ retry:
                pinned_pages->nr_pages = get_user_pages(
                                (u64)addr,
                                nr_pages,
-                               !!(prot & SCIF_PROT_WRITE),
-                               0,
+                               (prot & SCIF_PROT_WRITE) ? FOLL_WRITE : 0,
                                pinned_pages->pages,
                                NULL);
                up_write(&mm->mmap_sem);
index a2d97b9..6fb773d 100644 (file)
@@ -198,7 +198,7 @@ static int non_atomic_pte_lookup(struct vm_area_struct *vma,
 #else
        *pageshift = PAGE_SHIFT;
 #endif
-       if (get_user_pages(vaddr, 1, write, 0, &page, NULL) <= 0)
+       if (get_user_pages(vaddr, 1, write ? FOLL_WRITE : 0, &page, NULL) <= 0)
                return -EFAULT;
        *paddr = page_to_phys(page);
        put_page(page);
index 07462d7..1aba2c7 100644 (file)
@@ -309,7 +309,8 @@ static ssize_t goldfish_pipe_read_write(struct file *filp, char __user *buffer,
                 * much memory to the process.
                 */
                down_read(&current->mm->mmap_sem);
-               ret = get_user_pages(address, 1, !is_write, 0, &page, NULL);
+               ret = get_user_pages(address, 1, is_write ? 0 : FOLL_WRITE,
+                               &page, NULL);
                up_read(&current->mm->mmap_sem);
                if (ret < 0)
                        break;
index 436dfe8..9013a58 100644 (file)
@@ -892,7 +892,8 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode,
                down_read(&current->mm->mmap_sem);
                pinned = get_user_pages(
                                (unsigned long)xfer->loc_addr & PAGE_MASK,
-                               nr_pages, dir == DMA_FROM_DEVICE, 0,
+                               nr_pages,
+                               dir == DMA_FROM_DEVICE ? FOLL_WRITE : 0,
                                page_list, NULL);
                up_read(&current->mm->mmap_sem);
 
index 7af5226..618422e 100644 (file)
@@ -4922,9 +4922,8 @@ static int sgl_map_user_pages(struct st_buffer *STbp,
        res = get_user_pages_unlocked(
                uaddr,
                nr_pages,
-               rw == READ,
-               0, /* don't force */
-               pages);
+               pages,
+               rw == READ ? FOLL_WRITE : 0); /* don't force */
 
        /* Errors and no page mapped should return here */
        if (res < nr_pages)
index c29040f..1091b9f 100644 (file)
@@ -423,8 +423,7 @@ create_pagelist(char __user *buf, size_t count, unsigned short type,
                actual_pages = get_user_pages(task, task->mm,
                                          (unsigned long)buf & ~(PAGE_SIZE - 1),
                                          num_pages,
-                                         (type == PAGELIST_READ) /*Write */ ,
-                                         0 /*Force */ ,
+                                         (type == PAGELIST_READ) ? FOLL_WRITE : 0,
                                          pages,
                                          NULL /*vmas */);
                up_read(&task->mm->mmap_sem);
index e11c0e0..7b6cd4d 100644 (file)
@@ -1477,8 +1477,7 @@ dump_phys_mem(void *virt_addr, uint32_t num_bytes)
                current->mm,              /* mm */
                (unsigned long)virt_addr, /* start */
                num_pages,                /* len */
-               0,                        /* write */
-               0,                        /* force */
+               0,                        /* gup_flags */
                pages,                    /* pages (array of page pointers) */
                NULL);                    /* vmas */
        up_read(&current->mm->mmap_sem);
index 3b1ca44..a2564ab 100644 (file)
@@ -686,8 +686,8 @@ static ssize_t pvr2fb_write(struct fb_info *info, const char *buf,
        if (!pages)
                return -ENOMEM;
 
-       ret = get_user_pages_unlocked((unsigned long)buf, nr_pages, WRITE,
-                       0, pages);
+       ret = get_user_pages_unlocked((unsigned long)buf, nr_pages, pages,
+                       FOLL_WRITE);
 
        if (ret < nr_pages) {
                nr_pages = ret;
index 60bdad3..150ce2a 100644 (file)
@@ -245,8 +245,8 @@ static long ioctl_memcpy(struct fsl_hv_ioctl_memcpy __user *p)
        /* Get the physical addresses of the source buffer */
        down_read(&current->mm->mmap_sem);
        num_pinned = get_user_pages(param.local_vaddr - lb_offset,
-               num_pages, (param.source == -1) ? READ : WRITE,
-               0, pages, NULL);
+               num_pages, (param.source == -1) ? 0 : FOLL_WRITE,
+               pages, NULL);
        up_read(&current->mm->mmap_sem);
 
        if (num_pinned != num_pages) {
index ccc70d9..d4d8b7e 100644 (file)
@@ -698,7 +698,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 
                        ret = btrfs_map_bio(root, comp_bio, mirror_num, 0);
                        if (ret) {
-                               bio->bi_error = ret;
+                               comp_bio->bi_error = ret;
                                bio_endio(comp_bio);
                        }
 
@@ -728,7 +728,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
 
        ret = btrfs_map_bio(root, comp_bio, mirror_num, 0);
        if (ret) {
-               bio->bi_error = ret;
+               comp_bio->bi_error = ret;
                bio_endio(comp_bio);
        }
 
index 6fcfb3f..4e497b9 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -191,6 +191,7 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
 {
        struct page *page;
        int ret;
+       unsigned int gup_flags = FOLL_FORCE;
 
 #ifdef CONFIG_STACK_GROWSUP
        if (write) {
@@ -199,12 +200,16 @@ static struct page *get_arg_page(struct linux_binprm *bprm, unsigned long pos,
                        return NULL;
        }
 #endif
+
+       if (write)
+               gup_flags |= FOLL_WRITE;
+
        /*
         * We are doing an exec().  'current' is the process
         * doing the exec and bprm->mm is the new process's mm.
         */
-       ret = get_user_pages_remote(current, bprm->mm, pos, 1, write,
-                       1, &page, NULL);
+       ret = get_user_pages_remote(current, bprm->mm, pos, 1, gup_flags,
+                       &page, NULL);
        if (ret <= 0)
                return NULL;
 
index 93985c6..6f14ee9 100644 (file)
@@ -852,16 +852,16 @@ static int do_garbage_collect(struct f2fs_sb_info *sbi,
 
        for (segno = start_segno; segno < end_segno; segno++) {
 
-               if (get_valid_blocks(sbi, segno, 1) == 0 ||
-                                       unlikely(f2fs_cp_error(sbi)))
-                       goto next;
-
                /* find segment summary of victim */
                sum_page = find_get_page(META_MAPPING(sbi),
                                        GET_SUM_BLOCK(sbi, segno));
-               f2fs_bug_on(sbi, !PageUptodate(sum_page));
                f2fs_put_page(sum_page, 0);
 
+               if (get_valid_blocks(sbi, segno, 1) == 0 ||
+                               !PageUptodate(sum_page) ||
+                               unlikely(f2fs_cp_error(sbi)))
+                       goto next;
+
                sum = page_address(sum_page);
                f2fs_bug_on(sbi, type != GET_SUM_TYPE((&sum->footer)));
 
index ce93b41..22c5b4a 100644 (file)
@@ -1609,6 +1609,7 @@ int fcntl_getlease(struct file *filp)
 
        ctx = smp_load_acquire(&inode->i_flctx);
        if (ctx && !list_empty_careful(&ctx->flc_lease)) {
+               percpu_down_read_preempt_disable(&file_rwsem);
                spin_lock(&ctx->flc_lock);
                time_out_leases(inode, &dispose);
                list_for_each_entry(fl, &ctx->flc_lease, fl_list) {
@@ -1618,6 +1619,8 @@ int fcntl_getlease(struct file *filp)
                        break;
                }
                spin_unlock(&ctx->flc_lock);
+               percpu_up_read_preempt_enable(&file_rwsem);
+
                locks_dispose_list(&dispose);
        }
        return type;
@@ -2529,11 +2532,14 @@ locks_remove_lease(struct file *filp, struct file_lock_context *ctx)
        if (list_empty(&ctx->flc_lease))
                return;
 
+       percpu_down_read_preempt_disable(&file_rwsem);
        spin_lock(&ctx->flc_lock);
        list_for_each_entry_safe(fl, tmp, &ctx->flc_lease, fl_list)
                if (filp == fl->fl_file)
                        lease_modify(fl, F_UNLCK, &dispose);
        spin_unlock(&ctx->flc_lock);
+       percpu_up_read_preempt_enable(&file_rwsem);
+
        locks_dispose_list(&dispose);
 }
 
index c2964d8..8e65446 100644 (file)
@@ -252,7 +252,7 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
         * Inherently racy -- command line shares address space
         * with code and data.
         */
-       rv = access_remote_vm(mm, arg_end - 1, &c, 1, 0);
+       rv = access_remote_vm(mm, arg_end - 1, &c, 1, FOLL_FORCE);
        if (rv <= 0)
                goto out_free_page;
 
@@ -270,7 +270,8 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
                        int nr_read;
 
                        _count = min3(count, len, PAGE_SIZE);
-                       nr_read = access_remote_vm(mm, p, page, _count, 0);
+                       nr_read = access_remote_vm(mm, p, page, _count,
+                                       FOLL_FORCE);
                        if (nr_read < 0)
                                rv = nr_read;
                        if (nr_read <= 0)
@@ -305,7 +306,8 @@ static ssize_t proc_pid_cmdline_read(struct file *file, char __user *buf,
                        bool final;
 
                        _count = min3(count, len, PAGE_SIZE);
-                       nr_read = access_remote_vm(mm, p, page, _count, 0);
+                       nr_read = access_remote_vm(mm, p, page, _count,
+                                       FOLL_FORCE);
                        if (nr_read < 0)
                                rv = nr_read;
                        if (nr_read <= 0)
@@ -354,7 +356,8 @@ skip_argv:
                        bool final;
 
                        _count = min3(count, len, PAGE_SIZE);
-                       nr_read = access_remote_vm(mm, p, page, _count, 0);
+                       nr_read = access_remote_vm(mm, p, page, _count,
+                                       FOLL_FORCE);
                        if (nr_read < 0)
                                rv = nr_read;
                        if (nr_read <= 0)
@@ -832,6 +835,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
        unsigned long addr = *ppos;
        ssize_t copied;
        char *page;
+       unsigned int flags = FOLL_FORCE;
 
        if (!mm)
                return 0;
@@ -844,6 +848,9 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
        if (!atomic_inc_not_zero(&mm->mm_users))
                goto free;
 
+       if (write)
+               flags |= FOLL_WRITE;
+
        while (count > 0) {
                int this_len = min_t(int, count, PAGE_SIZE);
 
@@ -852,7 +859,7 @@ static ssize_t mem_rw(struct file *file, char __user *buf,
                        break;
                }
 
-               this_len = access_remote_vm(mm, addr, page, this_len, write);
+               this_len = access_remote_vm(mm, addr, page, this_len, flags);
                if (!this_len) {
                        if (!copied)
                                copied = -EIO;
@@ -965,7 +972,7 @@ static ssize_t environ_read(struct file *file, char __user *buf,
                this_len = min(max_len, this_len);
 
                retval = access_remote_vm(mm, (env_start + src),
-                       page, this_len, 0);
+                       page, this_len, FOLL_FORCE);
 
                if (retval <= 0) {
                        ret = retval;
index d600303..820c0ad 100644 (file)
@@ -44,6 +44,7 @@ static inline void kasan_disable_current(void)
 void kasan_unpoison_shadow(const void *address, size_t size);
 
 void kasan_unpoison_task_stack(struct task_struct *task);
+void kasan_unpoison_stack_above_sp_to(const void *watermark);
 
 void kasan_alloc_pages(struct page *page, unsigned int order);
 void kasan_free_pages(struct page *page, unsigned int order);
@@ -85,6 +86,7 @@ size_t kasan_metadata_size(struct kmem_cache *cache);
 static inline void kasan_unpoison_shadow(const void *address, size_t size) {}
 
 static inline void kasan_unpoison_task_stack(struct task_struct *task) {}
+static inline void kasan_unpoison_stack_above_sp_to(const void *watermark) {}
 
 static inline void kasan_enable_current(void) {}
 static inline void kasan_disable_current(void) {}
index e9caec6..ffbd729 100644 (file)
@@ -1266,9 +1266,10 @@ static inline int fixup_user_fault(struct task_struct *tsk,
 }
 #endif
 
-extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write);
+extern int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len,
+               unsigned int gup_flags);
 extern int access_remote_vm(struct mm_struct *mm, unsigned long addr,
-               void *buf, int len, int write);
+               void *buf, int len, unsigned int gup_flags);
 
 long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                      unsigned long start, unsigned long nr_pages,
@@ -1276,19 +1277,18 @@ long __get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
                      struct vm_area_struct **vmas, int *nonblocking);
 long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm,
                            unsigned long start, unsigned long nr_pages,
-                           int write, int force, struct page **pages,
+                           unsigned int gup_flags, struct page **pages,
                            struct vm_area_struct **vmas);
 long get_user_pages(unsigned long start, unsigned long nr_pages,
-                           int write, int force, struct page **pages,
+                           unsigned int gup_flags, struct page **pages,
                            struct vm_area_struct **vmas);
 long get_user_pages_locked(unsigned long start, unsigned long nr_pages,
-                   int write, int force, struct page **pages, int *locked);
+                   unsigned int gup_flags, struct page **pages, int *locked);
 long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
                               unsigned long start, unsigned long nr_pages,
-                              int write, int force, struct page **pages,
-                              unsigned int gup_flags);
+                              struct page **pages, unsigned int gup_flags);
 long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
-                   int write, int force, struct page **pages);
+                   struct page **pages, unsigned int gup_flags);
 int get_user_pages_fast(unsigned long start, int nr_pages, int write,
                        struct page **pages);
 
@@ -1306,7 +1306,7 @@ struct frame_vector {
 struct frame_vector *frame_vector_create(unsigned int nr_frames);
 void frame_vector_destroy(struct frame_vector *vec);
 int get_vaddr_frames(unsigned long start, unsigned int nr_pfns,
-                    bool write, bool force, struct frame_vector *vec);
+                    unsigned int gup_flags, struct frame_vector *vec);
 void put_vaddr_frames(struct frame_vector *vec);
 int frame_vector_to_pages(struct frame_vector *vec);
 void frame_vector_to_pfns(struct frame_vector *vec);
@@ -2232,6 +2232,7 @@ static inline struct page *follow_page(struct vm_area_struct *vma,
 #define FOLL_TRIED     0x800   /* a retry, previous pass started an IO */
 #define FOLL_MLOCK     0x1000  /* lock present pages */
 #define FOLL_REMOTE    0x2000  /* we are working on non-current tsk/mm */
+#define FOLL_COW       0x4000  /* internal GUP flag */
 
 typedef int (*pte_fn_t)(pte_t *pte, pgtable_t token, unsigned long addr,
                        void *data);
index 0d7abb8..91a740f 100644 (file)
@@ -902,8 +902,5 @@ asmlinkage long sys_pkey_mprotect(unsigned long start, size_t len,
                                  unsigned long prot, int pkey);
 asmlinkage long sys_pkey_alloc(unsigned long flags, unsigned long init_val);
 asmlinkage long sys_pkey_free(int pkey);
-//asmlinkage long sys_pkey_get(int pkey, unsigned long flags);
-//asmlinkage long sys_pkey_set(int pkey, unsigned long access_rights,
-//                          unsigned long flags);
 
 #endif
index dbfee7e..9b1462e 100644 (file)
@@ -730,10 +730,6 @@ __SYSCALL(__NR_pkey_mprotect, sys_pkey_mprotect)
 __SYSCALL(__NR_pkey_alloc,    sys_pkey_alloc)
 #define __NR_pkey_free 290
 __SYSCALL(__NR_pkey_free,     sys_pkey_free)
-#define __NR_pkey_get 291
-//__SYSCALL(__NR_pkey_get,      sys_pkey_get)
-#define __NR_pkey_set 292
-//__SYSCALL(__NR_pkey_set,      sys_pkey_set)
 
 #undef __NR_syscalls
 #define __NR_syscalls 291
index 5df20d6..29de1a9 100644 (file)
@@ -228,7 +228,7 @@ static struct {
        .wq = __WAIT_QUEUE_HEAD_INITIALIZER(cpu_hotplug.wq),
        .lock = __MUTEX_INITIALIZER(cpu_hotplug.lock),
 #ifdef CONFIG_DEBUG_LOCK_ALLOC
-       .dep_map = {.name = "cpu_hotplug.lock" },
+       .dep_map = STATIC_LOCKDEP_MAP_INIT("cpu_hotplug.dep_map", &cpu_hotplug.dep_map),
 #endif
 };
 
index d4129bb..f9ec9ad 100644 (file)
@@ -300,7 +300,8 @@ int uprobe_write_opcode(struct mm_struct *mm, unsigned long vaddr,
 
 retry:
        /* Read the page with vaddr into memory */
-       ret = get_user_pages_remote(NULL, mm, vaddr, 1, 0, 1, &old_page, &vma);
+       ret = get_user_pages_remote(NULL, mm, vaddr, 1, FOLL_FORCE, &old_page,
+                       &vma);
        if (ret <= 0)
                return ret;
 
@@ -1710,7 +1711,8 @@ static int is_trap_at_addr(struct mm_struct *mm, unsigned long vaddr)
         * but we treat this as a 'remote' access since it is
         * essentially a kernel access to the memory.
         */
-       result = get_user_pages_remote(NULL, mm, vaddr, 1, 0, 1, &page, NULL);
+       result = get_user_pages_remote(NULL, mm, vaddr, 1, FOLL_FORCE, &page,
+                       NULL);
        if (result < 0)
                return result;
 
index d5e3973..de08fc9 100644 (file)
@@ -1769,6 +1769,10 @@ static size_t log_output(int facility, int level, enum log_flags lflags, const c
                cont_flush();
        }
 
+       /* Skip empty continuation lines that couldn't be added - they just flush */
+       if (!text_len && (lflags & LOG_CONT))
+               return 0;
+
        /* If it doesn't end in a newline, try to buffer the current line */
        if (!(lflags & LOG_NEWLINE)) {
                if (cont_add(facility, level, lflags, text, text_len))
index 2a99027..e6474f7 100644 (file)
@@ -537,7 +537,7 @@ int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst
                int this_len, retval;
 
                this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
-               retval = access_process_vm(tsk, src, buf, this_len, 0);
+               retval = access_process_vm(tsk, src, buf, this_len, FOLL_FORCE);
                if (!retval) {
                        if (copied)
                                break;
@@ -564,7 +564,8 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds
                this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
                if (copy_from_user(buf, src, this_len))
                        return -EFAULT;
-               retval = access_process_vm(tsk, dst, buf, this_len, 1);
+               retval = access_process_vm(tsk, dst, buf, this_len,
+                               FOLL_FORCE | FOLL_WRITE);
                if (!retval) {
                        if (copied)
                                break;
@@ -1127,7 +1128,7 @@ int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
        unsigned long tmp;
        int copied;
 
-       copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
+       copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), FOLL_FORCE);
        if (copied != sizeof(tmp))
                return -EIO;
        return put_user(tmp, (unsigned long __user *)data);
@@ -1138,7 +1139,8 @@ int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
 {
        int copied;
 
-       copied = access_process_vm(tsk, addr, &data, sizeof(data), 1);
+       copied = access_process_vm(tsk, addr, &data, sizeof(data),
+                       FOLL_FORCE | FOLL_WRITE);
        return (copied == sizeof(data)) ? 0 : -EIO;
 }
 
@@ -1155,7 +1157,8 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
        switch (request) {
        case PTRACE_PEEKTEXT:
        case PTRACE_PEEKDATA:
-               ret = access_process_vm(child, addr, &word, sizeof(word), 0);
+               ret = access_process_vm(child, addr, &word, sizeof(word),
+                               FOLL_FORCE);
                if (ret != sizeof(word))
                        ret = -EIO;
                else
@@ -1164,7 +1167,8 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
 
        case PTRACE_POKETEXT:
        case PTRACE_POKEDATA:
-               ret = access_process_vm(child, addr, &data, sizeof(data), 1);
+               ret = access_process_vm(child, addr, &data, sizeof(data),
+                               FOLL_FORCE | FOLL_WRITE);
                ret = (ret != sizeof(data) ? -EIO : 0);
                break;
 
index 2d4ad72..76ee7de 100644 (file)
@@ -5471,13 +5471,18 @@ static inline int select_idle_smt(struct task_struct *p, struct sched_domain *sd
  */
 static int select_idle_cpu(struct task_struct *p, struct sched_domain *sd, int target)
 {
-       struct sched_domain *this_sd = rcu_dereference(*this_cpu_ptr(&sd_llc));
-       u64 avg_idle = this_rq()->avg_idle;
-       u64 avg_cost = this_sd->avg_scan_cost;
+       struct sched_domain *this_sd;
+       u64 avg_cost, avg_idle = this_rq()->avg_idle;
        u64 time, cost;
        s64 delta;
        int cpu, wrap;
 
+       this_sd = rcu_dereference(*this_cpu_ptr(&sd_llc));
+       if (!this_sd)
+               return -1;
+
+       avg_cost = this_sd->avg_scan_cost;
+
        /*
         * Due to large variance we need a large fuzz factor; hackbench in
         * particularly is sensitive here.
index c3aad68..12dd190 100644 (file)
@@ -542,7 +542,6 @@ static int alarm_clock_get(clockid_t which_clock, struct timespec *tp)
 static int alarm_timer_create(struct k_itimer *new_timer)
 {
        enum  alarmtimer_type type;
-       struct alarm_base *base;
 
        if (!alarmtimer_get_rtcdev())
                return -ENOTSUPP;
@@ -551,7 +550,6 @@ static int alarm_timer_create(struct k_itimer *new_timer)
                return -EPERM;
 
        type = clock2alarm(new_timer->it_clock);
-       base = &alarm_bases[type];
        alarm_init(&new_timer->it.alarm.alarmtimer, type, alarm_handle_timer);
        return 0;
 }
index 381bb07..db77dcb 100644 (file)
  * get_vaddr_frames() - map virtual addresses to pfns
  * @start:     starting user address
  * @nr_frames: number of pages / pfns from start to map
- * @write:     whether pages will be written to by the caller
- * @force:     whether to force write access even if user mapping is
- *             readonly. See description of the same argument of
-               get_user_pages().
+ * @gup_flags: flags modifying lookup behaviour
  * @vec:       structure which receives pages / pfns of the addresses mapped.
  *             It should have space for at least nr_frames entries.
  *
@@ -34,7 +31,7 @@
  * This function takes care of grabbing mmap_sem as necessary.
  */
 int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
-                    bool write, bool force, struct frame_vector *vec)
+                    unsigned int gup_flags, struct frame_vector *vec)
 {
        struct mm_struct *mm = current->mm;
        struct vm_area_struct *vma;
@@ -59,7 +56,7 @@ int get_vaddr_frames(unsigned long start, unsigned int nr_frames,
                vec->got_ref = true;
                vec->is_pfns = false;
                ret = get_user_pages_locked(start, nr_frames,
-                       write, force, (struct page **)(vec->ptrs), &locked);
+                       gup_flags, (struct page **)(vec->ptrs), &locked);
                goto out;
        }
 
index 96b2b2f..7aa113c 100644 (file)
--- a/mm/gup.c
+++ b/mm/gup.c
@@ -60,6 +60,16 @@ static int follow_pfn_pte(struct vm_area_struct *vma, unsigned long address,
        return -EEXIST;
 }
 
+/*
+ * FOLL_FORCE can write to even unwritable pte's, but only
+ * after we've gone through a COW cycle and they are dirty.
+ */
+static inline bool can_follow_write_pte(pte_t pte, unsigned int flags)
+{
+       return pte_write(pte) ||
+               ((flags & FOLL_FORCE) && (flags & FOLL_COW) && pte_dirty(pte));
+}
+
 static struct page *follow_page_pte(struct vm_area_struct *vma,
                unsigned long address, pmd_t *pmd, unsigned int flags)
 {
@@ -95,7 +105,7 @@ retry:
        }
        if ((flags & FOLL_NUMA) && pte_protnone(pte))
                goto no_page;
-       if ((flags & FOLL_WRITE) && !pte_write(pte)) {
+       if ((flags & FOLL_WRITE) && !can_follow_write_pte(pte, flags)) {
                pte_unmap_unlock(ptep, ptl);
                return NULL;
        }
@@ -412,7 +422,7 @@ static int faultin_page(struct task_struct *tsk, struct vm_area_struct *vma,
         * reCOWed by userspace write).
         */
        if ((ret & VM_FAULT_WRITE) && !(vma->vm_flags & VM_WRITE))
-               *flags &= ~FOLL_WRITE;
+               *flags |= FOLL_COW;
        return 0;
 }
 
@@ -729,7 +739,6 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
                                                struct mm_struct *mm,
                                                unsigned long start,
                                                unsigned long nr_pages,
-                                               int write, int force,
                                                struct page **pages,
                                                struct vm_area_struct **vmas,
                                                int *locked, bool notify_drop,
@@ -747,10 +756,6 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
 
        if (pages)
                flags |= FOLL_GET;
-       if (write)
-               flags |= FOLL_WRITE;
-       if (force)
-               flags |= FOLL_FORCE;
 
        pages_done = 0;
        lock_dropped = false;
@@ -843,12 +848,12 @@ static __always_inline long __get_user_pages_locked(struct task_struct *tsk,
  *          up_read(&mm->mmap_sem);
  */
 long get_user_pages_locked(unsigned long start, unsigned long nr_pages,
-                          int write, int force, struct page **pages,
+                          unsigned int gup_flags, struct page **pages,
                           int *locked)
 {
        return __get_user_pages_locked(current, current->mm, start, nr_pages,
-                                      write, force, pages, NULL, locked, true,
-                                      FOLL_TOUCH);
+                                      pages, NULL, locked, true,
+                                      gup_flags | FOLL_TOUCH);
 }
 EXPORT_SYMBOL(get_user_pages_locked);
 
@@ -864,14 +869,14 @@ EXPORT_SYMBOL(get_user_pages_locked);
  */
 __always_inline long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
                                               unsigned long start, unsigned long nr_pages,
-                                              int write, int force, struct page **pages,
-                                              unsigned int gup_flags)
+                                              struct page **pages, unsigned int gup_flags)
 {
        long ret;
        int locked = 1;
+
        down_read(&mm->mmap_sem);
-       ret = __get_user_pages_locked(tsk, mm, start, nr_pages, write, force,
-                                     pages, NULL, &locked, false, gup_flags);
+       ret = __get_user_pages_locked(tsk, mm, start, nr_pages, pages, NULL,
+                                     &locked, false, gup_flags);
        if (locked)
                up_read(&mm->mmap_sem);
        return ret;
@@ -896,10 +901,10 @@ EXPORT_SYMBOL(__get_user_pages_unlocked);
  * "force" parameter).
  */
 long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
-                            int write, int force, struct page **pages)
+                            struct page **pages, unsigned int gup_flags)
 {
        return __get_user_pages_unlocked(current, current->mm, start, nr_pages,
-                                        write, force, pages, FOLL_TOUCH);
+                                        pages, gup_flags | FOLL_TOUCH);
 }
 EXPORT_SYMBOL(get_user_pages_unlocked);
 
@@ -910,9 +915,7 @@ EXPORT_SYMBOL(get_user_pages_unlocked);
  * @mm:                mm_struct of target mm
  * @start:     starting user address
  * @nr_pages:  number of pages from start to pin
- * @write:     whether pages will be written to by the caller
- * @force:     whether to force access even when user mapping is currently
- *             protected (but never forces write access to shared mapping).
+ * @gup_flags: flags modifying lookup behaviour
  * @pages:     array that receives pointers to the pages pinned.
  *             Should be at least nr_pages long. Or NULL, if caller
  *             only intends to ensure the pages are faulted in.
@@ -941,9 +944,9 @@ EXPORT_SYMBOL(get_user_pages_unlocked);
  * or similar operation cannot guarantee anything stronger anyway because
  * locks can't be held over the syscall boundary.
  *
- * If write=0, the page must not be written to. If the page is written to,
- * set_page_dirty (or set_page_dirty_lock, as appropriate) must be called
- * after the page is finished with, and before put_page is called.
+ * If gup_flags & FOLL_WRITE == 0, the page must not be written to. If the page
+ * is written to, set_page_dirty (or set_page_dirty_lock, as appropriate) must
+ * be called after the page is finished with, and before put_page is called.
  *
  * get_user_pages is typically used for fewer-copy IO operations, to get a
  * handle on the memory by some means other than accesses via the user virtual
@@ -960,12 +963,12 @@ EXPORT_SYMBOL(get_user_pages_unlocked);
  */
 long get_user_pages_remote(struct task_struct *tsk, struct mm_struct *mm,
                unsigned long start, unsigned long nr_pages,
-               int write, int force, struct page **pages,
+               unsigned int gup_flags, struct page **pages,
                struct vm_area_struct **vmas)
 {
-       return __get_user_pages_locked(tsk, mm, start, nr_pages, write, force,
-                                      pages, vmas, NULL, false,
-                                      FOLL_TOUCH | FOLL_REMOTE);
+       return __get_user_pages_locked(tsk, mm, start, nr_pages, pages, vmas,
+                                      NULL, false,
+                                      gup_flags | FOLL_TOUCH | FOLL_REMOTE);
 }
 EXPORT_SYMBOL(get_user_pages_remote);
 
@@ -976,12 +979,12 @@ EXPORT_SYMBOL(get_user_pages_remote);
  * obviously don't pass FOLL_REMOTE in here.
  */
 long get_user_pages(unsigned long start, unsigned long nr_pages,
-               int write, int force, struct page **pages,
+               unsigned int gup_flags, struct page **pages,
                struct vm_area_struct **vmas)
 {
        return __get_user_pages_locked(current, current->mm, start, nr_pages,
-                                      write, force, pages, vmas, NULL, false,
-                                      FOLL_TOUCH);
+                                      pages, vmas, NULL, false,
+                                      gup_flags | FOLL_TOUCH);
 }
 EXPORT_SYMBOL(get_user_pages);
 
@@ -1505,7 +1508,8 @@ int get_user_pages_fast(unsigned long start, int nr_pages, int write,
                start += nr << PAGE_SHIFT;
                pages += nr;
 
-               ret = get_user_pages_unlocked(start, nr_pages - nr, write, 0, pages);
+               ret = get_user_pages_unlocked(start, nr_pages - nr, pages,
+                               write ? FOLL_WRITE : 0);
 
                /* Have to be a bit careful with return values */
                if (nr > 0) {
index 88af13c..70c0097 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/string.h>
 #include <linux/types.h>
 #include <linux/vmalloc.h>
+#include <linux/bug.h>
 
 #include "kasan.h"
 #include "../slab.h"
@@ -62,7 +63,7 @@ void kasan_unpoison_shadow(const void *address, size_t size)
        }
 }
 
-static void __kasan_unpoison_stack(struct task_struct *task, void *sp)
+static void __kasan_unpoison_stack(struct task_struct *task, const void *sp)
 {
        void *base = task_stack_page(task);
        size_t size = sp - base;
@@ -77,9 +78,24 @@ void kasan_unpoison_task_stack(struct task_struct *task)
 }
 
 /* Unpoison the stack for the current task beyond a watermark sp value. */
-asmlinkage void kasan_unpoison_remaining_stack(void *sp)
+asmlinkage void kasan_unpoison_task_stack_below(const void *watermark)
 {
-       __kasan_unpoison_stack(current, sp);
+       __kasan_unpoison_stack(current, watermark);
+}
+
+/*
+ * Clear all poison for the region between the current SP and a provided
+ * watermark value, as is sometimes required prior to hand-crafted asm function
+ * returns in the middle of functions.
+ */
+void kasan_unpoison_stack_above_sp_to(const void *watermark)
+{
+       const void *sp = __builtin_frame_address(0);
+       size_t size = watermark - sp;
+
+       if (WARN_ON(sp > watermark))
+               return;
+       kasan_unpoison_shadow(sp, size);
 }
 
 /*
index fc1987d..e18c57b 100644 (file)
@@ -3869,10 +3869,11 @@ EXPORT_SYMBOL_GPL(generic_access_phys);
  * given task for page fault accounting.
  */
 static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
-               unsigned long addr, void *buf, int len, int write)
+               unsigned long addr, void *buf, int len, unsigned int gup_flags)
 {
        struct vm_area_struct *vma;
        void *old_buf = buf;
+       int write = gup_flags & FOLL_WRITE;
 
        down_read(&mm->mmap_sem);
        /* ignore errors, just check how much was successfully transferred */
@@ -3882,7 +3883,7 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
                struct page *page = NULL;
 
                ret = get_user_pages_remote(tsk, mm, addr, 1,
-                               write, 1, &page, &vma);
+                               gup_flags, &page, &vma);
                if (ret <= 0) {
 #ifndef CONFIG_HAVE_IOREMAP_PROT
                        break;
@@ -3934,14 +3935,14 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
  * @addr:      start address to access
  * @buf:       source or destination buffer
  * @len:       number of bytes to transfer
- * @write:     whether the access is a write
+ * @gup_flags: flags modifying lookup behaviour
  *
  * The caller must hold a reference on @mm.
  */
 int access_remote_vm(struct mm_struct *mm, unsigned long addr,
-               void *buf, int len, int write)
+               void *buf, int len, unsigned int gup_flags)
 {
-       return __access_remote_vm(NULL, mm, addr, buf, len, write);
+       return __access_remote_vm(NULL, mm, addr, buf, len, gup_flags);
 }
 
 /*
@@ -3950,7 +3951,7 @@ int access_remote_vm(struct mm_struct *mm, unsigned long addr,
  * Do not walk the page table directly, use get_user_pages
  */
 int access_process_vm(struct task_struct *tsk, unsigned long addr,
-               void *buf, int len, int write)
+               void *buf, int len, unsigned int gup_flags)
 {
        struct mm_struct *mm;
        int ret;
@@ -3959,7 +3960,8 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr,
        if (!mm)
                return 0;
 
-       ret = __access_remote_vm(tsk, mm, addr, buf, len, write);
+       ret = __access_remote_vm(tsk, mm, addr, buf, len, gup_flags);
+
        mmput(mm);
 
        return ret;
index ad1c96a..0b859af 100644 (file)
@@ -850,7 +850,7 @@ static int lookup_node(unsigned long addr)
        struct page *p;
        int err;
 
-       err = get_user_pages(addr & PAGE_MASK, 1, 0, 0, &p, NULL);
+       err = get_user_pages(addr & PAGE_MASK, 1, 0, &p, NULL);
        if (err >= 0) {
                err = page_to_nid(p);
                put_page(p);
index 95daf81..db5fd17 100644 (file)
@@ -160,33 +160,25 @@ finish_or_fault:
  * - don't permit access to VMAs that don't support it, such as I/O mappings
  */
 long get_user_pages(unsigned long start, unsigned long nr_pages,
-                   int write, int force, struct page **pages,
+                   unsigned int gup_flags, struct page **pages,
                    struct vm_area_struct **vmas)
 {
-       int flags = 0;
-
-       if (write)
-               flags |= FOLL_WRITE;
-       if (force)
-               flags |= FOLL_FORCE;
-
-       return __get_user_pages(current, current->mm, start, nr_pages, flags,
-                               pages, vmas, NULL);
+       return __get_user_pages(current, current->mm, start, nr_pages,
+                               gup_flags, pages, vmas, NULL);
 }
 EXPORT_SYMBOL(get_user_pages);
 
 long get_user_pages_locked(unsigned long start, unsigned long nr_pages,
-                           int write, int force, struct page **pages,
+                           unsigned int gup_flags, struct page **pages,
                            int *locked)
 {
-       return get_user_pages(start, nr_pages, write, force, pages, NULL);
+       return get_user_pages(start, nr_pages, gup_flags, pages, NULL);
 }
 EXPORT_SYMBOL(get_user_pages_locked);
 
 long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
                               unsigned long start, unsigned long nr_pages,
-                              int write, int force, struct page **pages,
-                              unsigned int gup_flags)
+                              struct page **pages, unsigned int gup_flags)
 {
        long ret;
        down_read(&mm->mmap_sem);
@@ -198,10 +190,10 @@ long __get_user_pages_unlocked(struct task_struct *tsk, struct mm_struct *mm,
 EXPORT_SYMBOL(__get_user_pages_unlocked);
 
 long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages,
-                            int write, int force, struct page **pages)
+                            struct page **pages, unsigned int gup_flags)
 {
        return __get_user_pages_unlocked(current, current->mm, start, nr_pages,
-                                        write, force, pages, 0);
+                                        pages, gup_flags);
 }
 EXPORT_SYMBOL(get_user_pages_unlocked);
 
@@ -1817,9 +1809,10 @@ void filemap_map_pages(struct fault_env *fe,
 EXPORT_SYMBOL(filemap_map_pages);
 
 static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
-               unsigned long addr, void *buf, int len, int write)
+               unsigned long addr, void *buf, int len, unsigned int gup_flags)
 {
        struct vm_area_struct *vma;
+       int write = gup_flags & FOLL_WRITE;
 
        down_read(&mm->mmap_sem);
 
@@ -1854,21 +1847,22 @@ static int __access_remote_vm(struct task_struct *tsk, struct mm_struct *mm,
  * @addr:      start address to access
  * @buf:       source or destination buffer
  * @len:       number of bytes to transfer
- * @write:     whether the access is a write
+ * @gup_flags: flags modifying lookup behaviour
  *
  * The caller must hold a reference on @mm.
  */
 int access_remote_vm(struct mm_struct *mm, unsigned long addr,
-               void *buf, int len, int write)
+               void *buf, int len, unsigned int gup_flags)
 {
-       return __access_remote_vm(NULL, mm, addr, buf, len, write);
+       return __access_remote_vm(NULL, mm, addr, buf, len, gup_flags);
 }
 
 /*
  * Access another process' address space.
  * - source/target buffer must be kernel space
  */
-int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
+int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len,
+               unsigned int gup_flags)
 {
        struct mm_struct *mm;
 
@@ -1879,7 +1873,7 @@ int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, in
        if (!mm)
                return 0;
 
-       len = __access_remote_vm(tsk, mm, addr, buf, len, write);
+       len = __access_remote_vm(tsk, mm, addr, buf, len, gup_flags);
 
        mmput(mm);
        return len;
index 07514d4..be8dc8d 100644 (file)
@@ -88,12 +88,16 @@ static int process_vm_rw_single_vec(unsigned long addr,
        ssize_t rc = 0;
        unsigned long max_pages_per_loop = PVM_MAX_KMALLOC_PAGES
                / sizeof(struct pages *);
+       unsigned int flags = FOLL_REMOTE;
 
        /* Work out address and page range required */
        if (len == 0)
                return 0;
        nr_pages = (addr + len - 1) / PAGE_SIZE - addr / PAGE_SIZE + 1;
 
+       if (vm_write)
+               flags |= FOLL_WRITE;
+
        while (!rc && nr_pages && iov_iter_count(iter)) {
                int pages = min(nr_pages, max_pages_per_loop);
                size_t bytes;
@@ -104,8 +108,7 @@ static int process_vm_rw_single_vec(unsigned long addr,
                 * current/current->mm
                 */
                pages = __get_user_pages_unlocked(task, mm, pa, pages,
-                                                 vm_write, 0, process_pages,
-                                                 FOLL_REMOTE);
+                                                 process_pages, flags);
                if (pages <= 0)
                        return -EFAULT;
 
index 662cddf..952cbe7 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -283,7 +283,8 @@ EXPORT_SYMBOL_GPL(__get_user_pages_fast);
 int __weak get_user_pages_fast(unsigned long start,
                                int nr_pages, int write, struct page **pages)
 {
-       return get_user_pages_unlocked(start, nr_pages, write, 0, pages);
+       return get_user_pages_unlocked(start, nr_pages, pages,
+                                      write ? FOLL_WRITE : 0);
 }
 EXPORT_SYMBOL_GPL(get_user_pages_fast);
 
@@ -623,7 +624,7 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen)
        if (len > buflen)
                len = buflen;
 
-       res = access_process_vm(task, arg_start, buffer, len, 0);
+       res = access_process_vm(task, arg_start, buffer, len, FOLL_FORCE);
 
        /*
         * If the nul at the end of args has been overwritten, then
@@ -638,7 +639,8 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen)
                        if (len > buflen - res)
                                len = buflen - res;
                        res += access_process_vm(task, env_start,
-                                                buffer+res, len, 0);
+                                                buffer+res, len,
+                                                FOLL_FORCE);
                        res = strnlen(buffer, res);
                }
        }
index 00d2601..1a7c9a7 100644 (file)
@@ -26,7 +26,7 @@ struct page **ceph_get_direct_page_vector(const void __user *data,
        while (got < num_pages) {
                rc = get_user_pages_unlocked(
                    (unsigned long)data + ((unsigned long)got * PAGE_SIZE),
-                   num_pages - got, write_page, 0, pages + got);
+                   num_pages - got, pages + got, write_page ? FOLL_WRITE : 0);
                if (rc < 0)
                        break;
                BUG_ON(rc == 0);
index ade7c6c..682b73a 100644 (file)
@@ -881,7 +881,7 @@ bool tomoyo_dump_page(struct linux_binprm *bprm, unsigned long pos,
         * the execve().
         */
        if (get_user_pages_remote(current, bprm->mm, pos, 1,
-                               0, 1, &page, NULL) <= 0)
+                               FOLL_FORCE, &page, NULL) <= 0)
                return false;
 #else
        page = bprm->page[pos / PAGE_SIZE];
index c0c0b26..b63a31b 100644 (file)
@@ -98,6 +98,15 @@ int arch_decode_instruction(struct elf *elf, struct section *sec,
                        *type = INSN_FP_SETUP;
                break;
 
+       case 0x8d:
+               if (insn.rex_prefix.bytes &&
+                   insn.rex_prefix.bytes[0] == 0x48 &&
+                   insn.modrm.nbytes && insn.modrm.bytes[0] == 0x2c &&
+                   insn.sib.nbytes && insn.sib.bytes[0] == 0x24)
+                       /* lea %(rsp), %rbp */
+                       *type = INSN_FP_SETUP;
+               break;
+
        case 0x90:
                *type = INSN_NOP;
                break;
index 143b6cd..4490601 100644 (file)
@@ -97,6 +97,19 @@ static struct instruction *next_insn_same_sec(struct objtool_file *file,
        return next;
 }
 
+static bool gcov_enabled(struct objtool_file *file)
+{
+       struct section *sec;
+       struct symbol *sym;
+
+       list_for_each_entry(sec, &file->elf->sections, list)
+               list_for_each_entry(sym, &sec->symbol_list, list)
+                       if (!strncmp(sym->name, "__gcov_.", 8))
+                               return true;
+
+       return false;
+}
+
 #define for_each_insn(file, insn)                                      \
        list_for_each_entry(insn, &file->insn_list, list)
 
@@ -713,6 +726,7 @@ static struct rela *find_switch_table(struct objtool_file *file,
                                      struct instruction *insn)
 {
        struct rela *text_rela, *rodata_rela;
+       struct instruction *orig_insn = insn;
 
        text_rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
        if (text_rela && text_rela->sym == file->rodata->sym) {
@@ -733,10 +747,16 @@ static struct rela *find_switch_table(struct objtool_file *file,
 
        /* case 3 */
        func_for_each_insn_continue_reverse(file, func, insn) {
-               if (insn->type == INSN_JUMP_UNCONDITIONAL ||
-                   insn->type == INSN_JUMP_DYNAMIC)
+               if (insn->type == INSN_JUMP_DYNAMIC)
                        break;
 
+               /* allow small jumps within the range */
+               if (insn->type == INSN_JUMP_UNCONDITIONAL &&
+                   insn->jump_dest &&
+                   (insn->jump_dest->offset <= insn->offset ||
+                    insn->jump_dest->offset >= orig_insn->offset))
+                   break;
+
                text_rela = find_rela_by_dest_range(insn->sec, insn->offset,
                                                    insn->len);
                if (text_rela && text_rela->sym == file->rodata->sym)
@@ -1034,34 +1054,6 @@ static int validate_branch(struct objtool_file *file,
        return 0;
 }
 
-static bool is_gcov_insn(struct instruction *insn)
-{
-       struct rela *rela;
-       struct section *sec;
-       struct symbol *sym;
-       unsigned long offset;
-
-       rela = find_rela_by_dest_range(insn->sec, insn->offset, insn->len);
-       if (!rela)
-               return false;
-
-       if (rela->sym->type != STT_SECTION)
-               return false;
-
-       sec = rela->sym->sec;
-       offset = rela->addend + insn->offset + insn->len - rela->offset;
-
-       list_for_each_entry(sym, &sec->symbol_list, list) {
-               if (sym->type != STT_OBJECT)
-                       continue;
-
-               if (offset >= sym->offset && offset < sym->offset + sym->len)
-                       return (!memcmp(sym->name, "__gcov0.", 8));
-       }
-
-       return false;
-}
-
 static bool is_kasan_insn(struct instruction *insn)
 {
        return (insn->type == INSN_CALL &&
@@ -1083,9 +1075,6 @@ static bool ignore_unreachable_insn(struct symbol *func,
        if (insn->type == INSN_NOP)
                return true;
 
-       if (is_gcov_insn(insn))
-               return true;
-
        /*
         * Check if this (or a subsequent) instruction is related to
         * CONFIG_UBSAN or CONFIG_KASAN.
@@ -1146,6 +1135,19 @@ static int validate_functions(struct objtool_file *file)
                                    ignore_unreachable_insn(func, insn))
                                        continue;
 
+                               /*
+                                * gcov produces a lot of unreachable
+                                * instructions.  If we get an unreachable
+                                * warning and the file has gcov enabled, just
+                                * ignore it, and all other such warnings for
+                                * the file.
+                                */
+                               if (!file->ignore_unreachables &&
+                                   gcov_enabled(file)) {
+                                       file->ignore_unreachables = true;
+                                       continue;
+                               }
+
                                WARN_FUNC("function has unreachable instruction", insn->sec, insn->offset);
                                warnings++;
                        }
index 5ce61a1..df14e6b 100644 (file)
@@ -36,7 +36,7 @@ SOLIBEXT=so
 # The following works at least on fedora 23, you may need the next
 # line for other distros.
 ifneq (,$(wildcard /usr/sbin/update-java-alternatives))
-JDIR=$(shell /usr/sbin/update-java-alternatives -l | head -1 | cut -d ' ' -f 3)
+JDIR=$(shell /usr/sbin/update-java-alternatives -l | head -1 | awk '{print $$3}')
 else
   ifneq (,$(wildcard /usr/sbin/alternatives))
     JDIR=$(shell alternatives --display java | tail -1 | cut -d' ' -f 5 | sed 's%/jre/bin/java.%%g')
index fb8e42c..4ffff7b 100644 (file)
@@ -601,7 +601,8 @@ int hist_browser__run(struct hist_browser *browser, const char *help)
                        u64 nr_entries;
                        hbt->timer(hbt->arg);
 
-                       if (hist_browser__has_filter(browser))
+                       if (hist_browser__has_filter(browser) ||
+                           symbol_conf.report_hierarchy)
                                hist_browser__update_nr_entries(browser);
 
                        nr_entries = hist_browser__nr_entries(browser);
index 85dd0db..2f3eded 100644 (file)
@@ -1895,7 +1895,6 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse
        if (ph->needs_swap)
                nr = bswap_32(nr);
 
-       ph->env.nr_numa_nodes = nr;
        nodes = zalloc(sizeof(*nodes) * nr);
        if (!nodes)
                return -ENOMEM;
@@ -1932,6 +1931,7 @@ static int process_numa_topology(struct perf_file_section *section __maybe_unuse
 
                free(str);
        }
+       ph->env.nr_numa_nodes = nr;
        ph->env.numa_nodes = nodes;
        return 0;
 
index 9f43fda..660fca0 100644 (file)
@@ -136,8 +136,8 @@ do {                                                        \
 group          [^,{}/]*[{][^}]*[}][^,{}/]*
 event_pmu      [^,{}/]+[/][^/]*[/][^,{}/]*
 event          [^,{}/]+
-bpf_object     .*\.(o|bpf)
-bpf_source     .*\.c
+bpf_object     [^,{}]+\.(o|bpf)
+bpf_source     [^,{}]+\.c
 
 num_dec                [0-9]+
 num_hex                0x[a-fA-F0-9]+
index db96688..8035cc1 100644 (file)
@@ -84,7 +84,8 @@ static void async_pf_execute(struct work_struct *work)
         * mm and might be done in another context, so we must
         * use FOLL_REMOTE.
         */
-       __get_user_pages_unlocked(NULL, mm, addr, 1, 1, 0, NULL, FOLL_REMOTE);
+       __get_user_pages_unlocked(NULL, mm, addr, 1, NULL,
+                       FOLL_WRITE | FOLL_REMOTE);
 
        kvm_async_page_present_sync(vcpu, apf);
 
index 81dfc73..28510e7 100644 (file)
@@ -1416,10 +1416,15 @@ static int hva_to_pfn_slow(unsigned long addr, bool *async, bool write_fault,
                down_read(&current->mm->mmap_sem);
                npages = get_user_page_nowait(addr, write_fault, page);
                up_read(&current->mm->mmap_sem);
-       } else
+       } else {
+               unsigned int flags = FOLL_TOUCH | FOLL_HWPOISON;
+
+               if (write_fault)
+                       flags |= FOLL_WRITE;
+
                npages = __get_user_pages_unlocked(current, current->mm, addr, 1,
-                                                  write_fault, 0, page,
-                                                  FOLL_TOUCH|FOLL_HWPOISON);
+                                                  page, flags);
+       }
        if (npages != 1)
                return npages;