mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zipl: Fixing program check handler function
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 <zaslonko@linux.vnet.ibm.com>
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
edaad2a927
commit
9f2e406525
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user