Skip to content

Commit 7772260

Browse files
Kalesh SinghTreehugger Robot
authored andcommitted
ANDROID: 16K: Introduce pgsize_migration_inline.h
Introduce inline header to avoid circular dependency. This will be used in a subsequent patch. Also take opportunity to do some small noop refactor in vma_pad_pages() and split_pad_vma() for more robust code. Bug: 357901498 Change-Id: Ia5f447758d0d07ed3e1429ca1e35dcc0741cc22a Signed-off-by: Kalesh Singh <[email protected]>
1 parent f86b897 commit 7772260

File tree

3 files changed

+71
-51
lines changed

3 files changed

+71
-51
lines changed

include/linux/pgsize_migration.h

Lines changed: 2 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -13,35 +13,9 @@
1313
* page size in Android.
1414
*/
1515

16-
#include <linux/mm.h>
16+
#include <linux/pgsize_migration_inline.h>
1717
#include <linux/seq_file.h>
18-
#include <linux/sizes.h>
19-
20-
/*
21-
* vm_flags representation of VMA padding pages.
22-
*
23-
* This allows the kernel to identify the portion of an ELF LOAD segment VMA
24-
* that is padding.
25-
*
26-
* 4 high bits of vm_flags [63,60] are used to represent ELF segment padding
27-
* up to 60kB, which is sufficient for ELFs of both 16kB and 64kB segment
28-
* alignment (p_align).
29-
*
30-
* The representation is illustrated below.
31-
*
32-
* 63 62 61 60
33-
* _________ _________ _________ _________
34-
* | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
35-
* | of 4kB | of 4kB | of 4kB | of 4kB |
36-
* | chunks | chunks | chunks | chunks |
37-
* |_________|_________|_________|_________|
38-
*/
39-
40-
#define VM_PAD_WIDTH 4
41-
#define VM_PAD_SHIFT (BITS_PER_LONG - VM_PAD_WIDTH)
42-
#define VM_TOTAL_PAD_PAGES ((1ULL << VM_PAD_WIDTH) - 1)
43-
#define VM_PAD_MASK (VM_TOTAL_PAD_PAGES << VM_PAD_SHIFT)
44-
#define VMA_PAD_START(vma) (vma->vm_end - (vma_pad_pages(vma) << PAGE_SHIFT))
18+
#include <linux/mm.h>
4519

4620
#if PAGE_SIZE == SZ_4K && defined(CONFIG_64BIT)
4721
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,
6337
extern void split_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *new,
6438
unsigned long addr, int new_below);
6539

66-
extern unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
67-
unsigned long newflags);
68-
6940
extern bool is_mergable_pad_vma(struct vm_area_struct *vma,
7041
unsigned long vm_flags);
7142

@@ -107,12 +78,6 @@ static inline void split_pad_vma(struct vm_area_struct *vma, struct vm_area_stru
10778
{
10879
}
10980

110-
static inline unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
111-
unsigned long newflags)
112-
{
113-
return newflags;
114-
}
115-
11681
static inline bool is_mergable_pad_vma(struct vm_area_struct *vma,
11782
unsigned long vm_flags)
11883
{
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#ifndef _LINUX_PAGE_SIZE_MIGRATION_INLINE_H
3+
#define _LINUX_PAGE_SIZE_MIGRATION_INLINE_H
4+
5+
/*
6+
* Page Size Migration
7+
*
8+
* Copyright (c) 2024, Google LLC.
9+
* Author: Kalesh Singh <[email protected]>
10+
*
11+
* This file contains inline APIs for mitigations to ensure
12+
* app compatibility during the transition from 4kB to 16kB
13+
* page size in Android.
14+
*/
15+
16+
#include <linux/mm_types.h>
17+
#include <linux/sizes.h>
18+
19+
#include <asm/page.h>
20+
21+
/*
22+
* vm_flags representation of VMA padding pages.
23+
*
24+
* This allows the kernel to identify the portion of an ELF LOAD segment VMA
25+
* that is padding.
26+
*
27+
* 4 high bits of vm_flags [63,60] are used to represent ELF segment padding
28+
* up to 60kB, which is sufficient for ELFs of both 16kB and 64kB segment
29+
* alignment (p_align).
30+
*
31+
* The representation is illustrated below.
32+
*
33+
* 63 62 61 60
34+
* _________ _________ _________ _________
35+
* | Bit 3 | Bit 2 | Bit 1 | Bit 0 |
36+
* | of 4kB | of 4kB | of 4kB | of 4kB |
37+
* | chunks | chunks | chunks | chunks |
38+
* |_________|_________|_________|_________|
39+
*/
40+
41+
#define VM_PAD_WIDTH 4
42+
#define VM_PAD_SHIFT (BITS_PER_LONG - VM_PAD_WIDTH)
43+
#define VM_TOTAL_PAD_PAGES ((1ULL << VM_PAD_WIDTH) - 1)
44+
#define VM_PAD_MASK (VM_TOTAL_PAD_PAGES << VM_PAD_SHIFT)
45+
#define VMA_PAD_START(vma) (vma->vm_end - (vma_pad_pages(vma) << PAGE_SHIFT))
46+
47+
#if PAGE_SIZE == SZ_4K && defined(CONFIG_64BIT)
48+
/*
49+
* Sets the correct padding bits / flags for a VMA split.
50+
*/
51+
static inline unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
52+
unsigned long newflags)
53+
{
54+
if (newflags & VM_PAD_MASK)
55+
return (newflags & ~VM_PAD_MASK) | (vma->vm_flags & VM_PAD_MASK);
56+
else
57+
return newflags;
58+
}
59+
#else /* PAGE_SIZE != SZ_4K || !defined(CONFIG_64BIT) */
60+
static inline unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
61+
unsigned long newflags)
62+
{
63+
return newflags;
64+
}
65+
#endif /* PAGE_SIZE == SZ_4K && defined(CONFIG_64BIT) */
66+
67+
#endif /* _LINUX_PAGE_SIZE_MIGRATION_INLINE_H */

mm/pgsize_migration.c

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ unsigned long vma_pad_pages(struct vm_area_struct *vma)
126126
if (!is_pgsize_migration_enabled())
127127
return 0;
128128

129-
return vma->vm_flags >> VM_PAD_SHIFT;
129+
return (vma->vm_flags & VM_PAD_MASK) >> VM_PAD_SHIFT;
130130
}
131131

132132
static __always_inline bool str_has_suffix(const char *str, const char *suffix)
@@ -397,26 +397,14 @@ void split_pad_vma(struct vm_area_struct *vma, struct vm_area_struct *new,
397397
nr_vma2_pages = vma_pages(second);
398398

399399
if (nr_vma2_pages >= nr_pad_pages) { /* Case 1 & 3 */
400-
first->vm_flags &= ~VM_PAD_MASK;
400+
vma_set_pad_pages(first, 0);
401401
vma_set_pad_pages(second, nr_pad_pages);
402402
} else { /* Case 2 */
403403
vma_set_pad_pages(first, nr_pad_pages - nr_vma2_pages);
404404
vma_set_pad_pages(second, nr_vma2_pages);
405405
}
406406
}
407407

408-
/*
409-
* Sets the correct padding bits / flags for a VMA split.
410-
*/
411-
unsigned long vma_pad_fixup_flags(struct vm_area_struct *vma,
412-
unsigned long newflags)
413-
{
414-
if (newflags & VM_PAD_MASK)
415-
return (newflags & ~VM_PAD_MASK) | (vma->vm_flags & VM_PAD_MASK);
416-
else
417-
return newflags;
418-
}
419-
420408
/*
421409
* Merging of padding VMAs is uncommon, as padding is only allowed
422410
* from the linker context.

0 commit comments

Comments
 (0)