From 9f2e406525f2eef7acaa9a18c596d330f27e6038 Mon Sep 17 00:00:00 2001 From: Mikhail Zaslonko Date: Mon, 9 Apr 2018 10:50:52 +0200 Subject: [PATCH] zipl: Fixing program check handler function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The program check handler has a bug in calculating the address of the target to jump to. Furthermore the use of relative addresses in the exception table can lead to situations where the (calculated) fault is not unique. Storing the absolute address of the fault and target in the exception table solves both problems. This patch is intended to: - Modify exception table to store the absolute address of 'fault' and 'target' points - Adjust program check handler function pgm_check_handler_fn() accordingly Signed-off-by: Mikhail Zaslonko Reviewed-by: Heiko Carstens Signed-off-by: Jan Höppner --- zipl/boot/libc.c | 11 ++++------- zipl/boot/s390.h | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/zipl/boot/libc.c b/zipl/boot/libc.c index 7bff444d..f86f62ac 100644 --- a/zipl/boot/libc.c +++ b/zipl/boot/libc.c @@ -23,8 +23,8 @@ extern char __ex_table_start[]; extern char __ex_table_stop[]; struct ex_table_entry { - int fault; - int target; + unsigned int fault; + unsigned int target; }; #define MEM_ALLOC_START ((unsigned long) __heap_start) @@ -310,16 +310,13 @@ void pgm_check_handler_fn(void) struct ex_table_entry *ex_table = (void *) __ex_table_start; struct psw_t *psw_old = &S390_lowcore.program_old_psw; int i, ex_table_cnt; - unsigned long fault, target; ex_table_cnt = (__ex_table_stop - __ex_table_start) / sizeof(struct ex_table_entry); for (i = 0; i < ex_table_cnt; i++) { - fault = __pa(&ex_table[i]) + ex_table[i].fault; - if (fault == psw_old->addr) { - target = __pa(&ex_table[i]) + ex_table[i].target; - psw_old->addr = target; + if (ex_table[i].fault == psw_old->addr) { + psw_old->addr = ex_table[i].target; return; } } diff --git a/zipl/boot/s390.h b/zipl/boot/s390.h index 86fbebbc..acd27098 100644 --- a/zipl/boot/s390.h +++ b/zipl/boot/s390.h @@ -25,8 +25,8 @@ #define EX_TABLE(_fault, _target) \ ".section .ex_table,\"a\"\n" \ ".align 4\n" \ - ".long (" #_fault ") - .\n" \ - ".long (" #_target ") - .\n" \ + ".long (" #_fault ")\n" \ + ".long (" #_target ")\n" \ ".previous\n" struct psw_t {