diff options
author | Carsten Otte <cotte@de.ibm.com> | 2010-05-17 04:00:04 -0400 |
---|---|---|
committer | Martin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com> | 2010-05-17 04:00:15 -0400 |
commit | cd3b70f5d4d82f85d1e1d6e822f38ae098cf7c72 (patch) | |
tree | aa394e63d300312bece2afb53a53dfd93a0f5f23 /arch/s390 | |
parent | 6377981faf1a4425b0531e577736ef03df97c8f6 (diff) |
[S390] virtualization aware cpu measurement
Use the SPP instruction to set a tag on entry to / exit of the virtual
machine context. This allows the cpu measurement facility to distinguish
the samples from the host and the different guests.
Signed-off-by: Carsten Otte <cotte@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r-- | arch/s390/include/asm/lowcore.h | 3 | ||||
-rw-r--r-- | arch/s390/include/asm/setup.h | 5 | ||||
-rw-r--r-- | arch/s390/kernel/asm-offsets.c | 2 | ||||
-rw-r--r-- | arch/s390/kernel/early.c | 4 | ||||
-rw-r--r-- | arch/s390/kernel/entry64.S | 26 | ||||
-rw-r--r-- | arch/s390/kernel/setup.c | 3 | ||||
-rw-r--r-- | arch/s390/kvm/Kconfig | 11 | ||||
-rw-r--r-- | arch/s390/kvm/sie64a.S | 77 |
8 files changed, 105 insertions, 26 deletions
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h index 2c02d46c3588..0f97ef2d92ac 100644 --- a/arch/s390/include/asm/lowcore.h +++ b/arch/s390/include/asm/lowcore.h | |||
@@ -267,7 +267,8 @@ struct _lowcore { | |||
267 | __u64 vdso_per_cpu_data; /* 0x0358 */ | 267 | __u64 vdso_per_cpu_data; /* 0x0358 */ |
268 | __u64 machine_flags; /* 0x0360 */ | 268 | __u64 machine_flags; /* 0x0360 */ |
269 | __u64 ftrace_func; /* 0x0368 */ | 269 | __u64 ftrace_func; /* 0x0368 */ |
270 | __u8 pad_0x0370[0x0380-0x0370]; /* 0x0370 */ | 270 | __u64 sie_hook; /* 0x0370 */ |
271 | __u64 cmf_hpp; /* 0x0378 */ | ||
271 | 272 | ||
272 | /* Interrupt response block. */ | 273 | /* Interrupt response block. */ |
273 | __u8 irb[64]; /* 0x0380 */ | 274 | __u8 irb[64]; /* 0x0380 */ |
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h index 9ab6bd3a65d1..25e831d58e1e 100644 --- a/arch/s390/include/asm/setup.h +++ b/arch/s390/include/asm/setup.h | |||
@@ -2,7 +2,7 @@ | |||
2 | * include/asm-s390/setup.h | 2 | * include/asm-s390/setup.h |
3 | * | 3 | * |
4 | * S390 version | 4 | * S390 version |
5 | * Copyright IBM Corp. 1999,2006 | 5 | * Copyright IBM Corp. 1999,2010 |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #ifndef _ASM_S390_SETUP_H | 8 | #ifndef _ASM_S390_SETUP_H |
@@ -72,6 +72,7 @@ extern unsigned int user_mode; | |||
72 | #define MACHINE_FLAG_HPAGE (1UL << 10) | 72 | #define MACHINE_FLAG_HPAGE (1UL << 10) |
73 | #define MACHINE_FLAG_PFMF (1UL << 11) | 73 | #define MACHINE_FLAG_PFMF (1UL << 11) |
74 | #define MACHINE_FLAG_LPAR (1UL << 12) | 74 | #define MACHINE_FLAG_LPAR (1UL << 12) |
75 | #define MACHINE_FLAG_SPP (1UL << 13) | ||
75 | 76 | ||
76 | #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) | 77 | #define MACHINE_IS_VM (S390_lowcore.machine_flags & MACHINE_FLAG_VM) |
77 | #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) | 78 | #define MACHINE_IS_KVM (S390_lowcore.machine_flags & MACHINE_FLAG_KVM) |
@@ -88,6 +89,7 @@ extern unsigned int user_mode; | |||
88 | #define MACHINE_HAS_MVCOS (0) | 89 | #define MACHINE_HAS_MVCOS (0) |
89 | #define MACHINE_HAS_HPAGE (0) | 90 | #define MACHINE_HAS_HPAGE (0) |
90 | #define MACHINE_HAS_PFMF (0) | 91 | #define MACHINE_HAS_PFMF (0) |
92 | #define MACHINE_HAS_SPP (0) | ||
91 | #else /* __s390x__ */ | 93 | #else /* __s390x__ */ |
92 | #define MACHINE_HAS_IEEE (1) | 94 | #define MACHINE_HAS_IEEE (1) |
93 | #define MACHINE_HAS_CSP (1) | 95 | #define MACHINE_HAS_CSP (1) |
@@ -97,6 +99,7 @@ extern unsigned int user_mode; | |||
97 | #define MACHINE_HAS_MVCOS (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS) | 99 | #define MACHINE_HAS_MVCOS (S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS) |
98 | #define MACHINE_HAS_HPAGE (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE) | 100 | #define MACHINE_HAS_HPAGE (S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE) |
99 | #define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) | 101 | #define MACHINE_HAS_PFMF (S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) |
102 | #define MACHINE_HAS_SPP (S390_lowcore.machine_flags & MACHINE_FLAG_SPP) | ||
100 | #endif /* __s390x__ */ | 103 | #endif /* __s390x__ */ |
101 | 104 | ||
102 | #define ZFCPDUMP_HSA_SIZE (32UL<<20) | 105 | #define ZFCPDUMP_HSA_SIZE (32UL<<20) |
diff --git a/arch/s390/kernel/asm-offsets.c b/arch/s390/kernel/asm-offsets.c index 816d81f479c0..44a4336d9a33 100644 --- a/arch/s390/kernel/asm-offsets.c +++ b/arch/s390/kernel/asm-offsets.c | |||
@@ -131,6 +131,8 @@ int main(void) | |||
131 | DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); | 131 | DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); |
132 | DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); | 132 | DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); |
133 | DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func)); | 133 | DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func)); |
134 | DEFINE(__LC_SIE_HOOK, offsetof(struct _lowcore, sie_hook)); | ||
135 | DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp)); | ||
134 | DEFINE(__LC_IRB, offsetof(struct _lowcore, irb)); | 136 | DEFINE(__LC_IRB, offsetof(struct _lowcore, irb)); |
135 | DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area)); | 137 | DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area)); |
136 | DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area)); | 138 | DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area)); |
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c index 2d92c2cf92d7..c00856ad4e5a 100644 --- a/arch/s390/kernel/early.c +++ b/arch/s390/kernel/early.c | |||
@@ -356,6 +356,7 @@ static __init void detect_machine_facilities(void) | |||
356 | { | 356 | { |
357 | #ifdef CONFIG_64BIT | 357 | #ifdef CONFIG_64BIT |
358 | unsigned int facilities; | 358 | unsigned int facilities; |
359 | unsigned long long facility_bits; | ||
359 | 360 | ||
360 | facilities = stfl(); | 361 | facilities = stfl(); |
361 | if (facilities & (1 << 28)) | 362 | if (facilities & (1 << 28)) |
@@ -364,6 +365,9 @@ static __init void detect_machine_facilities(void) | |||
364 | S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; | 365 | S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; |
365 | if (facilities & (1 << 4)) | 366 | if (facilities & (1 << 4)) |
366 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; | 367 | S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; |
368 | if ((stfle(&facility_bits, 1) > 0) && | ||
369 | (facility_bits & (1ULL << (63 - 40)))) | ||
370 | S390_lowcore.machine_flags |= MACHINE_FLAG_SPP; | ||
367 | #endif | 371 | #endif |
368 | } | 372 | } |
369 | 373 | ||
diff --git a/arch/s390/kernel/entry64.S b/arch/s390/kernel/entry64.S index 6536f5ca46f5..829b759ba1e1 100644 --- a/arch/s390/kernel/entry64.S +++ b/arch/s390/kernel/entry64.S | |||
@@ -2,7 +2,7 @@ | |||
2 | * arch/s390/kernel/entry64.S | 2 | * arch/s390/kernel/entry64.S |
3 | * S390 low-level entry points. | 3 | * S390 low-level entry points. |
4 | * | 4 | * |
5 | * Copyright (C) IBM Corp. 1999,2006 | 5 | * Copyright (C) IBM Corp. 1999,2010 |
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | 6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), |
7 | * Hartmut Penner (hp@de.ibm.com), | 7 | * Hartmut Penner (hp@de.ibm.com), |
8 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), | 8 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), |
@@ -59,6 +59,16 @@ _TIF_SYSCALL = (_TIF_SYSCALL_TRACE>>8 | _TIF_SYSCALL_AUDIT>>8 | \ | |||
59 | 59 | ||
60 | #define BASED(name) name-system_call(%r13) | 60 | #define BASED(name) name-system_call(%r13) |
61 | 61 | ||
62 | .macro HANDLE_SIE_INTERCEPT | ||
63 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||
64 | lg %r3,__LC_SIE_HOOK | ||
65 | ltgr %r3,%r3 | ||
66 | jz 0f | ||
67 | basr %r14,%r3 | ||
68 | 0: | ||
69 | #endif | ||
70 | .endm | ||
71 | |||
62 | #ifdef CONFIG_TRACE_IRQFLAGS | 72 | #ifdef CONFIG_TRACE_IRQFLAGS |
63 | .macro TRACE_IRQS_ON | 73 | .macro TRACE_IRQS_ON |
64 | basr %r2,%r0 | 74 | basr %r2,%r0 |
@@ -466,6 +476,7 @@ pgm_check_handler: | |||
466 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 476 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
467 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 477 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
468 | pgm_no_vtime: | 478 | pgm_no_vtime: |
479 | HANDLE_SIE_INTERCEPT | ||
469 | TRACE_IRQS_CHECK_OFF | 480 | TRACE_IRQS_CHECK_OFF |
470 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 481 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
471 | mvc SP_ARGS(8,%r15),__LC_LAST_BREAK | 482 | mvc SP_ARGS(8,%r15),__LC_LAST_BREAK |
@@ -507,6 +518,7 @@ pgm_per_std: | |||
507 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | 518 | UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER |
508 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | 519 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER |
509 | pgm_no_vtime2: | 520 | pgm_no_vtime2: |
521 | HANDLE_SIE_INTERCEPT | ||
510 | TRACE_IRQS_CHECK_OFF | 522 | TRACE_IRQS_CHECK_OFF |
511 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 523 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
512 | lg %r1,__TI_task(%r9) | 524 | lg %r1,__TI_task(%r9) |
@@ -570,6 +582,7 @@ io_int_handler: | |||
570 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 582 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
571 | io_no_vtime: | 583 | io_no_vtime: |
572 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 584 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
585 | HANDLE_SIE_INTERCEPT | ||
573 | TRACE_IRQS_OFF | 586 | TRACE_IRQS_OFF |
574 | la %r2,SP_PTREGS(%r15) # address of register-save area | 587 | la %r2,SP_PTREGS(%r15) # address of register-save area |
575 | brasl %r14,do_IRQ # call standard irq handler | 588 | brasl %r14,do_IRQ # call standard irq handler |
@@ -595,15 +608,6 @@ io_done: | |||
595 | io_work: | 608 | io_work: |
596 | tm SP_PSW+1(%r15),0x01 # returning to user ? | 609 | tm SP_PSW+1(%r15),0x01 # returning to user ? |
597 | jo io_work_user # yes -> do resched & signal | 610 | jo io_work_user # yes -> do resched & signal |
598 | #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||
599 | lg %r2,SP_PSW+8(%r15) # check if current instruction is SIE | ||
600 | lh %r1,0(%r2) | ||
601 | chi %r1,-19948 # signed 16 bit compare with 0xb214 | ||
602 | jne 0f # no -> leave PSW alone | ||
603 | aghi %r2,4 # yes-> add 4 bytes to leave SIE | ||
604 | stg %r2,SP_PSW+8(%r15) | ||
605 | 0: | ||
606 | #endif | ||
607 | #ifdef CONFIG_PREEMPT | 611 | #ifdef CONFIG_PREEMPT |
608 | # check for preemptive scheduling | 612 | # check for preemptive scheduling |
609 | icm %r0,15,__TI_precount(%r9) | 613 | icm %r0,15,__TI_precount(%r9) |
@@ -712,6 +716,7 @@ ext_int_handler: | |||
712 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | 716 | mvc __LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER |
713 | ext_no_vtime: | 717 | ext_no_vtime: |
714 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct | 718 | lg %r9,__LC_THREAD_INFO # load pointer to thread_info struct |
719 | HANDLE_SIE_INTERCEPT | ||
715 | TRACE_IRQS_OFF | 720 | TRACE_IRQS_OFF |
716 | la %r2,SP_PTREGS(%r15) # address of register-save area | 721 | la %r2,SP_PTREGS(%r15) # address of register-save area |
717 | llgh %r3,__LC_EXT_INT_CODE # get interruption code | 722 | llgh %r3,__LC_EXT_INT_CODE # get interruption code |
@@ -786,6 +791,7 @@ mcck_no_vtime: | |||
786 | stosm __SF_EMPTY(%r15),0x04 # turn dat on | 791 | stosm __SF_EMPTY(%r15),0x04 # turn dat on |
787 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING | 792 | tm __TI_flags+7(%r9),_TIF_MCCK_PENDING |
788 | jno mcck_return | 793 | jno mcck_return |
794 | HANDLE_SIE_INTERCEPT | ||
789 | TRACE_IRQS_OFF | 795 | TRACE_IRQS_OFF |
790 | brasl %r14,s390_handle_mcck | 796 | brasl %r14,s390_handle_mcck |
791 | TRACE_IRQS_ON | 797 | TRACE_IRQS_ON |
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c index 598752499c3e..7d893248d265 100644 --- a/arch/s390/kernel/setup.c +++ b/arch/s390/kernel/setup.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * arch/s390/kernel/setup.c | 2 | * arch/s390/kernel/setup.c |
3 | * | 3 | * |
4 | * S390 version | 4 | * S390 version |
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | 5 | * Copyright (C) IBM Corp. 1999,2010 |
6 | * Author(s): Hartmut Penner (hp@de.ibm.com), | 6 | * Author(s): Hartmut Penner (hp@de.ibm.com), |
7 | * Martin Schwidefsky (schwidefsky@de.ibm.com) | 7 | * Martin Schwidefsky (schwidefsky@de.ibm.com) |
8 | * | 8 | * |
@@ -401,6 +401,7 @@ setup_lowcore(void) | |||
401 | lc->io_new_psw.mask = psw_kernel_bits; | 401 | lc->io_new_psw.mask = psw_kernel_bits; |
402 | lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; | 402 | lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; |
403 | lc->clock_comparator = -1ULL; | 403 | lc->clock_comparator = -1ULL; |
404 | lc->cmf_hpp = -1ULL; | ||
404 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; | 405 | lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; |
405 | lc->async_stack = (unsigned long) | 406 | lc->async_stack = (unsigned long) |
406 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; | 407 | __alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; |
diff --git a/arch/s390/kvm/Kconfig b/arch/s390/kvm/Kconfig index a7251580891c..2f4b687cc7fa 100644 --- a/arch/s390/kvm/Kconfig +++ b/arch/s390/kvm/Kconfig | |||
@@ -33,6 +33,17 @@ config KVM | |||
33 | 33 | ||
34 | If unsure, say N. | 34 | If unsure, say N. |
35 | 35 | ||
36 | config KVM_AWARE_CMF | ||
37 | depends on KVM | ||
38 | bool "KVM aware sampling" | ||
39 | ---help--- | ||
40 | This option enhances the sampling data from the CPU Measurement | ||
41 | Facility with additional information, that allows to distinguish | ||
42 | guest(s) and host when using the kernel based virtual machine | ||
43 | functionality. | ||
44 | |||
45 | If unsure, say N. | ||
46 | |||
36 | # OK, it's a little counter-intuitive to do this, but it puts it neatly under | 47 | # OK, it's a little counter-intuitive to do this, but it puts it neatly under |
37 | # the virtualization menu. | 48 | # the virtualization menu. |
38 | source drivers/vhost/Kconfig | 49 | source drivers/vhost/Kconfig |
diff --git a/arch/s390/kvm/sie64a.S b/arch/s390/kvm/sie64a.S index 934fd6a885f6..31646bd0e469 100644 --- a/arch/s390/kvm/sie64a.S +++ b/arch/s390/kvm/sie64a.S | |||
@@ -1,20 +1,60 @@ | |||
1 | /* | 1 | /* |
2 | * sie64a.S - low level sie call | 2 | * sie64a.S - low level sie call |
3 | * | 3 | * |
4 | * Copyright IBM Corp. 2008 | 4 | * Copyright IBM Corp. 2008,2010 |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 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) | 7 | * it under the terms of the GNU General Public License (version 2 only) |
8 | * as published by the Free Software Foundation. | 8 | * as published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | 10 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> |
11 | * Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com> | ||
11 | */ | 12 | */ |
12 | 13 | ||
13 | #include <linux/errno.h> | 14 | #include <linux/errno.h> |
14 | #include <asm/asm-offsets.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 | |||
15 | 33 | ||
16 | SP_R5 = 5 * 8 # offset into stackframe | 34 | .macro SPP newpp |
17 | SP_R6 = 6 * 8 | 35 | #ifdef CONFIG_KVM_AWARE_CMF |
36 | tm __LC_MACHINE_FLAGS+6,0x20 # MACHINE_FLAG_SPP | ||
37 | jz 0f | ||
38 | .insn s,0xb2800000,\newpp | ||
39 | 0: | ||
40 | #endif | ||
41 | .endm | ||
42 | |||
43 | sie_irq_handler: | ||
44 | SPP __LC_CMF_HPP # set host id | ||
45 | larl %r2,sie_inst | ||
46 | clg %r2,SPI_PSW+8(0,%r15) # intercepted sie | ||
47 | jne 1f | ||
48 | xc __LC_SIE_HOOK(8),__LC_SIE_HOOK | ||
49 | lg %r2,__LC_THREAD_INFO # pointer thread_info struct | ||
50 | tm __TI_flags+7(%r2),_TIF_EXIT_SIE | ||
51 | jz 0f | ||
52 | larl %r2,sie_exit # work pending, leave sie | ||
53 | stg %r2,__LC_RETURN_PSW+8 | ||
54 | br %r14 | ||
55 | 0: larl %r2,sie_reenter # re-enter with guest id | ||
56 | stg %r2,__LC_RETURN_PSW+8 | ||
57 | 1: br %r14 | ||
18 | 58 | ||
19 | /* | 59 | /* |
20 | * sie64a calling convention: | 60 | * sie64a calling convention: |
@@ -23,23 +63,34 @@ SP_R6 = 6 * 8 | |||
23 | */ | 63 | */ |
24 | .globl sie64a | 64 | .globl sie64a |
25 | sie64a: | 65 | sie64a: |
26 | lgr %r5,%r3 | 66 | stg %r3,SP_GREGS(%r15) # save guest register save area |
27 | stmg %r5,%r14,SP_R5(%r15) # save register on entry | 67 | stmg %r6,%r14,__SF_GPRS(%r15) # save registers on entry |
28 | lgr %r14,%r2 # pointer to sie control block | 68 | lgr %r14,%r2 # pointer to sie control block |
29 | lmg %r0,%r13,0(%r3) # load guest gprs 0-13 | 69 | larl %r5,sie_irq_handler |
70 | stg %r2,SP_GPP(%r15) | ||
71 | stg %r5,SP_HOOK(%r15) # save hook target | ||
72 | lmg %r0,%r13,0(%r3) # load guest gprs 0-13 | ||
73 | sie_reenter: | ||
74 | mvc __LC_SIE_HOOK(8),SP_HOOK(%r15) | ||
75 | SPP SP_GPP(%r15) # set guest id | ||
30 | sie_inst: | 76 | sie_inst: |
31 | sie 0(%r14) | 77 | sie 0(%r14) |
32 | lg %r14,SP_R5(%r15) | 78 | xc __LC_SIE_HOOK(8),__LC_SIE_HOOK |
33 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | 79 | SPP __LC_CMF_HPP # set host id |
80 | sie_exit: | ||
81 | lg %r14,SP_GREGS(%r15) | ||
82 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | ||
34 | lghi %r2,0 | 83 | lghi %r2,0 |
35 | lmg %r6,%r14,SP_R6(%r15) | 84 | lmg %r6,%r14,__SF_GPRS(%r15) |
36 | br %r14 | 85 | br %r14 |
37 | 86 | ||
38 | sie_err: | 87 | sie_err: |
39 | lg %r14,SP_R5(%r15) | 88 | xc __LC_SIE_HOOK(8),__LC_SIE_HOOK |
40 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | 89 | SPP __LC_CMF_HPP # set host id |
90 | lg %r14,SP_GREGS(%r15) | ||
91 | stmg %r0,%r13,0(%r14) # save guest gprs 0-13 | ||
41 | lghi %r2,-EFAULT | 92 | lghi %r2,-EFAULT |
42 | lmg %r6,%r14,SP_R6(%r15) | 93 | lmg %r6,%r14,__SF_GPRS(%r15) |
43 | br %r14 | 94 | br %r14 |
44 | 95 | ||
45 | .section __ex_table,"a" | 96 | .section __ex_table,"a" |