* Re: [PATCH v2] powerpc: Do not consider weak unresolved symbol relocations as bad
From: Alex Ghiti @ 2020-01-30 20:07 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
linuxppc-dev, linux-kernel, Stephen Rothwell, Alexei Starovoitov,
linux-next, Zong Li, Palmer Dabbelt
In-Reply-To: <20200118170335.21440-1-alex@ghiti.fr>
On 1/18/20 12:03 PM, Alexandre Ghiti wrote:
> Commit 8580ac9404f6 ("bpf: Process in-kernel BTF") introduced two weak
> symbols that may be unresolved at link time which result in an absolute
> relocation to 0. relocs_check.sh emits the following warning:
>
> "WARNING: 2 bad relocations
> c000000001a41478 R_PPC64_ADDR64 _binary__btf_vmlinux_bin_start
> c000000001a41480 R_PPC64_ADDR64 _binary__btf_vmlinux_bin_end"
>
> whereas those relocations are legitimate even for a relocatable kernel
> compiled with -pie option.
>
> relocs_check.sh already excluded some weak unresolved symbols explicitly:
> remove those hardcoded symbols and add some logic that parses the symbols
> using nm, retrieves all the weak unresolved symbols and excludes those from
> the list of the potential bad relocations.
>
> Reported-by: Stephen Rothwell <sfr@canb.auug.org.au>
> Signed-off-by: Alexandre Ghiti <alex@ghiti.fr>
> ---
>
> Changes in v2:
> - Follow Stephen advice of using grep -F instead of looping over weak symbols
> using read, patch is way smaller and cleaner.
> - Add missing nm in comment
>
> arch/powerpc/Makefile.postlink | 4 ++--
> arch/powerpc/tools/relocs_check.sh | 20 ++++++++++++--------
> 2 files changed, 14 insertions(+), 10 deletions(-)
>
> diff --git a/arch/powerpc/Makefile.postlink b/arch/powerpc/Makefile.postlink
> index 134f12f89b92..2268396ff4bb 100644
> --- a/arch/powerpc/Makefile.postlink
> +++ b/arch/powerpc/Makefile.postlink
> @@ -17,11 +17,11 @@ quiet_cmd_head_check = CHKHEAD $@
> quiet_cmd_relocs_check = CHKREL $@
> ifdef CONFIG_PPC_BOOK3S_64
> cmd_relocs_check = \
> - $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@" ; \
> + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@" ; \
> $(BASH) $(srctree)/arch/powerpc/tools/unrel_branch_check.sh "$(OBJDUMP)" "$@"
> else
> cmd_relocs_check = \
> - $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$@"
> + $(CONFIG_SHELL) $(srctree)/arch/powerpc/tools/relocs_check.sh "$(OBJDUMP)" "$(NM)" "$@"
> endif
>
> # `@true` prevents complaint when there is nothing to be done
> diff --git a/arch/powerpc/tools/relocs_check.sh b/arch/powerpc/tools/relocs_check.sh
> index 7b9fe0a567cf..014e00e74d2b 100755
> --- a/arch/powerpc/tools/relocs_check.sh
> +++ b/arch/powerpc/tools/relocs_check.sh
> @@ -10,14 +10,21 @@
> # based on relocs_check.pl
> # Copyright © 2009 IBM Corporation
>
> -if [ $# -lt 2 ]; then
> - echo "$0 [path to objdump] [path to vmlinux]" 1>&2
> +if [ $# -lt 3 ]; then
> + echo "$0 [path to objdump] [path to nm] [path to vmlinux]" 1>&2
> exit 1
> fi
>
> -# Have Kbuild supply the path to objdump so we handle cross compilation.
> +# Have Kbuild supply the path to objdump and nm so we handle cross compilation.
> objdump="$1"
> -vmlinux="$2"
> +nm="$2"
> +vmlinux="$3"
> +
> +# Remove from the bad relocations those that match an undefined weak symbol
> +# which will result in an absolute relocation to 0.
> +# Weak unresolved symbols are of that form in nm output:
> +# " w _binary__btf_vmlinux_bin_end"
> +undef_weak_symbols=$($nm "$vmlinux" | awk '$1 ~ /w/ { print $2 }')
>
> bad_relocs=$(
> $objdump -R "$vmlinux" |
> @@ -26,8 +33,6 @@ $objdump -R "$vmlinux" |
> # These relocations are okay
> # On PPC64:
> # R_PPC64_RELATIVE, R_PPC64_NONE
> - # R_PPC64_ADDR64 mach_<name>
> - # R_PPC64_ADDR64 __crc_<name>
> # On PPC:
> # R_PPC_RELATIVE, R_PPC_ADDR16_HI,
> # R_PPC_ADDR16_HA,R_PPC_ADDR16_LO,
> @@ -39,8 +44,7 @@ R_PPC_ADDR16_HI
> R_PPC_ADDR16_HA
> R_PPC_RELATIVE
> R_PPC_NONE' |
> - grep -E -v '\<R_PPC64_ADDR64[[:space:]]+mach_' |
> - grep -E -v '\<R_PPC64_ADDR64[[:space:]]+__crc_'
> + ([ "$undef_weak_symbols" ] && grep -F -w -v "$undef_weak_symbols" || cat)
> )
>
> if [ -z "$bad_relocs" ]; then
Hi guys,
Any thought about that ?
I do think this patch makes the whole check about absolute relocations
clearer.
And in the future, it will avoid anyone to spend some time on those
"bad" relocations
which actually aren't.
Thanks,
Alex
^ permalink raw reply
* Re: [PATCH] powerpc/drmem: cache LMBs in xarray to accelerate lookup
From: Fontenot, Nathan @ 2020-01-30 16:09 UTC (permalink / raw)
To: Scott Cheloha, Nathan Lynch; +Cc: linuxppc-dev, linux-kernel, Rick Lindsley
In-Reply-To: <20200129181013.lz6q5lpntnhwclqi@rascal.austin.ibm.com>
On 1/29/2020 12:10 PM, Scott Cheloha wrote:
> On Tue, Jan 28, 2020 at 05:56:55PM -0600, Nathan Lynch wrote:
>> Scott Cheloha <cheloha@linux.ibm.com> writes:
>>> LMB lookup is currently an O(n) linear search. This scales poorly when
>>> there are many LMBs.
>>>
>>> If we cache each LMB by both its base address and its DRC index
>>> in an xarray we can cut lookups to O(log n), greatly accelerating
>>> drmem initialization and memory hotplug.
>>>
>>> This patch introduces two xarrays of of LMBs and fills them during
>>> drmem initialization. The patch also adds two interfaces for LMB
>>> lookup.
>>
>> Good but can you replace the array of LMBs altogether
>> (drmem_info->lmbs)? xarray allows iteration over the members if needed.
>
> I don't think we can without potentially changing the current behavior.
>
> The current behavior in dlpar_memory_{add,remove}_by_ic() is to advance
> linearly through the array from the LMB with the matching DRC index.
>
> Iteration through the xarray via xa_for_each_start() will return LMBs
> indexed with monotonically increasing DRC indices.>
> Are they equivalent? Or can we have an LMB with a smaller DRC index
> appear at a greater offset in the array?
>
> If the following condition is possible:
>
> drmem_info->lmbs[i].drc_index > drmem_info->lmbs[j].drc_index
>
> where i < j, then we have a possible behavior change because
> xa_for_each_start() may not return a contiguous array slice. It might
> "leap backwards" in the array. Or it might skip over a chunk of LMBs.
>
The LMB array should have each LMB in monotonically increasing DRC Index
value. Note that this is set up based on the DT property but I don't recall
ever seeing the DT specify LMBs out of order or not being contiguous.
I am not very familiar with xarrays but it appears this should be possible.
-Nathan
^ permalink raw reply
* Re: [PATCH V12] mm/debug: Add tests validating architecture page table helpers
From: Anshuman Khandual @ 2020-01-30 15:06 UTC (permalink / raw)
To: linux-mm, linux-alpha, Richard Henderson, Ivan Kokshaysky,
Matt Turner, linux-c6x-dev, Mark Salter, Aurelien Jacquiot,
uclinux-h8-devel, Yoshinori Sato, linux-hexagon, Brian Cain,
linux-m68k, Geert Uytterhoeven, Michal Simek, linux-riscv,
Paul Walmsley, Palmer Dabbelt, Guan Xuetao, linux-xtensa,
Chris Zankel, Max Filippov
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra, James Hogan,
Heiko Carstens, Michal Hocko, Dave Hansen, Paul Mackerras,
sparclinux, Thomas Gleixner, linux-s390, Jason Gunthorpe, x86,
Russell King - ARM Linux, Matthew Wilcox, Steven Price,
Tetsuo Handa, Gerald Schaefer, linux-snps-arc, linux-arm-kernel,
Ingo Molnar, Kees Cook, Masahiro Yamada, Mark Brown,
Kirill A . Shutemov, Dan Williams, Vlastimil Babka,
Ard Biesheuvel, Greg Kroah-Hartman, linux-mips, Ralf Baechle,
linux-kernel, Paul Burton, Mike Rapoport, Vineet Gupta,
Martin Schwidefsky, Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <1580174873-18117-1-git-send-email-anshuman.khandual@arm.com>
On 01/28/2020 06:57 AM, Anshuman Khandual wrote:
> This adds tests which will validate architecture page table helpers and
> other accessors in their compliance with expected generic MM semantics.
> This will help various architectures in validating changes to existing
> page table helpers or addition of new ones.
>
> This test covers basic page table entry transformations including but not
> limited to old, young, dirty, clean, write, write protect etc at various
> level along with populating intermediate entries with next page table page
> and validating them.
>
> Test page table pages are allocated from system memory with required size
> and alignments. The mapped pfns at page table levels are derived from a
> real pfn representing a valid kernel text symbol. This test gets called
> right after page_alloc_init_late().
>
> This gets build and run when CONFIG_DEBUG_VM_PGTABLE is selected along with
> CONFIG_VM_DEBUG. Architectures willing to subscribe this test also need to
> select CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE which for now is limited to x86 and
> arm64. Going forward, other architectures too can enable this after fixing
> build or runtime problems (if any) with their page table helpers.
>
> Folks interested in making sure that a given platform's page table helpers
> conform to expected generic MM semantics should enable the above config
> which will just trigger this test during boot. Any non conformity here will
> be reported as an warning which would need to be fixed. This test will help
> catch any changes to the agreed upon semantics expected from generic MM and
> enable platforms to accommodate it thereafter.
>
> Cc: Andrew Morton <akpm@linux-foundation.org>
> Cc: Vlastimil Babka <vbabka@suse.cz>
> Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> Cc: Mike Rapoport <rppt@linux.vnet.ibm.com>
> Cc: Jason Gunthorpe <jgg@ziepe.ca>
> Cc: Dan Williams <dan.j.williams@intel.com>
> Cc: Peter Zijlstra <peterz@infradead.org>
> Cc: Michal Hocko <mhocko@kernel.org>
> Cc: Mark Rutland <mark.rutland@arm.com>
> Cc: Mark Brown <broonie@kernel.org>
> Cc: Steven Price <Steven.Price@arm.com>
> Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
> Cc: Masahiro Yamada <yamada.masahiro@socionext.com>
> Cc: Kees Cook <keescook@chromium.org>
> Cc: Tetsuo Handa <penguin-kernel@i-love.sakura.ne.jp>
> Cc: Matthew Wilcox <willy@infradead.org>
> Cc: Sri Krishna chowdary <schowdary@nvidia.com>
> Cc: Dave Hansen <dave.hansen@intel.com>
> Cc: Russell King - ARM Linux <linux@armlinux.org.uk>
> Cc: Michael Ellerman <mpe@ellerman.id.au>
> Cc: Paul Mackerras <paulus@samba.org>
> Cc: Martin Schwidefsky <schwidefsky@de.ibm.com>
> Cc: Heiko Carstens <heiko.carstens@de.ibm.com>
> Cc: "David S. Miller" <davem@davemloft.net>
> Cc: Vineet Gupta <vgupta@synopsys.com>
> Cc: James Hogan <jhogan@kernel.org>
> Cc: Paul Burton <paul.burton@mips.com>
> Cc: Ralf Baechle <ralf@linux-mips.org>
> Cc: Kirill A. Shutemov <kirill@shutemov.name>
> Cc: Gerald Schaefer <gerald.schaefer@de.ibm.com>
> Cc: Christophe Leroy <christophe.leroy@c-s.fr>
> Cc: Ingo Molnar <mingo@kernel.org>
> Cc: linux-snps-arc@lists.infradead.org
> Cc: linux-mips@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-ia64@vger.kernel.org
> Cc: linuxppc-dev@lists.ozlabs.org
> Cc: linux-s390@vger.kernel.org
> Cc: linux-sh@vger.kernel.org
> Cc: sparclinux@vger.kernel.org
> Cc: x86@kernel.org
> Cc: linux-kernel@vger.kernel.org
I should have included mailing lists for all missing platforms here.
Will add them in the patch next time around but for now just adding
them here explicitly so that hopefully in case some of them can build
and run the test successfully on respective platforms.
ALPHA:
+ linux-alpha@vger.kernel.org
+ Richard Henderson <rth@twiddle.net>
+ Ivan Kokshaysky <ink@jurassic.park.msu.ru>
+ Matt Turner <mattst88@gmail.com>
C6X:
+ linux-c6x-dev@linux-c6x.org
+ Mark Salter <msalter@redhat.com>
+ Aurelien Jacquiot <jacquiot.aurelien@gmail.com>
H8300:
+ uclinux-h8-devel@lists.sourceforge.jp
+ Yoshinori Sato <ysato@users.sourceforge.jp>
HEXAGON:
+ linux-hexagon@vger.kernel.org
+ Brian Cain <bcain@codeaurora.org>
M68K:
+ linux-m68k@lists.linux-m68k.org
+ Geert Uytterhoeven <geert@linux-m68k.org>
MICROBLAZE:
+ Michal Simek <monstr@monstr.eu>
RISCV:
+ linux-riscv@lists.infradead.org
+ Paul Walmsley <paul.walmsley@sifive.com>
+ Palmer Dabbelt <palmer@dabbelt.com>
UNICORE32:
+ Guan Xuetao <gxt@pku.edu.cn>
XTENSA:
+ linux-xtensa@linux-xtensa.org
+ Chris Zankel <chris@zankel.net>
+ Max Filippov <jcmvbkbc@gmail.com>
Please feel free to add others if I have missed.
^ permalink raw reply
* [PATCH] powerpc: configs: Cleanup old Kconfig options
From: Krzysztof Kozlowski @ 2020-01-30 19:52 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman,
Geert Uytterhoeven, linuxppc-dev, linux-kernel
Cc: Krzysztof Kozlowski
CONFIG_ENABLE_WARN_DEPRECATED is gone since
commit 771c035372a0 ("deprecate the '__deprecated' attribute warnings
entirely and for good").
CONFIG_IOSCHED_DEADLINE and CONFIG_IOSCHED_CFQ are gone since
commit f382fb0bcef4 ("block: remove legacy IO schedulers").
The IOSCHED_DEADLINE was replaced by MQ_IOSCHED_DEADLINE and it will be
now enabled by default (along with MQ_IOSCHED_KYBER).
Signed-off-by: Krzysztof Kozlowski <krzk@kernel.org>
---
arch/powerpc/configs/44x/sam440ep_defconfig | 2 --
arch/powerpc/configs/52xx/pcm030_defconfig | 2 --
arch/powerpc/configs/83xx/kmeter1_defconfig | 2 --
arch/powerpc/configs/adder875_defconfig | 1 -
arch/powerpc/configs/ep8248e_defconfig | 1 -
arch/powerpc/configs/ep88xc_defconfig | 1 -
arch/powerpc/configs/mgcoge_defconfig | 1 -
arch/powerpc/configs/mpc512x_defconfig | 1 -
arch/powerpc/configs/mpc885_ads_defconfig | 1 -
arch/powerpc/configs/storcenter_defconfig | 1 -
arch/powerpc/configs/tqm8xx_defconfig | 1 -
11 files changed, 14 deletions(-)
diff --git a/arch/powerpc/configs/44x/sam440ep_defconfig b/arch/powerpc/configs/44x/sam440ep_defconfig
index ed02f12dbd54..22dc0dadf576 100644
--- a/arch/powerpc/configs/44x/sam440ep_defconfig
+++ b/arch/powerpc/configs/44x/sam440ep_defconfig
@@ -10,8 +10,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
CONFIG_AMIGA_PARTITION=y
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
# CONFIG_EBONY is not set
CONFIG_SAM440EP=y
CONFIG_CMDLINE_BOOL=y
diff --git a/arch/powerpc/configs/52xx/pcm030_defconfig b/arch/powerpc/configs/52xx/pcm030_defconfig
index fdb11daeb688..789622ffd844 100644
--- a/arch/powerpc/configs/52xx/pcm030_defconfig
+++ b/arch/powerpc/configs/52xx/pcm030_defconfig
@@ -14,8 +14,6 @@ CONFIG_SLAB=y
CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
# CONFIG_PPC_CHRP is not set
CONFIG_PPC_MPC52xx=y
CONFIG_PPC_MPC5200_SIMPLE=y
diff --git a/arch/powerpc/configs/83xx/kmeter1_defconfig b/arch/powerpc/configs/83xx/kmeter1_defconfig
index 648c6b3dccf9..24bf1bde1bb4 100644
--- a/arch/powerpc/configs/83xx/kmeter1_defconfig
+++ b/arch/powerpc/configs/83xx/kmeter1_defconfig
@@ -11,8 +11,6 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
# CONFIG_MSDOS_PARTITION is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
# CONFIG_PPC_CHRP is not set
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_83xx=y
diff --git a/arch/powerpc/configs/adder875_defconfig b/arch/powerpc/configs/adder875_defconfig
index 510f7fd1f6a3..f55e23cb176c 100644
--- a/arch/powerpc/configs/adder875_defconfig
+++ b/arch/powerpc/configs/adder875_defconfig
@@ -9,7 +9,6 @@ CONFIG_EXPERT=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
CONFIG_PPC_ADDER875=y
CONFIG_8xx_COPYBACK=y
CONFIG_GEN_RTC=y
diff --git a/arch/powerpc/configs/ep8248e_defconfig b/arch/powerpc/configs/ep8248e_defconfig
index 6e08d9502d89..00d69965f898 100644
--- a/arch/powerpc/configs/ep8248e_defconfig
+++ b/arch/powerpc/configs/ep8248e_defconfig
@@ -6,7 +6,6 @@ CONFIG_EXPERT=y
CONFIG_KALLSYMS_ALL=y
CONFIG_SLAB=y
CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
# CONFIG_PPC_CHRP is not set
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_82xx=y
diff --git a/arch/powerpc/configs/ep88xc_defconfig b/arch/powerpc/configs/ep88xc_defconfig
index 9c1bf60f1e19..0e2e5e81a359 100644
--- a/arch/powerpc/configs/ep88xc_defconfig
+++ b/arch/powerpc/configs/ep88xc_defconfig
@@ -11,7 +11,6 @@ CONFIG_EXPERT=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
CONFIG_PPC_EP88XC=y
CONFIG_8xx_COPYBACK=y
CONFIG_GEN_RTC=y
diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig
index 6ce4f206eac7..dcc8dccf54f3 100644
--- a/arch/powerpc/configs/mgcoge_defconfig
+++ b/arch/powerpc/configs/mgcoge_defconfig
@@ -12,7 +12,6 @@ CONFIG_KALLSYMS_ALL=y
CONFIG_EMBEDDED=y
CONFIG_SLAB=y
CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
# CONFIG_PPC_PMAC is not set
CONFIG_PPC_82xx=y
CONFIG_MGCOGE=y
diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig
index 1f3a045ab081..e39346b3dc3b 100644
--- a/arch/powerpc/configs/mpc512x_defconfig
+++ b/arch/powerpc/configs/mpc512x_defconfig
@@ -9,7 +9,6 @@ CONFIG_MODULES=y
CONFIG_MODULE_UNLOAD=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
# CONFIG_PPC_CHRP is not set
CONFIG_PPC_MPC512x=y
CONFIG_MPC512x_LPBFIFO=y
diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig
index 0327a329316f..82a008c04eae 100644
--- a/arch/powerpc/configs/mpc885_ads_defconfig
+++ b/arch/powerpc/configs/mpc885_ads_defconfig
@@ -11,7 +11,6 @@ CONFIG_EXPERT=y
# CONFIG_VM_EVENT_COUNTERS is not set
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
CONFIG_8xx_COPYBACK=y
CONFIG_GEN_RTC=y
CONFIG_HZ_100=y
diff --git a/arch/powerpc/configs/storcenter_defconfig b/arch/powerpc/configs/storcenter_defconfig
index 29b19ec7e5d7..b964084e4056 100644
--- a/arch/powerpc/configs/storcenter_defconfig
+++ b/arch/powerpc/configs/storcenter_defconfig
@@ -77,5 +77,4 @@ CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_UTF8=y
CONFIG_CRC_T10DIF=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
# CONFIG_ENABLE_MUST_CHECK is not set
diff --git a/arch/powerpc/configs/tqm8xx_defconfig b/arch/powerpc/configs/tqm8xx_defconfig
index ffed2b4256d6..eda8bfb2d0a3 100644
--- a/arch/powerpc/configs/tqm8xx_defconfig
+++ b/arch/powerpc/configs/tqm8xx_defconfig
@@ -14,7 +14,6 @@ CONFIG_MODULE_UNLOAD=y
CONFIG_MODULE_SRCVERSION_ALL=y
# CONFIG_BLK_DEV_BSG is not set
CONFIG_PARTITION_ADVANCED=y
-# CONFIG_IOSCHED_CFQ is not set
CONFIG_TQM8XX=y
CONFIG_8xx_COPYBACK=y
# CONFIG_8xx_CPU15 is not set
--
2.17.1
^ permalink raw reply related
* Re: powerpc Linux scv support and scv system call ABI proposal
From: Adhemerval Zanella @ 2020-01-30 17:04 UTC (permalink / raw)
To: Segher Boessenkool, Florian Weimer
Cc: libc-alpha, Tulio Magno Quites Machado Filho, linuxppc-dev,
Nicholas Piggin
In-Reply-To: <20200130135030.GV22482@gate.crashing.org>
On 30/01/2020 10:50, Segher Boessenkool wrote:
> Hi again,
>
> On Thu, Jan 30, 2020 at 01:03:53PM +0100, Florian Weimer wrote:
>>> This is why that *is* the only supported use. The documentation could
>>> use a touch-up, I think. Unless we still have problems here?
>>
>> I really don't know. GCC still has *some* support for the old behavior,
>> though.
>
> No. No support. It still does some of the same things, but that can
> change (and probably should). But this hasn't been supported since the
> dark ages, and the documentation has become gradually more explicit
> about it.
>
I think this might be related to an odd sparc32 issue I am seeing with
newer clock_nanosleep. The expanded code is:
--
register long err __asm__("g1"); // INTERNAL_SYSCALL_DECL (err)
r = ({ // r = INTERNAL_SYSCALL_CANCEL (...)
long int sc_ret;
if (SINGLE_THREAD_P)
sc_ret = INTERNAL_SYSCALL_CALL (__VA_ARGS__);
else
{
int sc_cancel_oldtype = __libc_enable_asynccancel ();
sc_ret = INTERNAL_SYSCALL_CALL (__VA_ARGS__); // It issues the syscall with the asm (...)
__librt_disable_asynccancel (sc_cancel_oldtype);
}
sc_ret;
});
if ((void) (val), __builtin_expect((err) != 0, 0)) // if (! INTERNAL_SYSCALL_ERROR_P (r, err))
return 0;
if ((-(val)) != ENOSYS) // if (INTERNAL_SYSCALL_ERRNO (r, err) != ENOSYS)
return ((-(val))); // return INTERNAL_SYSCALL_ERRNO (r, err);
[...]
r = ({ // r = INTERNAL_SYSCALL_CANCEL (...)
[...]
)}
if ((void) (val), __builtin_expect((err) != 0, 0)) // if (! INTERNAL_SYSCALL_ERROR_P (r, err))
{
[...]
}
return ((void) (val), __builtin_expect((err) != 0, 0)) // return (INTERNAL_SYSCALL_ERROR_P (r, err)
? ((-(val))) : 0; // ? INTERNAL_SYSCALL_ERRNO (r, err) : 0);
--
It requires that 'err' (assigned to 'g1') be value propagated over
functions calls and over different scopes, which I take from your
explanation is not supported and fragile. It also seems that if I
move the __libc_enable_* calls before 'err' initialization and after
its usage the code seems to works, but again it seems this usage
is not really supported on gcc.
So it seems that the current usage of 'INTERNAL_SYSCALL_DECL' and
'INTERNAL_SYSCALL_ERROR_P' are fragile if the architecture *does*
use the 'err' variable and it is defined a register alias (which
its the case only for sparc currently).
Although a straightforward for sparc would be redefine
INTERNAL_SYSCALL_DECL to not use a register alias, I still think
we should just follow Linux kernel ABI convention where value in
the range between -4095 and -1 indicates an error and handle any
specific symbols that might not strictly follow it with an
arch-specific implementation (as we do for lseek on x32 and
mips64n32). It would allow cleanup a lot of code and avoid such
pitfalls.
^ permalink raw reply
* Looking for history of tlbia macro
From: Christophe Leroy @ 2020-01-30 16:29 UTC (permalink / raw)
To: linuxppc-dev@lists.ozlabs.org, Michael Ellerman,
Benjamin Herrenschmidt, Paul Mackerras, Segher Boessenkool
Hi,
I'm looking for the history of the tlbia macro. At the time being, the
tlbia macro performs 1024 tlbie, increasing the address by 0x1000
between each tlbie.
I looked into the fullhistory linux repository it was changed from 128
to 1024 at some point in time, but this was done in commit c57a0d4efdc8
("Import 2.4.0-test2pre2") which is a huge commit without the details
explaining the reason for this change.
In the e300 core manual, and in the ppc603e User manual, it is said to
perform 32 tlbie for flushing the entire TLB tables.
In the ppc604, it is said to perform 64 tlbie.
1024 is huge and tlbia takes a lot more time than it should. Does
anybody know which it was increased to 1024 ?
Christophe
^ permalink raw reply
* [PATCH v5 6/6] powerpc/vdso: Switch VDSO to generic C implementation.
From: Christophe Leroy @ 2020-01-30 16:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, nathanl,
arnd, tglx, vincenzo.frascino, luto
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-mips
In-Reply-To: <cover.1580399657.git.christophe.leroy@c-s.fr>
powerpc is a bit special for VDSO as well as system calls in the
way that it requires setting CR SO bit which cannot be done in C.
Therefore, entry/exit needs to be performed in ASM.
Implementing __arch_get_vdso_data() would clobbers the link register,
requiring the caller to save it. As the ASM calling function already
has to set a stack frame and saves the link register before calling
the C vdso function, retriving the vdso data pointer there is lighter.
Implement __arch_vdso_capable() and:
- When the timebase is used, make it always return true.
- When the RTC clock is used, make it always return false.
Provide vdso_shift_ns(), as the generic x >> s gives the following
bad result:
18: 35 25 ff e0 addic. r9,r5,-32
1c: 41 80 00 10 blt 2c <shift+0x14>
20: 7c 64 4c 30 srw r4,r3,r9
24: 38 60 00 00 li r3,0
...
2c: 54 69 08 3c rlwinm r9,r3,1,0,30
30: 21 45 00 1f subfic r10,r5,31
34: 7c 84 2c 30 srw r4,r4,r5
38: 7d 29 50 30 slw r9,r9,r10
3c: 7c 63 2c 30 srw r3,r3,r5
40: 7d 24 23 78 or r4,r9,r4
In our case the shift is always <= 32. In addition, the upper 32 bits
of the result are likely nul. Lets GCC know it, it also optimises the
following calculations.
With the patch, we get:
0: 21 25 00 20 subfic r9,r5,32
4: 7c 69 48 30 slw r9,r3,r9
8: 7c 84 2c 30 srw r4,r4,r5
c: 7d 24 23 78 or r4,r9,r4
10: 7c 63 2c 30 srw r3,r3,r5
For VDSO32 on PPC64, we create a fake 32 bits config, on the same
principle as MIPS architecture, in order to get the correct parts of
the different asm header files.
With the C VDSO, the performance is slightly lower, but it is worth
it as it will ease maintenance and evolution, and also brings clocks
that are not supported with the ASM VDSO.
On an 8xx at 132 MHz, vdsotest with the ASM VDSO:
gettimeofday: vdso: 828 nsec/call
clock-getres-realtime-coarse: vdso: 391 nsec/call
clock-gettime-realtime-coarse: vdso: 614 nsec/call
clock-getres-realtime: vdso: 460 nsec/call
clock-gettime-realtime: vdso: 876 nsec/call
clock-getres-monotonic-coarse: vdso: 399 nsec/call
clock-gettime-monotonic-coarse: vdso: 691 nsec/call
clock-getres-monotonic: vdso: 460 nsec/call
clock-gettime-monotonic: vdso: 1026 nsec/call
On an 8xx at 132 MHz, vdsotest with the C VDSO:
gettimeofday: vdso: 955 nsec/call
clock-getres-realtime-coarse: vdso: 545 nsec/call
clock-gettime-realtime-coarse: vdso: 592 nsec/call
clock-getres-realtime: vdso: 545 nsec/call
clock-gettime-realtime: vdso: 941 nsec/call
clock-getres-monotonic-coarse: vdso: 545 nsec/call
clock-gettime-monotonic-coarse: vdso: 591 nsec/call
clock-getres-monotonic: vdso: 545 nsec/call
clock-gettime-monotonic: vdso: 940 nsec/call
It is even better for gettime with monotonic clocks.
Unsupported clocks with ASM VDSO:
clock-gettime-boottime: vdso: 3851 nsec/call
clock-gettime-tai: vdso: 3852 nsec/call
clock-gettime-monotonic-raw: vdso: 3396 nsec/call
Same clocks with C VDSO:
clock-gettime-tai: vdso: 941 nsec/call
clock-gettime-monotonic-raw: vdso: 1001 nsec/call
clock-gettime-monotonic-coarse: vdso: 591 nsec/call
On an 8321E at 333 MHz, vdsotest with the ASM VDSO:
gettimeofday: vdso: 220 nsec/call
clock-getres-realtime-coarse: vdso: 102 nsec/call
clock-gettime-realtime-coarse: vdso: 178 nsec/call
clock-getres-realtime: vdso: 129 nsec/call
clock-gettime-realtime: vdso: 235 nsec/call
clock-getres-monotonic-coarse: vdso: 105 nsec/call
clock-gettime-monotonic-coarse: vdso: 208 nsec/call
clock-getres-monotonic: vdso: 129 nsec/call
clock-gettime-monotonic: vdso: 274 nsec/call
On an 8321E at 333 MHz, vdsotest with the C VDSO:
gettimeofday: vdso: 272 nsec/call
clock-getres-realtime-coarse: vdso: 160 nsec/call
clock-gettime-realtime-coarse: vdso: 184 nsec/call
clock-getres-realtime: vdso: 166 nsec/call
clock-gettime-realtime: vdso: 281 nsec/call
clock-getres-monotonic-coarse: vdso: 160 nsec/call
clock-gettime-monotonic-coarse: vdso: 184 nsec/call
clock-getres-monotonic: vdso: 169 nsec/call
clock-gettime-monotonic: vdso: 275 nsec/call
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/Kconfig | 2 +
arch/powerpc/include/asm/vdso/gettimeofday.h | 158 ++++++++++
arch/powerpc/include/asm/vdso/vsyscall.h | 25 ++
arch/powerpc/include/asm/vdso_datapage.h | 40 +--
arch/powerpc/kernel/asm-offsets.c | 49 +---
arch/powerpc/kernel/time.c | 90 ------
arch/powerpc/kernel/vdso.c | 5 +-
arch/powerpc/kernel/vdso32/Makefile | 32 +-
arch/powerpc/kernel/vdso32/config-fake32.h | 34 +++
arch/powerpc/kernel/vdso32/gettimeofday.S | 291 +------------------
arch/powerpc/kernel/vdso32/vgettimeofday.c | 29 ++
arch/powerpc/kernel/vdso64/Makefile | 23 +-
arch/powerpc/kernel/vdso64/gettimeofday.S | 243 +---------------
arch/powerpc/kernel/vdso64/vgettimeofday.c | 29 ++
14 files changed, 359 insertions(+), 691 deletions(-)
create mode 100644 arch/powerpc/include/asm/vdso/gettimeofday.h
create mode 100644 arch/powerpc/include/asm/vdso/vsyscall.h
create mode 100644 arch/powerpc/kernel/vdso32/config-fake32.h
create mode 100644 arch/powerpc/kernel/vdso32/vgettimeofday.c
create mode 100644 arch/powerpc/kernel/vdso64/vgettimeofday.c
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index a8fdb36a841e..5f7755cd80e3 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -165,6 +165,7 @@ config PPC
select GENERIC_STRNCPY_FROM_USER
select GENERIC_STRNLEN_USER
select GENERIC_TIME_VSYSCALL
+ select GENERIC_GETTIMEOFDAY
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_HUGE_VMAP if PPC_BOOK3S_64 && PPC_RADIX_MMU
select HAVE_ARCH_JUMP_LABEL
@@ -195,6 +196,7 @@ config PPC
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_FUNCTION_TRACER
select HAVE_GCC_PLUGINS if GCC_VERSION >= 50200 # plugin support on gcc <= 5.1 is buggy on PPC
+ select HAVE_GENERIC_VDSO
select HAVE_HW_BREAKPOINT if PERF_EVENTS && (PPC_BOOK3S || PPC_8xx)
select HAVE_IDE
select HAVE_IOREMAP_PROT
diff --git a/arch/powerpc/include/asm/vdso/gettimeofday.h b/arch/powerpc/include/asm/vdso/gettimeofday.h
new file mode 100644
index 000000000000..d59e0a0aeaca
--- /dev/null
+++ b/arch/powerpc/include/asm/vdso/gettimeofday.h
@@ -0,0 +1,158 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_VDSO_GETTIMEOFDAY_H
+#define __ASM_VDSO_GETTIMEOFDAY_H
+
+#ifdef __ASSEMBLY__
+
+.macro cvdso_call funct
+ .cfi_startproc
+ PPC_STLU r1, -INT_FRAME_SIZE(r1)
+ mflr r0
+ .cfi_register lr, r0
+ PPC_STL r0, INT_FRAME_SIZE + PPC_LR_STKOFF(r1)
+ get_datapage r5, VDSO_DATA_OFFSET
+ bl \funct
+ PPC_LL r0, INT_FRAME_SIZE + PPC_LR_STKOFF(r1)
+ cmpwi r3, 0
+ mtlr r0
+ .cfi_restore lr
+ addi r1, r1, INT_FRAME_SIZE
+ crclr so
+ beqlr+
+ crset so
+ neg r3, r3
+ blr
+ .cfi_endproc
+.endm
+
+.macro cvdso_call_time funct
+ .cfi_startproc
+ PPC_STLU r1, -INT_FRAME_SIZE(r1)
+ mflr r0
+ .cfi_register lr, r0
+ PPC_STL r0, INT_FRAME_SIZE + PPC_LR_STKOFF(r1)
+ get_datapage r4, VDSO_DATA_OFFSET
+ bl \funct
+ PPC_LL r0, INT_FRAME_SIZE + PPC_LR_STKOFF(r1)
+ crclr so
+ mtlr r0
+ .cfi_restore lr
+ addi r1, r1, INT_FRAME_SIZE
+ blr
+ .cfi_endproc
+.endm
+
+#else
+
+#include <asm/time.h>
+#include <asm/unistd.h>
+#include <uapi/linux/time.h>
+
+#define VDSO_HAS_CLOCK_GETRES 1
+
+#define VDSO_HAS_TIME 1
+
+static __always_inline int do_syscall_2(const unsigned long _r0, const unsigned long _r3,
+ const unsigned long _r4)
+{
+ register long r0 asm("r0") = _r0;
+ register unsigned long r3 asm("r3") = _r3;
+ register unsigned long r4 asm("r4") = _r4;
+ register int ret asm ("r3");
+
+ asm volatile(
+ " sc\n"
+ " bns+ 1f\n"
+ " neg %0, %0\n"
+ "1:\n"
+ : "+r" (ret), "+r" (r3), "+r" (r4), "+r" (r0)
+ :
+ : "memory", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "cr0", "ctr");
+
+ return ret;
+}
+
+static __always_inline
+int gettimeofday_fallback(struct __kernel_old_timeval *_tv, struct timezone *_tz)
+{
+ return do_syscall_2(__NR_gettimeofday, (unsigned long)_tv, (unsigned long)_tz);
+}
+
+static __always_inline
+int clock_gettime_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
+{
+ return do_syscall_2(__NR_clock_gettime, _clkid, (unsigned long)_ts);
+}
+
+static __always_inline
+int clock_getres_fallback(clockid_t _clkid, struct __kernel_timespec *_ts)
+{
+ return do_syscall_2(__NR_clock_getres, _clkid, (unsigned long)_ts);
+}
+
+#ifdef CONFIG_VDSO32
+
+#define BUILD_VDSO32 1
+
+static __always_inline
+int clock_gettime32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
+{
+ return do_syscall_2(__NR_clock_gettime, _clkid, (unsigned long)_ts);
+}
+
+static __always_inline
+int clock_getres32_fallback(clockid_t _clkid, struct old_timespec32 *_ts)
+{
+ return do_syscall_2(__NR_clock_getres, _clkid, (unsigned long)_ts);
+}
+#endif
+
+static __always_inline u64 __arch_get_hw_counter(s32 clock_mode)
+{
+ return get_tb();
+}
+
+const struct vdso_data *__arch_get_vdso_data(void);
+
+static inline bool __arch_vdso_capable(s32 clock_mode)
+{
+ return !__USE_RTC();
+}
+#define __arch_vdso_capable __arch_vdso_capable
+
+/*
+ * powerpc specific delta calculation.
+ *
+ * This variant removes the masking of the subtraction because the
+ * clocksource mask of all VDSO capable clocksources on powerpc is U64_MAX
+ * which would result in a pointless operation. The compiler cannot
+ * optimize it away as the mask comes from the vdso data and is not compile
+ * time constant.
+ */
+static __always_inline u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult)
+{
+ return (cycles - last) * mult;
+}
+#define vdso_calc_delta vdso_calc_delta
+
+#ifndef __powerpc64__
+static __always_inline u64 vdso_shift_ns(u64 ns, unsigned long shift)
+{
+ u32 hi = ns >> 32;
+ u32 lo = ns;
+
+ lo >>= shift;
+ lo |= hi << (32 - shift);
+ hi >>= shift;
+
+ if (likely(hi == 0))
+ return lo;
+
+ return ((u64)hi << 32) | lo;
+}
+#define vdso_shift_ns vdso_shift_ns
+#endif
+
+#endif /* __ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_GETTIMEOFDAY_H */
diff --git a/arch/powerpc/include/asm/vdso/vsyscall.h b/arch/powerpc/include/asm/vdso/vsyscall.h
new file mode 100644
index 000000000000..c56a030c0623
--- /dev/null
+++ b/arch/powerpc/include/asm/vdso/vsyscall.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_VDSO_VSYSCALL_H
+#define __ASM_VDSO_VSYSCALL_H
+
+#ifndef __ASSEMBLY__
+
+#include <linux/timekeeper_internal.h>
+#include <asm/vdso_datapage.h>
+
+/*
+ * Update the vDSO data page to keep in sync with kernel timekeeping.
+ */
+static __always_inline
+struct vdso_data *__arch_get_k_vdso_data(void)
+{
+ return vdso_data->data;
+}
+#define __arch_get_k_vdso_data __arch_get_k_vdso_data
+
+/* The asm-generic header needs to be included after the definitions above */
+#include <asm-generic/vdso/vsyscall.h>
+
+#endif /* !__ASSEMBLY__ */
+
+#endif /* __ASM_VDSO_VSYSCALL_H */
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index a361f07bec49..efcc56b041f4 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -36,6 +36,7 @@
#include <linux/unistd.h>
#include <linux/time.h>
+#include <vdso/datapage.h>
#define SYSCALL_MAP_SIZE ((NR_syscalls + 31) / 32)
@@ -45,7 +46,7 @@
#ifdef CONFIG_PPC64
-struct vdso_data {
+struct vdso_arch_data {
__u8 eye_catcher[16]; /* Eyecatcher: SYSTEMCFG:PPC64 0x00 */
struct { /* Systemcfg version numbers */
__u32 major; /* Major number 0x10 */
@@ -59,13 +60,13 @@ struct vdso_data {
__u32 processor; /* Processor type 0x1C */
__u64 processorCount; /* # of physical processors 0x20 */
__u64 physicalMemorySize; /* Size of real memory(B) 0x28 */
- __u64 tb_orig_stamp; /* Timebase at boot 0x30 */
+ __u64 tb_orig_stamp; /* (NU) Timebase at boot 0x30 */
__u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */
- __u64 tb_to_xs; /* Inverse of TB to 2^20 0x40 */
- __u64 stamp_xsec; /* 0x48 */
- __u64 tb_update_count; /* Timebase atomicity ctr 0x50 */
- __u32 tz_minuteswest; /* Minutes west of Greenwich 0x58 */
- __u32 tz_dsttime; /* Type of dst correction 0x5C */
+ __u64 tb_to_xs; /* (NU) Inverse of TB to 2^20 0x40 */
+ __u64 stamp_xsec; /* (NU) 0x48 */
+ __u64 tb_update_count; /* (NU) Timebase atomicity ctr 0x50 */
+ __u32 tz_minuteswest; /* (NU) Min. west of Greenwich 0x58 */
+ __u32 tz_dsttime; /* (NU) Type of dst correction 0x5C */
__u32 dcache_size; /* L1 d-cache size 0x60 */
__u32 dcache_line_size; /* L1 d-cache line size 0x64 */
__u32 icache_size; /* L1 i-cache size 0x68 */
@@ -78,14 +79,10 @@ struct vdso_data {
__u32 icache_block_size; /* L1 i-cache block size */
__u32 dcache_log_block_size; /* L1 d-cache log block size */
__u32 icache_log_block_size; /* L1 i-cache log block size */
- __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */
- __s32 wtom_clock_nsec; /* Wall to monotonic clock nsec */
- __s64 wtom_clock_sec; /* Wall to monotonic clock sec */
- __s64 stamp_xtime_sec; /* xtime secs as at tb_orig_stamp */
- __s64 stamp_xtime_nsec; /* xtime nsecs as at tb_orig_stamp */
- __u32 hrtimer_res; /* hrtimer resolution */
__u32 syscall_map_64[SYSCALL_MAP_SIZE]; /* map of syscalls */
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
+
+ struct vdso_data data[CS_BASES];
};
#else /* CONFIG_PPC64 */
@@ -93,26 +90,15 @@ struct vdso_data {
/*
* And here is the simpler 32 bits version
*/
-struct vdso_data {
- __u64 tb_orig_stamp; /* Timebase at boot 0x30 */
+struct vdso_arch_data {
__u64 tb_ticks_per_sec; /* Timebase tics / sec 0x38 */
- __u64 tb_to_xs; /* Inverse of TB to 2^20 0x40 */
- __u64 stamp_xsec; /* 0x48 */
- __u32 tb_update_count; /* Timebase atomicity ctr 0x50 */
- __u32 tz_minuteswest; /* Minutes west of Greenwich 0x58 */
- __u32 tz_dsttime; /* Type of dst correction 0x5C */
- __s32 wtom_clock_sec; /* Wall to monotonic clock */
- __s32 wtom_clock_nsec;
- __s32 stamp_xtime_sec; /* xtime seconds as at tb_orig_stamp */
- __s32 stamp_xtime_nsec; /* xtime nsecs as at tb_orig_stamp */
- __u32 stamp_sec_fraction; /* fractional seconds of stamp_xtime */
- __u32 hrtimer_res; /* hrtimer resolution */
__u32 syscall_map_32[SYSCALL_MAP_SIZE]; /* map of syscalls */
+ struct vdso_data data[CS_BASES];
};
#endif /* CONFIG_PPC64 */
-extern struct vdso_data *vdso_data;
+extern struct vdso_arch_data *vdso_data;
#else /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index c25e562f1cd9..676b69513a08 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -382,47 +382,16 @@ int main(void)
#endif /* ! CONFIG_PPC64 */
/* datapage offsets for use by vdso */
- OFFSET(CFG_TB_ORIG_STAMP, vdso_data, tb_orig_stamp);
- OFFSET(CFG_TB_TICKS_PER_SEC, vdso_data, tb_ticks_per_sec);
- OFFSET(CFG_TB_TO_XS, vdso_data, tb_to_xs);
- OFFSET(CFG_TB_UPDATE_COUNT, vdso_data, tb_update_count);
- OFFSET(CFG_TZ_MINUTEWEST, vdso_data, tz_minuteswest);
- OFFSET(CFG_TZ_DSTTIME, vdso_data, tz_dsttime);
- OFFSET(CFG_SYSCALL_MAP32, vdso_data, syscall_map_32);
- OFFSET(WTOM_CLOCK_SEC, vdso_data, wtom_clock_sec);
- OFFSET(WTOM_CLOCK_NSEC, vdso_data, wtom_clock_nsec);
- OFFSET(STAMP_XTIME_SEC, vdso_data, stamp_xtime_sec);
- OFFSET(STAMP_XTIME_NSEC, vdso_data, stamp_xtime_nsec);
- OFFSET(STAMP_SEC_FRAC, vdso_data, stamp_sec_fraction);
- OFFSET(CLOCK_HRTIMER_RES, vdso_data, hrtimer_res);
+ OFFSET(VDSO_DATA_OFFSET, vdso_arch_data, data);
+ OFFSET(CFG_TB_TICKS_PER_SEC, vdso_arch_data, tb_ticks_per_sec);
+ OFFSET(CFG_SYSCALL_MAP32, vdso_arch_data, syscall_map_32);
#ifdef CONFIG_PPC64
- OFFSET(CFG_ICACHE_BLOCKSZ, vdso_data, icache_block_size);
- OFFSET(CFG_DCACHE_BLOCKSZ, vdso_data, dcache_block_size);
- OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_data, icache_log_block_size);
- OFFSET(CFG_DCACHE_LOGBLOCKSZ, vdso_data, dcache_log_block_size);
- OFFSET(CFG_SYSCALL_MAP64, vdso_data, syscall_map_64);
- OFFSET(TVAL64_TV_SEC, __kernel_old_timeval, tv_sec);
- OFFSET(TVAL64_TV_USEC, __kernel_old_timeval, tv_usec);
-#endif
- OFFSET(TSPC64_TV_SEC, __kernel_timespec, tv_sec);
- OFFSET(TSPC64_TV_NSEC, __kernel_timespec, tv_nsec);
- OFFSET(TVAL32_TV_SEC, old_timeval32, tv_sec);
- OFFSET(TVAL32_TV_USEC, old_timeval32, tv_usec);
- OFFSET(TSPC32_TV_SEC, old_timespec32, tv_sec);
- OFFSET(TSPC32_TV_NSEC, old_timespec32, tv_nsec);
- /* timeval/timezone offsets for use by vdso */
- OFFSET(TZONE_TZ_MINWEST, timezone, tz_minuteswest);
- OFFSET(TZONE_TZ_DSTTIME, timezone, tz_dsttime);
-
- /* Other bits used by the vdso */
- DEFINE(CLOCK_REALTIME, CLOCK_REALTIME);
- DEFINE(CLOCK_MONOTONIC, CLOCK_MONOTONIC);
- DEFINE(CLOCK_REALTIME_COARSE, CLOCK_REALTIME_COARSE);
- DEFINE(CLOCK_MONOTONIC_COARSE, CLOCK_MONOTONIC_COARSE);
- DEFINE(CLOCK_MAX, CLOCK_TAI);
- DEFINE(NSEC_PER_SEC, NSEC_PER_SEC);
- DEFINE(EINVAL, EINVAL);
- DEFINE(KTIME_LOW_RES, KTIME_LOW_RES);
+ OFFSET(CFG_ICACHE_BLOCKSZ, vdso_arch_data, icache_block_size);
+ OFFSET(CFG_DCACHE_BLOCKSZ, vdso_arch_data, dcache_block_size);
+ OFFSET(CFG_ICACHE_LOGBLOCKSZ, vdso_arch_data, icache_log_block_size);
+ OFFSET(CFG_DCACHE_LOGBLOCKSZ, vdso_arch_data, dcache_log_block_size);
+ OFFSET(CFG_SYSCALL_MAP64, vdso_arch_data, syscall_map_64);
+#endif
#ifdef CONFIG_BUG
DEFINE(BUG_ENTRY_SIZE, sizeof(struct bug_entry));
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 1168e8b37e30..9075fe65424e 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -882,95 +882,6 @@ static notrace u64 timebase_read(struct clocksource *cs)
return (u64)get_tb();
}
-
-void update_vsyscall(struct timekeeper *tk)
-{
- struct timespec64 xt;
- struct clocksource *clock = tk->tkr_mono.clock;
- u32 mult = tk->tkr_mono.mult;
- u32 shift = tk->tkr_mono.shift;
- u64 cycle_last = tk->tkr_mono.cycle_last;
- u64 new_tb_to_xs, new_stamp_xsec;
- u64 frac_sec;
-
- if (clock != &clocksource_timebase)
- return;
-
- xt.tv_sec = tk->xtime_sec;
- xt.tv_nsec = (long)(tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift);
-
- /* Make userspace gettimeofday spin until we're done. */
- ++vdso_data->tb_update_count;
- smp_mb();
-
- /*
- * This computes ((2^20 / 1e9) * mult) >> shift as a
- * 0.64 fixed-point fraction.
- * The computation in the else clause below won't overflow
- * (as long as the timebase frequency is >= 1.049 MHz)
- * but loses precision because we lose the low bits of the constant
- * in the shift. Note that 19342813113834067 ~= 2^(20+64) / 1e9.
- * For a shift of 24 the error is about 0.5e-9, or about 0.5ns
- * over a second. (Shift values are usually 22, 23 or 24.)
- * For high frequency clocks such as the 512MHz timebase clock
- * on POWER[6789], the mult value is small (e.g. 32768000)
- * and so we can shift the constant by 16 initially
- * (295147905179 ~= 2^(20+64-16) / 1e9) and then do the
- * remaining shifts after the multiplication, which gives a
- * more accurate result (e.g. with mult = 32768000, shift = 24,
- * the error is only about 1.2e-12, or 0.7ns over 10 minutes).
- */
- if (mult <= 62500000 && clock->shift >= 16)
- new_tb_to_xs = ((u64) mult * 295147905179ULL) >> (clock->shift - 16);
- else
- new_tb_to_xs = (u64) mult * (19342813113834067ULL >> clock->shift);
-
- /*
- * Compute the fractional second in units of 2^-32 seconds.
- * The fractional second is tk->tkr_mono.xtime_nsec >> tk->tkr_mono.shift
- * in nanoseconds, so multiplying that by 2^32 / 1e9 gives
- * it in units of 2^-32 seconds.
- * We assume shift <= 32 because clocks_calc_mult_shift()
- * generates shift values in the range 0 - 32.
- */
- frac_sec = tk->tkr_mono.xtime_nsec << (32 - shift);
- do_div(frac_sec, NSEC_PER_SEC);
-
- /*
- * Work out new stamp_xsec value for any legacy users of systemcfg.
- * stamp_xsec is in units of 2^-20 seconds.
- */
- new_stamp_xsec = frac_sec >> 12;
- new_stamp_xsec += tk->xtime_sec * XSEC_PER_SEC;
-
- /*
- * tb_update_count is used to allow the userspace gettimeofday code
- * to assure itself that it sees a consistent view of the tb_to_xs and
- * stamp_xsec variables. It reads the tb_update_count, then reads
- * tb_to_xs and stamp_xsec and then reads tb_update_count again. If
- * the two values of tb_update_count match and are even then the
- * tb_to_xs and stamp_xsec values are consistent. If not, then it
- * loops back and reads them again until this criteria is met.
- */
- vdso_data->tb_orig_stamp = cycle_last;
- vdso_data->stamp_xsec = new_stamp_xsec;
- vdso_data->tb_to_xs = new_tb_to_xs;
- vdso_data->wtom_clock_sec = tk->wall_to_monotonic.tv_sec;
- vdso_data->wtom_clock_nsec = tk->wall_to_monotonic.tv_nsec;
- vdso_data->stamp_xtime_sec = xt.tv_sec;
- vdso_data->stamp_xtime_nsec = xt.tv_nsec;
- vdso_data->stamp_sec_fraction = frac_sec;
- vdso_data->hrtimer_res = hrtimer_resolution;
- smp_wmb();
- ++(vdso_data->tb_update_count);
-}
-
-void update_vsyscall_tz(void)
-{
- vdso_data->tz_minuteswest = sys_tz.tz_minuteswest;
- vdso_data->tz_dsttime = sys_tz.tz_dsttime;
-}
-
static void __init clocksource_init(void)
{
struct clocksource *clock;
@@ -1140,7 +1051,6 @@ void __init time_init(void)
sys_tz.tz_dsttime = 0;
}
- vdso_data->tb_update_count = 0;
vdso_data->tb_ticks_per_sec = tb_ticks_per_sec;
/* initialise and enable the large decrementer (if we have one) */
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index ebbb13d92a12..1be82e8f73b7 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -17,6 +17,7 @@
#include <linux/elf.h>
#include <linux/security.h>
#include <linux/memblock.h>
+#include <vdso/datapage.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
@@ -71,10 +72,10 @@ static int vdso_ready;
* with it, it will become dynamically allocated
*/
static union {
- struct vdso_data data;
+ struct vdso_arch_data data;
u8 page[PAGE_SIZE];
} vdso_data_store __page_aligned_data;
-struct vdso_data *vdso_data = &vdso_data_store.data;
+struct vdso_arch_data *vdso_data = &vdso_data_store.data;
/* Format of the patch table */
struct vdso_patch_def
diff --git a/arch/powerpc/kernel/vdso32/Makefile b/arch/powerpc/kernel/vdso32/Makefile
index e147bbdc12cd..f27add7cdecc 100644
--- a/arch/powerpc/kernel/vdso32/Makefile
+++ b/arch/powerpc/kernel/vdso32/Makefile
@@ -2,7 +2,23 @@
# List of files in the vdso, has to be asm only for now
-obj-vdso32 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o
+ARCH_REL_TYPE_ABS := R_PPC_JUMP_SLOT|R_PPC_GLOB_DAT|R_PPC_ADDR32|R_PPC_ADDR24|R_PPC_ADDR16|R_PPC_ADDR16_LO|R_PPC_ADDR16_HI|R_PPC_ADDR16_HA|R_PPC_ADDR14|R_PPC_ADDR14_BRTAKEN|R_PPC_ADDR14_BRNTAKEN
+include $(srctree)/lib/vdso/Makefile
+
+obj-vdso32 = sigtramp.o datapage.o cacheflush.o note.o getcpu.o $(obj-vdso32-y)
+obj-vdso32 += gettimeofday.o
+
+ifneq ($(c-gettimeofday-y),)
+ ifdef CONFIG_PPC64
+ CFLAGS_vgettimeofday.o += -include $(srctree)/$(src)/config-fake32.h
+ endif
+ CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y)
+ CFLAGS_vgettimeofday.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
+ CFLAGS_vgettimeofday.o += $(call cc-option, -fno-stack-protector)
+ CFLAGS_vgettimeofday.o += -DDISABLE_BRANCH_PROFILING
+ CFLAGS_vgettimeofday.o += -ffreestanding
+ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
+endif
# Build rules
@@ -15,6 +31,7 @@ endif
CC32FLAGS :=
ifdef CONFIG_PPC64
CC32FLAGS += -m32
+KBUILD_CFLAGS := $(filter-out -mcmodel=medium,$(KBUILD_CFLAGS))
endif
targets := $(obj-vdso32) vdso32.so vdso32.so.dbg
@@ -23,6 +40,7 @@ obj-vdso32 := $(addprefix $(obj)/, $(obj-vdso32))
GCOV_PROFILE := n
KCOV_INSTRUMENT := n
UBSAN_SANITIZE := n
+KASAN_SANITIZE := n
ccflags-y := -shared -fno-common -fno-builtin -nostdlib \
-Wl,-soname=linux-vdso32.so.1 -Wl,--hash-style=both
@@ -36,8 +54,8 @@ CPPFLAGS_vdso32.lds += -P -C -Upowerpc
$(obj)/vdso32_wrapper.o : $(obj)/vdso32.so
# link rule for the .so file, .lds has to be first
-$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) FORCE
- $(call if_changed,vdso32ld)
+$(obj)/vdso32.so.dbg: $(src)/vdso32.lds $(obj-vdso32) $(obj)/vgettimeofday.o FORCE
+ $(call if_changed,vdso32ld_and_check)
# strip rule for the .so file
$(obj)/%.so: OBJCOPYFLAGS := -S
@@ -47,12 +65,16 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
# assembly rules for the .S files
$(obj-vdso32): %.o: %.S FORCE
$(call if_changed_dep,vdso32as)
+$(obj)/vgettimeofday.o: %.o: %.c FORCE
+ $(call if_changed_dep,vdso32cc)
# actual build commands
-quiet_cmd_vdso32ld = VDSO32L $@
- cmd_vdso32ld = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^)
+quiet_cmd_vdso32ld_and_check = VDSO32L $@
+ cmd_vdso32ld_and_check = $(VDSOCC) $(c_flags) $(CC32FLAGS) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) ; $(cmd_vdso_check)
quiet_cmd_vdso32as = VDSO32A $@
cmd_vdso32as = $(VDSOCC) $(a_flags) $(CC32FLAGS) -c -o $@ $<
+quiet_cmd_vdso32cc = VDSO32C $@
+ cmd_vdso32cc = $(VDSOCC) $(c_flags) $(CC32FLAGS) -c -o $@ $<
# install commands for the unstripped file
quiet_cmd_vdso_install = INSTALL $@
diff --git a/arch/powerpc/kernel/vdso32/config-fake32.h b/arch/powerpc/kernel/vdso32/config-fake32.h
new file mode 100644
index 000000000000..e16041fc15c9
--- /dev/null
+++ b/arch/powerpc/kernel/vdso32/config-fake32.h
@@ -0,0 +1,34 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * In case of a 32 bit VDSO for a 64 bit kernel fake a 32 bit kernel
+ * configuration.
+ */
+
+#undef CONFIG_PPC64
+#undef CONFIG_64BIT
+#define CONFIG_PPC32
+#define CONFIG_32BIT 1
+#define CONFIG_GENERIC_ATOMIC64 1
+
+#ifdef CONFIG_PPC_BOOK3S_64
+#undef CONFIG_PPC_BOOK3S_64
+#undef CONFIG_PPC_PSERIES
+#define CONFIG_PPC_BOOK3S_32
+#else
+#define CONFIG_PPC_MMU_NOHASH_32
+#define CONFIG_FSL_BOOKE
+#endif
+
+#define CONFIG_TASK_SIZE 0
+#undef CONFIG_MMIOWB
+#undef CONFIG_PPC_SPLPAR
+#undef CONFIG_SPARSEMEM
+#undef CONFIG_PGTABLE_LEVELS
+#define CONFIG_PGTABLE_LEVELS 2
+#undef CONFIG_TRANSPARENT_HUGEPAGE
+#undef CONFIG_SPARSEMEM_VMEMMAP
+#undef CONFIG_FLATMEM
+#define CONFIG_FLATMEM
+#undef CONFIG_PPC_INDIRECT_MMIO
+#undef CONFIG_PPC_INDIRECT_PIO
+#undef CONFIG_EEH
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index 0bbdce0f2a9c..fd7b01c51281 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -12,13 +12,7 @@
#include <asm/vdso_datapage.h>
#include <asm/asm-offsets.h>
#include <asm/unistd.h>
-
-/* Offset for the low 32-bit part of a field of long type */
-#ifdef CONFIG_PPC64
-#define LOPART 4
-#else
-#define LOPART 0
-#endif
+#include <asm/vdso/gettimeofday.h>
.text
/*
@@ -28,32 +22,7 @@
*
*/
V_FUNCTION_BEGIN(__kernel_gettimeofday)
- .cfi_startproc
- mflr r12
- .cfi_register lr,r12
-
- mr. r10,r3 /* r10 saves tv */
- mr r11,r4 /* r11 saves tz */
- get_datapage r9
- beq 3f
- LOAD_REG_IMMEDIATE(r7, 1000000) /* load up USEC_PER_SEC */
- bl __do_get_tspec@local /* get sec/usec from tb & kernel */
- stw r3,TVAL32_TV_SEC(r10)
- stw r4,TVAL32_TV_USEC(r10)
-
-3: cmplwi r11,0 /* check if tz is NULL */
- mtlr r12
- crclr cr0*4+so
- li r3,0
- beqlr
-
- lwz r4,CFG_TZ_MINUTEWEST(r9)/* fill tz */
- lwz r5,CFG_TZ_DSTTIME(r9)
- stw r4,TZONE_TZ_MINWEST(r11)
- stw r5,TZONE_TZ_DSTTIME(r11)
-
- blr
- .cfi_endproc
+ cvdso_call __c_kernel_gettimeofday
V_FUNCTION_END(__kernel_gettimeofday)
/*
@@ -63,127 +32,7 @@ V_FUNCTION_END(__kernel_gettimeofday)
*
*/
V_FUNCTION_BEGIN(__kernel_clock_gettime)
- .cfi_startproc
- /* Check for supported clock IDs */
- cmpli cr0,r3,CLOCK_REALTIME
- cmpli cr1,r3,CLOCK_MONOTONIC
- cror cr0*4+eq,cr0*4+eq,cr1*4+eq
-
- cmpli cr5,r3,CLOCK_REALTIME_COARSE
- cmpli cr6,r3,CLOCK_MONOTONIC_COARSE
- cror cr5*4+eq,cr5*4+eq,cr6*4+eq
-
- cror cr0*4+eq,cr0*4+eq,cr5*4+eq
- bne cr0, .Lgettime_fallback
-
- mflr r12 /* r12 saves lr */
- .cfi_register lr,r12
- mr r11,r4 /* r11 saves tp */
- get_datapage r9
- LOAD_REG_IMMEDIATE(r7, NSEC_PER_SEC) /* load up NSEC_PER_SEC */
- beq cr5, .Lcoarse_clocks
-.Lprecise_clocks:
- bl __do_get_tspec@local /* get sec/nsec from tb & kernel */
- bne cr1, .Lfinish /* not monotonic -> all done */
-
- /*
- * CLOCK_MONOTONIC
- */
-
- /* now we must fixup using wall to monotonic. We need to snapshot
- * that value and do the counter trick again. Fortunately, we still
- * have the counter value in r8 that was returned by __do_get_xsec.
- * At this point, r3,r4 contain our sec/nsec values, r5 and r6
- * can be used, r7 contains NSEC_PER_SEC.
- */
-
- lwz r5,(WTOM_CLOCK_SEC+LOPART)(r9)
- lwz r6,WTOM_CLOCK_NSEC(r9)
-
- /* We now have our offset in r5,r6. We create a fake dependency
- * on that value and re-check the counter
- */
- or r0,r6,r5
- xor r0,r0,r0
- add r9,r9,r0
- lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
- cmpl cr0,r8,r0 /* check if updated */
- bne- .Lprecise_clocks
- b .Lfinish_monotonic
-
- /*
- * For coarse clocks we get data directly from the vdso data page, so
- * we don't need to call __do_get_tspec, but we still need to do the
- * counter trick.
- */
-.Lcoarse_clocks:
- lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
- andi. r0,r8,1 /* pending update ? loop */
- bne- .Lcoarse_clocks
- add r9,r9,r0 /* r0 is already 0 */
-
- /*
- * CLOCK_REALTIME_COARSE, below values are needed for MONOTONIC_COARSE
- * too
- */
- lwz r3,STAMP_XTIME_SEC+LOPART(r9)
- lwz r4,STAMP_XTIME_NSEC+LOPART(r9)
- bne cr6,1f
-
- /* CLOCK_MONOTONIC_COARSE */
- lwz r5,(WTOM_CLOCK_SEC+LOPART)(r9)
- lwz r6,WTOM_CLOCK_NSEC(r9)
-
- /* check if counter has updated */
- or r0,r6,r5
-1: or r0,r0,r3
- or r0,r0,r4
- xor r0,r0,r0
- add r3,r3,r0
- lwz r0,CFG_TB_UPDATE_COUNT+LOPART(r9)
- cmpl cr0,r0,r8 /* check if updated */
- bne- .Lcoarse_clocks
-
- /* Counter has not updated, so continue calculating proper values for
- * sec and nsec if monotonic coarse, or just return with the proper
- * values for realtime.
- */
- bne cr6, .Lfinish
-
- /* Calculate and store result. Note that this mimics the C code,
- * which may cause funny results if nsec goes negative... is that
- * possible at all ?
- */
-.Lfinish_monotonic:
- add r3,r3,r5
- add r4,r4,r6
- cmpw cr0,r4,r7
- cmpwi cr1,r4,0
- blt 1f
- subf r4,r7,r4
- addi r3,r3,1
-1: bge cr1, .Lfinish
- addi r3,r3,-1
- add r4,r4,r7
-
-.Lfinish:
- stw r3,TSPC32_TV_SEC(r11)
- stw r4,TSPC32_TV_NSEC(r11)
-
- mtlr r12
- crclr cr0*4+so
- li r3,0
- blr
-
- /*
- * syscall fallback
- */
-.Lgettime_fallback:
- li r0,__NR_clock_gettime
- .cfi_restore lr
- sc
- blr
- .cfi_endproc
+ cvdso_call __c_kernel_clock_gettime
V_FUNCTION_END(__kernel_clock_gettime)
@@ -194,37 +43,7 @@ V_FUNCTION_END(__kernel_clock_gettime)
*
*/
V_FUNCTION_BEGIN(__kernel_clock_getres)
- .cfi_startproc
- /* Check for supported clock IDs */
- cmplwi cr0, r3, CLOCK_MAX
- cmpwi cr1, r3, CLOCK_REALTIME_COARSE
- cmpwi cr7, r3, CLOCK_MONOTONIC_COARSE
- bgt cr0, 99f
- LOAD_REG_IMMEDIATE(r5, KTIME_LOW_RES)
- beq cr1, 1f
- beq cr7, 1f
-
- mflr r12
- .cfi_register lr,r12
- get_datapage r3
- lwz r5, CLOCK_HRTIMER_RES(r3)
- mtlr r12
-1: li r3,0
- cmpli cr0,r4,0
- crclr cr0*4+so
- beqlr
- stw r3,TSPC32_TV_SEC(r4)
- stw r5,TSPC32_TV_NSEC(r4)
- blr
-
- /*
- * invalid clock
- */
-99:
- li r3, EINVAL
- crset so
- blr
- .cfi_endproc
+ cvdso_call __c_kernel_clock_getres
V_FUNCTION_END(__kernel_clock_getres)
@@ -235,105 +54,5 @@ V_FUNCTION_END(__kernel_clock_getres)
*
*/
V_FUNCTION_BEGIN(__kernel_time)
- .cfi_startproc
- mflr r12
- .cfi_register lr,r12
-
- mr r11,r3 /* r11 holds t */
- get_datapage r9
-
- lwz r3,STAMP_XTIME_SEC+LOPART(r9)
-
- cmplwi r11,0 /* check if t is NULL */
- mtlr r12
- crclr cr0*4+so
- beqlr
- stw r3,0(r11) /* store result at *t */
- blr
- .cfi_endproc
+ cvdso_call_time __c_kernel_time
V_FUNCTION_END(__kernel_time)
-
-/*
- * This is the core of clock_gettime() and gettimeofday(),
- * it returns the current time in r3 (seconds) and r4.
- * On entry, r7 gives the resolution of r4, either USEC_PER_SEC
- * or NSEC_PER_SEC, giving r4 in microseconds or nanoseconds.
- * It expects the datapage ptr in r9 and doesn't clobber it.
- * It clobbers r0, r5 and r6.
- * On return, r8 contains the counter value that can be reused.
- * This clobbers cr0 but not any other cr field.
- */
-__do_get_tspec:
- .cfi_startproc
- /* Check for update count & load values. We use the low
- * order 32 bits of the update count
- */
-1: lwz r8,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
- andi. r0,r8,1 /* pending update ? loop */
- bne- 1b
- xor r0,r8,r8 /* create dependency */
- add r9,r9,r0
-
- /* Load orig stamp (offset to TB) */
- lwz r5,CFG_TB_ORIG_STAMP(r9)
- lwz r6,(CFG_TB_ORIG_STAMP+4)(r9)
-
- /* Get a stable TB value */
-2: MFTBU(r3)
- MFTBL(r4)
- MFTBU(r0)
- cmplw cr0,r3,r0
- bne- 2b
-
- /* Subtract tb orig stamp and shift left 12 bits.
- */
- subfc r4,r6,r4
- subfe r0,r5,r3
- slwi r0,r0,12
- rlwimi. r0,r4,12,20,31
- slwi r4,r4,12
-
- /*
- * Load scale factor & do multiplication.
- * We only use the high 32 bits of the tb_to_xs value.
- * Even with a 1GHz timebase clock, the high 32 bits of
- * tb_to_xs will be at least 4 million, so the error from
- * ignoring the low 32 bits will be no more than 0.25ppm.
- * The error will just make the clock run very very slightly
- * slow until the next time the kernel updates the VDSO data,
- * at which point the clock will catch up to the kernel's value,
- * so there is no long-term error accumulation.
- */
- lwz r5,CFG_TB_TO_XS(r9) /* load values */
- mulhwu r4,r4,r5
- li r3,0
-
- beq+ 4f /* skip high part computation if 0 */
- mulhwu r3,r0,r5
- mullw r5,r0,r5
- addc r4,r4,r5
- addze r3,r3
-4:
- /* At this point, we have seconds since the xtime stamp
- * as a 32.32 fixed-point number in r3 and r4.
- * Load & add the xtime stamp.
- */
- lwz r5,STAMP_XTIME_SEC+LOPART(r9)
- lwz r6,STAMP_SEC_FRAC(r9)
- addc r4,r4,r6
- adde r3,r3,r5
-
- /* We create a fake dependency on the result in r3/r4
- * and re-check the counter
- */
- or r6,r4,r3
- xor r0,r6,r6
- add r9,r9,r0
- lwz r0,(CFG_TB_UPDATE_COUNT+LOPART)(r9)
- cmplw cr0,r8,r0 /* check if updated */
- bne- 1b
-
- mulhwu r4,r4,r7 /* convert to micro or nanoseconds */
-
- blr
- .cfi_endproc
diff --git a/arch/powerpc/kernel/vdso32/vgettimeofday.c b/arch/powerpc/kernel/vdso32/vgettimeofday.c
new file mode 100644
index 000000000000..9bdc3c435846
--- /dev/null
+++ b/arch/powerpc/kernel/vdso32/vgettimeofday.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Powerpc userspace implementations of gettimeofday() and similar.
+ */
+#include <linux/time.h>
+#include <linux/types.h>
+
+int __c_kernel_clock_gettime(clockid_t clock, struct old_timespec32 *ts,
+ const struct vdso_data *vd)
+{
+ return __cvdso_clock_gettime32_data(vd, clock, ts);
+}
+
+int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz,
+ const struct vdso_data *vd)
+{
+ return __cvdso_gettimeofday_data(vd, tv, tz);
+}
+
+int __c_kernel_clock_getres(clockid_t clock_id, struct old_timespec32 *res,
+ const struct vdso_data *vd)
+{
+ return __cvdso_clock_getres_time32_data(vd, clock_id, res);
+}
+
+time_t __c_kernel_time(time_t *time, const struct vdso_data *vd)
+{
+ return __cvdso_time_data(vd, time);
+}
diff --git a/arch/powerpc/kernel/vdso64/Makefile b/arch/powerpc/kernel/vdso64/Makefile
index 32ebb3522ea1..0d80069233e0 100644
--- a/arch/powerpc/kernel/vdso64/Makefile
+++ b/arch/powerpc/kernel/vdso64/Makefile
@@ -1,8 +1,20 @@
# SPDX-License-Identifier: GPL-2.0
# List of files in the vdso, has to be asm only for now
+ARCH_REL_TYPE_ABS := R_PPC_JUMP_SLOT|R_PPC_GLOB_DAT|R_PPC_ADDR32|R_PPC_ADDR24|R_PPC_ADDR16|R_PPC_ADDR16_LO|R_PPC_ADDR16_HI|R_PPC_ADDR16_HA|R_PPC_ADDR14|R_PPC_ADDR14_BRTAKEN|R_PPC_ADDR14_BRNTAKEN
+include $(srctree)/lib/vdso/Makefile
+
obj-vdso64 = sigtramp.o gettimeofday.o datapage.o cacheflush.o note.o getcpu.o
+ifneq ($(c-gettimeofday-y),)
+ CFLAGS_vgettimeofday.o += -include $(c-gettimeofday-y)
+ CFLAGS_vgettimeofday.o += $(DISABLE_LATENT_ENTROPY_PLUGIN)
+ CFLAGS_vgettimeofday.o += $(call cc-option, -fno-stack-protector)
+ CFLAGS_vgettimeofday.o += -DDISABLE_BRANCH_PROFILING
+ CFLAGS_vgettimeofday.o += -ffreestanding
+ CFLAGS_REMOVE_vgettimeofday.o = $(CC_FLAGS_FTRACE)
+endif
+
# Build rules
targets := $(obj-vdso64) vdso64.so vdso64.so.dbg
@@ -11,6 +23,7 @@ obj-vdso64 := $(addprefix $(obj)/, $(obj-vdso64))
GCOV_PROFILE := n
KCOV_INSTRUMENT := n
UBSAN_SANITIZE := n
+KASAN_SANITIZE := n
ccflags-y := -shared -fno-common -fno-builtin -nostdlib \
-Wl,-soname=linux-vdso64.so.1 -Wl,--hash-style=both
@@ -20,12 +33,14 @@ obj-y += vdso64_wrapper.o
extra-y += vdso64.lds
CPPFLAGS_vdso64.lds += -P -C -U$(ARCH)
+$(obj)/vgettimeofday.o: %.o: %.c FORCE
+
# Force dependency (incbin is bad)
$(obj)/vdso64_wrapper.o : $(obj)/vdso64.so
# link rule for the .so file, .lds has to be first
-$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) FORCE
- $(call if_changed,vdso64ld)
+$(obj)/vdso64.so.dbg: $(src)/vdso64.lds $(obj-vdso64) $(obj)/vgettimeofday.o FORCE
+ $(call if_changed,vdso64ld_and_check)
# strip rule for the .so file
$(obj)/%.so: OBJCOPYFLAGS := -S
@@ -33,8 +48,8 @@ $(obj)/%.so: $(obj)/%.so.dbg FORCE
$(call if_changed,objcopy)
# actual build commands
-quiet_cmd_vdso64ld = VDSO64L $@
- cmd_vdso64ld = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^)
+quiet_cmd_vdso64ld_and_check = VDSO64L $@
+ cmd_vdso64ld_and_check = $(CC) $(c_flags) -o $@ -Wl,-T$(filter %.lds,$^) $(filter %.o,$^) ; $(cmd_vdso_check)
# install commands for the unstripped file
quiet_cmd_vdso_install = INSTALL $@
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index 275f031d0bf1..d7a7bfb51081 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -9,8 +9,10 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
#include <asm/vdso.h>
+#include <asm/vdso_datapage.h>
#include <asm/asm-offsets.h>
#include <asm/unistd.h>
+#include <asm/vdso/gettimeofday.h>
.text
/*
@@ -20,31 +22,7 @@
*
*/
V_FUNCTION_BEGIN(__kernel_gettimeofday)
- .cfi_startproc
- mflr r12
- .cfi_register lr,r12
-
- mr r11,r3 /* r11 holds tv */
- mr r10,r4 /* r10 holds tz */
- get_datapage r3
- cmpldi r11,0 /* check if tv is NULL */
- beq 2f
- lis r7,1000000@ha /* load up USEC_PER_SEC */
- addi r7,r7,1000000@l
- bl V_LOCAL_FUNC(__do_get_tspec) /* get sec/us from tb & kernel */
- std r4,TVAL64_TV_SEC(r11) /* store sec in tv */
- std r5,TVAL64_TV_USEC(r11) /* store usec in tv */
-2: cmpldi r10,0 /* check if tz is NULL */
- beq 1f
- lwz r4,CFG_TZ_MINUTEWEST(r3)/* fill tz */
- lwz r5,CFG_TZ_DSTTIME(r3)
- stw r4,TZONE_TZ_MINWEST(r10)
- stw r5,TZONE_TZ_DSTTIME(r10)
-1: mtlr r12
- crclr cr0*4+so
- li r3,0 /* always success */
- blr
- .cfi_endproc
+ cvdso_call __c_kernel_gettimeofday
V_FUNCTION_END(__kernel_gettimeofday)
@@ -55,120 +33,7 @@ V_FUNCTION_END(__kernel_gettimeofday)
*
*/
V_FUNCTION_BEGIN(__kernel_clock_gettime)
- .cfi_startproc
- /* Check for supported clock IDs */
- cmpwi cr0,r3,CLOCK_REALTIME
- cmpwi cr1,r3,CLOCK_MONOTONIC
- cror cr0*4+eq,cr0*4+eq,cr1*4+eq
-
- cmpwi cr5,r3,CLOCK_REALTIME_COARSE
- cmpwi cr6,r3,CLOCK_MONOTONIC_COARSE
- cror cr5*4+eq,cr5*4+eq,cr6*4+eq
-
- cror cr0*4+eq,cr0*4+eq,cr5*4+eq
- bne cr0,99f
-
- mflr r12 /* r12 saves lr */
- .cfi_register lr,r12
- mr r11,r4 /* r11 saves tp */
- get_datapage r3
- lis r7,NSEC_PER_SEC@h /* want nanoseconds */
- ori r7,r7,NSEC_PER_SEC@l
- beq cr5,70f
-50: bl V_LOCAL_FUNC(__do_get_tspec) /* get time from tb & kernel */
- bne cr1,80f /* if not monotonic, all done */
-
- /*
- * CLOCK_MONOTONIC
- */
-
- /* now we must fixup using wall to monotonic. We need to snapshot
- * that value and do the counter trick again. Fortunately, we still
- * have the counter value in r8 that was returned by __do_get_tspec.
- * At this point, r4,r5 contain our sec/nsec values.
- */
-
- ld r6,WTOM_CLOCK_SEC(r3)
- lwa r9,WTOM_CLOCK_NSEC(r3)
-
- /* We now have our result in r6,r9. We create a fake dependency
- * on that result and re-check the counter
- */
- or r0,r6,r9
- xor r0,r0,r0
- add r3,r3,r0
- ld r0,CFG_TB_UPDATE_COUNT(r3)
- cmpld cr0,r0,r8 /* check if updated */
- bne- 50b
- b 78f
-
- /*
- * For coarse clocks we get data directly from the vdso data page, so
- * we don't need to call __do_get_tspec, but we still need to do the
- * counter trick.
- */
-70: ld r8,CFG_TB_UPDATE_COUNT(r3)
- andi. r0,r8,1 /* pending update ? loop */
- bne- 70b
- add r3,r3,r0 /* r0 is already 0 */
-
- /*
- * CLOCK_REALTIME_COARSE, below values are needed for MONOTONIC_COARSE
- * too
- */
- ld r4,STAMP_XTIME_SEC(r3)
- ld r5,STAMP_XTIME_NSEC(r3)
- bne cr6,75f
-
- /* CLOCK_MONOTONIC_COARSE */
- ld r6,WTOM_CLOCK_SEC(r3)
- lwa r9,WTOM_CLOCK_NSEC(r3)
-
- /* check if counter has updated */
- or r0,r6,r9
-75: or r0,r0,r4
- or r0,r0,r5
- xor r0,r0,r0
- add r3,r3,r0
- ld r0,CFG_TB_UPDATE_COUNT(r3)
- cmpld cr0,r0,r8 /* check if updated */
- bne- 70b
-
- /* Counter has not updated, so continue calculating proper values for
- * sec and nsec if monotonic coarse, or just return with the proper
- * values for realtime.
- */
- bne cr6,80f
-
- /* Add wall->monotonic offset and check for overflow or underflow */
-78: add r4,r4,r6
- add r5,r5,r9
- cmpd cr0,r5,r7
- cmpdi cr1,r5,0
- blt 79f
- subf r5,r7,r5
- addi r4,r4,1
-79: bge cr1,80f
- addi r4,r4,-1
- add r5,r5,r7
-
-80: std r4,TSPC64_TV_SEC(r11)
- std r5,TSPC64_TV_NSEC(r11)
-
- mtlr r12
- crclr cr0*4+so
- li r3,0
- blr
-
- /*
- * syscall fallback
- */
-99:
- li r0,__NR_clock_gettime
- .cfi_restore lr
- sc
- blr
- .cfi_endproc
+ cvdso_call __c_kernel_clock_gettime
V_FUNCTION_END(__kernel_clock_gettime)
@@ -179,34 +44,7 @@ V_FUNCTION_END(__kernel_clock_gettime)
*
*/
V_FUNCTION_BEGIN(__kernel_clock_getres)
- .cfi_startproc
- /* Check for supported clock IDs */
- cmpwi cr0,r3,CLOCK_REALTIME
- cmpwi cr1,r3,CLOCK_MONOTONIC
- cror cr0*4+eq,cr0*4+eq,cr1*4+eq
- bne cr0,99f
-
- mflr r12
- .cfi_register lr,r12
- get_datapage r3
- lwz r5, CLOCK_HRTIMER_RES(r3)
- mtlr r12
- li r3,0
- cmpldi cr0,r4,0
- crclr cr0*4+so
- beqlr
- std r3,TSPC64_TV_SEC(r4)
- std r5,TSPC64_TV_NSEC(r4)
- blr
-
- /*
- * syscall fallback
- */
-99:
- li r0,__NR_clock_getres
- sc
- blr
- .cfi_endproc
+ cvdso_call __c_kernel_clock_getres
V_FUNCTION_END(__kernel_clock_getres)
/*
@@ -216,74 +54,5 @@ V_FUNCTION_END(__kernel_clock_getres)
*
*/
V_FUNCTION_BEGIN(__kernel_time)
- .cfi_startproc
- mflr r12
- .cfi_register lr,r12
-
- mr r11,r3 /* r11 holds t */
- get_datapage r3
-
- ld r4,STAMP_XTIME_SEC(r3)
-
- cmpldi r11,0 /* check if t is NULL */
- beq 2f
- std r4,0(r11) /* store result at *t */
-2: mtlr r12
- crclr cr0*4+so
- mr r3,r4
- blr
- .cfi_endproc
+ cvdso_call_time __c_kernel_time
V_FUNCTION_END(__kernel_time)
-
-
-/*
- * This is the core of clock_gettime() and gettimeofday(),
- * it returns the current time in r4 (seconds) and r5.
- * On entry, r7 gives the resolution of r5, either USEC_PER_SEC
- * or NSEC_PER_SEC, giving r5 in microseconds or nanoseconds.
- * It expects the datapage ptr in r3 and doesn't clobber it.
- * It clobbers r0, r6 and r9.
- * On return, r8 contains the counter value that can be reused.
- * This clobbers cr0 but not any other cr field.
- */
-V_FUNCTION_BEGIN(__do_get_tspec)
- .cfi_startproc
- /* check for update count & load values */
-1: ld r8,CFG_TB_UPDATE_COUNT(r3)
- andi. r0,r8,1 /* pending update ? loop */
- bne- 1b
- xor r0,r8,r8 /* create dependency */
- add r3,r3,r0
-
- /* Get TB & offset it. We use the MFTB macro which will generate
- * workaround code for Cell.
- */
- MFTB(r6)
- ld r9,CFG_TB_ORIG_STAMP(r3)
- subf r6,r9,r6
-
- /* Scale result */
- ld r5,CFG_TB_TO_XS(r3)
- sldi r6,r6,12 /* compute time since stamp_xtime */
- mulhdu r6,r6,r5 /* in units of 2^-32 seconds */
-
- /* Add stamp since epoch */
- ld r4,STAMP_XTIME_SEC(r3)
- lwz r5,STAMP_SEC_FRAC(r3)
- or r0,r4,r5
- or r0,r0,r6
- xor r0,r0,r0
- add r3,r3,r0
- ld r0,CFG_TB_UPDATE_COUNT(r3)
- cmpld r0,r8 /* check if updated */
- bne- 1b /* reload if so */
-
- /* convert to seconds & nanoseconds and add to stamp */
- add r6,r6,r5 /* add on fractional seconds of xtime */
- mulhwu r5,r6,r7 /* compute micro or nanoseconds and */
- srdi r6,r6,32 /* seconds since stamp_xtime */
- clrldi r5,r5,32
- add r4,r4,r6
- blr
- .cfi_endproc
-V_FUNCTION_END(__do_get_tspec)
diff --git a/arch/powerpc/kernel/vdso64/vgettimeofday.c b/arch/powerpc/kernel/vdso64/vgettimeofday.c
new file mode 100644
index 000000000000..cd80867c501c
--- /dev/null
+++ b/arch/powerpc/kernel/vdso64/vgettimeofday.c
@@ -0,0 +1,29 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Powerpc userspace implementations of gettimeofday() and similar.
+ */
+#include <linux/time.h>
+#include <linux/types.h>
+
+int __c_kernel_clock_gettime(clockid_t clock, struct __kernel_timespec *ts,
+ const struct vdso_data *vd)
+{
+ return __cvdso_clock_gettime_data(vd, clock, ts);
+}
+
+int __c_kernel_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz,
+ const struct vdso_data *vd)
+{
+ return __cvdso_gettimeofday_data(vd, tv, tz);
+}
+
+int __c_kernel_clock_getres(clockid_t clock_id, struct __kernel_timespec *res,
+ const struct vdso_data *vd)
+{
+ return __cvdso_clock_getres_data(vd, clock_id, res);
+}
+
+time_t __c_kernel_time(time_t *time, const struct vdso_data *vd)
+{
+ return __cvdso_time_data(vd, time);
+}
--
2.25.0
^ permalink raw reply related
* [PATCH v5 5/6] lib/vdso: Allow architectures to override the ns shift operation
From: Christophe Leroy @ 2020-01-30 16:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, nathanl,
arnd, tglx, vincenzo.frascino, luto
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-mips
In-Reply-To: <cover.1580399657.git.christophe.leroy@c-s.fr>
On powerpc/32, GCC (8.1) generates pretty bad code for the
ns >>= vd->shift operation taking into account that the
shift is always <= 32 and the upper part of the result is
likely to be nul. GCC makes reversed assumptions considering
the shift to be likely >= 32 and the upper part to be like not nul.
unsigned long long shift(unsigned long long x, unsigned char s)
{
return x >> s;
}
results in:
00000018 <shift>:
18: 35 25 ff e0 addic. r9,r5,-32
1c: 41 80 00 10 blt 2c <shift+0x14>
20: 7c 64 4c 30 srw r4,r3,r9
24: 38 60 00 00 li r3,0
28: 4e 80 00 20 blr
2c: 54 69 08 3c rlwinm r9,r3,1,0,30
30: 21 45 00 1f subfic r10,r5,31
34: 7c 84 2c 30 srw r4,r4,r5
38: 7d 29 50 30 slw r9,r9,r10
3c: 7c 63 2c 30 srw r3,r3,r5
40: 7d 24 23 78 or r4,r9,r4
44: 4e 80 00 20 blr
Even when forcing the shift with an &= 31, it still considers
the shift as likely >= 32.
Define a vdso_shift_ns() macro that can be overriden by
architectures.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
lib/vdso/gettimeofday.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 0b4b71880f22..a5ee53d1ecee 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -38,6 +38,13 @@ u64 vdso_calc_delta(u64 cycles, u64 last, u64 mask, u32 mult)
}
#endif
+#ifndef vdso_shift_ns
+static __always_inline u64 vdso_shift_ns(u64 ns, unsigned long shift)
+{
+ return ns >> shift;
+}
+#endif
+
#ifdef CONFIG_TIME_NS
static int do_hres_timens(const struct vdso_data *vdns, clockid_t clk,
struct __kernel_timespec *ts)
@@ -134,7 +141,7 @@ static __always_inline int do_hres(const struct vdso_data *vd, clockid_t clk,
#endif
ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
- ns >>= vd->shift;
+ ns = vdso_shift_ns(ns, vd->shift);
sec = vdso_ts->sec;
} while (unlikely(vdso_read_retry(vd, seq)));
--
2.25.0
^ permalink raw reply related
* [PATCH v5 4/6] lib/vdso: Allow fixed clock mode
From: Christophe Leroy @ 2020-01-30 16:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, nathanl,
arnd, tglx, vincenzo.frascino, luto
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-mips
In-Reply-To: <cover.1580399657.git.christophe.leroy@c-s.fr>
Some architectures have a fixed clocksource which is known at compile
time and cannot be replaced or disabled at runtime, e.g. timebase on
PowerPC. For such cases the clock mode check in the VDSO code is
pointless.
Therefore, give architectures the opportunity to redefine the way
clock_mode is checked by moving the check into an
__arch_vdso_capable() macro.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
lib/vdso/gettimeofday.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index 72d65dd50cb4..0b4b71880f22 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -120,12 +120,18 @@ static __always_inline int do_hres(const struct vdso_data *vd, clockid_t clk,
cpu_relax();
}
smp_rmb();
+#ifdef __arch_vdso_capable
+ if (unlikely(!__arch_vdso_capable(vd->clock_mode)))
+ return -1;
+#endif
cycles = __arch_get_hw_counter(vd->clock_mode);
ns = vdso_ts->nsec;
last = vd->cycle_last;
+#ifndef __arch_vdso_capable
if (unlikely((s64)cycles < 0))
return -1;
+#endif
ns += vdso_calc_delta(cycles, last, vd->mask, vd->mult);
ns >>= vd->shift;
--
2.25.0
^ permalink raw reply related
* [PATCH v5 3/6] lib/vdso: Allow architectures to provide the vdso data pointer
From: Christophe Leroy @ 2020-01-30 16:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, nathanl,
arnd, tglx, vincenzo.frascino, luto
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-mips
In-Reply-To: <cover.1580399657.git.christophe.leroy@c-s.fr>
On powerpc, __arch_get_vdso_data() clobbers the link register,
requiring the caller to save it.
As the parent function already has to set a stack frame and saves
the link register before calling the C vdso function, retriving the
vdso data pointer there is lighter.
Give architectures the opportunity to hand the vdso data pointer
to C vdso functions.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
lib/vdso/gettimeofday.c | 83 +++++++++++++++++++++++++++++++++--------
1 file changed, 67 insertions(+), 16 deletions(-)
diff --git a/lib/vdso/gettimeofday.c b/lib/vdso/gettimeofday.c
index f8b8ec5e63ac..72d65dd50cb4 100644
--- a/lib/vdso/gettimeofday.c
+++ b/lib/vdso/gettimeofday.c
@@ -206,9 +206,9 @@ static __always_inline int do_coarse(const struct vdso_data *vd, clockid_t clk,
}
static __maybe_unused int
-__cvdso_clock_gettime_common(clockid_t clock, struct __kernel_timespec *ts)
+__cvdso_clock_gettime_common(const struct vdso_data *vd, clockid_t clock,
+ struct __kernel_timespec *ts)
{
- const struct vdso_data *vd = __arch_get_vdso_data();
u32 msk;
/* Check for negative values or invalid clocks */
@@ -233,23 +233,33 @@ __cvdso_clock_gettime_common(clockid_t clock, struct __kernel_timespec *ts)
}
static __maybe_unused int
-__cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
+__cvdso_clock_gettime_data(const struct vdso_data *vd, clockid_t clock,
+ struct __kernel_timespec *ts)
{
- int ret = __cvdso_clock_gettime_common(clock, ts);
+ int ret = __cvdso_clock_gettime_common(vd, clock, ts);
if (unlikely(ret))
return clock_gettime_fallback(clock, ts);
return 0;
}
+static __maybe_unused int
+__cvdso_clock_gettime(clockid_t clock, struct __kernel_timespec *ts)
+{
+ const struct vdso_data *vd = __arch_get_vdso_data();
+
+ return __cvdso_clock_gettime_data(vd, clock, ts);
+}
+
#ifdef BUILD_VDSO32
static __maybe_unused int
-__cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res)
+__cvdso_clock_gettime32_data(const struct vdso_data *vd, clockid_t clock,
+ struct old_timespec32 *res)
{
struct __kernel_timespec ts;
int ret;
- ret = __cvdso_clock_gettime_common(clock, &ts);
+ ret = __cvdso_clock_gettime_common(vd, clock, &ts);
if (unlikely(ret))
return clock_gettime32_fallback(clock, res);
@@ -260,13 +270,21 @@ __cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res)
return ret;
}
-#endif /* BUILD_VDSO32 */
static __maybe_unused int
-__cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
+__cvdso_clock_gettime32(clockid_t clock, struct old_timespec32 *res)
{
const struct vdso_data *vd = __arch_get_vdso_data();
+ return __cvdso_clock_gettime32_data(vd, clock, res);
+}
+#endif /* BUILD_VDSO32 */
+
+static __maybe_unused int
+__cvdso_gettimeofday_data(const struct vdso_data *vd,
+ struct __kernel_old_timeval *tv, struct timezone *tz)
+{
+
if (likely(tv != NULL)) {
struct __kernel_timespec ts;
@@ -289,10 +307,18 @@ __cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
return 0;
}
-#ifdef VDSO_HAS_TIME
-static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time)
+static __maybe_unused int
+__cvdso_gettimeofday(struct __kernel_old_timeval *tv, struct timezone *tz)
{
const struct vdso_data *vd = __arch_get_vdso_data();
+
+ return __cvdso_gettimeofday_data(vd, tv, tz);
+}
+
+#ifdef VDSO_HAS_TIME
+static __maybe_unused __kernel_old_time_t
+__cvdso_time_data(const struct vdso_data *vd, __kernel_old_time_t *time)
+{
__kernel_old_time_t t;
if (IS_ENABLED(CONFIG_TIME_NS) && vd->clock_mode == VCLOCK_TIMENS)
@@ -305,13 +331,20 @@ static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time
return t;
}
+
+static __maybe_unused __kernel_old_time_t __cvdso_time(__kernel_old_time_t *time)
+{
+ const struct vdso_data *vd = __arch_get_vdso_data();
+
+ return __cvdso_time_data(vd, time);
+}
#endif /* VDSO_HAS_TIME */
#ifdef VDSO_HAS_CLOCK_GETRES
static __maybe_unused
-int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res)
+int __cvdso_clock_getres_common(const struct vdso_data *vd, clockid_t clock,
+ struct __kernel_timespec *res)
{
- const struct vdso_data *vd = __arch_get_vdso_data();
u32 msk;
u64 ns;
@@ -349,23 +382,33 @@ int __cvdso_clock_getres_common(clockid_t clock, struct __kernel_timespec *res)
}
static __maybe_unused
-int __cvdso_clock_getres(clockid_t clock, struct __kernel_timespec *res)
+int __cvdso_clock_getres_data(const struct vdso_data *vd, clockid_t clock,
+ struct __kernel_timespec *res)
{
- int ret = __cvdso_clock_getres_common(clock, res);
+ int ret = __cvdso_clock_getres_common(vd, clock, res);
if (unlikely(ret))
return clock_getres_fallback(clock, res);
return 0;
}
+static __maybe_unused
+int __cvdso_clock_getres(clockid_t clock, struct __kernel_timespec *res)
+{
+ const struct vdso_data *vd = __arch_get_vdso_data();
+
+ return __cvdso_clock_getres_data(vd, clock, res);
+}
+
#ifdef BUILD_VDSO32
static __maybe_unused int
-__cvdso_clock_getres_time32(clockid_t clock, struct old_timespec32 *res)
+__cvdso_clock_getres_time32_data(const struct vdso_data *vd, clockid_t clock,
+ struct old_timespec32 *res)
{
struct __kernel_timespec ts;
int ret;
- ret = __cvdso_clock_getres_common(clock, &ts);
+ ret = __cvdso_clock_getres_common(vd, clock, &ts);
if (unlikely(ret))
return clock_getres32_fallback(clock, res);
@@ -376,5 +419,13 @@ __cvdso_clock_getres_time32(clockid_t clock, struct old_timespec32 *res)
}
return ret;
}
+
+static __maybe_unused int
+__cvdso_clock_getres_time32(clockid_t clock, struct old_timespec32 *res)
+{
+ const struct vdso_data *vd = __arch_get_vdso_data();
+
+ return __cvdso_clock_getres_time32_data(vd, clock, res);
+}
#endif /* BUILD_VDSO32 */
#endif /* VDSO_HAS_CLOCK_GETRES */
--
2.25.0
^ permalink raw reply related
* [PATCH v5 1/6] powerpc/vdso64: Switch from __get_datapage() to get_datapage inline macro
From: Christophe Leroy @ 2020-01-30 16:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, nathanl,
arnd, tglx, vincenzo.frascino, luto
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-mips
In-Reply-To: <cover.1580399657.git.christophe.leroy@c-s.fr>
On the same way as already done on PPC32, drop __get_datapage()
function and use get_datapage inline macro instead.
See commit ec0895f08f99 ("powerpc/vdso32: inline __get_datapage()")
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/kernel/vdso64/cacheflush.S | 9 ++++----
arch/powerpc/kernel/vdso64/datapage.S | 28 +++--------------------
arch/powerpc/kernel/vdso64/gettimeofday.S | 8 +++----
3 files changed, 11 insertions(+), 34 deletions(-)
diff --git a/arch/powerpc/kernel/vdso64/cacheflush.S b/arch/powerpc/kernel/vdso64/cacheflush.S
index 526f5ba2593e..cab14324242b 100644
--- a/arch/powerpc/kernel/vdso64/cacheflush.S
+++ b/arch/powerpc/kernel/vdso64/cacheflush.S
@@ -8,6 +8,7 @@
#include <asm/processor.h>
#include <asm/ppc_asm.h>
#include <asm/vdso.h>
+#include <asm/vdso_datapage.h>
#include <asm/asm-offsets.h>
.text
@@ -24,14 +25,12 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
.cfi_startproc
mflr r12
.cfi_register lr,r12
- mr r11,r3
- bl V_LOCAL_FUNC(__get_datapage)
+ get_datapage r10, r0
mtlr r12
- mr r10,r3
lwz r7,CFG_DCACHE_BLOCKSZ(r10)
addi r5,r7,-1
- andc r6,r11,r5 /* round low to line bdy */
+ andc r6,r3,r5 /* round low to line bdy */
subf r8,r6,r4 /* compute length */
add r8,r8,r5 /* ensure we get enough */
lwz r9,CFG_DCACHE_LOGBLOCKSZ(r10)
@@ -48,7 +47,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
lwz r7,CFG_ICACHE_BLOCKSZ(r10)
addi r5,r7,-1
- andc r6,r11,r5 /* round low to line bdy */
+ andc r6,r3,r5 /* round low to line bdy */
subf r8,r6,r4 /* compute length */
add r8,r8,r5
lwz r9,CFG_ICACHE_LOGBLOCKSZ(r10)
diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
index dc84f5ae3802..067247d3efb9 100644
--- a/arch/powerpc/kernel/vdso64/datapage.S
+++ b/arch/powerpc/kernel/vdso64/datapage.S
@@ -10,35 +10,13 @@
#include <asm/asm-offsets.h>
#include <asm/unistd.h>
#include <asm/vdso.h>
+#include <asm/vdso_datapage.h>
.text
.global __kernel_datapage_offset;
__kernel_datapage_offset:
.long 0
-V_FUNCTION_BEGIN(__get_datapage)
- .cfi_startproc
- /* We don't want that exposed or overridable as we want other objects
- * to be able to bl directly to here
- */
- .protected __get_datapage
- .hidden __get_datapage
-
- mflr r0
- .cfi_register lr,r0
-
- bcl 20,31,data_page_branch
-data_page_branch:
- mflr r3
- mtlr r0
- addi r3, r3, __kernel_datapage_offset-data_page_branch
- lwz r0,0(r3)
- .cfi_restore lr
- add r3,r0,r3
- blr
- .cfi_endproc
-V_FUNCTION_END(__get_datapage)
-
/*
* void *__kernel_get_syscall_map(unsigned int *syscall_count) ;
*
@@ -53,7 +31,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
mflr r12
.cfi_register lr,r12
mr r4,r3
- bl V_LOCAL_FUNC(__get_datapage)
+ get_datapage r3, r0
mtlr r12
addi r3,r3,CFG_SYSCALL_MAP64
cmpldi cr0,r4,0
@@ -75,7 +53,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
.cfi_startproc
mflr r12
.cfi_register lr,r12
- bl V_LOCAL_FUNC(__get_datapage)
+ get_datapage r3, r0
ld r3,CFG_TB_TICKS_PER_SEC(r3)
mtlr r12
crclr cr0*4+so
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index 1c9a04703250..e54c4ce4d356 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -26,7 +26,7 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday)
mr r11,r3 /* r11 holds tv */
mr r10,r4 /* r10 holds tz */
- bl V_LOCAL_FUNC(__get_datapage) /* get data page */
+ get_datapage r3, r0
cmpldi r11,0 /* check if tv is NULL */
beq 2f
lis r7,1000000@ha /* load up USEC_PER_SEC */
@@ -71,7 +71,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
mflr r12 /* r12 saves lr */
.cfi_register lr,r12
mr r11,r4 /* r11 saves tp */
- bl V_LOCAL_FUNC(__get_datapage) /* get data page */
+ get_datapage r3, r0
lis r7,NSEC_PER_SEC@h /* want nanoseconds */
ori r7,r7,NSEC_PER_SEC@l
beq cr5,70f
@@ -188,7 +188,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
mflr r12
.cfi_register lr,r12
- bl V_LOCAL_FUNC(__get_datapage)
+ get_datapage r3, r0
lwz r5, CLOCK_HRTIMER_RES(r3)
mtlr r12
li r3,0
@@ -221,7 +221,7 @@ V_FUNCTION_BEGIN(__kernel_time)
.cfi_register lr,r12
mr r11,r3 /* r11 holds t */
- bl V_LOCAL_FUNC(__get_datapage)
+ get_datapage r3, r0
ld r4,STAMP_XTIME_SEC(r3)
--
2.25.0
^ permalink raw reply related
* [PATCH v5 2/6] powerpc/vdso: Remove __kernel_datapage_offset and simplify __get_datapage()
From: Christophe Leroy @ 2020-01-30 16:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, nathanl,
arnd, tglx, vincenzo.frascino, luto
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-mips
In-Reply-To: <cover.1580399657.git.christophe.leroy@c-s.fr>
The VDSO datapage and the text pages are always located immediately
next to each other, so it can be hardcoded without an indirection
through __kernel_datapage_offset
In order to ease things, move the data page in front like other
arches, that way there is no need to know the size of the library
to locate the data page.
Before:
clock-getres-realtime-coarse: vdso: 714 nsec/call
clock-gettime-realtime-coarse: vdso: 792 nsec/call
clock-gettime-realtime: vdso: 1243 nsec/call
After:
clock-getres-realtime-coarse: vdso: 699 nsec/call
clock-gettime-realtime-coarse: vdso: 784 nsec/call
clock-gettime-realtime: vdso: 1231 nsec/call
In the mean time, allow users to pass a constant offset to
get_datapage macro. That offset will be integrated to the
calculation to directly get the address of the given object
inside the VDSO datapage. This avoids having to perform a
subsequent addition.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/vdso_datapage.h | 11 ++---
arch/powerpc/kernel/vdso.c | 53 +++--------------------
arch/powerpc/kernel/vdso32/cacheflush.S | 2 +-
arch/powerpc/kernel/vdso32/datapage.S | 7 +--
arch/powerpc/kernel/vdso32/gettimeofday.S | 8 ++--
arch/powerpc/kernel/vdso32/vdso32.lds.S | 7 +--
arch/powerpc/kernel/vdso64/cacheflush.S | 2 +-
arch/powerpc/kernel/vdso64/datapage.S | 7 +--
arch/powerpc/kernel/vdso64/gettimeofday.S | 8 ++--
arch/powerpc/kernel/vdso64/vdso64.lds.S | 7 +--
10 files changed, 31 insertions(+), 81 deletions(-)
diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h
index b9ef6cf50ea5..a361f07bec49 100644
--- a/arch/powerpc/include/asm/vdso_datapage.h
+++ b/arch/powerpc/include/asm/vdso_datapage.h
@@ -116,12 +116,13 @@ extern struct vdso_data *vdso_data;
#else /* __ASSEMBLY__ */
-.macro get_datapage ptr, tmp
+.macro get_datapage ptr, offset=0
bcl 20, 31, .+4
- mflr \ptr
- addi \ptr, \ptr, (__kernel_datapage_offset - (.-4))@l
- lwz \tmp, 0(\ptr)
- add \ptr, \tmp, \ptr
+999: mflr \ptr
+#if CONFIG_PPC_PAGE_SHIFT > 14
+ addis \ptr, \ptr, (_vdso_datapage + \offset - 999b)@ha
+#endif
+ addi \ptr, \ptr, (_vdso_datapage + \offset - 999b)@l
.endm
#endif /* __ASSEMBLY__ */
diff --git a/arch/powerpc/kernel/vdso.c b/arch/powerpc/kernel/vdso.c
index b9a108411c0d..ebbb13d92a12 100644
--- a/arch/powerpc/kernel/vdso.c
+++ b/arch/powerpc/kernel/vdso.c
@@ -190,7 +190,7 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp)
* install_special_mapping or the perf counter mmap tracking code
* will fail to recognise it as a vDSO (since arch_vma_name fails).
*/
- current->mm->context.vdso_base = vdso_base;
+ current->mm->context.vdso_base = vdso_base + PAGE_SIZE;
/*
* our vma flags don't have VM_WRITE so by default, the process isn't
@@ -487,42 +487,6 @@ static __init void vdso_setup_trampolines(struct lib32_elfinfo *v32,
vdso32_rt_sigtramp = find_function32(v32, "__kernel_sigtramp_rt32");
}
-static __init int vdso_fixup_datapage(struct lib32_elfinfo *v32,
- struct lib64_elfinfo *v64)
-{
-#ifdef CONFIG_VDSO32
- Elf32_Sym *sym32;
-#endif
-#ifdef CONFIG_PPC64
- Elf64_Sym *sym64;
-
- sym64 = find_symbol64(v64, "__kernel_datapage_offset");
- if (sym64 == NULL) {
- printk(KERN_ERR "vDSO64: Can't find symbol "
- "__kernel_datapage_offset !\n");
- return -1;
- }
- *((int *)(vdso64_kbase + sym64->st_value - VDSO64_LBASE)) =
- (vdso64_pages << PAGE_SHIFT) -
- (sym64->st_value - VDSO64_LBASE);
-#endif /* CONFIG_PPC64 */
-
-#ifdef CONFIG_VDSO32
- sym32 = find_symbol32(v32, "__kernel_datapage_offset");
- if (sym32 == NULL) {
- printk(KERN_ERR "vDSO32: Can't find symbol "
- "__kernel_datapage_offset !\n");
- return -1;
- }
- *((int *)(vdso32_kbase + (sym32->st_value - VDSO32_LBASE))) =
- (vdso32_pages << PAGE_SHIFT) -
- (sym32->st_value - VDSO32_LBASE);
-#endif
-
- return 0;
-}
-
-
static __init int vdso_fixup_features(struct lib32_elfinfo *v32,
struct lib64_elfinfo *v64)
{
@@ -623,9 +587,6 @@ static __init int vdso_setup(void)
if (vdso_do_find_sections(&v32, &v64))
return -1;
- if (vdso_fixup_datapage(&v32, &v64))
- return -1;
-
if (vdso_fixup_features(&v32, &v64))
return -1;
@@ -765,26 +726,26 @@ static int __init vdso_init(void)
vdso32_pagelist = kcalloc(vdso32_pages + 2, sizeof(struct page *),
GFP_KERNEL);
BUG_ON(vdso32_pagelist == NULL);
+ vdso32_pagelist[0] = virt_to_page(vdso_data);
for (i = 0; i < vdso32_pages; i++) {
struct page *pg = virt_to_page(vdso32_kbase + i*PAGE_SIZE);
get_page(pg);
- vdso32_pagelist[i] = pg;
+ vdso32_pagelist[i + 1] = pg;
}
- vdso32_pagelist[i++] = virt_to_page(vdso_data);
- vdso32_pagelist[i] = NULL;
+ vdso32_pagelist[i + 1] = NULL;
#endif
#ifdef CONFIG_PPC64
vdso64_pagelist = kcalloc(vdso64_pages + 2, sizeof(struct page *),
GFP_KERNEL);
BUG_ON(vdso64_pagelist == NULL);
+ vdso64_pagelist[0] = virt_to_page(vdso_data);
for (i = 0; i < vdso64_pages; i++) {
struct page *pg = virt_to_page(vdso64_kbase + i*PAGE_SIZE);
get_page(pg);
- vdso64_pagelist[i] = pg;
+ vdso64_pagelist[i + 1] = pg;
}
- vdso64_pagelist[i++] = virt_to_page(vdso_data);
- vdso64_pagelist[i] = NULL;
+ vdso64_pagelist[i + 1] = NULL;
#endif /* CONFIG_PPC64 */
get_page(virt_to_page(vdso_data));
diff --git a/arch/powerpc/kernel/vdso32/cacheflush.S b/arch/powerpc/kernel/vdso32/cacheflush.S
index 3440ddf21c8b..017843bf5382 100644
--- a/arch/powerpc/kernel/vdso32/cacheflush.S
+++ b/arch/powerpc/kernel/vdso32/cacheflush.S
@@ -27,7 +27,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
#ifdef CONFIG_PPC64
mflr r12
.cfi_register lr,r12
- get_datapage r10, r0
+ get_datapage r10
mtlr r12
#endif
diff --git a/arch/powerpc/kernel/vdso32/datapage.S b/arch/powerpc/kernel/vdso32/datapage.S
index 217bb630f8f9..0513a2eabec8 100644
--- a/arch/powerpc/kernel/vdso32/datapage.S
+++ b/arch/powerpc/kernel/vdso32/datapage.S
@@ -13,9 +13,6 @@
#include <asm/vdso_datapage.h>
.text
- .global __kernel_datapage_offset;
-__kernel_datapage_offset:
- .long 0
/*
* void *__kernel_get_syscall_map(unsigned int *syscall_count) ;
@@ -31,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
mflr r12
.cfi_register lr,r12
mr. r4,r3
- get_datapage r3, r0
+ get_datapage r3
mtlr r12
addi r3,r3,CFG_SYSCALL_MAP32
beqlr
@@ -52,7 +49,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
.cfi_startproc
mflr r12
.cfi_register lr,r12
- get_datapage r3, r0
+ get_datapage r3
lwz r4,(CFG_TB_TICKS_PER_SEC + 4)(r3)
lwz r3,CFG_TB_TICKS_PER_SEC(r3)
mtlr r12
diff --git a/arch/powerpc/kernel/vdso32/gettimeofday.S b/arch/powerpc/kernel/vdso32/gettimeofday.S
index a3951567118a..0bbdce0f2a9c 100644
--- a/arch/powerpc/kernel/vdso32/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso32/gettimeofday.S
@@ -34,7 +34,7 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday)
mr. r10,r3 /* r10 saves tv */
mr r11,r4 /* r11 saves tz */
- get_datapage r9, r0
+ get_datapage r9
beq 3f
LOAD_REG_IMMEDIATE(r7, 1000000) /* load up USEC_PER_SEC */
bl __do_get_tspec@local /* get sec/usec from tb & kernel */
@@ -79,7 +79,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
mflr r12 /* r12 saves lr */
.cfi_register lr,r12
mr r11,r4 /* r11 saves tp */
- get_datapage r9, r0
+ get_datapage r9
LOAD_REG_IMMEDIATE(r7, NSEC_PER_SEC) /* load up NSEC_PER_SEC */
beq cr5, .Lcoarse_clocks
.Lprecise_clocks:
@@ -206,7 +206,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
mflr r12
.cfi_register lr,r12
- get_datapage r3, r0
+ get_datapage r3
lwz r5, CLOCK_HRTIMER_RES(r3)
mtlr r12
1: li r3,0
@@ -240,7 +240,7 @@ V_FUNCTION_BEGIN(__kernel_time)
.cfi_register lr,r12
mr r11,r3 /* r11 holds t */
- get_datapage r9, r0
+ get_datapage r9
lwz r3,STAMP_XTIME_SEC+LOPART(r9)
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 5206c2eb2a1d..6cf729612268 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -4,6 +4,7 @@
* library
*/
#include <asm/vdso.h>
+#include <asm/page.h>
#ifdef __LITTLE_ENDIAN__
OUTPUT_FORMAT("elf32-powerpcle", "elf32-powerpcle", "elf32-powerpcle")
@@ -15,6 +16,7 @@ ENTRY(_start)
SECTIONS
{
+ PROVIDE(_vdso_datapage = . - PAGE_SIZE);
. = VDSO32_LBASE + SIZEOF_HEADERS;
.hash : { *(.hash) } :text
@@ -138,11 +140,6 @@ VERSION
{
VDSO_VERSION_STRING {
global:
- /*
- * Has to be there for the kernel to find
- */
- __kernel_datapage_offset;
-
__kernel_get_syscall_map;
#ifndef CONFIG_PPC_BOOK3S_601
__kernel_gettimeofday;
diff --git a/arch/powerpc/kernel/vdso64/cacheflush.S b/arch/powerpc/kernel/vdso64/cacheflush.S
index cab14324242b..61985de5758f 100644
--- a/arch/powerpc/kernel/vdso64/cacheflush.S
+++ b/arch/powerpc/kernel/vdso64/cacheflush.S
@@ -25,7 +25,7 @@ V_FUNCTION_BEGIN(__kernel_sync_dicache)
.cfi_startproc
mflr r12
.cfi_register lr,r12
- get_datapage r10, r0
+ get_datapage r10
mtlr r12
lwz r7,CFG_DCACHE_BLOCKSZ(r10)
diff --git a/arch/powerpc/kernel/vdso64/datapage.S b/arch/powerpc/kernel/vdso64/datapage.S
index 067247d3efb9..00760dc69d68 100644
--- a/arch/powerpc/kernel/vdso64/datapage.S
+++ b/arch/powerpc/kernel/vdso64/datapage.S
@@ -13,9 +13,6 @@
#include <asm/vdso_datapage.h>
.text
-.global __kernel_datapage_offset;
-__kernel_datapage_offset:
- .long 0
/*
* void *__kernel_get_syscall_map(unsigned int *syscall_count) ;
@@ -31,7 +28,7 @@ V_FUNCTION_BEGIN(__kernel_get_syscall_map)
mflr r12
.cfi_register lr,r12
mr r4,r3
- get_datapage r3, r0
+ get_datapage r3
mtlr r12
addi r3,r3,CFG_SYSCALL_MAP64
cmpldi cr0,r4,0
@@ -53,7 +50,7 @@ V_FUNCTION_BEGIN(__kernel_get_tbfreq)
.cfi_startproc
mflr r12
.cfi_register lr,r12
- get_datapage r3, r0
+ get_datapage r3
ld r3,CFG_TB_TICKS_PER_SEC(r3)
mtlr r12
crclr cr0*4+so
diff --git a/arch/powerpc/kernel/vdso64/gettimeofday.S b/arch/powerpc/kernel/vdso64/gettimeofday.S
index e54c4ce4d356..275f031d0bf1 100644
--- a/arch/powerpc/kernel/vdso64/gettimeofday.S
+++ b/arch/powerpc/kernel/vdso64/gettimeofday.S
@@ -26,7 +26,7 @@ V_FUNCTION_BEGIN(__kernel_gettimeofday)
mr r11,r3 /* r11 holds tv */
mr r10,r4 /* r10 holds tz */
- get_datapage r3, r0
+ get_datapage r3
cmpldi r11,0 /* check if tv is NULL */
beq 2f
lis r7,1000000@ha /* load up USEC_PER_SEC */
@@ -71,7 +71,7 @@ V_FUNCTION_BEGIN(__kernel_clock_gettime)
mflr r12 /* r12 saves lr */
.cfi_register lr,r12
mr r11,r4 /* r11 saves tp */
- get_datapage r3, r0
+ get_datapage r3
lis r7,NSEC_PER_SEC@h /* want nanoseconds */
ori r7,r7,NSEC_PER_SEC@l
beq cr5,70f
@@ -188,7 +188,7 @@ V_FUNCTION_BEGIN(__kernel_clock_getres)
mflr r12
.cfi_register lr,r12
- get_datapage r3, r0
+ get_datapage r3
lwz r5, CLOCK_HRTIMER_RES(r3)
mtlr r12
li r3,0
@@ -221,7 +221,7 @@ V_FUNCTION_BEGIN(__kernel_time)
.cfi_register lr,r12
mr r11,r3 /* r11 holds t */
- get_datapage r3, r0
+ get_datapage r3
ld r4,STAMP_XTIME_SEC(r3)
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S
index 256fb9720298..f58c7e2e9cbd 100644
--- a/arch/powerpc/kernel/vdso64/vdso64.lds.S
+++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S
@@ -4,6 +4,7 @@
* library
*/
#include <asm/vdso.h>
+#include <asm/page.h>
#ifdef __LITTLE_ENDIAN__
OUTPUT_FORMAT("elf64-powerpcle", "elf64-powerpcle", "elf64-powerpcle")
@@ -15,6 +16,7 @@ ENTRY(_start)
SECTIONS
{
+ PROVIDE(_vdso_datapage = . - PAGE_SIZE);
. = VDSO64_LBASE + SIZEOF_HEADERS;
.hash : { *(.hash) } :text
@@ -138,11 +140,6 @@ VERSION
{
VDSO_VERSION_STRING {
global:
- /*
- * Has to be there for the kernel to find
- */
- __kernel_datapage_offset;
-
__kernel_get_syscall_map;
__kernel_gettimeofday;
__kernel_clock_gettime;
--
2.25.0
^ permalink raw reply related
* [PATCH v5 0/6] powerpc: switch VDSO to C implementation.
From: Christophe Leroy @ 2020-01-30 16:08 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, nathanl,
arnd, tglx, vincenzo.frascino, luto
Cc: x86, linuxppc-dev, linux-kernel, linux-arm-kernel, linux-mips
This is a fifth version of a series to switch powerpc VDSO to generic
C implementation. All previous where RFCs. This one has reached a
mature status.
It is tested on PPC32 (mpc885 and mpc8321E).
It is build tested on kisskb
(http://kisskb.ellerman.id.au/kisskb/head/abf15916bd65f808b07fe9a2377db965a37071e4/)
In PPC64 mode it now builds both VDSO64 and VDSO32.
The two first patches are optimisation around the way vdso datapage is
handled. They are worth merging now even if we want to wait a little
more for the entire series.
The next three patches are optimisations to the GENERIC C VDSO code.
Without them, the performance of the VDSO time functions are too
degraded compared to the current ASM version to be worth switching
the C VDSO.
This series applies on today's powerpc/merge branch.
See the last patch for details on changes and performance.
Christophe Leroy (6):
powerpc/vdso64: Switch from __get_datapage() to get_datapage inline
macro
powerpc/vdso: Remove __kernel_datapage_offset and simplify
__get_datapage()
lib/vdso: Allow architectures to provide the vdso data pointer
lib/vdso: Allow fixed clock mode
lib/vdso: Allow architectures to override the ns shift operation
powerpc/vdso: Switch VDSO to generic C implementation.
arch/powerpc/Kconfig | 2 +
arch/powerpc/include/asm/vdso/gettimeofday.h | 158 ++++++++++
arch/powerpc/include/asm/vdso/vsyscall.h | 25 ++
arch/powerpc/include/asm/vdso_datapage.h | 51 ++--
arch/powerpc/kernel/asm-offsets.c | 49 +---
arch/powerpc/kernel/time.c | 90 ------
arch/powerpc/kernel/vdso.c | 58 +---
arch/powerpc/kernel/vdso32/Makefile | 32 +-
arch/powerpc/kernel/vdso32/cacheflush.S | 2 +-
arch/powerpc/kernel/vdso32/config-fake32.h | 34 +++
arch/powerpc/kernel/vdso32/datapage.S | 7 +-
arch/powerpc/kernel/vdso32/gettimeofday.S | 291 +------------------
arch/powerpc/kernel/vdso32/vdso32.lds.S | 7 +-
arch/powerpc/kernel/vdso32/vgettimeofday.c | 29 ++
arch/powerpc/kernel/vdso64/Makefile | 23 +-
arch/powerpc/kernel/vdso64/cacheflush.S | 9 +-
arch/powerpc/kernel/vdso64/datapage.S | 31 +-
arch/powerpc/kernel/vdso64/gettimeofday.S | 243 +---------------
arch/powerpc/kernel/vdso64/vdso64.lds.S | 7 +-
arch/powerpc/kernel/vdso64/vgettimeofday.c | 29 ++
lib/vdso/gettimeofday.c | 98 +++++--
21 files changed, 467 insertions(+), 808 deletions(-)
create mode 100644 arch/powerpc/include/asm/vdso/gettimeofday.h
create mode 100644 arch/powerpc/include/asm/vdso/vsyscall.h
create mode 100644 arch/powerpc/kernel/vdso32/config-fake32.h
create mode 100644 arch/powerpc/kernel/vdso32/vgettimeofday.c
create mode 100644 arch/powerpc/kernel/vdso64/vgettimeofday.c
--
2.25.0
^ permalink raw reply
* Re: [PATCH V12] mm/debug: Add tests validating architecture page table helpers
From: Christophe Leroy @ 2020-01-30 14:13 UTC (permalink / raw)
To: Anshuman Khandual, linux-mm
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra, James Hogan,
Heiko Carstens, Michal Hocko, Dave Hansen, Paul Mackerras,
sparclinux, Thomas Gleixner, linux-s390, Jason Gunthorpe, x86,
Russell King - ARM Linux, Matthew Wilcox, Steven Price,
Tetsuo Handa, Gerald Schaefer, linux-snps-arc, Ingo Molnar,
Kees Cook, Masahiro Yamada, Mark Brown, Kirill A . Shutemov,
Dan Williams, Vlastimil Babka, linux-arm-kernel,
Sri Krishna chowdary, Ard Biesheuvel, Greg Kroah-Hartman,
linux-mips, Ralf Baechle, linux-kernel, Paul Burton,
Mike Rapoport, Vineet Gupta, Martin Schwidefsky, Andrew Morton,
linuxppc-dev, David S. Miller
In-Reply-To: <49754f74-53a7-0e4a-bb16-53617f8c902c@arm.com>
Le 30/01/2020 à 14:04, Anshuman Khandual a écrit :
>
> On 01/28/2020 10:35 PM, Christophe Leroy wrote:
>>
>>
>> Le 28/01/2020 à 02:27, Anshuman Khandual a écrit :
>>> diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
>>> index 0b6c4042942a..fb0e76d254b3 100644
>>> --- a/arch/x86/include/asm/pgtable_64.h
>>> +++ b/arch/x86/include/asm/pgtable_64.h
>>> @@ -53,6 +53,12 @@ static inline void sync_initial_page_table(void) { }
>>> struct mm_struct;
>>> +#define mm_p4d_folded mm_p4d_folded
>>> +static inline bool mm_p4d_folded(struct mm_struct *mm)
>>> +{
>>> + return !pgtable_l5_enabled();
>>> +}
>>> +
>>
>> For me this should be part of another patch, it is not directly linked to the tests.
>
> We did discuss about this earlier and Kirril mentioned its not worth
> a separate patch.
>
> https://lore.kernel.org/linux-arm-kernel/20190913091305.rkds4f3fqv3yjhjy@box/
For me it would make sense to not mix this patch which implement tests,
and changes that are needed for the test to work (or even build) on the
different architectures.
But that's up to you.
>
>>
>>> void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte);
>>> void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte);
>>> diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
>>> index 798ea36a0549..e0b04787e789 100644
>>> --- a/include/asm-generic/pgtable.h
>>> +++ b/include/asm-generic/pgtable.h
>>> @@ -1208,6 +1208,12 @@ static inline bool arch_has_pfn_modify_check(void)
>>> # define PAGE_KERNEL_EXEC PAGE_KERNEL
>>> #endif
>>> +#ifdef CONFIG_DEBUG_VM_PGTABLE
>>
>> Not sure it is a good idea to put that in include/asm-generic/pgtable.h
>
> Logically that is the right place, as it is related to page table but
> not something platform related.
I can't see any debug related features in that file.
>
>>
>> By doing this you are forcing a rebuild of almost all files, whereas only init/main.o and mm/debug_vm_pgtable.o should be rebuilt when activating this config option.
>
> I agreed but whats the alternative ? We could move these into init/main.c
> to make things simpler but will that be a right place, given its related
> to generic page table.
What about linux/mmdebug.h instead ? (I have not checked if it would
reduce the impact, but that's where things related to CONFIG_DEBUG_VM
seems to be).
Otherwise, you can just create new file, for instance
<linux/mmdebug-pgtable.h> and include that file only in the init/main.c
and mm/debug_vm_pgtable.c
>
>>
>>> +extern void debug_vm_pgtable(void);
>>
>> Please don't use the 'extern' keyword, it is useless and not to be used for functions declaration.
>
> Really ? But, there are tons of examples doing the same thing both in
> generic and platform code as well.
Yes, but how can we improve if we blindly copy the errors from the past
? Having tons of 'extern' doesn't mean we must add more.
I think checkpatch.pl usually complains when a patch brings a new
unreleval extern symbol.
>
>>
>>> +#else
>>> +static inline void debug_vm_pgtable(void) { }
>>> +#endif
>>> +
>>> #endif /* !__ASSEMBLY__ */
>>> #ifndef io_remap_pfn_range
>>> diff --git a/init/main.c b/init/main.c
>>> index da1bc0b60a7d..5e59e6ac0780 100644
>>> --- a/init/main.c
>>> +++ b/init/main.c
>>> @@ -1197,6 +1197,7 @@ static noinline void __init kernel_init_freeable(void)
>>> sched_init_smp();
>>> page_alloc_init_late();
>>> + debug_vm_pgtable();
>>
>> Wouldn't it be better to call debug_vm_pgtable() in kernel_init() between the call to async_synchronise_full() and ftrace_free_init_mem() ?
>
> IIRC, proposed location is the earliest we could call debug_vm_pgtable().
> Is there any particular benefit or reason to move it into kernel_init() ?
It would avoid having it lost in the middle of drivers logs, would be
close to the end of init, at a place we can't miss it, close to the
result of other tests like CONFIG_DEBUG_RODATA_TEST for instance.
At the moment, you have to look for it to be sure the test is done and
what the result is.
>
>>
>>> /* Initialize page ext after all struct pages are initialized. */
>>> page_ext_init();
>>> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
>>> index 5ffe144c9794..7cceae923c05 100644
>>> --- a/lib/Kconfig.debug
>>> +++ b/lib/Kconfig.debug
>>> @@ -653,6 +653,12 @@ config SCHED_STACK_END_CHECK
>>> data corruption or a sporadic crash at a later stage once the region
>>> is examined. The runtime overhead introduced is minimal.
>>> +config ARCH_HAS_DEBUG_VM_PGTABLE
>>> + bool
>>> + help
>>> + An architecture should select this when it can successfully
>>> + build and run DEBUG_VM_PGTABLE.
>>> +
>>> config DEBUG_VM
>>> bool "Debug VM"
>>> depends on DEBUG_KERNEL
>>> @@ -688,6 +694,22 @@ config DEBUG_VM_PGFLAGS
>>> If unsure, say N.
>>> +config DEBUG_VM_PGTABLE
>>> + bool "Debug arch page table for semantics compliance"
>>> + depends on MMU
>>> + depends on DEBUG_VM
>>
>> Does it really need to depend on DEBUG_VM ?
>
> No. It seemed better to package this test along with DEBUG_VM (although I
> dont remember the conversation around it) and hence this dependency.
Yes but it perfectly work as standalone. The more easy it is to activate
and the more people will use it. DEBUG_VM obliges to rebuild the kernel
entirely and could modify the behaviour. Could the helpers we are
testing behave differently when DEBUG_VM is not set ? I think it's good
the test things as close as possible to final config.
>
>> I think we could make it standalone and 'default y if DEBUG_VM' instead.
>
> Which will yield the same result like before but in a different way. But
> yes, this test could go about either way but unless there is a good enough
> reason why change the current one.
I think if we want people to really use it on other architectures it
must be possible to activate it without having to modify Kconfig.
Otherwise people won't even know the test exists and the architecture
fails the test.
The purpose of a test suite is to detect bugs. If you can't run the test
until you have fixed the bugs, I guess nobody will ever detect the bugs
and they will never be fixed.
So I think:
- the test should be 'default y' when ARCH_HAS_DEBUG_VM_PGTABLE is selected
- the test should be 'default n' when ARCH_HAS_DEBUG_VM_PGTABLE is not
selected, and it should be user selectable if EXPERT is selected.
Something like:
config DEBUG_VM_PGTABLE
bool "Debug arch page table for semantics compliance" if
ARCH_HAS_DEBUG_VM_PGTABLE || EXPERT
depends on MMU
default 'n' if !ARCH_HAS_DEBUG_VM_PGTABLE
default 'y' if DEBUG_VM
>
>>
>>> + depends on ARCH_HAS_DEBUG_VM_PGTABLE
>>> + default y
>>> + help
>>> + This option provides a debug method which can be used to test
>>> + architecture page table helper functions on various platforms in
>>> + verifying if they comply with expected generic MM semantics. This
>>> + will help architecture code in making sure that any changes or
>>> + new additions of these helpers still conform to expected
>>> + semantics of the generic MM.
>>> +
>>> + If unsure, say N.
>>> +
>>
>> Does it make sense to make it 'default y' and say 'If unsure, say N' ?
>
> No it does. Not when it defaults 'y' unconditionally. Will drop the last
> sentence "If unsure, say N". Nice catch, thank you.
Well I was not asking if 'default y' was making sense but only if 'If
unsure say N' was making sense due to the 'default y'. You got it.
Christophe
^ permalink raw reply
* Re: powerpc Linux scv support and scv system call ABI proposal
From: Segher Boessenkool @ 2020-01-30 13:50 UTC (permalink / raw)
To: Florian Weimer
Cc: libc-alpha, Tulio Magno Quites Machado Filho, linuxppc-dev,
Nicholas Piggin
In-Reply-To: <87y2tp40d2.fsf@oldenburg2.str.redhat.com>
Hi again,
On Thu, Jan 30, 2020 at 01:03:53PM +0100, Florian Weimer wrote:
> > This is why that *is* the only supported use. The documentation could
> > use a touch-up, I think. Unless we still have problems here?
>
> I really don't know. GCC still has *some* support for the old behavior,
> though.
No. No support. It still does some of the same things, but that can
change (and probably should). But this hasn't been supported since the
dark ages, and the documentation has become gradually more explicit
about it.
> For example, local register variables are treated as
> initialized, and I think you can still use registers like global
> variables. GCC does not perform copy propagation here:
>
> int f1 (int);
>
> int
> f (void)
> {
> register int edi __asm__ ("edi");
> int edi_copy = edi;
> return f1 (1) + edi_copy;
> }
f:
pushl %edi
subl $20, %esp
pushl $1
call f1
addl %edi, %eax
addl $24, %esp
popl %edi
ret
It takes the edi value *after* the call. The behaviour is undefined,
so that is not a problem. (This is a GCC 10 from September, fwiw).
> And the case that we agreed should be defined in fact is not:
>
> void f1 (int);
>
> int
> f (void)
> {
> register int edi __asm__ ("edi");
> asm ("#" : "=r" (edi));
> f1 (1);
> return edi;
> }
f:
pushl %edi
subl $20, %esp
#APP
#
#NO_APP
pushl $1
call f1
movl %edi, %eax
addl $24, %esp
popl %edi
ret
Changing it to "# %0" (so that we can see what we are doing) gives
#APP
# %edi
#NO_APP
All as expected.
> On x86-64,
Oh, this was i386, since you used edi. On x86-64:
f:
pushq %rbx
movl %edi, %ebx
movl $1, %edi
call f1
addl %ebx, %eax
popq %rbx
ret
for that first testcase, taking edi before the call, which is not
*guaranteed* to happen, but still can; and
f:
subq $8, %rsp
movl $1, %edi
call f1
addq $8, %rsp
movl %edi, %eax
ret
The asm was right before that "mov $1,%edi", so it was optimised away:
it is not a volatile asm, and its output is unused. Making the asm
statement volatile gives
f:
subq $8, %rsp
#APP
# %edi
#NO_APP
movl $1, %edi
call f1
addq $8, %rsp
movl %edi, %eax
ret
> %edi is used to pass the first function parameter, so the
> call clobbers %edi. It is simply ambiguous whether edi (the variable)
> should retain the value prior to the call to f1 (which I think is what
> should happen under the new model, where register variables are only
> affect asm operands), or if edi (the variable) should have the value of
> %edi (the register) after the call (the old model).
There is nothing ambiguous there, afaics? Other than the edi value you
use in the asm is coming out of thin air (but it will always work with
current GCC; that's not really specified though).
> Should we move this to the gcc list?
Whoops, I thought that was on Cc:. Sure.
Segher
^ permalink raw reply
* Re: [PATCH V12] mm/debug: Add tests validating architecture page table helpers
From: Anshuman Khandual @ 2020-01-30 13:32 UTC (permalink / raw)
To: Mike Rapoport, Gerald Schaefer
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra, James Hogan,
Tetsuo Handa, Heiko Carstens, Michal Hocko, Linux-MM, Dave Hansen,
Paul Mackerras, sparclinux, Thomas Gleixner, linux-s390, x86,
Russell King - ARM Linux, Matthew Wilcox, Steven Price,
Jason Gunthorpe, linux-arm-kernel, linux-snps-arc, Ingo Molnar,
Kees Cook, Masahiro Yamada, Mark Brown, Qian Cai,
Kirill A . Shutemov, Dan Williams, Vlastimil Babka,
Sri Krishna chowdary, Ard Biesheuvel, Greg Kroah-Hartman,
linux-mips, Ralf Baechle, linux-kernel, Paul Burton,
Mike Rapoport, Vineet Gupta, Martin Schwidefsky, Andrew Morton,
linuxppc-dev, David S. Miller
In-Reply-To: <20200130072741.GA23707@linux.ibm.com>
On 01/30/2020 12:57 PM, Mike Rapoport wrote:
> On Wed, Jan 29, 2020 at 11:20:44PM +0100, Gerald Schaefer wrote:
>> On Mon, 27 Jan 2020 22:33:08 -0500
>>
>> For example, who would have thought that pXd_bad() is supposed to
>> report large entries as bad? It's not really documented anywhere,
>
> A bit off-topic,
>
> @Anshuman, maybe you could start a Documentation/ patch that describes at
> least some of the pXd_whaterver()?
> Or that would be too much to ask? ;-)
No, it would not be :) I have been documenting the expected semantics for
the helpers in the test itself. The idea is to collate them all (have been
working on some additional tests but waiting for this one to get merged
first) here and once most of the test gets settled, will move semantics
documentation from here into Documentation/ directory in a proper format.
/*
* Basic operations
*
* mkold(entry) = An old and not a young entry
* mkyoung(entry) = A young and not an old entry
* mkdirty(entry) = A dirty and not a clean entry
* mkclean(entry) = A clean and not a dirty entry
* mkwrite(entry) = A write and not a write protected entry
* wrprotect(entry) = A write protected and not a write entry
* pxx_bad(entry) = A mapped and non-table entry
* pxx_same(entry1, entry2) = Both entries hold the exact same value
*/
>
>> so we just checked them for sanity like normal entries, which
>> apparently worked fine so far, but for how long?
>
^ permalink raw reply
* Re: [PATCH] bus: fsl-mc: add api to retrieve mc version
From: Horia Geanta @ 2020-01-30 13:27 UTC (permalink / raw)
To: Laurentiu Tudor, Andrei Botila, Stuart Yoder, Leo Li, Herbert Xu
Cc: Andrey Smirnov, Greg Kroah-Hartman, linux-kernel@vger.kernel.org,
linux-crypto@vger.kernel.org, linuxppc-dev@lists.ozlabs.org,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <AM6PR04MB58788A33BCFD161773375C8DEC0B0@AM6PR04MB5878.eurprd04.prod.outlook.com>
On 1/27/2020 1:49 PM, Laurentiu Tudor wrote:
>
>> -----Original Message-----
>> From: Andrei Botila <andrei.botila@nxp.com>
>> Sent: Monday, January 27, 2020 1:16 PM
>>
>> Add a new api that returns Management Complex firmware version
>> and make the required structure public. The api's first user will be
>> the caam driver for setting prediction resistance bits.
>>
>> Signed-off-by: Andrei Botila <andrei.botila@nxp.com>
>
> Acked-by: Laurentiu Tudor <laurentiu.tudor@nxp.com>
Reviewed-by: Horia Geantă <horia.geanta@nxp.com>
We'll need this patch in the crypto subsystem,
such that the CAAM HWRNG patch series (currently v7)
https://patchwork.kernel.org/project/linux-crypto/list/?series=233763&archive=both&state=*
is updated to work with existing (and future) FSL MC f/w versions.
CAAM HWRNG series has been in review for quite some time
and AFAICT is in pretty good shape.
Unfortunately it missed v5.6 merge window. I would like it to go
in v5.7, but for this we'll need current patch (a dependency)
to go through (or be cherry-picked into) the crypto tree.
>> ---
>> drivers/bus/fsl-mc/fsl-mc-bus.c | 33 +++++++++++++++++----------------
>> include/linux/fsl/mc.h | 16 ++++++++++++++++
>> 2 files changed, 33 insertions(+), 16 deletions(-)
>>
>> diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-
>> bus.c
>> index a07cc19becdb..330c76181604 100644
>> --- a/drivers/bus/fsl-mc/fsl-mc-bus.c
>> +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
>> @@ -26,6 +26,8 @@
>> */
>> #define FSL_MC_DEFAULT_DMA_MASK (~0ULL)
>>
>> +static struct fsl_mc_version mc_version;
>> +
>> /**
>> * struct fsl_mc - Private data of a "fsl,qoriq-mc" platform device
>> * @root_mc_bus_dev: fsl-mc device representing the root DPRC
>> @@ -54,20 +56,6 @@ struct fsl_mc_addr_translation_range {
>> phys_addr_t start_phys_addr;
>> };
>>
>> -/**
>> - * struct mc_version
>> - * @major: Major version number: incremented on API compatibility changes
>> - * @minor: Minor version number: incremented on API additions (that are
>> - * backward compatible); reset when major version is incremented
>> - * @revision: Internal revision number: incremented on implementation
>> changes
>> - * and/or bug fixes that have no impact on API
>> - */
>> -struct mc_version {
>> - u32 major;
>> - u32 minor;
>> - u32 revision;
>> -};
>> -
>> /**
>> * fsl_mc_bus_match - device to driver matching callback
>> * @dev: the fsl-mc device to match against
>> @@ -338,7 +326,7 @@ EXPORT_SYMBOL_GPL(fsl_mc_driver_unregister);
>> */
>> static int mc_get_version(struct fsl_mc_io *mc_io,
>> u32 cmd_flags,
>> - struct mc_version *mc_ver_info)
>> + struct fsl_mc_version *mc_ver_info)
>> {
>> struct fsl_mc_command cmd = { 0 };
>> struct dpmng_rsp_get_version *rsp_params;
>> @@ -363,6 +351,20 @@ static int mc_get_version(struct fsl_mc_io *mc_io,
>> return 0;
>> }
>>
>> +/**
>> + * fsl_mc_get_version - function to retrieve the MC f/w version
>> information
>> + *
>> + * Return: mc version when called after fsl-mc-bus probe; NULL otherwise.
>> + */
>> +struct fsl_mc_version *fsl_mc_get_version(void)
>> +{
>> + if (mc_version.major)
>> + return &mc_version;
>> +
>> + return NULL;
>> +}
>> +EXPORT_SYMBOL_GPL(fsl_mc_get_version);
>> +
>> /**
>> * fsl_mc_get_root_dprc - function to traverse to the root dprc
>> */
>> @@ -862,7 +864,6 @@ static int fsl_mc_bus_probe(struct platform_device
>> *pdev)
>> int container_id;
>> phys_addr_t mc_portal_phys_addr;
>> u32 mc_portal_size;
>> - struct mc_version mc_version;
>> struct resource res;
>>
>> mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL);
>> diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h
>> index 54d9436600c7..2b5f8366dbe1 100644
>> --- a/include/linux/fsl/mc.h
>> +++ b/include/linux/fsl/mc.h
>> @@ -381,6 +381,22 @@ int __must_check __fsl_mc_driver_register(struct
>> fsl_mc_driver *fsl_mc_driver,
>>
>> void fsl_mc_driver_unregister(struct fsl_mc_driver *driver);
>>
>> +/**
>> + * struct fsl_mc_version
>> + * @major: Major version number: incremented on API compatibility changes
>> + * @minor: Minor version number: incremented on API additions (that are
>> + * backward compatible); reset when major version is incremented
>> + * @revision: Internal revision number: incremented on implementation
>> changes
>> + * and/or bug fixes that have no impact on API
>> + */
>> +struct fsl_mc_version {
>> + u32 major;
>> + u32 minor;
>> + u32 revision;
>> +};
>> +
>> +struct fsl_mc_version *fsl_mc_get_version(void);
>> +
>> int __must_check fsl_mc_portal_allocate(struct fsl_mc_device *mc_dev,
>> u16 mc_io_flags,
>> struct fsl_mc_io **new_mc_io);
>> --
>> 2.17.1
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
^ permalink raw reply
* Re: [PATCH v4] powerpc/smp: Use nid as fallback for package_id
From: Srikar Dronamraju @ 2020-01-30 13:18 UTC (permalink / raw)
To: Gautham R Shenoy; +Cc: Vasant Hegde, Vaidyanathan Srinivasan, linuxppc-dev
In-Reply-To: <20200130105747.GD1988@in.ibm.com>
* Gautham R Shenoy <ego@linux.vnet.ibm.com> [2020-01-30 16:27:47]:
> On Wed, Jan 29, 2020 at 07:21:21PM +0530, Srikar Dronamraju wrote:
>
> [..snip..]
>
> > --- a/arch/powerpc/kernel/smp.c
> > +++ b/arch/powerpc/kernel/smp.c
> > @@ -1185,10 +1185,34 @@ static inline void add_cpu_to_smallcore_masks(int cpu)
> > }
> > }
> >
> > +int get_physical_package_id(int cpu)
> > +{
> > + int ppid = cpu_to_chip_id(cpu);
> > +
> > +#ifdef CONFIG_PPC_SPLPAR
> > + /*
> > + * If the platform is PowerNV or Guest on KVM, ibm,chip-id is
> > + * defined. Hence we would return the chip-id as the
> > + * get_physical_package_id.
> > + */
> > + if (ppid == -1 && firmware_has_feature(FW_FEATURE_LPAR)) {
> > + struct device_node *np = of_get_cpu_node(cpu, NULL);
> > +
> > + if (np) {
> > + ppid = of_node_to_nid(np);
> > + of_node_put(np);
> > + }
> > + }
> > +#endif /* CONFIG_PPC_SPLPAR */
> > +
> > + return ppid;
> > +}
> > static void add_cpu_to_masks(int cpu)
> > {
> > int first_thread = cpu_first_thread_sibling(cpu);
> > - int chipid = cpu_to_chip_id(cpu);
> > + int ppid = get_physical_package_id(cpu);
> > int i;
> >
> > /*
> > @@ -1217,11 +1241,11 @@ static void add_cpu_to_masks(int cpu)
> > for_each_cpu(i, cpu_l2_cache_mask(cpu))
> > set_cpus_related(cpu, i, cpu_core_mask);
> >
> > - if (chipid == -1)
> > + if (ppid == -1)
> > return;
>
> Can get_physical_package_id() return -1 ?
>
Yes, it can return -1,
1. A System doesnt have CONFIG_PPC_SPLPAR: cpu_to_chip_id() might return -1.
2. A System with CONFIG_PPC_SPLPAR: Still can return -1 for following cases.
a. Not having firmware feature FW_FEATURE_LPAR
b. If for some reason, of_get_cpu_node property is not present.
> >
> > for_each_cpu(i, cpu_online_mask)
> > - if (cpu_to_chip_id(i) == chipid)
> > + if (get_physical_package_id(i) == ppid)
> > set_cpus_related(cpu, i, cpu_core_mask);
> > }
--
Thanks and Regards
Srikar Dronamraju
^ permalink raw reply
* Re: [PATCH V12] mm/debug: Add tests validating architecture page table helpers
From: Anshuman Khandual @ 2020-01-30 13:11 UTC (permalink / raw)
To: Gerald Schaefer
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra, James Hogan,
Tetsuo Handa, Heiko Carstens, Michal Hocko, linux-mm, Dave Hansen,
Paul Mackerras, sparclinux, Thomas Gleixner, linux-s390, x86,
Russell King - ARM Linux, Matthew Wilcox, Steven Price,
Jason Gunthorpe, linux-arm-kernel, linux-snps-arc, Ingo Molnar,
Kees Cook, Masahiro Yamada, Mark Brown, Kirill A . Shutemov,
Dan Williams, Vlastimil Babka, Sri Krishna chowdary,
Ard Biesheuvel, Greg Kroah-Hartman, linux-mips, Ralf Baechle,
linux-kernel, Paul Burton, Mike Rapoport, Vineet Gupta,
Martin Schwidefsky, Andrew Morton, linuxppc-dev, David S. Miller
In-Reply-To: <20200129232028.5a27e656@thinkpad>
On 01/30/2020 03:50 AM, Gerald Schaefer wrote:
> On Tue, 28 Jan 2020 06:57:53 +0530
> Anshuman Khandual <anshuman.khandual@arm.com> wrote:
>
>> This adds tests which will validate architecture page table helpers and
>> other accessors in their compliance with expected generic MM semantics.
>> This will help various architectures in validating changes to existing
>> page table helpers or addition of new ones.
>>
>> This test covers basic page table entry transformations including but not
>> limited to old, young, dirty, clean, write, write protect etc at various
>> level along with populating intermediate entries with next page table page
>> and validating them.
>>
>> Test page table pages are allocated from system memory with required size
>> and alignments. The mapped pfns at page table levels are derived from a
>> real pfn representing a valid kernel text symbol. This test gets called
>> right after page_alloc_init_late().
>>
>> This gets build and run when CONFIG_DEBUG_VM_PGTABLE is selected along with
>> CONFIG_VM_DEBUG. Architectures willing to subscribe this test also need to
>> select CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE which for now is limited to x86 and
>> arm64. Going forward, other architectures too can enable this after fixing
>> build or runtime problems (if any) with their page table helpers.
>>
>> Folks interested in making sure that a given platform's page table helpers
>> conform to expected generic MM semantics should enable the above config
>> which will just trigger this test during boot. Any non conformity here will
>> be reported as an warning which would need to be fixed. This test will help
>> catch any changes to the agreed upon semantics expected from generic MM and
>> enable platforms to accommodate it thereafter.
>>
>
> [...]
>
>>
>> Tested-by: Christophe Leroy <christophe.leroy@c-s.fr> #PPC32
>
> Tested-by: Gerald Schaefer <gerald.schaefer@de.ibm.com> # s390
Thanks for testing.
>
> Thanks again for this effort, and for keeping up the spirit against
> all odds and even after 12 iterations :-)
>
>>
>> diff --git a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
>> new file mode 100644
>> index 000000000000..f3f8111edbe3
>> --- /dev/null
>> +++ b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
>> @@ -0,0 +1,35 @@
>> +#
>> +# Feature name: debug-vm-pgtable
>> +# Kconfig: ARCH_HAS_DEBUG_VM_PGTABLE
>> +# description: arch supports pgtable tests for semantics compliance
>> +#
>> + -----------------------
>> + | arch |status|
>> + -----------------------
>> + | alpha: | TODO |
>> + | arc: | ok |
>> + | arm: | TODO |
>> + | arm64: | ok |
>> + | c6x: | TODO |
>> + | csky: | TODO |
>> + | h8300: | TODO |
>> + | hexagon: | TODO |
>> + | ia64: | TODO |
>> + | m68k: | TODO |
>> + | microblaze: | TODO |
>> + | mips: | TODO |
>> + | nds32: | TODO |
>> + | nios2: | TODO |
>> + | openrisc: | TODO |
>> + | parisc: | TODO |
>> + | powerpc/32: | ok |
>> + | powerpc/64: | TODO |
>> + | riscv: | TODO |
>> + | s390: | TODO |
>
> s390 is ok now, with my patches included in v5.5-rc1. So you can now add
>
> --- a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
> +++ b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
> @@ -25,7 +25,7 @@
> | powerpc/32: | ok |
> | powerpc/64: | TODO |
> | riscv: | TODO |
> - | s390: | TODO |
> + | s390: | ok |
> | sh: | TODO |
> | sparc: | TODO |
> | um: | TODO |
> --- a/arch/s390/Kconfig
> +++ b/arch/s390/Kconfig
> @@ -59,6 +59,7 @@ config KASAN_SHADOW_OFFSET
> config S390
> def_bool y
> select ARCH_BINFMT_ELF_STATE
> + select ARCH_HAS_DEBUG_VM_PGTABLE
> select ARCH_HAS_DEVMEM_IS_ALLOWED
> select ARCH_HAS_ELF_RANDOMIZE
> select ARCH_HAS_FORTIFY_SOURCE
Sure, will add this up.
^ permalink raw reply
* Re: [PATCH V12] mm/debug: Add tests validating architecture page table helpers
From: Anshuman Khandual @ 2020-01-30 13:04 UTC (permalink / raw)
To: Christophe Leroy, linux-mm
Cc: Mark Rutland, linux-ia64, linux-sh, Peter Zijlstra, James Hogan,
Heiko Carstens, Michal Hocko, Dave Hansen, Paul Mackerras,
sparclinux, Thomas Gleixner, linux-s390, Jason Gunthorpe, x86,
Russell King - ARM Linux, Matthew Wilcox, Steven Price,
Tetsuo Handa, Gerald Schaefer, linux-snps-arc, Ingo Molnar,
Kees Cook, Masahiro Yamada, Mark Brown, Kirill A . Shutemov,
Dan Williams, Vlastimil Babka, linux-arm-kernel,
Sri Krishna chowdary, Ard Biesheuvel, Greg Kroah-Hartman,
linux-mips, Ralf Baechle, linux-kernel, Paul Burton,
Mike Rapoport, Vineet Gupta, Martin Schwidefsky, Andrew Morton,
linuxppc-dev, David S. Miller
In-Reply-To: <68ed6488-aa25-ab41-8da6-f0ddeb15d52b@c-s.fr>
On 01/28/2020 10:35 PM, Christophe Leroy wrote:
>
>
> Le 28/01/2020 à 02:27, Anshuman Khandual a écrit :
>> This adds tests which will validate architecture page table helpers and
>> other accessors in their compliance with expected generic MM semantics.
>> This will help various architectures in validating changes to existing
>> page table helpers or addition of new ones.
>>
>> This test covers basic page table entry transformations including but not
>> limited to old, young, dirty, clean, write, write protect etc at various
>> level along with populating intermediate entries with next page table page
>> and validating them.
>>
>> Test page table pages are allocated from system memory with required size
>> and alignments. The mapped pfns at page table levels are derived from a
>> real pfn representing a valid kernel text symbol. This test gets called
>> right after page_alloc_init_late().
>>
>> This gets build and run when CONFIG_DEBUG_VM_PGTABLE is selected along with
>> CONFIG_VM_DEBUG. Architectures willing to subscribe this test also need to
>> select CONFIG_ARCH_HAS_DEBUG_VM_PGTABLE which for now is limited to x86 and
>> arm64. Going forward, other architectures too can enable this after fixing
>> build or runtime problems (if any) with their page table helpers.
>>
>> Folks interested in making sure that a given platform's page table helpers
>> conform to expected generic MM semantics should enable the above config
>> which will just trigger this test during boot. Any non conformity here will
>> be reported as an warning which would need to be fixed. This test will help
>> catch any changes to the agreed upon semantics expected from generic MM and
>> enable platforms to accommodate it thereafter.
>>
>
> [...]
>
>>
>> Tested-by: Christophe Leroy <christophe.leroy@c-s.fr> #PPC32
>
> Also tested on PPC64 (under QEMU): book3s/64 64k pages, book3s/64 4k pages and book3e/64
Hmm but earlier Michael Ellerman had reported some problems while
running these tests on PPC64, a soft lock up in hash__pte_update()
and a kernel BUG (radix MMU). Are those problems gone away now ?
Details in this thread - https://patchwork.kernel.org/patch/11214603/
>
>> Reviewed-by: Ingo Molnar <mingo@kernel.org>
>> Suggested-by: Catalin Marinas <catalin.marinas@arm.com>
>> Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
>> Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
>> Signed-off-by: Anshuman Khandual <anshuman.khandual@arm.com>
>> ---
>
> [...]
>
>>
>> diff --git a/Documentation/features/debug/debug-vm-pgtable/arch-support.txt b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
>> new file mode 100644
>> index 000000000000..f3f8111edbe3
>> --- /dev/null
>> +++ b/Documentation/features/debug/debug-vm-pgtable/arch-support.txt
>> @@ -0,0 +1,35 @@
>> +#
>> +# Feature name: debug-vm-pgtable
>> +# Kconfig: ARCH_HAS_DEBUG_VM_PGTABLE
>> +# description: arch supports pgtable tests for semantics compliance
>> +#
>> + -----------------------
>> + | arch |status|
>> + -----------------------
>> + | alpha: | TODO |
>> + | arc: | ok |
>> + | arm: | TODO |
>> + | arm64: | ok |
>> + | c6x: | TODO |
>> + | csky: | TODO |
>> + | h8300: | TODO |
>> + | hexagon: | TODO |
>> + | ia64: | TODO |
>> + | m68k: | TODO |
>> + | microblaze: | TODO |
>> + | mips: | TODO |
>> + | nds32: | TODO |
>> + | nios2: | TODO |
>> + | openrisc: | TODO |
>> + | parisc: | TODO |
>> + | powerpc/32: | ok |
>> + | powerpc/64: | TODO |
>
> You can change the two above lines by
>
> powerpc: ok
>
>> + | riscv: | TODO |
>> + | s390: | TODO |
>> + | sh: | TODO |
>> + | sparc: | TODO |
>> + | um: | TODO |
>> + | unicore32: | TODO |
>> + | x86: | ok |
>> + | xtensa: | TODO |
>> + -----------------------
>
>> diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
>> index 1ec34e16ed65..253dcab0bebc 100644
>> --- a/arch/powerpc/Kconfig
>> +++ b/arch/powerpc/Kconfig
>> @@ -120,6 +120,7 @@ config PPC
>> #
>> select ARCH_32BIT_OFF_T if PPC32
>> select ARCH_HAS_DEBUG_VIRTUAL
>> + select ARCH_HAS_DEBUG_VM_PGTABLE if PPC32
>
> Remove the 'if PPC32' as we now know it also work on PPC64.
But in case there is a subset of PPC64 which still does not work
(problem reported earlier) with the test, will have to adjust the
config accordingly.
>
>> select ARCH_HAS_DEVMEM_IS_ALLOWED
>> select ARCH_HAS_ELF_RANDOMIZE
>> select ARCH_HAS_FORTIFY_SOURCE
>
>> diff --git a/arch/x86/include/asm/pgtable_64.h b/arch/x86/include/asm/pgtable_64.h
>> index 0b6c4042942a..fb0e76d254b3 100644
>> --- a/arch/x86/include/asm/pgtable_64.h
>> +++ b/arch/x86/include/asm/pgtable_64.h
>> @@ -53,6 +53,12 @@ static inline void sync_initial_page_table(void) { }
>> struct mm_struct;
>> +#define mm_p4d_folded mm_p4d_folded
>> +static inline bool mm_p4d_folded(struct mm_struct *mm)
>> +{
>> + return !pgtable_l5_enabled();
>> +}
>> +
>
> For me this should be part of another patch, it is not directly linked to the tests.
We did discuss about this earlier and Kirril mentioned its not worth
a separate patch.
https://lore.kernel.org/linux-arm-kernel/20190913091305.rkds4f3fqv3yjhjy@box/
>
>> void set_pte_vaddr_p4d(p4d_t *p4d_page, unsigned long vaddr, pte_t new_pte);
>> void set_pte_vaddr_pud(pud_t *pud_page, unsigned long vaddr, pte_t new_pte);
>> diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
>> index 798ea36a0549..e0b04787e789 100644
>> --- a/include/asm-generic/pgtable.h
>> +++ b/include/asm-generic/pgtable.h
>> @@ -1208,6 +1208,12 @@ static inline bool arch_has_pfn_modify_check(void)
>> # define PAGE_KERNEL_EXEC PAGE_KERNEL
>> #endif
>> +#ifdef CONFIG_DEBUG_VM_PGTABLE
>
> Not sure it is a good idea to put that in include/asm-generic/pgtable.h
Logically that is the right place, as it is related to page table but
not something platform related.
>
> By doing this you are forcing a rebuild of almost all files, whereas only init/main.o and mm/debug_vm_pgtable.o should be rebuilt when activating this config option.
I agreed but whats the alternative ? We could move these into init/main.c
to make things simpler but will that be a right place, given its related
to generic page table.
>
>> +extern void debug_vm_pgtable(void);
>
> Please don't use the 'extern' keyword, it is useless and not to be used for functions declaration.
Really ? But, there are tons of examples doing the same thing both in
generic and platform code as well.
>
>> +#else
>> +static inline void debug_vm_pgtable(void) { }
>> +#endif
>> +
>> #endif /* !__ASSEMBLY__ */
>> #ifndef io_remap_pfn_range
>> diff --git a/init/main.c b/init/main.c
>> index da1bc0b60a7d..5e59e6ac0780 100644
>> --- a/init/main.c
>> +++ b/init/main.c
>> @@ -1197,6 +1197,7 @@ static noinline void __init kernel_init_freeable(void)
>> sched_init_smp();
>> page_alloc_init_late();
>> + debug_vm_pgtable();
>
> Wouldn't it be better to call debug_vm_pgtable() in kernel_init() between the call to async_synchronise_full() and ftrace_free_init_mem() ?
IIRC, proposed location is the earliest we could call debug_vm_pgtable().
Is there any particular benefit or reason to move it into kernel_init() ?
>
>> /* Initialize page ext after all struct pages are initialized. */
>> page_ext_init();
>> diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
>> index 5ffe144c9794..7cceae923c05 100644
>> --- a/lib/Kconfig.debug
>> +++ b/lib/Kconfig.debug
>> @@ -653,6 +653,12 @@ config SCHED_STACK_END_CHECK
>> data corruption or a sporadic crash at a later stage once the region
>> is examined. The runtime overhead introduced is minimal.
>> +config ARCH_HAS_DEBUG_VM_PGTABLE
>> + bool
>> + help
>> + An architecture should select this when it can successfully
>> + build and run DEBUG_VM_PGTABLE.
>> +
>> config DEBUG_VM
>> bool "Debug VM"
>> depends on DEBUG_KERNEL
>> @@ -688,6 +694,22 @@ config DEBUG_VM_PGFLAGS
>> If unsure, say N.
>> +config DEBUG_VM_PGTABLE
>> + bool "Debug arch page table for semantics compliance"
>> + depends on MMU
>> + depends on DEBUG_VM
>
> Does it really need to depend on DEBUG_VM ?
No. It seemed better to package this test along with DEBUG_VM (although I
dont remember the conversation around it) and hence this dependency.
> I think we could make it standalone and 'default y if DEBUG_VM' instead.
Which will yield the same result like before but in a different way. But
yes, this test could go about either way but unless there is a good enough
reason why change the current one.
>
>> + depends on ARCH_HAS_DEBUG_VM_PGTABLE
>> + default y
>> + help
>> + This option provides a debug method which can be used to test
>> + architecture page table helper functions on various platforms in
>> + verifying if they comply with expected generic MM semantics. This
>> + will help architecture code in making sure that any changes or
>> + new additions of these helpers still conform to expected
>> + semantics of the generic MM.
>> +
>> + If unsure, say N.
>> +
>
> Does it make sense to make it 'default y' and say 'If unsure, say N' ?
No it does. Not when it defaults 'y' unconditionally. Will drop the last
sentence "If unsure, say N". Nice catch, thank you.
>
>> config ARCH_HAS_DEBUG_VIRTUAL
>> bool
>>
>
> Christophe
>
^ permalink raw reply
* Re: powerpc Linux scv support and scv system call ABI proposal
From: Florian Weimer @ 2020-01-30 12:03 UTC (permalink / raw)
To: Segher Boessenkool
Cc: libc-alpha, Tulio Magno Quites Machado Filho, linuxppc-dev,
Nicholas Piggin
In-Reply-To: <20200130112512.GS22482@gate.crashing.org>
* Segher Boessenkool:
>> I *assumed* that I would still get
>> the value of r0 (the register) from the associated extended asm in this
>> expression, even if it may now be a different register. Your comment
>> made me think that this is undefined.
>
> Please show full(er) examples, I think we are talking about something
> else?
No, I think we are in agreement here how things should behave under the
new model. But I have doubts whether that is implemented in GCC 9.
>> The GCC documentation has this warning:
>>
>> | _Warning:_ In the above example, be aware that a register (for
>> | example 'r0') can be call-clobbered by subsequent code, including
>> | function calls and library calls for arithmetic operators on other
>> | variables (for example the initialization of 'p2').
>
> Yes. This does not matter for the only supported use.
I'm not so sure. See below.
> This is why that *is* the only supported use. The documentation could
> use a touch-up, I think. Unless we still have problems here?
I really don't know. GCC still has *some* support for the old behavior,
though. For example, local register variables are treated as
initialized, and I think you can still use registers like global
variables. GCC does not perform copy propagation here:
int f1 (int);
int
f (void)
{
register int edi __asm__ ("edi");
int edi_copy = edi;
return f1 (1) + edi_copy;
}
And the case that we agreed should be defined in fact is not:
void f1 (int);
int
f (void)
{
register int edi __asm__ ("edi");
asm ("#" : "=r" (edi));
f1 (1);
return edi;
}
On x86-64, %edi is used to pass the first function parameter, so the
call clobbers %edi. It is simply ambiguous whether edi (the variable)
should retain the value prior to the call to f1 (which I think is what
should happen under the new model, where register variables are only
affect asm operands), or if edi (the variable) should have the value of
%edi (the register) after the call (the old model).
Should we move this to the gcc list?
Thanks,
Florian
^ permalink raw reply
* Re: powerpc Linux scv support and scv system call ABI proposal
From: Segher Boessenkool @ 2020-01-30 11:25 UTC (permalink / raw)
To: Florian Weimer
Cc: libc-alpha, Tulio Magno Quites Machado Filho, linuxppc-dev,
Nicholas Piggin
In-Reply-To: <87k1595iok.fsf@oldenburg2.str.redhat.com>
On Thu, Jan 30, 2020 at 11:42:51AM +0100, Florian Weimer wrote:
> * Segher Boessenkool:
> > No, that *is* supported: as input to or output from an asm, a local
> > register asm variable *is* guaranteed to live in the specified register.
> > This is the *only* supported use. Other uses may sometimes still work,
> > but they never worked reliably, and it cannot be made reliable; it has
> > been documented as not supported since ages, and it will not work at all
> > anymore some day.
>
> I must say I find this situation *very* confusing.
Local register variables live in that register when they are operands to
an (extended) inline asm. There are no other guarantees. That is all.
> You said that r0 & 1 is undefined.
I said that in
int reg asm("r0");
...
... reg & 1 ...
in that last expression, reg can be in any register, not necessarily r0.
The code is still perfectly well-defined of course, it just might not do
what you expected.
> I *assumed* that I would still get
> the value of r0 (the register) from the associated extended asm in this
> expression, even if it may now be a different register. Your comment
> made me think that this is undefined.
Please show full(er) examples, I think we are talking about something
else?
> But then the syscall wrappers use
> this construct:
>
> __asm__ __volatile__ \
> ("sc\n\t" \
> "mfcr %0\n\t" \
> "0:" \
> : "=&r" (r0), \
> "=&r" (r3), "=&r" (r4), "=&r" (r5), \
> "=&r" (r6), "=&r" (r7), "=&r" (r8) \
> : ASM_INPUT_##nr \
> : "r9", "r10", "r11", "r12", \
> "cr0", "ctr", "memory"); \
> err = r0; \
> r3; \
>
> That lone r3 at the end would be equally undefined because it is not
> used in an input or output operand of an extended asm statement.
Nothing is undefined. That r3 variable at the end might not live in
register r3 there; but the output from the asm does (the compiler can
have swapped registers around already, or even put this in memory
(which is what will probably happen here at -O0!), etc.
> The GCC documentation has this warning:
>
> | _Warning:_ In the above example, be aware that a register (for
> | example 'r0') can be call-clobbered by subsequent code, including
> | function calls and library calls for arithmetic operators on other
> | variables (for example the initialization of 'p2').
Yes. This does not matter for the only supported use. This is why that
*is* the only supported use. The documentation could use a touch-up, I
think. Unless we still have problems here?
> On POWER, the LOADARGS macros attempt to deal with this by using
> non-register temporaries. However, I don't know how effective this is
> if the compiler really doesn't deal with call-clobbered registers
> properly.
It worked on old compilers. This isn't necessary on newer compilers.
> For the extended asm use case (to express register assignments that
> cannot be listed in constraints), I would expect that these variables
> retain their values according to the C specification (so they are never
> clobbered by calls), but that they only reside in their designated
> registers when used as input or output operands in extended asm
> statements.
That is what is done now.
In the old days (more than ten years ago), local register variables had
more guarantees, guarantees that were broken once by one (or all all of
the time, depends on your viewpoint ;-) ) Such variables *did* live in
the specified register everywhere, well, not *everywhere*, and there
the problems started.
Nowadays:
Local register variables live in that register when they are operands to
an (extended) inline asm. There are no other guarantees. That is all.
Segher
^ permalink raw reply
* Re: [PATCH v4] powerpc/smp: Use nid as fallback for package_id
From: Gautham R Shenoy @ 2020-01-30 10:57 UTC (permalink / raw)
To: Srikar Dronamraju; +Cc: Vasant Hegde, Vaidyanathan Srinivasan, linuxppc-dev
In-Reply-To: <20200129135121.24617-1-srikar@linux.vnet.ibm.com>
Hello Srikar,
On Wed, Jan 29, 2020 at 07:21:21PM +0530, Srikar Dronamraju wrote:
[..snip..]
> --- a/arch/powerpc/kernel/smp.c
> +++ b/arch/powerpc/kernel/smp.c
> @@ -1185,10 +1185,34 @@ static inline void add_cpu_to_smallcore_masks(int cpu)
> }
> }
>
> +int get_physical_package_id(int cpu)
> +{
> + int ppid = cpu_to_chip_id(cpu);
> +
> +#ifdef CONFIG_PPC_SPLPAR
> + /*
> + * If the platform is PowerNV or Guest on KVM, ibm,chip-id is
> + * defined. Hence we would return the chip-id as the
> + * get_physical_package_id.
> + */
> + if (ppid == -1 && firmware_has_feature(FW_FEATURE_LPAR)) {
> + struct device_node *np = of_get_cpu_node(cpu, NULL);
> +
> + if (np) {
> + ppid = of_node_to_nid(np);
> + of_node_put(np);
> + }
> + }
> +#endif /* CONFIG_PPC_SPLPAR */
> +
> + return ppid;
> +}
> +EXPORT_SYMBOL_GPL(get_physical_package_id);
> +
> static void add_cpu_to_masks(int cpu)
> {
> int first_thread = cpu_first_thread_sibling(cpu);
> - int chipid = cpu_to_chip_id(cpu);
> + int ppid = get_physical_package_id(cpu);
> int i;
>
> /*
> @@ -1217,11 +1241,11 @@ static void add_cpu_to_masks(int cpu)
> for_each_cpu(i, cpu_l2_cache_mask(cpu))
> set_cpus_related(cpu, i, cpu_core_mask);
>
> - if (chipid == -1)
> + if (ppid == -1)
> return;
Can get_physical_package_id() return -1 ?
>
> for_each_cpu(i, cpu_online_mask)
> - if (cpu_to_chip_id(i) == chipid)
> + if (get_physical_package_id(i) == ppid)
> set_cpus_related(cpu, i, cpu_core_mask);
> }
>
> --
> 2.18.1
>
--
Thanks and Regards
gautham.
^ permalink raw reply
* Re: powerpc Linux scv support and scv system call ABI proposal
From: Florian Weimer @ 2020-01-30 10:42 UTC (permalink / raw)
To: Segher Boessenkool
Cc: libc-alpha, Tulio Magno Quites Machado Filho, linuxppc-dev,
Nicholas Piggin
In-Reply-To: <20200129175104.GO22482@gate.crashing.org>
* Segher Boessenkool:
> On Wed, Jan 29, 2020 at 06:02:34PM +0100, Florian Weimer wrote:
>> * Segher Boessenkool:
>>
>> > On Wed, Jan 29, 2020 at 05:19:19PM +0100, Florian Weimer wrote:
>> >> * Segher Boessenkool:
>> >> >> But GCC doesn't expose them as integers to C code, so you can't do much
>> >> >> without them.
>> >> >
>> >> > Sure, it doesn't expose any other registers directly, either.
>> >>
>> >> I can use r0 & 1 with a register variable r0 to check a bit.
>> >
>> > That is not reliable, or supported, and it *will* break. This is
>> > explicit for local register asm, and global register asm is
>> > underdefined.
>>
>> Ugh. I did not know that. And neither did the person who wrote
>> powerpc64/sysdep.h because it uses register variables in regular C
>> expressions. 8-( Other architectures are affected as well.
>
> Where? I don't see any? Ah, the other one, heh (there are two).
>
> No, that *is* supported: as input to or output from an asm, a local
> register asm variable *is* guaranteed to live in the specified register.
> This is the *only* supported use. Other uses may sometimes still work,
> but they never worked reliably, and it cannot be made reliable; it has
> been documented as not supported since ages, and it will not work at all
> anymore some day.
I must say I find this situation *very* confusing.
You said that r0 & 1 is undefined. I *assumed* that I would still get
the value of r0 (the register) from the associated extended asm in this
expression, even if it may now be a different register. Your comment
made me think that this is undefined. But then the syscall wrappers use
this construct:
__asm__ __volatile__ \
("sc\n\t" \
"mfcr %0\n\t" \
"0:" \
: "=&r" (r0), \
"=&r" (r3), "=&r" (r4), "=&r" (r5), \
"=&r" (r6), "=&r" (r7), "=&r" (r8) \
: ASM_INPUT_##nr \
: "r9", "r10", "r11", "r12", \
"cr0", "ctr", "memory"); \
err = r0; \
r3; \
That lone r3 at the end would be equally undefined because it is not
used in an input or output operand of an extended asm statement.
The GCC documentation has this warning:
| _Warning:_ In the above example, be aware that a register (for
| example 'r0') can be call-clobbered by subsequent code, including
| function calls and library calls for arithmetic operators on other
| variables (for example the initialization of 'p2').
On POWER, the LOADARGS macros attempt to deal with this by using
non-register temporaries. However, I don't know how effective this is
if the compiler really doesn't deal with call-clobbered registers
properly.
For the extended asm use case (to express register assignments that
cannot be listed in constraints), I would expect that these variables
retain their values according to the C specification (so they are never
clobbered by calls), but that they only reside in their designated
registers when used as input or output operands in extended asm
statements.
However, this is incompatible with other (ab)uses of local and global
register variables, which may well expect that they are clobbered by
calls. It looks like GCC uses the same construct for two unrelated
things.
Thanks,
Florian
^ permalink raw reply
* Re: [PATCH v16 00/23] selftests, powerpc, x86: Memory Protection Keys
From: Sandipan Das @ 2020-01-30 9:20 UTC (permalink / raw)
To: Dave Hansen
Cc: linux-arch, fweimer, aneesh.kumar, x86, linuxram, linuxppc-dev,
mhocko, linux-mm, mingo, linux-kselftest, msuchanek, shuah,
bauerman
In-Reply-To: <26f630e5-1f70-888c-4b43-30e73c9f270c@linux.ibm.com>
On 30/01/20 11:49 am, Sandipan Das wrote:
> Hi Dave,
>
> On 30/01/20 12:29 am, Dave Hansen wrote:
>> On 1/28/20 1:38 AM, Sandipan Das wrote:
>>> On 27/01/20 9:12 pm, Dave Hansen wrote:
>>>> How have you tested this patch (and the whole series for that matter)?
>>>>
>>> I replaced the second patch with this one and did a build test.
>>> Till v16, I had tested the whole series (build + run) on both a POWER8
>>> system (with 4K and 64K page sizes) and a Skylake SP system but for
>>> x86_64 only.
>>
>> Do you have any idea why I was seeing x86 build errors and you were not?
>>
>
> There were problems with patch 2 from v17. The fixed patch is what I replied
> with previously in this thread. The test results that I posted were with that
> patch included. Will post out v18 today with the fix.
>
In patch 2 of v17, the issue was with the target names. Upon adding something
to TEST_GEN_FILES, rules for targets like the following are expected to be
defined.
<path-to-linux-source>/tools/testing/selftests/vm/protection_keys_32
<path-to-linux-source>/tools/testing/selftests/vm/protection_keys_64
<path-to-linux-source>/tools/testing/selftests/vm/protection_keys
But instead, I only defined rules for these.
protection_keys_32
protection_keys_64
protection_keys
Hence the build was failing in these cases:
$ make -C tools/testing/selftests
$ make -C tools/testing/selftests/vm
$ cd tools/testing/selftests/vm
$ make
But worked in these cases:
$ make -C tools/testing/selftests/vm protection_keys
$ cd tools/testing/selftests/vm
$ make protection_keys
This has been addressed in v18.
- Sandipan
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox