Skip to content

Commit c730493

Browse files
chleroyzx2c4
authored andcommitted
powerpc/vdso: Fix VDSO data access when running in a non-root time namespace
When running in a non-root time namespace, the global VDSO data page is replaced by a dedicated namespace data page and the global data page is mapped next to it. Detailed explanations can be found at commit 660fd04 ("lib/vdso: Prepare for time namespace support"). When it happens, __kernel_get_syscall_map and __kernel_get_tbfreq and __kernel_sync_dicache don't work anymore because they read 0 instead of the data they need. To address that, clock_mode has to be read. When it is set to VDSO_CLOCKMODE_TIMENS, it means it is a dedicated namespace data page and the global data is located on the following page. Add a macro called get_realdatapage which reads clock_mode and add PAGE_SIZE to the pointer provided by get_datapage macro when clock_mode is equal to VDSO_CLOCKMODE_TIMENS. Use this new macro instead of get_datapage macro except for time functions as they handle it internally. Fixes: 74205b3 ("powerpc/vdso: Add support for time namespaces") Reported-by: Jason A. Donenfeld <[email protected]> Closes: https://lore.kernel.org/all/[email protected]/ Signed-off-by: Christophe Leroy <[email protected]> Acked-by: Michael Ellerman <[email protected]> Signed-off-by: Jason A. Donenfeld <[email protected]>
1 parent 8bc7c5e commit c730493

File tree

4 files changed

+20
-3
lines changed

4 files changed

+20
-3
lines changed

arch/powerpc/include/asm/vdso_datapage.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,21 @@ extern struct vdso_arch_data *vdso_data;
111111
addi \ptr, \ptr, (_vdso_datapage - 999b)@l
112112
.endm
113113

114+
#include <asm/asm-offsets.h>
115+
#include <asm/page.h>
116+
117+
.macro get_realdatapage ptr scratch
118+
get_datapage \ptr
119+
#ifdef CONFIG_TIME_NS
120+
lwz \scratch, VDSO_CLOCKMODE_OFFSET(\ptr)
121+
xoris \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@h
122+
xori \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@l
123+
cntlzw \scratch, \scratch
124+
rlwinm \scratch, \scratch, PAGE_SHIFT - 5, 1 << PAGE_SHIFT
125+
add \ptr, \ptr, \scratch
126+
#endif
127+
.endm
128+
114129
#endif /* __ASSEMBLY__ */
115130

116131
#endif /* __KERNEL__ */

arch/powerpc/kernel/asm-offsets.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,8 @@ int main(void)
346346
#else
347347
OFFSET(CFG_SYSCALL_MAP32, vdso_arch_data, syscall_map);
348348
#endif
349+
OFFSET(VDSO_CLOCKMODE_OFFSET, vdso_arch_data, data[0].clock_mode);
350+
DEFINE(VDSO_CLOCKMODE_TIMENS, VDSO_CLOCKMODE_TIMENS);
349351

350352
#ifdef CONFIG_BUG
351353
DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));

arch/powerpc/kernel/vdso/cacheflush.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
3030
#ifdef CONFIG_PPC64
3131
mflr r12
3232
.cfi_register lr,r12
33-
get_datapage r10
33+
get_realdatapage r10, r11
3434
mtlr r12
3535
.cfi_restore lr
3636
#endif

arch/powerpc/kernel/vdso/datapage.S

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
2828
mflr r12
2929
.cfi_register lr,r12
3030
mr. r4,r3
31-
get_datapage r3
31+
get_realdatapage r3, r11
3232
mtlr r12
3333
#ifdef __powerpc64__
3434
addi r3,r3,CFG_SYSCALL_MAP64
@@ -52,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
5252
.cfi_startproc
5353
mflr r12
5454
.cfi_register lr,r12
55-
get_datapage r3
55+
get_realdatapage r3, r11
5656
#ifndef __powerpc64__
5757
lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
5858
#endif

0 commit comments

Comments
 (0)