From 54519b4465140f0e98232cc1348d309f95858d9c Mon Sep 17 00:00:00 2001 From: Mikhail Zaslonko Date: Tue, 27 Mar 2018 13:10:17 +0200 Subject: [PATCH] zipl: Update page_is_valid() function to avoid tprot usage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Old implementation was using Test Protection (TPROT) instruction to validate the memory page. Given that it is a rather slow instruction and the fact that we only need to validate the read-access for a page, we can use simple Load or Insert Character instruction to test that. The new version of page_is_valid() without a TPROT is introduced. Signed-off-by: Mikhail Zaslonko Reviewed-by: Heiko Carstens Signed-off-by: Jan Höppner --- zipl/boot/Makefile | 1 + zipl/boot/s390.h | 34 +++++++++++++++------------------- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/zipl/boot/Makefile b/zipl/boot/Makefile index fcf4e942..52b3a230 100644 --- a/zipl/boot/Makefile +++ b/zipl/boot/Makefile @@ -74,6 +74,7 @@ stage3.exec: head.o stage3.o kdump3.o libc.o sclp.o sclp_stage3.o \ --only-section=.rodata \ --only-section=.stage2dump.tail \ --only-section=.eckd2dump_mv.tail \ + --only-section=.fixup \ $< $@ data.o: $(FILES) diff --git a/zipl/boot/s390.h b/zipl/boot/s390.h index acd27098..279d16b8 100644 --- a/zipl/boot/s390.h +++ b/zipl/boot/s390.h @@ -18,6 +18,7 @@ #define __pa(x) ((unsigned long)(x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) #define barrier() __asm__ __volatile__("": : :"memory") +#define inline inline __attribute__((always_inline)) /* * Helper macro for exception table entries @@ -207,29 +208,24 @@ do { \ libc_stop(reason); \ } while (0) -#define CHUNK_READ_WRITE 0 -#define CHUNK_READ_ONLY 1 - -static inline int tprot(unsigned long addr) -{ - int rc = -EFAULT; - - asm volatile( - " tprot 0(%1),0\n" - "0: ipm %0\n" - " srl %0,28\n" - "1:\n" - EX_TABLE(0b, 1b) - : "+d" (rc) : "a" (addr) : "cc"); - return rc; -} - static inline int page_is_valid(unsigned long addr) { + unsigned long tmp; int rc; - rc = tprot(addr); - return (rc == CHUNK_READ_WRITE) || (rc == CHUNK_READ_ONLY); + asm volatile( + "0: ic %1,%2\n" + "1: lhi %0,1\n" + "2:\n" + ".pushsection .fixup, \"ax\"\n" + "3: xr %0,%0\n" + " jg 2b\n" + ".popsection\n" + EX_TABLE(0b, 3b) EX_TABLE(1b, 3b) + : "=d" (rc), "=d" (tmp) + : "Q" (*(unsigned long *) addr) + : "cc"); + return rc; } static inline uint32_t csum_partial(const void *buf, int len, uint32_t sum)