powerpc/vdso: Fix VDSO data access when running in a non-root time namespace
[ Upstream commit c73049389e58c01e2e3bbfae900c8daeee177191 ] 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 commit660fd04f93
("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:74205b3fc2
("powerpc/vdso: Add support for time namespaces") Reported-by: Jason A. Donenfeld <Jason@zx2c4.com> Closes: https://lore.kernel.org/all/ZtnYqZI-nrsNslwy@zx2c4.com/ Signed-off-by: Christophe Leroy <christophe.leroy@csgroup.eu> Acked-by: Michael Ellerman <mpe@ellerman.id.au> Signed-off-by: Jason A. Donenfeld <Jason@zx2c4.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
eba34000e7
commit
3c9f0c9d59
@ -111,6 +111,21 @@ extern struct vdso_arch_data *vdso_data;
|
||||
addi \ptr, \ptr, (_vdso_datapage - 999b)@l
|
||||
.endm
|
||||
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/page.h>
|
||||
|
||||
.macro get_realdatapage ptr scratch
|
||||
get_datapage \ptr
|
||||
#ifdef CONFIG_TIME_NS
|
||||
lwz \scratch, VDSO_CLOCKMODE_OFFSET(\ptr)
|
||||
xoris \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@h
|
||||
xori \scratch, \scratch, VDSO_CLOCKMODE_TIMENS@l
|
||||
cntlzw \scratch, \scratch
|
||||
rlwinm \scratch, \scratch, PAGE_SHIFT - 5, 1 << PAGE_SHIFT
|
||||
add \ptr, \ptr, \scratch
|
||||
#endif
|
||||
.endm
|
||||
|
||||
#endif /* __ASSEMBLY__ */
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
@ -347,6 +347,8 @@ int main(void)
|
||||
#else
|
||||
OFFSET(CFG_SYSCALL_MAP32, vdso_arch_data, syscall_map);
|
||||
#endif
|
||||
OFFSET(VDSO_CLOCKMODE_OFFSET, vdso_arch_data, data[0].clock_mode);
|
||||
DEFINE(VDSO_CLOCKMODE_TIMENS, VDSO_CLOCKMODE_TIMENS);
|
||||
|
||||
#ifdef CONFIG_BUG
|
||||
DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
|
||||
|
@ -30,7 +30,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE)
|
||||
#ifdef CONFIG_PPC64
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
get_datapage r10
|
||||
get_realdatapage r10, r11
|
||||
mtlr r12
|
||||
.cfi_restore lr
|
||||
#endif
|
||||
|
@ -28,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
mr. r4,r3
|
||||
get_datapage r3
|
||||
get_realdatapage r3, r11
|
||||
mtlr r12
|
||||
#ifdef __powerpc64__
|
||||
addi r3,r3,CFG_SYSCALL_MAP64
|
||||
@ -52,7 +52,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
|
||||
.cfi_startproc
|
||||
mflr r12
|
||||
.cfi_register lr,r12
|
||||
get_datapage r3
|
||||
get_realdatapage r3, r11
|
||||
#ifndef __powerpc64__
|
||||
lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user