diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-09-06 18:42:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-09-06 18:42:10 -0400 |
commit | 2601dd392dd1cabd11935448c0afe3293feb27a3 (patch) | |
tree | d204487c81f4662ab95e6f71659d3f0030397e48 | |
parent | c6ff25ce3564ac3a61f2f0a45d5d9c3af423359e (diff) | |
parent | 0f02cfbc3d9e413d450d8d0fd660077c23f67eff (diff) |
Merge tag 'mips_fixes_4.19_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux
Pull MIPS fix from Paul Burton:
"A single fix for v4.19-rc3, resolving a problem with our VDSO data
page for systems with dcache aliasing. Those systems could previously
observe stale data, causing clock_gettime() & gettimeofday() to return
incorrect values"
* tag 'mips_fixes_4.19_1' of git://git.kernel.org/pub/scm/linux/kernel/git/mips/linux:
MIPS: VDSO: Match data page cache colouring when D$ aliases
-rw-r--r-- | arch/mips/kernel/vdso.c | 20 |
1 files changed, 20 insertions, 0 deletions
diff --git a/arch/mips/kernel/vdso.c b/arch/mips/kernel/vdso.c index 019035d7225c..8f845f6e5f42 100644 --- a/arch/mips/kernel/vdso.c +++ b/arch/mips/kernel/vdso.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/err.h> | 13 | #include <linux/err.h> |
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/ioport.h> | 15 | #include <linux/ioport.h> |
16 | #include <linux/kernel.h> | ||
16 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
17 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
18 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
@@ -20,6 +21,7 @@ | |||
20 | 21 | ||
21 | #include <asm/abi.h> | 22 | #include <asm/abi.h> |
22 | #include <asm/mips-cps.h> | 23 | #include <asm/mips-cps.h> |
24 | #include <asm/page.h> | ||
23 | #include <asm/vdso.h> | 25 | #include <asm/vdso.h> |
24 | 26 | ||
25 | /* Kernel-provided data used by the VDSO. */ | 27 | /* Kernel-provided data used by the VDSO. */ |
@@ -128,12 +130,30 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) | |||
128 | vvar_size = gic_size + PAGE_SIZE; | 130 | vvar_size = gic_size + PAGE_SIZE; |
129 | size = vvar_size + image->size; | 131 | size = vvar_size + image->size; |
130 | 132 | ||
133 | /* | ||
134 | * Find a region that's large enough for us to perform the | ||
135 | * colour-matching alignment below. | ||
136 | */ | ||
137 | if (cpu_has_dc_aliases) | ||
138 | size += shm_align_mask + 1; | ||
139 | |||
131 | base = get_unmapped_area(NULL, 0, size, 0, 0); | 140 | base = get_unmapped_area(NULL, 0, size, 0, 0); |
132 | if (IS_ERR_VALUE(base)) { | 141 | if (IS_ERR_VALUE(base)) { |
133 | ret = base; | 142 | ret = base; |
134 | goto out; | 143 | goto out; |
135 | } | 144 | } |
136 | 145 | ||
146 | /* | ||
147 | * If we suffer from dcache aliasing, ensure that the VDSO data page | ||
148 | * mapping is coloured the same as the kernel's mapping of that memory. | ||
149 | * This ensures that when the kernel updates the VDSO data userland | ||
150 | * will observe it without requiring cache invalidations. | ||
151 | */ | ||
152 | if (cpu_has_dc_aliases) { | ||
153 | base = __ALIGN_MASK(base, shm_align_mask); | ||
154 | base += ((unsigned long)&vdso_data - gic_size) & shm_align_mask; | ||
155 | } | ||
156 | |||
137 | data_addr = base + gic_size; | 157 | data_addr = base + gic_size; |
138 | vdso_addr = data_addr + PAGE_SIZE; | 158 | vdso_addr = data_addr + PAGE_SIZE; |
139 | 159 | ||