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/kernel | |
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/kernel')
-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 |
4 files changed, 24 insertions, 11 deletions
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; |