aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/lowcore.h3
-rw-r--r--arch/s390/include/asm/setup.h5
-rw-r--r--arch/s390/kernel/asm-offsets.c2
-rw-r--r--arch/s390/kernel/early.c4
-rw-r--r--arch/s390/kernel/entry64.S26
-rw-r--r--arch/s390/kernel/setup.c3
-rw-r--r--arch/s390/kvm/Kconfig11
-rw-r--r--arch/s390/kvm/sie64a.S77
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
468pgm_no_vtime: 478pgm_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
509pgm_no_vtime2: 520pgm_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
571io_no_vtime: 583io_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:
595io_work: 608io_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)
6050:
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
713ext_no_vtime: 717ext_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
36config 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.
38source drivers/vhost/Kconfig 49source 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 */
28SP_GREGS = __SF_EMPTY
29SP_HOOK = __SF_EMPTY+8
30SP_GPP = __SF_EMPTY+16
31SPI_PSW = STACK_FRAME_OVERHEAD + __PT_PSW
32
15 33
16SP_R5 = 5 * 8 # offset into stackframe 34 .macro SPP newpp
17SP_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
43sie_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
550: larl %r2,sie_reenter # re-enter with guest id
56 stg %r2,__LC_RETURN_PSW+8
571: 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
25sie64a: 65sie64a:
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
73sie_reenter:
74 mvc __LC_SIE_HOOK(8),SP_HOOK(%r15)
75 SPP SP_GPP(%r15) # set guest id
30sie_inst: 76sie_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
80sie_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
38sie_err: 87sie_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"