diff options
-rw-r--r-- | arch/s390/include/asm/thread_info.h | 2 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 80 | ||||
-rw-r--r-- | arch/s390/kernel/s390_ksyms.c | 4 | ||||
-rw-r--r-- | arch/s390/kvm/Makefile | 2 | ||||
-rw-r--r-- | arch/s390/kvm/sie64a.S | 98 |
5 files changed, 79 insertions, 107 deletions
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h index ad1382f7932e..1a5dbb6f1495 100644 --- a/arch/s390/include/asm/thread_info.h +++ b/arch/s390/include/asm/thread_info.h | |||
@@ -94,6 +94,7 @@ static inline struct thread_info *current_thread_info(void) | |||
94 | #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ | 94 | #define TIF_SYSCALL_AUDIT 9 /* syscall auditing active */ |
95 | #define TIF_SECCOMP 10 /* secure computing */ | 95 | #define TIF_SECCOMP 10 /* secure computing */ |
96 | #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ | 96 | #define TIF_SYSCALL_TRACEPOINT 11 /* syscall tracepoint instrumentation */ |
97 | #define TIF_SIE 12 /* guest execution active */ | ||
97 | #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling | 98 | #define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling |
98 | TIF_NEED_RESCHED */ | 99 | TIF_NEED_RESCHED */ |
99 | #define TIF_31BIT 17 /* 32bit process */ | 100 | #define TIF_31BIT 17 /* 32bit process */ |
@@ -113,6 +114,7 @@ static inline struct thread_info *current_thread_info(void) | |||
113 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | 114 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) |
114 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) | 115 | #define _TIF_SECCOMP (1<<TIF_SECCOMP) |
115 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) | 116 | #define _TIF_SYSCALL_TRACEPOINT (1<<TIF_SYSCALL_TRACEPOINT) |
117 | #define _TIF_SIE (1<<TIF_SIE) | ||
116 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | 118 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) |
117 | #define _TIF_31BIT (1<<TIF_31BIT) | 119 | #define _TIF_31BIT (1<<TIF_31BIT) |
118 | #define _TIF_SINGLE_STEP (1<<TIF_FREEZE) | 120 | #define _TIF_SINGLE_STEP (1<<TIF_FREEZE) |
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index d61967e2eab0..ab596a865300 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -56,15 +56,28 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_NOTIFY_RESUME | _TIF_NEED_RESCHED | \ | |||
56 | _TIF_MCCK_PENDING) | 56 | _TIF_MCCK_PENDING) |
57 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | 57 | _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ |
58 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) | 58 | _TIF_SECCOMP>>8 | _TIF_SYSCALL_TRACEPOINT>>8) |
59 | _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | ||
59 | 60 | ||
60 | #define BASED(name) name-system_call(%r13) | 61 | #define BASED(name) name-system_call(%r13) |
61 | 62 | ||
63 | .macro SPP newpp | ||
64 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||
65 | tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP | ||
66 | jz .+8 | ||
67 | .insn s,0xb2800000,\newpp | ||
68 | #endif | ||
69 | .endm | ||
70 | |||
62 | .macro HANDLE_SIE_INTERCEPT | 71 | .macro HANDLE_SIE_INTERCEPT |
63 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | 72 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) |
64 | lg %r3,__LC_SIE_HOOK | 73 | tm __TI_flags+6(%r12),_TIF_SIE>>8 |
65 | ltgr %r3,%r3 | ||
66 | jz 0f | 74 | jz 0f |
67 | basr %r14,%r3 | 75 | SPP __LC_CMF_HPP # set host id |
76 | clc SP_PSW+8(8,%r15),BASED(.Lsie_loop) | ||
77 | jl 0f | ||
78 | clc SP_PSW+8(8,%r15),BASED(.Lsie_done) | ||
79 | jhe 0f | ||
80 | mvc SP_PSW+8(8,%r15),BASED(.Lsie_loop) | ||
68 | 0: | 81 | 0: |
69 | #endif | 82 | #endif |
70 | .endm | 83 | .endm |
@@ -465,6 +478,7 @@ pgm_check_handler: | |||
465 | xc SP_ILC(4,%r15),SP_ILC(%r15) | 478 | xc SP_ILC(4,%r15),SP_ILC(%r15) |
466 | mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW | 479 | mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW |
467 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 480 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct |
481 | HANDLE_SIE_INTERCEPT | ||
468 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 482 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
469 | jz pgm_no_vtime | 483 | jz pgm_no_vtime |
470 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 484 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
@@ -472,7 +486,6 @@ pgm_check_handler: | |||
472 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 486 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
473 | LAST_BREAK | 487 | LAST_BREAK |
474 | pgm_no_vtime: | 488 | pgm_no_vtime: |
475 | HANDLE_SIE_INTERCEPT | ||
476 | stg %r11,SP_ARGS(%r15) | 489 | stg %r11,SP_ARGS(%r15) |
477 | lgf %r3,__LC_PGM_ILC # load program interruption code | 490 | lgf %r3,__LC_PGM_ILC # load program interruption code |
478 | lg %r4,__LC_TRANS_EXC_CODE | 491 | lg %r4,__LC_TRANS_EXC_CODE |
@@ -507,6 +520,7 @@ pgm_per_std: | |||
507 | CREATE_STACK_FRAME __LC_SAVE_AREA | 520 | CREATE_STACK_FRAME __LC_SAVE_AREA |
508 | mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW | 521 | mvc SP_PSW(16,%r15),__LC_PGM_OLD_PSW |
509 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 522 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct |
523 | HANDLE_SIE_INTERCEPT | ||
510 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 524 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
511 | jz pgm_no_vtime2 | 525 | jz pgm_no_vtime2 |
512 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER | 526 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_SYNC_ENTER_TIMER,__LC_USER_TIMER |
@@ -514,7 +528,6 @@ pgm_per_std: | |||
514 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 528 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
515 | LAST_BREAK | 529 | LAST_BREAK |
516 | pgm_no_vtime2: | 530 | pgm_no_vtime2: |
517 | HANDLE_SIE_INTERCEPT | ||
518 | lg %r1,__TI_task(%r12) | 531 | lg %r1,__TI_task(%r12) |
519 | tm SP_PSW+1(%r15),0x01 # kernel per event ? | 532 | tm SP_PSW+1(%r15),0x01 # kernel per event ? |
520 | jz kernel_per | 533 | jz kernel_per |
@@ -579,6 +592,7 @@ io_int_handler: | |||
579 | CREATE_STACK_FRAME __LC_SAVE_AREA+40 | 592 | CREATE_STACK_FRAME __LC_SAVE_AREA+40 |
580 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack | 593 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack |
581 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 594 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct |
595 | HANDLE_SIE_INTERCEPT | ||
582 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 596 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
583 | jz io_no_vtime | 597 | jz io_no_vtime |
584 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 598 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
@@ -586,7 +600,6 @@ io_int_handler: | |||
586 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 600 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
587 | LAST_BREAK | 601 | LAST_BREAK |
588 | io_no_vtime: | 602 | io_no_vtime: |
589 | HANDLE_SIE_INTERCEPT | ||
590 | TRACE_IRQS_OFF | 603 | TRACE_IRQS_OFF |
591 | la %r2,SP_PTREGS(%r15) # address of register-save area | 604 | la %r2,SP_PTREGS(%r15) # address of register-save area |
592 | brasl %r14,do_IRQ # call standard irq handler | 605 | brasl %r14,do_IRQ # call standard irq handler |
@@ -714,6 +727,7 @@ ext_int_handler: | |||
714 | CREATE_STACK_FRAME __LC_SAVE_AREA+40 | 727 | CREATE_STACK_FRAME __LC_SAVE_AREA+40 |
715 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack | 728 | mvc SP_PSW(16,%r15),0(%r12) # move user PSW to stack |
716 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 729 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct |
730 | HANDLE_SIE_INTERCEPT | ||
717 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 731 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
718 | jz ext_no_vtime | 732 | jz ext_no_vtime |
719 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER | 733 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER |
@@ -721,7 +735,6 @@ ext_int_handler: | |||
721 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 735 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
722 | LAST_BREAK | 736 | LAST_BREAK |
723 | ext_no_vtime: | 737 | ext_no_vtime: |
724 | HANDLE_SIE_INTERCEPT | ||
725 | TRACE_IRQS_OFF | 738 | TRACE_IRQS_OFF |
726 | lghi %r1,4096 | 739 | lghi %r1,4096 |
727 | la %r2,SP_PTREGS(%r15) # address of register-save area | 740 | la %r2,SP_PTREGS(%r15) # address of register-save area |
@@ -785,6 +798,7 @@ mcck_int_main: | |||
785 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct | 798 | lg %r12,__LC_THREAD_INFO # load pointer to thread_info struct |
786 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? | 799 | tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? |
787 | jno mcck_no_vtime # no -> no timer update | 800 | jno mcck_no_vtime # no -> no timer update |
801 | HANDLE_SIE_INTERCEPT | ||
788 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? | 802 | tm SP_PSW+1(%r15),0x01 # interrupting from user ? |
789 | jz mcck_no_vtime | 803 | jz mcck_no_vtime |
790 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER | 804 | UPDATE_VTIME __LC_EXIT_TIMER,__LC_MCCK_ENTER_TIMER,__LC_USER_TIMER |
@@ -804,7 +818,6 @@ mcck_no_vtime: | |||
804 | stosm __SF_EMPTY(%r15),0x04 # turn dat on | 818 | stosm __SF_EMPTY(%r15),0x04 # turn dat on |
805 | tm __TI_flags+7(%r12),_TIF_MCCK_PENDING | 819 | tm __TI_flags+7(%r12),_TIF_MCCK_PENDING |
806 | jno mcck_return | 820 | jno mcck_return |
807 | HANDLE_SIE_INTERCEPT | ||
808 | TRACE_IRQS_OFF | 821 | TRACE_IRQS_OFF |
809 | brasl %r14,s390_handle_mcck | 822 | brasl %r14,s390_handle_mcck |
810 | TRACE_IRQS_ON | 823 | TRACE_IRQS_ON |
@@ -1036,6 +1049,57 @@ cleanup_io_restore_insn: | |||
1036 | .Lcritical_end: | 1049 | .Lcritical_end: |
1037 | .quad __critical_end | 1050 | .quad __critical_end |
1038 | 1051 | ||
1052 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||
1053 | /* | ||
1054 | * sie64a calling convention: | ||
1055 | * %r2 pointer to sie control block | ||
1056 | * %r3 guest register save area | ||
1057 | */ | ||
1058 | .globl sie64a | ||
1059 | sie64a: | ||
1060 | stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers | ||
1061 | stg %r2,__SF_EMPTY(%r15) # save control block pointer | ||
1062 | stg %r3,__SF_EMPTY+8(%r15) # save guest register save area | ||
1063 | lmg %r0,%r13,0(%r3) # load guest gprs 0-13 | ||
1064 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | ||
1065 | oi __TI_flags+6(%r14),_TIF_SIE>>8 | ||
1066 | sie_loop: | ||
1067 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | ||
1068 | tm __TI_flags+7(%r14),_TIF_EXIT_SIE | ||
1069 | jnz sie_exit | ||
1070 | lg %r14,__SF_EMPTY(%r15) # get control block pointer | ||
1071 | SPP __SF_EMPTY(%r15) # set guest id | ||
1072 | sie 0(%r14) | ||
1073 | sie_done: | ||
1074 | SPP __LC_CMF_HPP # set host id | ||
1075 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | ||
1076 | sie_exit: | ||
1077 | ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) | ||
1078 | lg %r14,__SF_EMPTY+8(%r15) # load guest register save area | ||
1079 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | ||
1080 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers | ||
1081 | lghi %r2,0 | ||
1082 | br %r14 | ||
1083 | sie_fault: | ||
1084 | lg %r14,__LC_THREAD_INFO # pointer thread_info struct | ||
1085 | ni __TI_flags+6(%r14),255-(_TIF_SIE>>8) | ||
1086 | lg %r14,__SF_EMPTY+8(%r15) # load guest register save area | ||
1087 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | ||
1088 | lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers | ||
1089 | lghi %r2,-EFAULT | ||
1090 | br %r14 | ||
1091 | |||
1092 | .align 8 | ||
1093 | .Lsie_loop: | ||
1094 | .quad sie_loop | ||
1095 | .Lsie_done: | ||
1096 | .quad sie_done | ||
1097 | |||
1098 | .section __ex_table,"a" | ||
1099 | .quad sie_loop,sie_fault | ||
1100 | .previous | ||
1101 | #endif | ||
1102 | |||
1039 | .section .rodata, "a" | 1103 | .section .rodata, "a" |
1040 | #define SYSCALL(esa,esame,emu) .long esame | 1104 | #define SYSCALL(esa,esame,emu) .long esame |
1041 | .globl sys_call_table | 1105 | .globl sys_call_table |
diff --git a/arch/s390/kernel/s390_ksyms.c b/arch/s390/kernel/s390_ksyms.c index 656fcbb9bd83..57b536649b00 100644 --- a/arch/s390/kernel/s390_ksyms.c +++ b/arch/s390/kernel/s390_ksyms.c | |||
@@ -1,6 +1,10 @@ | |||
1 | #include <linux/module.h> | 1 | #include <linux/module.h> |
2 | #include <linux/kvm_host.h> | ||
2 | #include <asm/ftrace.h> | 3 | #include <asm/ftrace.h> |
3 | 4 | ||
4 | #ifdef CONFIG_FUNCTION_TRACER | 5 | #ifdef CONFIG_FUNCTION_TRACER |
5 | EXPORT_SYMBOL(_mcount); | 6 | EXPORT_SYMBOL(_mcount); |
6 | #endif | 7 | #endif |
8 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||
9 | EXPORT_SYMBOL(sie64a); | ||
10 | #endif | ||
diff --git a/arch/s390/kvm/Makefile b/arch/s390/kvm/Makefile index 860d26514c08..3975722bb19d 100644 --- a/arch/s390/kvm/Makefile +++ b/arch/s390/kvm/Makefile | |||
@@ -10,5 +10,5 @@ common-objs = $(addprefix ../../../virt/kvm/, kvm_main.o) | |||
10 | 10 | ||
11 | ccflags-y := -Ivirt/kvm -Iarch/s390/kvm | 11 | ccflags-y := -Ivirt/kvm -Iarch/s390/kvm |
12 | 12 | ||
13 | kvm-objs := $(common-objs) kvm-s390.o sie64a.o intercept.o interrupt.o priv.o sigp.o diag.o | 13 | kvm-objs := $(common-objs) kvm-s390.o intercept.o interrupt.o priv.o sigp.o diag.o |
14 | obj-$(CONFIG_KVM) += kvm.o | 14 | obj-$(CONFIG_KVM) += kvm.o |
diff --git a/arch/s390/kvm/sie64a.S b/arch/s390/kvm/sie64a.S deleted file mode 100644 index 5faa1b1b23fa..000000000000 --- a/arch/s390/kvm/sie64a.S +++ /dev/null | |||
@@ -1,98 +0,0 @@ | |||
1 | /* | ||
2 | * sie64a.S - low level sie call | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008,2010 | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
11 | * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> | ||
12 | */ | ||
13 | |||
14 | #include <linux/errno.h> | ||
15 | #include <asm/asm-offsets.h> | ||
16 | #include <asm/setup.h> | ||
17 | #include <asm/asm-offsets.h> | ||
18 | #include <asm/ptrace.h> | ||
19 | #include <asm/thread_info.h> | ||
20 | |||
21 | _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | ||
22 | |||
23 | /* | ||
24 | * offsets into stackframe | ||
25 | * SP_ = offsets into stack sie64 is called with | ||
26 | * SPI_ = offsets into irq stack | ||
27 | */ | ||
28 | SP_GREGS = __SF_EMPTY | ||
29 | SP_HOOK = __SF_EMPTY+8 | ||
30 | SP_GPP = __SF_EMPTY+16 | ||
31 | SPI_PSW = STACK_FRAME_OVERHEAD + __PT_PSW | ||
32 | |||
33 | |||
34 | .macro SPP newpp | ||
35 | tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP | ||
36 | jz 0f | ||
37 | .insn s,0xb2800000,\newpp | ||
38 | 0: | ||
39 | .endm | ||
40 | |||
41 | sie_irq_handler: | ||
42 | SPP __LC_CMF_HPP # set host id | ||
43 | larl %r2,sie_inst | ||
44 | clg %r2,SPI_PSW+8(0,%r15) # intercepted sie | ||
45 | jne 1f | ||
46 | xc __LC_SIE_HOOK(8),__LC_SIE_HOOK | ||
47 | lg %r2,__LC_THREAD_INFO # pointer thread_info struct | ||
48 | tm __TI_flags+7(%r2),_TIF_EXIT_SIE | ||
49 | jz 0f | ||
50 | larl %r2,sie_exit # work pending, leave sie | ||
51 | stg %r2,SPI_PSW+8(0,%r15) | ||
52 | br %r14 | ||
53 | 0: larl %r2,sie_reenter # re-enter with guest id | ||
54 | stg %r2,SPI_PSW+8(0,%r15) | ||
55 | 1: br %r14 | ||
56 | |||
57 | /* | ||
58 | * sie64a calling convention: | ||
59 | * %r2 pointer to sie control block | ||
60 | * %r3 guest register save area | ||
61 | */ | ||
62 | .globl sie64a | ||
63 | sie64a: | ||
64 | stg %r3,SP_GREGS(%r15) # save guest register save area | ||
65 | stmg %r6,%r14,__SF_GPRS(%r15) # save registers on entry | ||
66 | lgr %r14,%r2 # pointer to sie control block | ||
67 | larl %r5,sie_irq_handler | ||
68 | stg %r2,SP_GPP(%r15) | ||
69 | stg %r5,SP_HOOK(%r15) # save hook target | ||
70 | lmg %r0,%r13,0(%r3) # load guest gprs 0-13 | ||
71 | sie_reenter: | ||
72 | mvc __LC_SIE_HOOK(8),SP_HOOK(%r15) | ||
73 | SPP SP_GPP(%r15) # set guest id | ||
74 | sie_inst: | ||
75 | sie 0(%r14) | ||
76 | xc __LC_SIE_HOOK(8),__LC_SIE_HOOK | ||
77 | SPP __LC_CMF_HPP # set host id | ||
78 | sie_exit: | ||
79 | lg %r14,SP_GREGS(%r15) | ||
80 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | ||
81 | lghi %r2,0 | ||
82 | lmg %r6,%r14,__SF_GPRS(%r15) | ||
83 | br %r14 | ||
84 | |||
85 | sie_err: | ||
86 | xc __LC_SIE_HOOK(8),__LC_SIE_HOOK | ||
87 | SPP __LC_CMF_HPP # set host id | ||
88 | lg %r14,SP_GREGS(%r15) | ||
89 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | ||
90 | lghi %r2,-EFAULT | ||
91 | lmg %r6,%r14,__SF_GPRS(%r15) | ||
92 | br %r14 | ||
93 | |||
94 | .section __ex_table,"a" | ||
95 | .quad sie_inst,sie_err | ||
96 | .quad sie_exit,sie_err | ||
97 | .quad sie_reenter,sie_err | ||
98 | .previous | ||