Merge branch 'akpm' (patches from Andrew)
Merge fixes from Andrew Morton: "26 fixes" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (26 commits) userfaultfd: remove wrong comment from userfaultfd_ctx_get() fat: fix using uninitialized fields of fat_inode/fsinfo_inode sh: cayman: IDE support fix kasan: fix races in quarantine_remove_cache() kasan: resched in quarantine_remove_cache() mm: do not call mem_cgroup_free() from within mem_cgroup_alloc() thp: fix another corner case of munlock() vs. THPs rmap: fix NULL-pointer dereference on THP munlocking mm/memblock.c: fix memblock_next_valid_pfn() userfaultfd: selftest: vm: allow to build in vm/ directory userfaultfd: non-cooperative: userfaultfd_remove revalidate vma in MADV_DONTNEED userfaultfd: non-cooperative: fix fork fctx->new memleak mm/cgroup: avoid panic when init with low memory drivers/md/bcache/util.h: remove duplicate inclusion of blkdev.h mm/vmstats: add thp_split_pud event for clarity include/linux/fs.h: fix unsigned enum warning with gcc-4.2 userfaultfd: non-cooperative: release all ctx in dup_userfaultfd_complete userfaultfd: non-cooperative: robustness check userfaultfd: non-cooperative: rollback userfaultfd_exit x86, mm: unify exit paths in gup_pte_range() ...
This commit is contained in:
@@ -2086,7 +2086,7 @@ static void cryptocop_job_queue_close(void)
|
||||
dma_in_cfg.en = regk_dma_no;
|
||||
REG_WR(dma, IN_DMA_INST, rw_cfg, dma_in_cfg);
|
||||
|
||||
/* Disble the cryptocop. */
|
||||
/* Disable the cryptocop. */
|
||||
rw_cfg = REG_RD(strcop, regi_strcop, rw_cfg);
|
||||
rw_cfg.en = 0;
|
||||
REG_WR(strcop, regi_strcop, rw_cfg, rw_cfg);
|
||||
|
||||
@@ -347,23 +347,58 @@ static inline int __ptep_test_and_clear_young(struct mm_struct *mm,
|
||||
__r; \
|
||||
})
|
||||
|
||||
static inline int __pte_write(pte_t pte)
|
||||
{
|
||||
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_WRITE));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_NUMA_BALANCING
|
||||
#define pte_savedwrite pte_savedwrite
|
||||
static inline bool pte_savedwrite(pte_t pte)
|
||||
{
|
||||
/*
|
||||
* Saved write ptes are prot none ptes that doesn't have
|
||||
* privileged bit sit. We mark prot none as one which has
|
||||
* present and pviliged bit set and RWX cleared. To mark
|
||||
* protnone which used to have _PAGE_WRITE set we clear
|
||||
* the privileged bit.
|
||||
*/
|
||||
return !(pte_raw(pte) & cpu_to_be64(_PAGE_RWX | _PAGE_PRIVILEGED));
|
||||
}
|
||||
#else
|
||||
#define pte_savedwrite pte_savedwrite
|
||||
static inline bool pte_savedwrite(pte_t pte)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int pte_write(pte_t pte)
|
||||
{
|
||||
return __pte_write(pte) || pte_savedwrite(pte);
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
|
||||
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep)
|
||||
{
|
||||
if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
|
||||
return;
|
||||
|
||||
pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 0);
|
||||
if (__pte_write(*ptep))
|
||||
pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 0);
|
||||
else if (unlikely(pte_savedwrite(*ptep)))
|
||||
pte_update(mm, addr, ptep, 0, _PAGE_PRIVILEGED, 0);
|
||||
}
|
||||
|
||||
static inline void huge_ptep_set_wrprotect(struct mm_struct *mm,
|
||||
unsigned long addr, pte_t *ptep)
|
||||
{
|
||||
if ((pte_raw(*ptep) & cpu_to_be64(_PAGE_WRITE)) == 0)
|
||||
return;
|
||||
|
||||
pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 1);
|
||||
/*
|
||||
* We should not find protnone for hugetlb, but this complete the
|
||||
* interface.
|
||||
*/
|
||||
if (__pte_write(*ptep))
|
||||
pte_update(mm, addr, ptep, _PAGE_WRITE, 0, 1);
|
||||
else if (unlikely(pte_savedwrite(*ptep)))
|
||||
pte_update(mm, addr, ptep, 0, _PAGE_PRIVILEGED, 1);
|
||||
}
|
||||
|
||||
#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
|
||||
@@ -397,11 +432,6 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr,
|
||||
pte_update(mm, addr, ptep, ~0UL, 0, 0);
|
||||
}
|
||||
|
||||
static inline int pte_write(pte_t pte)
|
||||
{
|
||||
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_WRITE));
|
||||
}
|
||||
|
||||
static inline int pte_dirty(pte_t pte)
|
||||
{
|
||||
return !!(pte_raw(pte) & cpu_to_be64(_PAGE_DIRTY));
|
||||
@@ -465,19 +495,12 @@ static inline pte_t pte_clear_savedwrite(pte_t pte)
|
||||
VM_BUG_ON(!pte_protnone(pte));
|
||||
return __pte(pte_val(pte) | _PAGE_PRIVILEGED);
|
||||
}
|
||||
|
||||
#define pte_savedwrite pte_savedwrite
|
||||
static inline bool pte_savedwrite(pte_t pte)
|
||||
#else
|
||||
#define pte_clear_savedwrite pte_clear_savedwrite
|
||||
static inline pte_t pte_clear_savedwrite(pte_t pte)
|
||||
{
|
||||
/*
|
||||
* Saved write ptes are prot none ptes that doesn't have
|
||||
* privileged bit sit. We mark prot none as one which has
|
||||
* present and pviliged bit set and RWX cleared. To mark
|
||||
* protnone which used to have _PAGE_WRITE set we clear
|
||||
* the privileged bit.
|
||||
*/
|
||||
VM_BUG_ON(!pte_protnone(pte));
|
||||
return !(pte_raw(pte) & cpu_to_be64(_PAGE_RWX | _PAGE_PRIVILEGED));
|
||||
VM_WARN_ON(1);
|
||||
return __pte(pte_val(pte) & ~_PAGE_WRITE);
|
||||
}
|
||||
#endif /* CONFIG_NUMA_BALANCING */
|
||||
|
||||
@@ -506,6 +529,8 @@ static inline unsigned long pte_pfn(pte_t pte)
|
||||
/* Generic modifiers for PTE bits */
|
||||
static inline pte_t pte_wrprotect(pte_t pte)
|
||||
{
|
||||
if (unlikely(pte_savedwrite(pte)))
|
||||
return pte_clear_savedwrite(pte);
|
||||
return __pte(pte_val(pte) & ~_PAGE_WRITE);
|
||||
}
|
||||
|
||||
@@ -926,6 +951,7 @@ static inline int pmd_protnone(pmd_t pmd)
|
||||
|
||||
#define __HAVE_ARCH_PMD_WRITE
|
||||
#define pmd_write(pmd) pte_write(pmd_pte(pmd))
|
||||
#define __pmd_write(pmd) __pte_write(pmd_pte(pmd))
|
||||
#define pmd_savedwrite(pmd) pte_savedwrite(pmd_pte(pmd))
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
@@ -982,11 +1008,10 @@ static inline int __pmdp_test_and_clear_young(struct mm_struct *mm,
|
||||
static inline void pmdp_set_wrprotect(struct mm_struct *mm, unsigned long addr,
|
||||
pmd_t *pmdp)
|
||||
{
|
||||
|
||||
if ((pmd_raw(*pmdp) & cpu_to_be64(_PAGE_WRITE)) == 0)
|
||||
return;
|
||||
|
||||
pmd_hugepage_update(mm, addr, pmdp, _PAGE_WRITE, 0);
|
||||
if (__pmd_write((*pmdp)))
|
||||
pmd_hugepage_update(mm, addr, pmdp, _PAGE_WRITE, 0);
|
||||
else if (unlikely(pmd_savedwrite(*pmdp)))
|
||||
pmd_hugepage_update(mm, addr, pmdp, 0, _PAGE_PRIVILEGED);
|
||||
}
|
||||
|
||||
static inline int pmd_trans_huge(pmd_t pmd)
|
||||
|
||||
@@ -601,7 +601,7 @@ int kvmppc_book3s_hv_page_fault(struct kvm_run *run, struct kvm_vcpu *vcpu,
|
||||
hva, NULL, NULL);
|
||||
if (ptep) {
|
||||
pte = kvmppc_read_update_linux_pte(ptep, 1);
|
||||
if (pte_write(pte))
|
||||
if (__pte_write(pte))
|
||||
write_ok = 1;
|
||||
}
|
||||
local_irq_restore(flags);
|
||||
|
||||
@@ -256,7 +256,7 @@ long kvmppc_do_h_enter(struct kvm *kvm, unsigned long flags,
|
||||
}
|
||||
pte = kvmppc_read_update_linux_pte(ptep, writing);
|
||||
if (pte_present(pte) && !pte_protnone(pte)) {
|
||||
if (writing && !pte_write(pte))
|
||||
if (writing && !__pte_write(pte))
|
||||
/* make the actual HPTE be read-only */
|
||||
ptel = hpte_make_readonly(ptel);
|
||||
is_ci = pte_ci(pte);
|
||||
|
||||
@@ -128,7 +128,6 @@ static int __init smsc_superio_setup(void)
|
||||
SMSC_SUPERIO_WRITE_INDEXED(1, SMSC_PRIMARY_INT_INDEX);
|
||||
SMSC_SUPERIO_WRITE_INDEXED(12, SMSC_SECONDARY_INT_INDEX);
|
||||
|
||||
#ifdef CONFIG_IDE
|
||||
/*
|
||||
* Only IDE1 exists on the Cayman
|
||||
*/
|
||||
@@ -158,7 +157,6 @@ static int __init smsc_superio_setup(void)
|
||||
SMSC_SUPERIO_WRITE_INDEXED(0x01, 0xc5); /* GP45 = IDE1_IRQ */
|
||||
SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc6); /* GP46 = nIOROP */
|
||||
SMSC_SUPERIO_WRITE_INDEXED(0x00, 0xc7); /* GP47 = nIOWOP */
|
||||
#endif
|
||||
|
||||
/* Exit the configuration state */
|
||||
outb(SMSC_EXIT_CONFIG_KEY, SMSC_CONFIG_PORT_ADDR);
|
||||
|
||||
@@ -535,7 +535,7 @@ static void run_sync(void)
|
||||
{
|
||||
int enable_irqs = irqs_disabled();
|
||||
|
||||
/* We may be called with interrupts disbled (on bootup). */
|
||||
/* We may be called with interrupts disabled (on bootup). */
|
||||
if (enable_irqs)
|
||||
local_irq_enable();
|
||||
on_each_cpu(do_sync_core, NULL, 1);
|
||||
|
||||
@@ -106,32 +106,35 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
|
||||
unsigned long end, int write, struct page **pages, int *nr)
|
||||
{
|
||||
struct dev_pagemap *pgmap = NULL;
|
||||
int nr_start = *nr;
|
||||
pte_t *ptep;
|
||||
int nr_start = *nr, ret = 0;
|
||||
pte_t *ptep, *ptem;
|
||||
|
||||
ptep = pte_offset_map(&pmd, addr);
|
||||
/*
|
||||
* Keep the original mapped PTE value (ptem) around since we
|
||||
* might increment ptep off the end of the page when finishing
|
||||
* our loop iteration.
|
||||
*/
|
||||
ptem = ptep = pte_offset_map(&pmd, addr);
|
||||
do {
|
||||
pte_t pte = gup_get_pte(ptep);
|
||||
struct page *page;
|
||||
|
||||
/* Similar to the PMD case, NUMA hinting must take slow path */
|
||||
if (pte_protnone(pte)) {
|
||||
pte_unmap(ptep);
|
||||
return 0;
|
||||
}
|
||||
if (pte_protnone(pte))
|
||||
break;
|
||||
|
||||
if (!pte_allows_gup(pte_val(pte), write))
|
||||
break;
|
||||
|
||||
if (pte_devmap(pte)) {
|
||||
pgmap = get_dev_pagemap(pte_pfn(pte), pgmap);
|
||||
if (unlikely(!pgmap)) {
|
||||
undo_dev_pagemap(nr, nr_start, pages);
|
||||
pte_unmap(ptep);
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
} else if (!pte_allows_gup(pte_val(pte), write) ||
|
||||
pte_special(pte)) {
|
||||
pte_unmap(ptep);
|
||||
return 0;
|
||||
}
|
||||
} else if (pte_special(pte))
|
||||
break;
|
||||
|
||||
VM_BUG_ON(!pfn_valid(pte_pfn(pte)));
|
||||
page = pte_page(pte);
|
||||
get_page(page);
|
||||
@@ -141,9 +144,11 @@ static noinline int gup_pte_range(pmd_t pmd, unsigned long addr,
|
||||
(*nr)++;
|
||||
|
||||
} while (ptep++, addr += PAGE_SIZE, addr != end);
|
||||
pte_unmap(ptep - 1);
|
||||
if (addr == end)
|
||||
ret = 1;
|
||||
pte_unmap(ptem);
|
||||
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline void get_head_page_multiple(struct page *page, int nr)
|
||||
|
||||
Reference in New Issue
Block a user