Merge 5a29232d87 ("Merge tag 'for-5.19-rc6-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux") into android-mainline
Steps on the way to 5.19-rc7 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com> Change-Id: I4acb270268421ee369583b16917b156c2c88820c
This commit is contained in:
@@ -223,7 +223,7 @@ Module Loading
|
||||
Inter Module support
|
||||
--------------------
|
||||
|
||||
Refer to the file kernel/module.c for more information.
|
||||
Refer to the files in kernel/module/ for more information.
|
||||
|
||||
Hardware Interfaces
|
||||
===================
|
||||
|
||||
@@ -51,8 +51,8 @@ namespace ``USB_STORAGE``, use::
|
||||
The corresponding ksymtab entry struct ``kernel_symbol`` will have the member
|
||||
``namespace`` set accordingly. A symbol that is exported without a namespace will
|
||||
refer to ``NULL``. There is no default namespace if none is defined. ``modpost``
|
||||
and kernel/module.c make use the namespace at build time or module load time,
|
||||
respectively.
|
||||
and kernel/module/main.c make use the namespace at build time or module load
|
||||
time, respectively.
|
||||
|
||||
2.2 Using the DEFAULT_SYMBOL_NAMESPACE define
|
||||
=============================================
|
||||
|
||||
@@ -210,11 +210,11 @@ module->symtab.
|
||||
=====================================
|
||||
Normally, a stripped down copy of a module's symbol table (containing only
|
||||
"core" symbols) is made available through module->symtab (See layout_symtab()
|
||||
in kernel/module.c). For livepatch modules, the symbol table copied into memory
|
||||
on module load must be exactly the same as the symbol table produced when the
|
||||
patch module was compiled. This is because the relocations in each livepatch
|
||||
relocation section refer to their respective symbols with their symbol indices,
|
||||
and the original symbol indices (and thus the symtab ordering) must be
|
||||
in kernel/module/kallsyms.c). For livepatch modules, the symbol table copied
|
||||
into memory on module load must be exactly the same as the symbol table produced
|
||||
when the patch module was compiled. This is because the relocations in each
|
||||
livepatch relocation section refer to their respective symbols with their symbol
|
||||
indices, and the original symbol indices (and thus the symtab ordering) must be
|
||||
preserved in order for apply_relocate_add() to find the right symbol.
|
||||
|
||||
For example, take this particular rela from a livepatch module:::
|
||||
|
||||
@@ -50,9 +50,9 @@ Di conseguenza, nella tabella dei simboli del kernel ci sarà una voce
|
||||
rappresentata dalla struttura ``kernel_symbol`` che avrà il campo
|
||||
``namespace`` (spazio dei nomi) impostato. Un simbolo esportato senza uno spazio
|
||||
dei nomi avrà questo campo impostato a ``NULL``. Non esiste uno spazio dei nomi
|
||||
di base. Il programma ``modpost`` e il codice in kernel/module.c usano lo spazio
|
||||
dei nomi, rispettivamente, durante la compilazione e durante il caricamento
|
||||
di un modulo.
|
||||
di base. Il programma ``modpost`` e il codice in kernel/module/main.c usano lo
|
||||
spazio dei nomi, rispettivamente, durante la compilazione e durante il
|
||||
caricamento di un modulo.
|
||||
|
||||
2.2 Usare il simbolo di preprocessore DEFAULT_SYMBOL_NAMESPACE
|
||||
==============================================================
|
||||
|
||||
@@ -224,7 +224,7 @@ kernel/kmod.c
|
||||
模块接口支持
|
||||
------------
|
||||
|
||||
更多信息请参考文件kernel/module.c。
|
||||
更多信息请参阅kernel/module/目录下的文件。
|
||||
|
||||
硬件接口
|
||||
========
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
|
||||
相应的 ksymtab 条目结构体 ``kernel_symbol`` 将有相应的成员 ``命名空间`` 集。
|
||||
导出时未指明命名空间的符号将指向 ``NULL`` 。如果没有定义命名空间,则默认没有。
|
||||
``modpost`` 和kernel/module.c分别在构建时或模块加载时使用名称空间。
|
||||
``modpost`` 和kernel/module/main.c分别在构建时或模块加载时使用名称空间。
|
||||
|
||||
2.2 使用DEFAULT_SYMBOL_NAMESPACE定义
|
||||
====================================
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@ config RISCV
|
||||
select ARCH_SUPPORTS_ATOMIC_RMW
|
||||
select ARCH_SUPPORTS_DEBUG_PAGEALLOC if MMU
|
||||
select ARCH_SUPPORTS_HUGETLBFS if MMU
|
||||
select ARCH_SUPPORTS_PAGE_TABLE_CHECK
|
||||
select ARCH_SUPPORTS_PAGE_TABLE_CHECK if MMU
|
||||
select ARCH_USE_MEMTEST
|
||||
select ARCH_USE_QUEUED_RWLOCKS
|
||||
select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU
|
||||
|
||||
@@ -271,8 +271,12 @@ static inline void __iomem *ioremap_prot(phys_addr_t offset, unsigned long size,
|
||||
#endif /* CONFIG_HAVE_IOREMAP_PROT */
|
||||
|
||||
#else /* CONFIG_MMU */
|
||||
#define iounmap(addr) do { } while (0)
|
||||
#define ioremap(offset, size) ((void __iomem *)(unsigned long)(offset))
|
||||
static inline void __iomem *ioremap(phys_addr_t offset, size_t size)
|
||||
{
|
||||
return (void __iomem *)(unsigned long)offset;
|
||||
}
|
||||
|
||||
static inline void iounmap(volatile void __iomem *addr) { }
|
||||
#endif /* CONFIG_MMU */
|
||||
|
||||
#define ioremap_uc ioremap
|
||||
|
||||
+10
-7
@@ -549,6 +549,16 @@ static struct vfio_group *vfio_group_find_or_alloc(struct device *dev)
|
||||
if (!iommu_group)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/*
|
||||
* VFIO always sets IOMMU_CACHE because we offer no way for userspace to
|
||||
* restore cache coherency. It has to be checked here because it is only
|
||||
* valid for cases where we are using iommu groups.
|
||||
*/
|
||||
if (!iommu_capable(dev->bus, IOMMU_CAP_CACHE_COHERENCY)) {
|
||||
iommu_group_put(iommu_group);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
group = vfio_group_get_from_iommu(iommu_group);
|
||||
if (!group)
|
||||
group = vfio_create_group(iommu_group, VFIO_IOMMU);
|
||||
@@ -601,13 +611,6 @@ static int __vfio_register_dev(struct vfio_device *device,
|
||||
|
||||
int vfio_register_group_dev(struct vfio_device *device)
|
||||
{
|
||||
/*
|
||||
* VFIO always sets IOMMU_CACHE because we offer no way for userspace to
|
||||
* restore cache coherency.
|
||||
*/
|
||||
if (!iommu_capable(device->dev->bus, IOMMU_CAP_CACHE_COHERENCY))
|
||||
return -EINVAL;
|
||||
|
||||
return __vfio_register_dev(device,
|
||||
vfio_group_find_or_alloc(device->dev));
|
||||
}
|
||||
|
||||
+13
-1
@@ -7681,7 +7681,19 @@ static int btrfs_dio_iomap_begin(struct inode *inode, loff_t start,
|
||||
if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags) ||
|
||||
em->block_start == EXTENT_MAP_INLINE) {
|
||||
free_extent_map(em);
|
||||
ret = -ENOTBLK;
|
||||
/*
|
||||
* If we are in a NOWAIT context, return -EAGAIN in order to
|
||||
* fallback to buffered IO. This is not only because we can
|
||||
* block with buffered IO (no support for NOWAIT semantics at
|
||||
* the moment) but also to avoid returning short reads to user
|
||||
* space - this happens if we were able to read some data from
|
||||
* previous non-compressed extents and then when we fallback to
|
||||
* buffered IO, at btrfs_file_read_iter() by calling
|
||||
* filemap_read(), we fail to fault in pages for the read buffer,
|
||||
* in which case filemap_read() returns a short read (the number
|
||||
* of bytes previously read is > 0, so it does not return -EFAULT).
|
||||
*/
|
||||
ret = (flags & IOMAP_NOWAIT) ? -EAGAIN : -ENOTBLK;
|
||||
goto unlock_err;
|
||||
}
|
||||
|
||||
|
||||
+14
-20
@@ -1735,12 +1735,14 @@ static int read_zone_info(struct btrfs_fs_info *fs_info, u64 logical,
|
||||
ret = btrfs_map_sblock(fs_info, BTRFS_MAP_GET_READ_MIRRORS, logical,
|
||||
&mapped_length, &bioc);
|
||||
if (ret || !bioc || mapped_length < PAGE_SIZE) {
|
||||
btrfs_put_bioc(bioc);
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto out_put_bioc;
|
||||
}
|
||||
|
||||
if (bioc->map_type & BTRFS_BLOCK_GROUP_RAID56_MASK)
|
||||
return -EINVAL;
|
||||
if (bioc->map_type & BTRFS_BLOCK_GROUP_RAID56_MASK) {
|
||||
ret = -EINVAL;
|
||||
goto out_put_bioc;
|
||||
}
|
||||
|
||||
nofs_flag = memalloc_nofs_save();
|
||||
nmirrors = (int)bioc->num_stripes;
|
||||
@@ -1759,7 +1761,8 @@ static int read_zone_info(struct btrfs_fs_info *fs_info, u64 logical,
|
||||
break;
|
||||
}
|
||||
memalloc_nofs_restore(nofs_flag);
|
||||
|
||||
out_put_bioc:
|
||||
btrfs_put_bioc(bioc);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -1885,7 +1888,6 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
|
||||
{
|
||||
struct btrfs_fs_info *fs_info = block_group->fs_info;
|
||||
struct map_lookup *map;
|
||||
bool need_zone_finish;
|
||||
int ret = 0;
|
||||
int i;
|
||||
|
||||
@@ -1942,12 +1944,6 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The block group is not fully allocated, so not fully written yet. We
|
||||
* need to send ZONE_FINISH command to free up an active zone.
|
||||
*/
|
||||
need_zone_finish = !btrfs_zoned_bg_is_full(block_group);
|
||||
|
||||
block_group->zone_is_active = 0;
|
||||
block_group->alloc_offset = block_group->zone_capacity;
|
||||
block_group->free_space_ctl->free_space = 0;
|
||||
@@ -1963,15 +1959,13 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
|
||||
if (device->zone_info->max_active_zones == 0)
|
||||
continue;
|
||||
|
||||
if (need_zone_finish) {
|
||||
ret = blkdev_zone_mgmt(device->bdev, REQ_OP_ZONE_FINISH,
|
||||
physical >> SECTOR_SHIFT,
|
||||
device->zone_info->zone_size >> SECTOR_SHIFT,
|
||||
GFP_NOFS);
|
||||
ret = blkdev_zone_mgmt(device->bdev, REQ_OP_ZONE_FINISH,
|
||||
physical >> SECTOR_SHIFT,
|
||||
device->zone_info->zone_size >> SECTOR_SHIFT,
|
||||
GFP_NOFS);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
btrfs_dev_clear_active_zone(device, physical);
|
||||
}
|
||||
|
||||
@@ -1301,7 +1301,7 @@ int begin_new_exec(struct linux_binprm * bprm)
|
||||
bprm->mm = NULL;
|
||||
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
exit_itimers(me->signal);
|
||||
exit_itimers(me);
|
||||
flush_itimer_signals();
|
||||
#endif
|
||||
|
||||
|
||||
@@ -198,6 +198,9 @@ static inline int nilfs_acl_chmod(struct inode *inode)
|
||||
|
||||
static inline int nilfs_init_acl(struct inode *inode, struct inode *dir)
|
||||
{
|
||||
if (S_ISLNK(inode->i_mode))
|
||||
return 0;
|
||||
|
||||
inode->i_mode &= ~current_umask();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -149,19 +149,19 @@ static inline void *kmap_local_folio(struct folio *folio, size_t offset);
|
||||
* It is used in atomic context when code wants to access the contents of a
|
||||
* page that might be allocated from high memory (see __GFP_HIGHMEM), for
|
||||
* example a page in the pagecache. The API has two functions, and they
|
||||
* can be used in a manner similar to the following:
|
||||
* can be used in a manner similar to the following::
|
||||
*
|
||||
* -- Find the page of interest. --
|
||||
* struct page *page = find_get_page(mapping, offset);
|
||||
* // Find the page of interest.
|
||||
* struct page *page = find_get_page(mapping, offset);
|
||||
*
|
||||
* -- Gain access to the contents of that page. --
|
||||
* void *vaddr = kmap_atomic(page);
|
||||
* // Gain access to the contents of that page.
|
||||
* void *vaddr = kmap_atomic(page);
|
||||
*
|
||||
* -- Do something to the contents of that page. --
|
||||
* memset(vaddr, 0, PAGE_SIZE);
|
||||
* // Do something to the contents of that page.
|
||||
* memset(vaddr, 0, PAGE_SIZE);
|
||||
*
|
||||
* -- Unmap that page. --
|
||||
* kunmap_atomic(vaddr);
|
||||
* // Unmap that page.
|
||||
* kunmap_atomic(vaddr);
|
||||
*
|
||||
* Note that the kunmap_atomic() call takes the result of the kmap_atomic()
|
||||
* call, not the argument.
|
||||
|
||||
@@ -85,7 +85,7 @@ static inline void exit_thread(struct task_struct *tsk)
|
||||
extern __noreturn void do_group_exit(int);
|
||||
|
||||
extern void exit_files(struct task_struct *);
|
||||
extern void exit_itimers(struct signal_struct *);
|
||||
extern void exit_itimers(struct task_struct *);
|
||||
|
||||
extern pid_t kernel_clone(struct kernel_clone_args *kargs);
|
||||
struct task_struct *create_io_thread(int (*fn)(void *), void *arg, int node);
|
||||
|
||||
+4
-1
@@ -64,7 +64,7 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
|
||||
goto fail_put;
|
||||
|
||||
if (!setup_ipc_sysctls(ns))
|
||||
goto fail_put;
|
||||
goto fail_mq;
|
||||
|
||||
sem_init_ns(ns);
|
||||
msg_init_ns(ns);
|
||||
@@ -72,6 +72,9 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
|
||||
|
||||
return ns;
|
||||
|
||||
fail_mq:
|
||||
retire_mq_sysctls(ns);
|
||||
|
||||
fail_put:
|
||||
put_user_ns(ns->user_ns);
|
||||
ns_free_inum(&ns->ns);
|
||||
|
||||
+1
-1
@@ -766,7 +766,7 @@ void __noreturn do_exit(long code)
|
||||
|
||||
#ifdef CONFIG_POSIX_TIMERS
|
||||
hrtimer_cancel(&tsk->signal->real_timer);
|
||||
exit_itimers(tsk->signal);
|
||||
exit_itimers(tsk);
|
||||
#endif
|
||||
if (tsk->mm)
|
||||
setmax_mm_hiwater_rss(&tsk->signal->maxrss, tsk->mm);
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/rculist.h>
|
||||
#include <linux/rcupdate.h>
|
||||
#include <linux/mm.h>
|
||||
|
||||
#ifndef ARCH_SHF_SMALL
|
||||
#define ARCH_SHF_SMALL 0
|
||||
@@ -30,11 +31,13 @@
|
||||
* to ensure complete separation of code and data, but
|
||||
* only when CONFIG_STRICT_MODULE_RWX=y
|
||||
*/
|
||||
#ifdef CONFIG_STRICT_MODULE_RWX
|
||||
# define strict_align(X) PAGE_ALIGN(X)
|
||||
#else
|
||||
# define strict_align(X) (X)
|
||||
#endif
|
||||
static inline unsigned int strict_align(unsigned int size)
|
||||
{
|
||||
if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
|
||||
return PAGE_ALIGN(size);
|
||||
else
|
||||
return size;
|
||||
}
|
||||
|
||||
extern struct mutex module_mutex;
|
||||
extern struct list_head modules;
|
||||
|
||||
+22
-13
@@ -137,6 +137,7 @@ void layout_symtab(struct module *mod, struct load_info *info)
|
||||
info->symoffs = ALIGN(mod->data_layout.size, symsect->sh_addralign ?: 1);
|
||||
info->stroffs = mod->data_layout.size = info->symoffs + ndst * sizeof(Elf_Sym);
|
||||
mod->data_layout.size += strtab_size;
|
||||
/* Note add_kallsyms() computes strtab_size as core_typeoffs - stroffs */
|
||||
info->core_typeoffs = mod->data_layout.size;
|
||||
mod->data_layout.size += ndst * sizeof(char);
|
||||
mod->data_layout.size = strict_align(mod->data_layout.size);
|
||||
@@ -169,19 +170,20 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
|
||||
Elf_Sym *dst;
|
||||
char *s;
|
||||
Elf_Shdr *symsec = &info->sechdrs[info->index.sym];
|
||||
unsigned long strtab_size;
|
||||
|
||||
/* Set up to point into init section. */
|
||||
mod->kallsyms = (void __rcu *)mod->init_layout.base +
|
||||
info->mod_kallsyms_init_off;
|
||||
|
||||
preempt_disable();
|
||||
rcu_read_lock();
|
||||
/* The following is safe since this pointer cannot change */
|
||||
rcu_dereference_sched(mod->kallsyms)->symtab = (void *)symsec->sh_addr;
|
||||
rcu_dereference_sched(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
|
||||
rcu_dereference(mod->kallsyms)->symtab = (void *)symsec->sh_addr;
|
||||
rcu_dereference(mod->kallsyms)->num_symtab = symsec->sh_size / sizeof(Elf_Sym);
|
||||
/* Make sure we get permanent strtab: don't use info->strtab. */
|
||||
rcu_dereference_sched(mod->kallsyms)->strtab =
|
||||
rcu_dereference(mod->kallsyms)->strtab =
|
||||
(void *)info->sechdrs[info->index.str].sh_addr;
|
||||
rcu_dereference_sched(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs;
|
||||
rcu_dereference(mod->kallsyms)->typetab = mod->init_layout.base + info->init_typeoffs;
|
||||
|
||||
/*
|
||||
* Now populate the cut down core kallsyms for after init
|
||||
@@ -190,22 +192,29 @@ void add_kallsyms(struct module *mod, const struct load_info *info)
|
||||
mod->core_kallsyms.symtab = dst = mod->data_layout.base + info->symoffs;
|
||||
mod->core_kallsyms.strtab = s = mod->data_layout.base + info->stroffs;
|
||||
mod->core_kallsyms.typetab = mod->data_layout.base + info->core_typeoffs;
|
||||
src = rcu_dereference_sched(mod->kallsyms)->symtab;
|
||||
for (ndst = i = 0; i < rcu_dereference_sched(mod->kallsyms)->num_symtab; i++) {
|
||||
rcu_dereference_sched(mod->kallsyms)->typetab[i] = elf_type(src + i, info);
|
||||
strtab_size = info->core_typeoffs - info->stroffs;
|
||||
src = rcu_dereference(mod->kallsyms)->symtab;
|
||||
for (ndst = i = 0; i < rcu_dereference(mod->kallsyms)->num_symtab; i++) {
|
||||
rcu_dereference(mod->kallsyms)->typetab[i] = elf_type(src + i, info);
|
||||
if (i == 0 || is_livepatch_module(mod) ||
|
||||
is_core_symbol(src + i, info->sechdrs, info->hdr->e_shnum,
|
||||
info->index.pcpu)) {
|
||||
ssize_t ret;
|
||||
|
||||
mod->core_kallsyms.typetab[ndst] =
|
||||
rcu_dereference_sched(mod->kallsyms)->typetab[i];
|
||||
rcu_dereference(mod->kallsyms)->typetab[i];
|
||||
dst[ndst] = src[i];
|
||||
dst[ndst++].st_name = s - mod->core_kallsyms.strtab;
|
||||
s += strscpy(s,
|
||||
&rcu_dereference_sched(mod->kallsyms)->strtab[src[i].st_name],
|
||||
KSYM_NAME_LEN) + 1;
|
||||
ret = strscpy(s,
|
||||
&rcu_dereference(mod->kallsyms)->strtab[src[i].st_name],
|
||||
strtab_size);
|
||||
if (ret < 0)
|
||||
break;
|
||||
s += ret + 1;
|
||||
strtab_size -= ret + 1;
|
||||
}
|
||||
}
|
||||
preempt_enable();
|
||||
rcu_read_unlock();
|
||||
mod->core_kallsyms.num_symtab = ndst;
|
||||
}
|
||||
|
||||
|
||||
@@ -2956,24 +2956,25 @@ static void cfi_init(struct module *mod)
|
||||
{
|
||||
#ifdef CONFIG_CFI_CLANG
|
||||
initcall_t *init;
|
||||
#ifdef CONFIG_MODULE_UNLOAD
|
||||
exitcall_t *exit;
|
||||
#endif
|
||||
|
||||
rcu_read_lock_sched();
|
||||
mod->cfi_check = (cfi_check_fn)
|
||||
find_kallsyms_symbol_value(mod, "__cfi_check");
|
||||
init = (initcall_t *)
|
||||
find_kallsyms_symbol_value(mod, "__cfi_jt_init_module");
|
||||
exit = (exitcall_t *)
|
||||
find_kallsyms_symbol_value(mod, "__cfi_jt_cleanup_module");
|
||||
rcu_read_unlock_sched();
|
||||
|
||||
/* Fix init/exit functions to point to the CFI jump table */
|
||||
if (init)
|
||||
mod->init = *init;
|
||||
#ifdef CONFIG_MODULE_UNLOAD
|
||||
exit = (exitcall_t *)
|
||||
find_kallsyms_symbol_value(mod, "__cfi_jt_cleanup_module");
|
||||
if (exit)
|
||||
mod->exit = *exit;
|
||||
#endif
|
||||
rcu_read_unlock_sched();
|
||||
|
||||
cfi_module_add(mod, mod_tree.addr_min);
|
||||
#endif
|
||||
|
||||
@@ -1051,15 +1051,24 @@ retry_delete:
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called by do_exit or de_thread, only when there are no more
|
||||
* references to the shared signal_struct.
|
||||
* This is called by do_exit or de_thread, only when nobody else can
|
||||
* modify the signal->posix_timers list. Yet we need sighand->siglock
|
||||
* to prevent the race with /proc/pid/timers.
|
||||
*/
|
||||
void exit_itimers(struct signal_struct *sig)
|
||||
void exit_itimers(struct task_struct *tsk)
|
||||
{
|
||||
struct list_head timers;
|
||||
struct k_itimer *tmr;
|
||||
|
||||
while (!list_empty(&sig->posix_timers)) {
|
||||
tmr = list_entry(sig->posix_timers.next, struct k_itimer, list);
|
||||
if (list_empty(&tsk->signal->posix_timers))
|
||||
return;
|
||||
|
||||
spin_lock_irq(&tsk->sighand->siglock);
|
||||
list_replace_init(&tsk->signal->posix_timers, &timers);
|
||||
spin_unlock_irq(&tsk->sighand->siglock);
|
||||
|
||||
while (!list_empty(&timers)) {
|
||||
tmr = list_first_entry(&timers, struct k_itimer, list);
|
||||
itimer_delete(tmr);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-2
@@ -336,8 +336,7 @@ static void damon_hugetlb_mkold(pte_t *pte, struct mm_struct *mm,
|
||||
if (pte_young(entry)) {
|
||||
referenced = true;
|
||||
entry = pte_mkold(entry);
|
||||
huge_ptep_set_access_flags(vma, addr, pte, entry,
|
||||
vma->vm_flags & VM_WRITE);
|
||||
set_huge_pte_at(mm, addr, pte, entry);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MMU_NOTIFIER
|
||||
|
||||
+14
-13
@@ -4799,6 +4799,19 @@ static inline vm_fault_t wp_huge_pmd(struct vm_fault *vmf)
|
||||
|
||||
static vm_fault_t create_huge_pud(struct vm_fault *vmf)
|
||||
{
|
||||
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \
|
||||
defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
|
||||
/* No support for anonymous transparent PUD pages yet */
|
||||
if (vma_is_anonymous(vmf->vma))
|
||||
return VM_FAULT_FALLBACK;
|
||||
if (vmf->vma->vm_ops->huge_fault)
|
||||
return vmf->vma->vm_ops->huge_fault(vmf, PE_SIZE_PUD);
|
||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||
return VM_FAULT_FALLBACK;
|
||||
}
|
||||
|
||||
static vm_fault_t wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud)
|
||||
{
|
||||
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && \
|
||||
defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)
|
||||
/* No support for anonymous transparent PUD pages yet */
|
||||
@@ -4813,19 +4826,7 @@ static vm_fault_t create_huge_pud(struct vm_fault *vmf)
|
||||
split:
|
||||
/* COW or write-notify not handled on PUD level: split pud.*/
|
||||
__split_huge_pud(vmf->vma, vmf->pud, vmf->address);
|
||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||
return VM_FAULT_FALLBACK;
|
||||
}
|
||||
|
||||
static vm_fault_t wp_huge_pud(struct vm_fault *vmf, pud_t orig_pud)
|
||||
{
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
/* No support for anonymous transparent PUD pages yet */
|
||||
if (vma_is_anonymous(vmf->vma))
|
||||
return VM_FAULT_FALLBACK;
|
||||
if (vmf->vma->vm_ops->huge_fault)
|
||||
return vmf->vma->vm_ops->huge_fault(vmf, PE_SIZE_PUD);
|
||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
|
||||
#endif /* CONFIG_TRANSPARENT_HUGEPAGE && CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD */
|
||||
return VM_FAULT_FALLBACK;
|
||||
}
|
||||
|
||||
|
||||
@@ -1899,8 +1899,23 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
|
||||
/* Unexpected PMD-mapped THP? */
|
||||
VM_BUG_ON_FOLIO(!pvmw.pte, folio);
|
||||
|
||||
subpage = folio_page(folio,
|
||||
pte_pfn(*pvmw.pte) - folio_pfn(folio));
|
||||
if (folio_is_zone_device(folio)) {
|
||||
/*
|
||||
* Our PTE is a non-present device exclusive entry and
|
||||
* calculating the subpage as for the common case would
|
||||
* result in an invalid pointer.
|
||||
*
|
||||
* Since only PAGE_SIZE pages can currently be
|
||||
* migrated, just set it to page. This will need to be
|
||||
* changed when hugepage migrations to device private
|
||||
* memory are supported.
|
||||
*/
|
||||
VM_BUG_ON_FOLIO(folio_nr_pages(folio) > 1, folio);
|
||||
subpage = &folio->page;
|
||||
} else {
|
||||
subpage = folio_page(folio,
|
||||
pte_pfn(*pvmw.pte) - folio_pfn(folio));
|
||||
}
|
||||
address = pvmw.address;
|
||||
anon_exclusive = folio_test_anon(folio) &&
|
||||
PageAnonExclusive(subpage);
|
||||
@@ -1993,15 +2008,7 @@ static bool try_to_migrate_one(struct folio *folio, struct vm_area_struct *vma,
|
||||
/*
|
||||
* No need to invalidate here it will synchronize on
|
||||
* against the special swap migration pte.
|
||||
*
|
||||
* The assignment to subpage above was computed from a
|
||||
* swap PTE which results in an invalid pointer.
|
||||
* Since only PAGE_SIZE pages can currently be
|
||||
* migrated, just set it to page. This will need to be
|
||||
* changed when hugepage migrations to device private
|
||||
* memory are supported.
|
||||
*/
|
||||
subpage = &folio->page;
|
||||
} else if (PageHWPoison(subpage)) {
|
||||
pteval = swp_entry_to_pte(make_hwpoison_entry(subpage));
|
||||
if (folio_test_hugetlb(folio)) {
|
||||
|
||||
@@ -78,6 +78,14 @@ static int __split_vmemmap_huge_pmd(pmd_t *pmd, unsigned long start)
|
||||
|
||||
spin_lock(&init_mm.page_table_lock);
|
||||
if (likely(pmd_leaf(*pmd))) {
|
||||
/*
|
||||
* Higher order allocations from buddy allocator must be able to
|
||||
* be treated as indepdenent small pages (as they can be freed
|
||||
* individually).
|
||||
*/
|
||||
if (!PageReserved(page))
|
||||
split_page(page, get_order(PMD_SIZE));
|
||||
|
||||
/* Make pte visible before pmd. See comment in pmd_install(). */
|
||||
smp_wmb();
|
||||
pmd_populate_kernel(&init_mm, pmd, pgtable);
|
||||
|
||||
+4
-1
@@ -246,7 +246,10 @@ static int mcontinue_atomic_pte(struct mm_struct *dst_mm,
|
||||
struct page *page;
|
||||
int ret;
|
||||
|
||||
ret = shmem_getpage(inode, pgoff, &page, SGP_READ);
|
||||
ret = shmem_getpage(inode, pgoff, &page, SGP_NOALLOC);
|
||||
/* Our caller expects us to return -EFAULT if we failed to find page. */
|
||||
if (ret == -ENOENT)
|
||||
ret = -EFAULT;
|
||||
if (ret)
|
||||
goto out;
|
||||
if (!page) {
|
||||
|
||||
Reference in New Issue
Block a user