18 hotfixes, 7 of which are cc:stable.
More fixups for this cycle's page_owner updates. And a few userfaultfd fixes. Otherwise, random singletons - see the individual changelogs for details. -----BEGIN PGP SIGNATURE----- iHUEABYIAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCZj6AhAAKCRDdBJ7gKXxA jsvHAQCoSRI4qM0a6j5Fs2Q+B1in+kGWTe50q5Rd755VgolEsgD8CUASDgZ2Qv7g yDAlluXMv4uvA4RqkZvDiezsENzYQw0= =MApd -----END PGP SIGNATURE----- Merge tag 'mm-hotfixes-stable-2024-05-10-13-14' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm Pull MM fixes from Andrew Morton: "18 hotfixes, 7 of which are cc:stable. More fixups for this cycle's page_owner updates. And a few userfaultfd fixes. Otherwise, random singletons - see the individual changelogs for details" * tag 'mm-hotfixes-stable-2024-05-10-13-14' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: mailmap: add entry for Barry Song selftests/mm: fix powerpc ARCH check mailmap: add entry for John Garry XArray: set the marks correctly when splitting an entry selftests/vDSO: fix runtime errors on LoongArch selftests/vDSO: fix building errors on LoongArch mm,page_owner: don't remove __GFP_NOLOCKDEP in add_stack_record_to_list fs/proc/task_mmu: fix uffd-wp confusion in pagemap_scan_pmd_entry() fs/proc/task_mmu: fix loss of young/dirty bits during pagemap scan mm/vmalloc: fix return value of vb_alloc if size is 0 mm: use memalloc_nofs_save() in page_cache_ra_order() kmsan: compiler_types: declare __no_sanitize_or_inline lib/test_xarray.c: fix error assumptions on check_xa_multi_store_adv_add() tools: fix userspace compilation with new test_xarray changes MAINTAINERS: update URL's for KEYS/KEYRINGS_INTEGRITY and TPM DEVICE DRIVER mm: page_owner: fix wrong information in dump_page_owner maple_tree: fix mas_empty_area_rev() null pointer dereference mm/userfaultfd: reset ptes when close() for wr-protected ones
This commit is contained in:
commit
c22c3e0753
6
.mailmap
6
.mailmap
|
@ -97,6 +97,11 @@ Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@linaro.org>
|
||||||
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@spreadtrum.com>
|
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@spreadtrum.com>
|
||||||
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@unisoc.com>
|
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang@unisoc.com>
|
||||||
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang7@gmail.com>
|
Baolin Wang <baolin.wang@linux.alibaba.com> <baolin.wang7@gmail.com>
|
||||||
|
Barry Song <baohua@kernel.org> <21cnbao@gmail.com>
|
||||||
|
Barry Song <baohua@kernel.org> <v-songbaohua@oppo.com>
|
||||||
|
Barry Song <baohua@kernel.org> <song.bao.hua@hisilicon.com>
|
||||||
|
Barry Song <baohua@kernel.org> <Baohua.Song@csr.com>
|
||||||
|
Barry Song <baohua@kernel.org> <barry.song@analog.com>
|
||||||
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
|
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@sandisk.com>
|
||||||
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
|
Bart Van Assche <bvanassche@acm.org> <bart.vanassche@wdc.com>
|
||||||
Bartosz Golaszewski <brgl@bgdev.pl> <bgolaszewski@baylibre.com>
|
Bartosz Golaszewski <brgl@bgdev.pl> <bgolaszewski@baylibre.com>
|
||||||
|
@ -304,6 +309,7 @@ Johan Hovold <johan@kernel.org> <jhovold@gmail.com>
|
||||||
Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
|
Johan Hovold <johan@kernel.org> <johan@hovoldconsulting.com>
|
||||||
John Crispin <john@phrozen.org> <blogic@openwrt.org>
|
John Crispin <john@phrozen.org> <blogic@openwrt.org>
|
||||||
John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com>
|
John Fastabend <john.fastabend@gmail.com> <john.r.fastabend@intel.com>
|
||||||
|
John Garry <john.g.garry@oracle.com> <john.garry@huawei.com>
|
||||||
John Keeping <john@keeping.me.uk> <john@metanate.com>
|
John Keeping <john@keeping.me.uk> <john@metanate.com>
|
||||||
John Moon <john@jmoon.dev> <quic_johmoo@quicinc.com>
|
John Moon <john@jmoon.dev> <quic_johmoo@quicinc.com>
|
||||||
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
|
John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
|
||||||
|
|
|
@ -12041,6 +12041,7 @@ M: Mimi Zohar <zohar@linux.ibm.com>
|
||||||
L: linux-integrity@vger.kernel.org
|
L: linux-integrity@vger.kernel.org
|
||||||
L: keyrings@vger.kernel.org
|
L: keyrings@vger.kernel.org
|
||||||
S: Supported
|
S: Supported
|
||||||
|
W: https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity
|
||||||
F: security/integrity/platform_certs
|
F: security/integrity/platform_certs
|
||||||
|
|
||||||
KFENCE
|
KFENCE
|
||||||
|
@ -22409,7 +22410,7 @@ M: Jarkko Sakkinen <jarkko@kernel.org>
|
||||||
R: Jason Gunthorpe <jgg@ziepe.ca>
|
R: Jason Gunthorpe <jgg@ziepe.ca>
|
||||||
L: linux-integrity@vger.kernel.org
|
L: linux-integrity@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
W: https://kernsec.org/wiki/index.php/Linux_Kernel_Integrity
|
W: https://gitlab.com/jarkkojs/linux-tpmdd-test
|
||||||
Q: https://patchwork.kernel.org/project/linux-integrity/list/
|
Q: https://patchwork.kernel.org/project/linux-integrity/list/
|
||||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git
|
T: git git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git
|
||||||
F: Documentation/devicetree/bindings/tpm/
|
F: Documentation/devicetree/bindings/tpm/
|
||||||
|
|
|
@ -1817,15 +1817,13 @@ static unsigned long pagemap_page_category(struct pagemap_scan_private *p,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void make_uffd_wp_pte(struct vm_area_struct *vma,
|
static void make_uffd_wp_pte(struct vm_area_struct *vma,
|
||||||
unsigned long addr, pte_t *pte)
|
unsigned long addr, pte_t *pte, pte_t ptent)
|
||||||
{
|
{
|
||||||
pte_t ptent = ptep_get(pte);
|
|
||||||
|
|
||||||
if (pte_present(ptent)) {
|
if (pte_present(ptent)) {
|
||||||
pte_t old_pte;
|
pte_t old_pte;
|
||||||
|
|
||||||
old_pte = ptep_modify_prot_start(vma, addr, pte);
|
old_pte = ptep_modify_prot_start(vma, addr, pte);
|
||||||
ptent = pte_mkuffd_wp(ptent);
|
ptent = pte_mkuffd_wp(old_pte);
|
||||||
ptep_modify_prot_commit(vma, addr, pte, old_pte, ptent);
|
ptep_modify_prot_commit(vma, addr, pte, old_pte, ptent);
|
||||||
} else if (is_swap_pte(ptent)) {
|
} else if (is_swap_pte(ptent)) {
|
||||||
ptent = pte_swp_mkuffd_wp(ptent);
|
ptent = pte_swp_mkuffd_wp(ptent);
|
||||||
|
@ -2175,9 +2173,12 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
|
||||||
if ((p->arg.flags & PM_SCAN_WP_MATCHING) && !p->vec_out) {
|
if ((p->arg.flags & PM_SCAN_WP_MATCHING) && !p->vec_out) {
|
||||||
/* Fast path for performing exclusive WP */
|
/* Fast path for performing exclusive WP */
|
||||||
for (addr = start; addr != end; pte++, addr += PAGE_SIZE) {
|
for (addr = start; addr != end; pte++, addr += PAGE_SIZE) {
|
||||||
if (pte_uffd_wp(ptep_get(pte)))
|
pte_t ptent = ptep_get(pte);
|
||||||
|
|
||||||
|
if ((pte_present(ptent) && pte_uffd_wp(ptent)) ||
|
||||||
|
pte_swp_uffd_wp_any(ptent))
|
||||||
continue;
|
continue;
|
||||||
make_uffd_wp_pte(vma, addr, pte);
|
make_uffd_wp_pte(vma, addr, pte, ptent);
|
||||||
if (!flush_end)
|
if (!flush_end)
|
||||||
start = addr;
|
start = addr;
|
||||||
flush_end = addr + PAGE_SIZE;
|
flush_end = addr + PAGE_SIZE;
|
||||||
|
@ -2190,8 +2191,10 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
|
||||||
p->arg.return_mask == PAGE_IS_WRITTEN) {
|
p->arg.return_mask == PAGE_IS_WRITTEN) {
|
||||||
for (addr = start; addr < end; pte++, addr += PAGE_SIZE) {
|
for (addr = start; addr < end; pte++, addr += PAGE_SIZE) {
|
||||||
unsigned long next = addr + PAGE_SIZE;
|
unsigned long next = addr + PAGE_SIZE;
|
||||||
|
pte_t ptent = ptep_get(pte);
|
||||||
|
|
||||||
if (pte_uffd_wp(ptep_get(pte)))
|
if ((pte_present(ptent) && pte_uffd_wp(ptent)) ||
|
||||||
|
pte_swp_uffd_wp_any(ptent))
|
||||||
continue;
|
continue;
|
||||||
ret = pagemap_scan_output(p->cur_vma_category | PAGE_IS_WRITTEN,
|
ret = pagemap_scan_output(p->cur_vma_category | PAGE_IS_WRITTEN,
|
||||||
p, addr, &next);
|
p, addr, &next);
|
||||||
|
@ -2199,7 +2202,7 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
|
||||||
break;
|
break;
|
||||||
if (~p->arg.flags & PM_SCAN_WP_MATCHING)
|
if (~p->arg.flags & PM_SCAN_WP_MATCHING)
|
||||||
continue;
|
continue;
|
||||||
make_uffd_wp_pte(vma, addr, pte);
|
make_uffd_wp_pte(vma, addr, pte, ptent);
|
||||||
if (!flush_end)
|
if (!flush_end)
|
||||||
start = addr;
|
start = addr;
|
||||||
flush_end = next;
|
flush_end = next;
|
||||||
|
@ -2208,8 +2211,9 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (addr = start; addr != end; pte++, addr += PAGE_SIZE) {
|
for (addr = start; addr != end; pte++, addr += PAGE_SIZE) {
|
||||||
|
pte_t ptent = ptep_get(pte);
|
||||||
unsigned long categories = p->cur_vma_category |
|
unsigned long categories = p->cur_vma_category |
|
||||||
pagemap_page_category(p, vma, addr, ptep_get(pte));
|
pagemap_page_category(p, vma, addr, ptent);
|
||||||
unsigned long next = addr + PAGE_SIZE;
|
unsigned long next = addr + PAGE_SIZE;
|
||||||
|
|
||||||
if (!pagemap_scan_is_interesting_page(categories, p))
|
if (!pagemap_scan_is_interesting_page(categories, p))
|
||||||
|
@ -2224,7 +2228,7 @@ static int pagemap_scan_pmd_entry(pmd_t *pmd, unsigned long start,
|
||||||
if (~categories & PAGE_IS_WRITTEN)
|
if (~categories & PAGE_IS_WRITTEN)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
make_uffd_wp_pte(vma, addr, pte);
|
make_uffd_wp_pte(vma, addr, pte, ptent);
|
||||||
if (!flush_end)
|
if (!flush_end)
|
||||||
start = addr;
|
start = addr;
|
||||||
flush_end = next;
|
flush_end = next;
|
||||||
|
|
|
@ -895,6 +895,10 @@ static int userfaultfd_release(struct inode *inode, struct file *file)
|
||||||
prev = vma;
|
prev = vma;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
/* Reset ptes for the whole vma range if wr-protected */
|
||||||
|
if (userfaultfd_wp(vma))
|
||||||
|
uffd_wp_range(vma, vma->vm_start,
|
||||||
|
vma->vm_end - vma->vm_start, false);
|
||||||
new_flags = vma->vm_flags & ~__VM_UFFD_FLAGS;
|
new_flags = vma->vm_flags & ~__VM_UFFD_FLAGS;
|
||||||
vma = vma_modify_flags_uffd(&vmi, prev, vma, vma->vm_start,
|
vma = vma_modify_flags_uffd(&vmi, prev, vma, vma->vm_start,
|
||||||
vma->vm_end, new_flags,
|
vma->vm_end, new_flags,
|
||||||
|
|
|
@ -278,6 +278,17 @@ struct ftrace_likely_data {
|
||||||
# define __no_kcsan
|
# define __no_kcsan
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef __SANITIZE_MEMORY__
|
||||||
|
/*
|
||||||
|
* Similarly to KASAN and KCSAN, KMSAN loses function attributes of inlined
|
||||||
|
* functions, therefore disabling KMSAN checks also requires disabling inlining.
|
||||||
|
*
|
||||||
|
* __no_sanitize_or_inline effectively prevents KMSAN from reporting errors
|
||||||
|
* within the function and marks all its outputs as initialized.
|
||||||
|
*/
|
||||||
|
# define __no_sanitize_or_inline __no_kmsan_checks notrace __maybe_unused
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef __no_sanitize_or_inline
|
#ifndef __no_sanitize_or_inline
|
||||||
#define __no_sanitize_or_inline __always_inline
|
#define __no_sanitize_or_inline __always_inline
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -5109,18 +5109,18 @@ int mas_empty_area_rev(struct ma_state *mas, unsigned long min,
|
||||||
if (size == 0 || max - min < size - 1)
|
if (size == 0 || max - min < size - 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (mas_is_start(mas)) {
|
if (mas_is_start(mas))
|
||||||
mas_start(mas);
|
mas_start(mas);
|
||||||
mas->offset = mas_data_end(mas);
|
else if ((mas->offset < 2) && (!mas_rewind_node(mas)))
|
||||||
} else if (mas->offset >= 2) {
|
|
||||||
mas->offset -= 2;
|
|
||||||
} else if (!mas_rewind_node(mas)) {
|
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
|
||||||
|
|
||||||
/* Empty set. */
|
if (unlikely(mas_is_none(mas) || mas_is_ptr(mas)))
|
||||||
if (mas_is_none(mas) || mas_is_ptr(mas))
|
|
||||||
return mas_sparse_area(mas, min, max, size, false);
|
return mas_sparse_area(mas, min, max, size, false);
|
||||||
|
else if (mas->offset >= 2)
|
||||||
|
mas->offset -= 2;
|
||||||
|
else
|
||||||
|
mas->offset = mas_data_end(mas);
|
||||||
|
|
||||||
|
|
||||||
/* The start of the window can only be within these values. */
|
/* The start of the window can only be within these values. */
|
||||||
mas->index = min;
|
mas->index = min;
|
||||||
|
|
|
@ -744,15 +744,20 @@ static noinline void check_xa_multi_store_adv_add(struct xarray *xa,
|
||||||
|
|
||||||
do {
|
do {
|
||||||
xas_lock_irq(&xas);
|
xas_lock_irq(&xas);
|
||||||
|
|
||||||
xas_store(&xas, p);
|
xas_store(&xas, p);
|
||||||
XA_BUG_ON(xa, xas_error(&xas));
|
|
||||||
XA_BUG_ON(xa, xa_load(xa, index) != p);
|
|
||||||
|
|
||||||
xas_unlock_irq(&xas);
|
xas_unlock_irq(&xas);
|
||||||
|
/*
|
||||||
|
* In our selftest case the only failure we can expect is for
|
||||||
|
* there not to be enough memory as we're not mimicking the
|
||||||
|
* entire page cache, so verify that's the only error we can run
|
||||||
|
* into here. The xas_nomem() which follows will ensure to fix
|
||||||
|
* that condition for us so to chug on on the loop.
|
||||||
|
*/
|
||||||
|
XA_BUG_ON(xa, xas_error(&xas) && xas_error(&xas) != -ENOMEM);
|
||||||
} while (xas_nomem(&xas, GFP_KERNEL));
|
} while (xas_nomem(&xas, GFP_KERNEL));
|
||||||
|
|
||||||
XA_BUG_ON(xa, xas_error(&xas));
|
XA_BUG_ON(xa, xas_error(&xas));
|
||||||
|
XA_BUG_ON(xa, xa_load(xa, index) != p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* mimics page_cache_delete() */
|
/* mimics page_cache_delete() */
|
||||||
|
@ -1783,9 +1788,11 @@ static void check_split_1(struct xarray *xa, unsigned long index,
|
||||||
unsigned int order, unsigned int new_order)
|
unsigned int order, unsigned int new_order)
|
||||||
{
|
{
|
||||||
XA_STATE_ORDER(xas, xa, index, new_order);
|
XA_STATE_ORDER(xas, xa, index, new_order);
|
||||||
unsigned int i;
|
unsigned int i, found;
|
||||||
|
void *entry;
|
||||||
|
|
||||||
xa_store_order(xa, index, order, xa, GFP_KERNEL);
|
xa_store_order(xa, index, order, xa, GFP_KERNEL);
|
||||||
|
xa_set_mark(xa, index, XA_MARK_1);
|
||||||
|
|
||||||
xas_split_alloc(&xas, xa, order, GFP_KERNEL);
|
xas_split_alloc(&xas, xa, order, GFP_KERNEL);
|
||||||
xas_lock(&xas);
|
xas_lock(&xas);
|
||||||
|
@ -1802,6 +1809,16 @@ static void check_split_1(struct xarray *xa, unsigned long index,
|
||||||
xa_set_mark(xa, index, XA_MARK_0);
|
xa_set_mark(xa, index, XA_MARK_0);
|
||||||
XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0));
|
XA_BUG_ON(xa, !xa_get_mark(xa, index, XA_MARK_0));
|
||||||
|
|
||||||
|
xas_set_order(&xas, index, 0);
|
||||||
|
found = 0;
|
||||||
|
rcu_read_lock();
|
||||||
|
xas_for_each_marked(&xas, entry, ULONG_MAX, XA_MARK_1) {
|
||||||
|
found++;
|
||||||
|
XA_BUG_ON(xa, xa_is_internal(entry));
|
||||||
|
}
|
||||||
|
rcu_read_unlock();
|
||||||
|
XA_BUG_ON(xa, found != 1 << (order - new_order));
|
||||||
|
|
||||||
xa_destroy(xa);
|
xa_destroy(xa);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
23
lib/xarray.c
23
lib/xarray.c
|
@ -969,8 +969,22 @@ static unsigned int node_get_marks(struct xa_node *node, unsigned int offset)
|
||||||
return marks;
|
return marks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void node_mark_slots(struct xa_node *node, unsigned int sibs,
|
||||||
|
xa_mark_t mark)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (sibs == 0)
|
||||||
|
node_mark_all(node, mark);
|
||||||
|
else {
|
||||||
|
for (i = 0; i < XA_CHUNK_SIZE; i += sibs + 1)
|
||||||
|
node_set_mark(node, i, mark);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void node_set_marks(struct xa_node *node, unsigned int offset,
|
static void node_set_marks(struct xa_node *node, unsigned int offset,
|
||||||
struct xa_node *child, unsigned int marks)
|
struct xa_node *child, unsigned int sibs,
|
||||||
|
unsigned int marks)
|
||||||
{
|
{
|
||||||
xa_mark_t mark = XA_MARK_0;
|
xa_mark_t mark = XA_MARK_0;
|
||||||
|
|
||||||
|
@ -978,7 +992,7 @@ static void node_set_marks(struct xa_node *node, unsigned int offset,
|
||||||
if (marks & (1 << (__force unsigned int)mark)) {
|
if (marks & (1 << (__force unsigned int)mark)) {
|
||||||
node_set_mark(node, offset, mark);
|
node_set_mark(node, offset, mark);
|
||||||
if (child)
|
if (child)
|
||||||
node_mark_all(child, mark);
|
node_mark_slots(child, sibs, mark);
|
||||||
}
|
}
|
||||||
if (mark == XA_MARK_MAX)
|
if (mark == XA_MARK_MAX)
|
||||||
break;
|
break;
|
||||||
|
@ -1077,7 +1091,8 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)
|
||||||
child->nr_values = xa_is_value(entry) ?
|
child->nr_values = xa_is_value(entry) ?
|
||||||
XA_CHUNK_SIZE : 0;
|
XA_CHUNK_SIZE : 0;
|
||||||
RCU_INIT_POINTER(child->parent, node);
|
RCU_INIT_POINTER(child->parent, node);
|
||||||
node_set_marks(node, offset, child, marks);
|
node_set_marks(node, offset, child, xas->xa_sibs,
|
||||||
|
marks);
|
||||||
rcu_assign_pointer(node->slots[offset],
|
rcu_assign_pointer(node->slots[offset],
|
||||||
xa_mk_node(child));
|
xa_mk_node(child));
|
||||||
if (xa_is_value(curr))
|
if (xa_is_value(curr))
|
||||||
|
@ -1086,7 +1101,7 @@ void xas_split(struct xa_state *xas, void *entry, unsigned int order)
|
||||||
} else {
|
} else {
|
||||||
unsigned int canon = offset - xas->xa_sibs;
|
unsigned int canon = offset - xas->xa_sibs;
|
||||||
|
|
||||||
node_set_marks(node, canon, NULL, marks);
|
node_set_marks(node, canon, NULL, 0, marks);
|
||||||
rcu_assign_pointer(node->slots[canon], entry);
|
rcu_assign_pointer(node->slots[canon], entry);
|
||||||
while (offset > canon)
|
while (offset > canon)
|
||||||
rcu_assign_pointer(node->slots[offset--],
|
rcu_assign_pointer(node->slots[offset--],
|
||||||
|
|
|
@ -170,7 +170,7 @@ static void add_stack_record_to_list(struct stack_record *stack_record,
|
||||||
|
|
||||||
/* Filter gfp_mask the same way stackdepot does, for consistency */
|
/* Filter gfp_mask the same way stackdepot does, for consistency */
|
||||||
gfp_mask &= ~GFP_ZONEMASK;
|
gfp_mask &= ~GFP_ZONEMASK;
|
||||||
gfp_mask &= (GFP_ATOMIC | GFP_KERNEL);
|
gfp_mask &= (GFP_ATOMIC | GFP_KERNEL | __GFP_NOLOCKDEP);
|
||||||
gfp_mask |= __GFP_NOWARN;
|
gfp_mask |= __GFP_NOWARN;
|
||||||
|
|
||||||
set_current_in_page_owner();
|
set_current_in_page_owner();
|
||||||
|
@ -328,7 +328,7 @@ noinline void __set_page_owner(struct page *page, unsigned short order,
|
||||||
if (unlikely(!page_ext))
|
if (unlikely(!page_ext))
|
||||||
return;
|
return;
|
||||||
__update_page_owner_handle(page_ext, handle, order, gfp_mask, -1,
|
__update_page_owner_handle(page_ext, handle, order, gfp_mask, -1,
|
||||||
current->pid, current->tgid, ts_nsec,
|
ts_nsec, current->pid, current->tgid,
|
||||||
current->comm);
|
current->comm);
|
||||||
page_ext_put(page_ext);
|
page_ext_put(page_ext);
|
||||||
inc_stack_record_count(handle, gfp_mask, 1 << order);
|
inc_stack_record_count(handle, gfp_mask, 1 << order);
|
||||||
|
|
|
@ -490,6 +490,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
|
||||||
pgoff_t index = readahead_index(ractl);
|
pgoff_t index = readahead_index(ractl);
|
||||||
pgoff_t limit = (i_size_read(mapping->host) - 1) >> PAGE_SHIFT;
|
pgoff_t limit = (i_size_read(mapping->host) - 1) >> PAGE_SHIFT;
|
||||||
pgoff_t mark = index + ra->size - ra->async_size;
|
pgoff_t mark = index + ra->size - ra->async_size;
|
||||||
|
unsigned int nofs;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
gfp_t gfp = readahead_gfp_mask(mapping);
|
gfp_t gfp = readahead_gfp_mask(mapping);
|
||||||
|
|
||||||
|
@ -504,6 +505,8 @@ void page_cache_ra_order(struct readahead_control *ractl,
|
||||||
new_order = min_t(unsigned int, new_order, ilog2(ra->size));
|
new_order = min_t(unsigned int, new_order, ilog2(ra->size));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* See comment in page_cache_ra_unbounded() */
|
||||||
|
nofs = memalloc_nofs_save();
|
||||||
filemap_invalidate_lock_shared(mapping);
|
filemap_invalidate_lock_shared(mapping);
|
||||||
while (index <= limit) {
|
while (index <= limit) {
|
||||||
unsigned int order = new_order;
|
unsigned int order = new_order;
|
||||||
|
@ -527,6 +530,7 @@ void page_cache_ra_order(struct readahead_control *ractl,
|
||||||
|
|
||||||
read_pages(ractl);
|
read_pages(ractl);
|
||||||
filemap_invalidate_unlock_shared(mapping);
|
filemap_invalidate_unlock_shared(mapping);
|
||||||
|
memalloc_nofs_restore(nofs);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If there were already pages in the page cache, then we may have
|
* If there were already pages in the page cache, then we may have
|
||||||
|
|
|
@ -2710,7 +2710,7 @@ static void *vb_alloc(unsigned long size, gfp_t gfp_mask)
|
||||||
* get_order(0) returns funny result. Just warn and terminate
|
* get_order(0) returns funny result. Just warn and terminate
|
||||||
* early.
|
* early.
|
||||||
*/
|
*/
|
||||||
return NULL;
|
return ERR_PTR(-EINVAL);
|
||||||
}
|
}
|
||||||
order = get_order(size);
|
order = get_order(size);
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
#define pr_info printk
|
#define pr_info printk
|
||||||
#define pr_debug printk
|
#define pr_debug printk
|
||||||
#define pr_cont printk
|
#define pr_cont printk
|
||||||
|
#define schedule()
|
||||||
|
#define PAGE_SHIFT 12
|
||||||
|
|
||||||
#define __acquires(x)
|
#define __acquires(x)
|
||||||
#define __releases(x)
|
#define __releases(x)
|
||||||
|
|
|
@ -12,7 +12,7 @@ uname_M := $(shell uname -m 2>/dev/null || echo not)
|
||||||
else
|
else
|
||||||
uname_M := $(shell echo $(CROSS_COMPILE) | grep -o '^[a-z0-9]\+')
|
uname_M := $(shell echo $(CROSS_COMPILE) | grep -o '^[a-z0-9]\+')
|
||||||
endif
|
endif
|
||||||
ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/' -e 's/ppc64.*/ppc64/')
|
ARCH ?= $(shell echo $(uname_M) | sed -e 's/aarch64.*/arm64/' -e 's/ppc64.*/powerpc/')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# Without this, failed build products remain, with up-to-date timestamps,
|
# Without this, failed build products remain, with up-to-date timestamps,
|
||||||
|
@ -98,13 +98,13 @@ TEST_GEN_FILES += $(BINARIES_64)
|
||||||
endif
|
endif
|
||||||
else
|
else
|
||||||
|
|
||||||
ifneq (,$(findstring $(ARCH),ppc64))
|
ifneq (,$(findstring $(ARCH),powerpc))
|
||||||
TEST_GEN_FILES += protection_keys
|
TEST_GEN_FILES += protection_keys
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 ppc64 riscv64 s390x sparc64 x86_64))
|
ifneq (,$(filter $(ARCH),arm64 ia64 mips64 parisc64 powerpc riscv64 s390x sparc64 x86_64))
|
||||||
TEST_GEN_FILES += va_high_addr_switch
|
TEST_GEN_FILES += va_high_addr_switch
|
||||||
TEST_GEN_FILES += virtual_address_range
|
TEST_GEN_FILES += virtual_address_range
|
||||||
TEST_GEN_FILES += write_to_hugetlbfs
|
TEST_GEN_FILES += write_to_hugetlbfs
|
||||||
|
|
|
@ -53,15 +53,19 @@
|
||||||
#if __riscv_xlen == 32
|
#if __riscv_xlen == 32
|
||||||
#define VDSO_32BIT 1
|
#define VDSO_32BIT 1
|
||||||
#endif
|
#endif
|
||||||
|
#elif defined(__loongarch__)
|
||||||
|
#define VDSO_VERSION 6
|
||||||
|
#define VDSO_NAMES 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const char *versions[6] = {
|
static const char *versions[7] = {
|
||||||
"LINUX_2.6",
|
"LINUX_2.6",
|
||||||
"LINUX_2.6.15",
|
"LINUX_2.6.15",
|
||||||
"LINUX_2.6.29",
|
"LINUX_2.6.29",
|
||||||
"LINUX_2.6.39",
|
"LINUX_2.6.39",
|
||||||
"LINUX_4",
|
"LINUX_4",
|
||||||
"LINUX_4.15",
|
"LINUX_4.15",
|
||||||
|
"LINUX_5.10"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *names[2][6] = {
|
static const char *names[2][6] = {
|
||||||
|
|
|
@ -13,13 +13,7 @@
|
||||||
|
|
||||||
#include "../kselftest.h"
|
#include "../kselftest.h"
|
||||||
#include "parse_vdso.h"
|
#include "parse_vdso.h"
|
||||||
|
#include "vdso_config.h"
|
||||||
#if defined(__riscv)
|
|
||||||
const char *version = "LINUX_4.15";
|
|
||||||
#else
|
|
||||||
const char *version = "LINUX_2.6";
|
|
||||||
#endif
|
|
||||||
const char *name = "__vdso_getcpu";
|
|
||||||
|
|
||||||
struct getcpu_cache;
|
struct getcpu_cache;
|
||||||
typedef long (*getcpu_t)(unsigned int *, unsigned int *,
|
typedef long (*getcpu_t)(unsigned int *, unsigned int *,
|
||||||
|
@ -27,6 +21,8 @@ typedef long (*getcpu_t)(unsigned int *, unsigned int *,
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
const char *version = versions[VDSO_VERSION];
|
||||||
|
const char **name = (const char **)&names[VDSO_NAMES];
|
||||||
unsigned long sysinfo_ehdr;
|
unsigned long sysinfo_ehdr;
|
||||||
unsigned int cpu, node;
|
unsigned int cpu, node;
|
||||||
getcpu_t get_cpu;
|
getcpu_t get_cpu;
|
||||||
|
@ -40,9 +36,9 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
|
vdso_init_from_sysinfo_ehdr(getauxval(AT_SYSINFO_EHDR));
|
||||||
|
|
||||||
get_cpu = (getcpu_t)vdso_sym(version, name);
|
get_cpu = (getcpu_t)vdso_sym(version, name[4]);
|
||||||
if (!get_cpu) {
|
if (!get_cpu) {
|
||||||
printf("Could not find %s\n", name);
|
printf("Could not find %s\n", name[4]);
|
||||||
return KSFT_SKIP;
|
return KSFT_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,7 +46,7 @@ int main(int argc, char **argv)
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
printf("Running on CPU %u node %u\n", cpu, node);
|
printf("Running on CPU %u node %u\n", cpu, node);
|
||||||
} else {
|
} else {
|
||||||
printf("%s failed\n", name);
|
printf("%s failed\n", name[4]);
|
||||||
return KSFT_FAIL;
|
return KSFT_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,25 +18,13 @@
|
||||||
|
|
||||||
#include "../kselftest.h"
|
#include "../kselftest.h"
|
||||||
#include "parse_vdso.h"
|
#include "parse_vdso.h"
|
||||||
|
#include "vdso_config.h"
|
||||||
/*
|
|
||||||
* ARM64's vDSO exports its gettimeofday() implementation with a different
|
|
||||||
* name and version from other architectures, so we need to handle it as
|
|
||||||
* a special case.
|
|
||||||
*/
|
|
||||||
#if defined(__aarch64__)
|
|
||||||
const char *version = "LINUX_2.6.39";
|
|
||||||
const char *name = "__kernel_gettimeofday";
|
|
||||||
#elif defined(__riscv)
|
|
||||||
const char *version = "LINUX_4.15";
|
|
||||||
const char *name = "__vdso_gettimeofday";
|
|
||||||
#else
|
|
||||||
const char *version = "LINUX_2.6";
|
|
||||||
const char *name = "__vdso_gettimeofday";
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
const char *version = versions[VDSO_VERSION];
|
||||||
|
const char **name = (const char **)&names[VDSO_NAMES];
|
||||||
|
|
||||||
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
|
unsigned long sysinfo_ehdr = getauxval(AT_SYSINFO_EHDR);
|
||||||
if (!sysinfo_ehdr) {
|
if (!sysinfo_ehdr) {
|
||||||
printf("AT_SYSINFO_EHDR is not present!\n");
|
printf("AT_SYSINFO_EHDR is not present!\n");
|
||||||
|
@ -47,10 +35,10 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
/* Find gettimeofday. */
|
/* Find gettimeofday. */
|
||||||
typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
|
typedef long (*gtod_t)(struct timeval *tv, struct timezone *tz);
|
||||||
gtod_t gtod = (gtod_t)vdso_sym(version, name);
|
gtod_t gtod = (gtod_t)vdso_sym(version, name[0]);
|
||||||
|
|
||||||
if (!gtod) {
|
if (!gtod) {
|
||||||
printf("Could not find %s\n", name);
|
printf("Could not find %s\n", name[0]);
|
||||||
return KSFT_SKIP;
|
return KSFT_SKIP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +49,7 @@ int main(int argc, char **argv)
|
||||||
printf("The time is %lld.%06lld\n",
|
printf("The time is %lld.%06lld\n",
|
||||||
(long long)tv.tv_sec, (long long)tv.tv_usec);
|
(long long)tv.tv_sec, (long long)tv.tv_usec);
|
||||||
} else {
|
} else {
|
||||||
printf("%s failed\n", name);
|
printf("%s failed\n", name[0]);
|
||||||
return KSFT_FAIL;
|
return KSFT_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue