Merge branch 'android11-5.4' into android11-5.4-lts
Do a backmerge of android11-5.4 to catch some recent changes in that branch. Included in here are the following changes: *ca48ea8b94Merge tag 'android11-5.4.284_r00' into android11-5.4 *425419e5b2UPSTREAM: unicode: Don't special case ignorable code points *171355878eANDROID: 16K: Fixup padding vm_flags bits on VMA splits *f6da812ab6ANDROID: 16K: Introduce pgsize_migration_inline.h Change-Id: Ic982642e039217d4469f48aeb2da91e7c372c5ce Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
commit
b1c3b1041a
7 changed files with 3421 additions and 3481 deletions
|
|
@ -2230,75 +2230,6 @@ static void nfdicf_init(void)
|
|||
file_fail(fold_name);
|
||||
}
|
||||
|
||||
static void ignore_init(void)
|
||||
{
|
||||
FILE *file;
|
||||
unsigned int unichar;
|
||||
unsigned int first;
|
||||
unsigned int last;
|
||||
unsigned int *um;
|
||||
int count;
|
||||
int ret;
|
||||
|
||||
if (verbose > 0)
|
||||
printf("Parsing %s\n", prop_name);
|
||||
file = fopen(prop_name, "r");
|
||||
if (!file)
|
||||
open_fail(prop_name, errno);
|
||||
assert(file);
|
||||
count = 0;
|
||||
while (fgets(line, LINESIZE, file)) {
|
||||
ret = sscanf(line, "%X..%X ; %s # ", &first, &last, buf0);
|
||||
if (ret == 3) {
|
||||
if (strcmp(buf0, "Default_Ignorable_Code_Point"))
|
||||
continue;
|
||||
if (!utf32valid(first) || !utf32valid(last))
|
||||
line_fail(prop_name, line);
|
||||
for (unichar = first; unichar <= last; unichar++) {
|
||||
free(unicode_data[unichar].utf32nfdi);
|
||||
um = malloc(sizeof(unsigned int));
|
||||
*um = 0;
|
||||
unicode_data[unichar].utf32nfdi = um;
|
||||
free(unicode_data[unichar].utf32nfdicf);
|
||||
um = malloc(sizeof(unsigned int));
|
||||
*um = 0;
|
||||
unicode_data[unichar].utf32nfdicf = um;
|
||||
count++;
|
||||
}
|
||||
if (verbose > 1)
|
||||
printf(" %X..%X Default_Ignorable_Code_Point\n",
|
||||
first, last);
|
||||
continue;
|
||||
}
|
||||
ret = sscanf(line, "%X ; %s # ", &unichar, buf0);
|
||||
if (ret == 2) {
|
||||
if (strcmp(buf0, "Default_Ignorable_Code_Point"))
|
||||
continue;
|
||||
if (!utf32valid(unichar))
|
||||
line_fail(prop_name, line);
|
||||
free(unicode_data[unichar].utf32nfdi);
|
||||
um = malloc(sizeof(unsigned int));
|
||||
*um = 0;
|
||||
unicode_data[unichar].utf32nfdi = um;
|
||||
free(unicode_data[unichar].utf32nfdicf);
|
||||
um = malloc(sizeof(unsigned int));
|
||||
*um = 0;
|
||||
unicode_data[unichar].utf32nfdicf = um;
|
||||
if (verbose > 1)
|
||||
printf(" %X Default_Ignorable_Code_Point\n",
|
||||
unichar);
|
||||
count++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
if (verbose > 0)
|
||||
printf("Found %d entries\n", count);
|
||||
if (count == 0)
|
||||
file_fail(prop_name);
|
||||
}
|
||||
|
||||
static void corrections_init(void)
|
||||
{
|
||||
FILE *file;
|
||||
|
|
@ -3396,7 +3327,6 @@ int main(int argc, char *argv[])
|
|||
ccc_init();
|
||||
nfdi_init();
|
||||
nfdicf_init();
|
||||
ignore_init();
|
||||
corrections_init();
|
||||
hangul_decompose();
|
||||
nfdi_decompose();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -27,6 +27,7 @@
|
|||
#include <linux/ioctl.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/hugetlb.h>
|
||||
#include <linux/pgsize_migration.h>
|
||||
|
||||
int sysctl_unprivileged_userfaultfd __read_mostly = 1;
|
||||
|
||||
|
|
@ -1480,7 +1481,7 @@ static int userfaultfd_register(struct userfaultfd_ctx *ctx,
|
|||
* the next vma was merged into the current one and
|
||||
* the current one has not been updated yet.
|
||||
*/
|
||||
vma->vm_flags = new_flags;
|
||||
vma->vm_flags = vma_pad_fixup_flags(vma, new_flags);
|
||||
vma->vm_userfaultfd_ctx.ctx = ctx;
|
||||
|
||||
skip:
|
||||
|
|
@ -1643,7 +1644,7 @@ static int userfaultfd_unregister(struct userfaultfd_ctx *ctx,
|
|||
* the next vma was merged into the current one and
|
||||
* the current one has not been updated yet.
|
||||
*/
|
||||
vma->vm_flags = new_flags;
|
||||
vma->vm_flags = vma_pad_fixup_flags(vma, new_flags);
|
||||
vma->vm_userfaultfd_ctx = NULL_VM_UFFD_CTX;
|
||||
|
||||
skip:
|
||||
|
|
|
|||
|
|
@ -13,35 +13,9 @@
|
|||
* page size in Android.
|
||||
*/
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/pgsize_migration_inline.h>
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
/*
|
||||
* vm_flags representation of VMA padding pages.
|
||||
*
|
||||
* This allows the kernel to identify the portion of an ELF LOAD segment VMA
|
||||
* that is padding.
|
||||
*
|
||||
* 4 high bits of vm_flags [63,60] are used to represent ELF segment padding
|
||||
* up to 60kB, which is sufficient for ELFs of both 16kB and 64kB segment
|
||||
* alignment (p_align).
|
||||
*
|
||||
* The representation is illustrated below.
|
||||
*
|
||||
* 63 62 61 60
|
||||
* _________ _________ _________ _________
|
||||
* | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|
||||
* | of 4kB | of 4kB | of 4kB | of 4kB |
|
||||
* | chunks | chunks | chunks | chunks |
|
||||
* |_________|_________|_________|_________|
|
||||
*/
|
||||
|
||||
#define VM_PAD_WIDTH 4
|
||||
#define VM_PAD_SHIFT (BITS_PER_LONG - VM_PAD_WIDTH)
|
||||
#define VM_TOTAL_PAD_PAGES ((1ULL << VM_PAD_WIDTH) - 1)
|
||||
#define VM_PAD_MASK (VM_TOTAL_PAD_PAGES << VM_PAD_SHIFT)
|
||||
#define VMA_PAD_START(vma) (vma->vm_end - (vma_pad_pages(vma) << PAGE_SHIFT))
|
||||
#include <linux/mm.h>
|
||||
|
||||
#if PAGE_SIZE == SZ_4K && defined(CONFIG_64BIT)
|
||||
extern void vma_set_pad_pages(struct vm_area_struct *vma,
|
||||
|
|
@ -63,9 +37,6 @@ extern void show_map_pad_vma(struct vm_area_struct *vma,
|
|||
extern void split_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *new,
|
||||
unsigned long addr, int new_below);
|
||||
|
||||
extern unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
|
||||
unsigned long newflags);
|
||||
|
||||
extern bool is_mergable_pad_vma(struct vm_area_struct *vma,
|
||||
unsigned long vm_flags);
|
||||
|
||||
|
|
@ -107,12 +78,6 @@ static inline void split_pad_vma(struct vm_area_struct *vma, struct vm_area_stru
|
|||
{
|
||||
}
|
||||
|
||||
static inline unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
|
||||
unsigned long newflags)
|
||||
{
|
||||
return newflags;
|
||||
}
|
||||
|
||||
static inline bool is_mergable_pad_vma(struct vm_area_struct *vma,
|
||||
unsigned long vm_flags)
|
||||
{
|
||||
|
|
|
|||
67
include/linux/pgsize_migration_inline.h
Normal file
67
include/linux/pgsize_migration_inline.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _LINUX_PAGE_SIZE_MIGRATION_INLINE_H
|
||||
#define _LINUX_PAGE_SIZE_MIGRATION_INLINE_H
|
||||
|
||||
/*
|
||||
* Page Size Migration
|
||||
*
|
||||
* Copyright (c) 2024, Google LLC.
|
||||
* Author: Kalesh Singh <kaleshsingh@goole.com>
|
||||
*
|
||||
* This file contains inline APIs for mitigations to ensure
|
||||
* app compatibility during the transition from 4kB to 16kB
|
||||
* page size in Android.
|
||||
*/
|
||||
|
||||
#include <linux/mm_types.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
|
||||
/*
|
||||
* vm_flags representation of VMA padding pages.
|
||||
*
|
||||
* This allows the kernel to identify the portion of an ELF LOAD segment VMA
|
||||
* that is padding.
|
||||
*
|
||||
* 4 high bits of vm_flags [63,60] are used to represent ELF segment padding
|
||||
* up to 60kB, which is sufficient for ELFs of both 16kB and 64kB segment
|
||||
* alignment (p_align).
|
||||
*
|
||||
* The representation is illustrated below.
|
||||
*
|
||||
* 63 62 61 60
|
||||
* _________ _________ _________ _________
|
||||
* | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
|
||||
* | of 4kB | of 4kB | of 4kB | of 4kB |
|
||||
* | chunks | chunks | chunks | chunks |
|
||||
* |_________|_________|_________|_________|
|
||||
*/
|
||||
|
||||
#define VM_PAD_WIDTH 4
|
||||
#define VM_PAD_SHIFT (BITS_PER_LONG - VM_PAD_WIDTH)
|
||||
#define VM_TOTAL_PAD_PAGES ((1ULL << VM_PAD_WIDTH) - 1)
|
||||
#define VM_PAD_MASK (VM_TOTAL_PAD_PAGES << VM_PAD_SHIFT)
|
||||
#define VMA_PAD_START(vma) (vma->vm_end - (vma_pad_pages(vma) << PAGE_SHIFT))
|
||||
|
||||
#if PAGE_SIZE == SZ_4K && defined(CONFIG_64BIT)
|
||||
/*
|
||||
* Sets the correct padding bits / flags for a VMA split.
|
||||
*/
|
||||
static inline unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
|
||||
unsigned long newflags)
|
||||
{
|
||||
if (newflags & VM_PAD_MASK)
|
||||
return (newflags & ~VM_PAD_MASK) | (vma->vm_flags & VM_PAD_MASK);
|
||||
else
|
||||
return newflags;
|
||||
}
|
||||
#else /* PAGE_SIZE != SZ_4K || !defined(CONFIG_64BIT) */
|
||||
static inline unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
|
||||
unsigned long newflags)
|
||||
{
|
||||
return newflags;
|
||||
}
|
||||
#endif /* PAGE_SIZE == SZ_4K && defined(CONFIG_64BIT) */
|
||||
|
||||
#endif /* _LINUX_PAGE_SIZE_MIGRATION_INLINE_H */
|
||||
|
|
@ -167,7 +167,7 @@ success:
|
|||
/*
|
||||
* vm_flags is protected by the mmap_sem held in write mode.
|
||||
*/
|
||||
vma->vm_flags = new_flags;
|
||||
vma->vm_flags = vma_pad_fixup_flags(vma, new_flags);
|
||||
|
||||
out_convert_errno:
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ unsigned long vma_pad_pages(struct vm_area_struct *vma)
|
|||
if (!is_pgsize_migration_enabled())
|
||||
return 0;
|
||||
|
||||
return vma->vm_flags >> VM_PAD_SHIFT;
|
||||
return (vma->vm_flags & VM_PAD_MASK) >> VM_PAD_SHIFT;
|
||||
}
|
||||
|
||||
static __always_inline bool str_has_suffix(const char *str, const char *suffix)
|
||||
|
|
@ -398,7 +398,7 @@ void split_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *new,
|
|||
nr_vma2_pages = vma_pages(second);
|
||||
|
||||
if (nr_vma2_pages >= nr_pad_pages) { /* Case 1 & 3 */
|
||||
first->vm_flags &= ~VM_PAD_MASK;
|
||||
vma_set_pad_pages(first, 0);
|
||||
vma_set_pad_pages(second, nr_pad_pages);
|
||||
} else { /* Case 2 */
|
||||
vma_set_pad_pages(first, nr_pad_pages - nr_vma2_pages);
|
||||
|
|
@ -406,18 +406,6 @@ void split_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *new,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets the correct padding bits / flags for a VMA split.
|
||||
*/
|
||||
unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
|
||||
unsigned long newflags)
|
||||
{
|
||||
if (newflags & VM_PAD_MASK)
|
||||
return (newflags & ~VM_PAD_MASK) | (vma->vm_flags & VM_PAD_MASK);
|
||||
else
|
||||
return newflags;
|
||||
}
|
||||
|
||||
/*
|
||||
* Merging of padding VMAs is uncommon, as padding is only allowed
|
||||
* from the linker context.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue