[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>
This commit is contained in:
		
							parent
							
								
									6377981faf
								
							
						
					
					
						commit
						cd3b70f5d4
					
				| @ -267,7 +267,8 @@ struct _lowcore { | ||||
| 	__u64	vdso_per_cpu_data;		/* 0x0358 */ | ||||
| 	__u64	machine_flags;			/* 0x0360 */ | ||||
| 	__u64	ftrace_func;			/* 0x0368 */ | ||||
| 	__u8	pad_0x0370[0x0380-0x0370];	/* 0x0370 */ | ||||
| 	__u64	sie_hook;			/* 0x0370 */ | ||||
| 	__u64	cmf_hpp;			/* 0x0378 */ | ||||
| 
 | ||||
| 	/* Interrupt response block. */ | ||||
| 	__u8	irb[64];			/* 0x0380 */ | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
|  *  include/asm-s390/setup.h | ||||
|  * | ||||
|  *  S390 version | ||||
|  *    Copyright IBM Corp. 1999,2006 | ||||
|  *    Copyright IBM Corp. 1999,2010 | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _ASM_S390_SETUP_H | ||||
| @ -72,6 +72,7 @@ extern unsigned int user_mode; | ||||
| #define MACHINE_FLAG_HPAGE	(1UL << 10) | ||||
| #define MACHINE_FLAG_PFMF	(1UL << 11) | ||||
| #define MACHINE_FLAG_LPAR	(1UL << 12) | ||||
| #define MACHINE_FLAG_SPP	(1UL << 13) | ||||
| 
 | ||||
| #define MACHINE_IS_VM		(S390_lowcore.machine_flags & MACHINE_FLAG_VM) | ||||
| #define MACHINE_IS_KVM		(S390_lowcore.machine_flags & MACHINE_FLAG_KVM) | ||||
| @ -88,6 +89,7 @@ extern unsigned int user_mode; | ||||
| #define MACHINE_HAS_MVCOS	(0) | ||||
| #define MACHINE_HAS_HPAGE	(0) | ||||
| #define MACHINE_HAS_PFMF	(0) | ||||
| #define MACHINE_HAS_SPP		(0) | ||||
| #else /* __s390x__ */ | ||||
| #define MACHINE_HAS_IEEE	(1) | ||||
| #define MACHINE_HAS_CSP		(1) | ||||
| @ -97,6 +99,7 @@ extern unsigned int user_mode; | ||||
| #define MACHINE_HAS_MVCOS	(S390_lowcore.machine_flags & MACHINE_FLAG_MVCOS) | ||||
| #define MACHINE_HAS_HPAGE	(S390_lowcore.machine_flags & MACHINE_FLAG_HPAGE) | ||||
| #define MACHINE_HAS_PFMF	(S390_lowcore.machine_flags & MACHINE_FLAG_PFMF) | ||||
| #define MACHINE_HAS_SPP		(S390_lowcore.machine_flags & MACHINE_FLAG_SPP) | ||||
| #endif /* __s390x__ */ | ||||
| 
 | ||||
| #define ZFCPDUMP_HSA_SIZE	(32UL<<20) | ||||
|  | ||||
| @ -131,6 +131,8 @@ int main(void) | ||||
| 	DEFINE(__LC_MCCK_CLOCK, offsetof(struct _lowcore, mcck_clock)); | ||||
| 	DEFINE(__LC_MACHINE_FLAGS, offsetof(struct _lowcore, machine_flags)); | ||||
| 	DEFINE(__LC_FTRACE_FUNC, offsetof(struct _lowcore, ftrace_func)); | ||||
| 	DEFINE(__LC_SIE_HOOK, offsetof(struct _lowcore, sie_hook)); | ||||
| 	DEFINE(__LC_CMF_HPP, offsetof(struct _lowcore, cmf_hpp)); | ||||
| 	DEFINE(__LC_IRB, offsetof(struct _lowcore, irb)); | ||||
| 	DEFINE(__LC_CPU_TIMER_SAVE_AREA, offsetof(struct _lowcore, cpu_timer_save_area)); | ||||
| 	DEFINE(__LC_CLOCK_COMP_SAVE_AREA, offsetof(struct _lowcore, clock_comp_save_area)); | ||||
|  | ||||
| @ -356,6 +356,7 @@ static __init void detect_machine_facilities(void) | ||||
| { | ||||
| #ifdef CONFIG_64BIT | ||||
| 	unsigned int facilities; | ||||
| 	unsigned long long facility_bits; | ||||
| 
 | ||||
| 	facilities = stfl(); | ||||
| 	if (facilities & (1 << 28)) | ||||
| @ -364,6 +365,9 @@ static __init void detect_machine_facilities(void) | ||||
| 		S390_lowcore.machine_flags |= MACHINE_FLAG_PFMF; | ||||
| 	if (facilities & (1 << 4)) | ||||
| 		S390_lowcore.machine_flags |= MACHINE_FLAG_MVCOS; | ||||
| 	if ((stfle(&facility_bits, 1) > 0) && | ||||
| 	    (facility_bits & (1ULL << (63 - 40)))) | ||||
| 		S390_lowcore.machine_flags |= MACHINE_FLAG_SPP; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
|  *  arch/s390/kernel/entry64.S | ||||
|  *    S390 low-level entry points. | ||||
|  * | ||||
|  *    Copyright (C) IBM Corp. 1999,2006 | ||||
|  *    Copyright (C) IBM Corp. 1999,2010 | ||||
|  *    Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com),
 | ||||
|  *		 Hartmut Penner (hp@de.ibm.com),
 | ||||
|  *		 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 | \ | ||||
| 
 | ||||
| #define BASED(name) name-system_call(%r13) | ||||
| 
 | ||||
| 	.macro	HANDLE_SIE_INTERCEPT
 | ||||
| #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||||
| 	lg	%r3,__LC_SIE_HOOK | ||||
| 	ltgr	%r3,%r3 | ||||
| 	jz	0f | ||||
| 	basr	%r14,%r3 | ||||
| 	0: | ||||
| #endif | ||||
| 	.endm | ||||
| 
 | ||||
| #ifdef CONFIG_TRACE_IRQFLAGS | ||||
| 	.macro	TRACE_IRQS_ON
 | ||||
| 	basr	%r2,%r0 | ||||
| @ -466,6 +476,7 @@ pgm_check_handler: | ||||
| 	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | ||||
| 	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | ||||
| pgm_no_vtime: | ||||
| 	HANDLE_SIE_INTERCEPT | ||||
| 	TRACE_IRQS_CHECK_OFF | ||||
| 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct | ||||
| 	mvc	SP_ARGS(8,%r15),__LC_LAST_BREAK | ||||
| @ -507,6 +518,7 @@ pgm_per_std: | ||||
| 	UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER | ||||
| 	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_SYNC_ENTER_TIMER | ||||
| pgm_no_vtime2: | ||||
| 	HANDLE_SIE_INTERCEPT | ||||
| 	TRACE_IRQS_CHECK_OFF | ||||
| 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct | ||||
| 	lg	%r1,__TI_task(%r9) | ||||
| @ -570,6 +582,7 @@ io_int_handler: | ||||
| 	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | ||||
| io_no_vtime: | ||||
| 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct | ||||
| 	HANDLE_SIE_INTERCEPT | ||||
| 	TRACE_IRQS_OFF | ||||
| 	la	%r2,SP_PTREGS(%r15)	# address of register-save area | ||||
| 	brasl	%r14,do_IRQ		# call standard irq handler | ||||
| @ -595,15 +608,6 @@ io_done: | ||||
| io_work: | ||||
| 	tm	SP_PSW+1(%r15),0x01	# returning to user ? | ||||
| 	jo	io_work_user		# yes -> do resched & signal | ||||
| #if defined(CONFIG_KVM) || defined(CONFIG_KVM_MODULE) | ||||
| 	lg	%r2,SP_PSW+8(%r15)	# check if current instruction is SIE | ||||
| 	lh	%r1,0(%r2) | ||||
| 	chi	%r1,-19948		# signed 16 bit compare with 0xb214 | ||||
| 	jne	0f			# no -> leave PSW alone | ||||
| 	aghi	%r2,4			# yes-> add 4 bytes to leave SIE | ||||
| 	stg	%r2,SP_PSW+8(%r15) | ||||
| 0: | ||||
| #endif | ||||
| #ifdef CONFIG_PREEMPT | ||||
| 	# check for preemptive scheduling | ||||
| 	icm	%r0,15,__TI_precount(%r9) | ||||
| @ -712,6 +716,7 @@ ext_int_handler: | ||||
| 	mvc	__LC_LAST_UPDATE_TIMER(8),__LC_ASYNC_ENTER_TIMER | ||||
| ext_no_vtime: | ||||
| 	lg	%r9,__LC_THREAD_INFO	# load pointer to thread_info struct | ||||
| 	HANDLE_SIE_INTERCEPT | ||||
| 	TRACE_IRQS_OFF | ||||
| 	la	%r2,SP_PTREGS(%r15)	# address of register-save area | ||||
| 	llgh	%r3,__LC_EXT_INT_CODE	# get interruption code | ||||
| @ -786,6 +791,7 @@ mcck_no_vtime: | ||||
| 	stosm	__SF_EMPTY(%r15),0x04	# turn dat on | ||||
| 	tm	__TI_flags+7(%r9),_TIF_MCCK_PENDING | ||||
| 	jno	mcck_return | ||||
| 	HANDLE_SIE_INTERCEPT | ||||
| 	TRACE_IRQS_OFF | ||||
| 	brasl	%r14,s390_handle_mcck | ||||
| 	TRACE_IRQS_ON | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
|  *  arch/s390/kernel/setup.c | ||||
|  * | ||||
|  *  S390 version | ||||
|  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||||
|  *    Copyright (C) IBM Corp. 1999,2010 | ||||
|  *    Author(s): Hartmut Penner (hp@de.ibm.com), | ||||
|  *               Martin Schwidefsky (schwidefsky@de.ibm.com) | ||||
|  * | ||||
| @ -401,6 +401,7 @@ setup_lowcore(void) | ||||
| 	lc->io_new_psw.mask = psw_kernel_bits; | ||||
| 	lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler; | ||||
| 	lc->clock_comparator = -1ULL; | ||||
| 	lc->cmf_hpp = -1ULL; | ||||
| 	lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE; | ||||
| 	lc->async_stack = (unsigned long) | ||||
| 		__alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE; | ||||
|  | ||||
| @ -33,6 +33,17 @@ config KVM | ||||
| 
 | ||||
| 	  If unsure, say N. | ||||
| 
 | ||||
| config KVM_AWARE_CMF | ||||
| 	depends on KVM | ||||
| 	bool "KVM aware sampling" | ||||
| 	---help--- | ||||
| 	  This option enhances the sampling data from the CPU Measurement | ||||
| 	  Facility with additional information, that allows to distinguish | ||||
| 	  guest(s) and host when using the kernel based virtual machine | ||||
| 	  functionality. | ||||
| 
 | ||||
| 	  If unsure, say N. | ||||
| 
 | ||||
| # OK, it's a little counter-intuitive to do this, but it puts it neatly under | ||||
| # the virtualization menu. | ||||
| source drivers/vhost/Kconfig | ||||
|  | ||||
| @ -1,20 +1,60 @@ | ||||
| /* | ||||
|  * sie64a.S - low level sie call | ||||
|  * | ||||
|  * Copyright IBM Corp. 2008 | ||||
|  * Copyright IBM Corp. 2008,2010 | ||||
|  * | ||||
|  * This program is free software; you can redistribute it and/or modify
 | ||||
|  * it under the terms of the GNU General Public License (version 2 only) | ||||
|  * as published by the Free Software Foundation. | ||||
|  * | ||||
|  *    Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
 | ||||
|  *		 Christian Ehrhardt <ehrhardt@linux.vnet.ibm.com>
 | ||||
|  */ | ||||
| 
 | ||||
| #include <linux/errno.h> | ||||
| #include <asm/asm-offsets.h> | ||||
| #include <asm/setup.h> | ||||
| #include <asm/asm-offsets.h> | ||||
| #include <asm/ptrace.h> | ||||
| #include <asm/thread_info.h> | ||||
| 
 | ||||
| SP_R5 =	5 * 8	# offset into stackframe | ||||
| SP_R6 =	6 * 8 | ||||
| _TIF_EXIT_SIE = (_TIF_SIGPENDING | _TIF_NEED_RESCHED | _TIF_MCCK_PENDING) | ||||
| 
 | ||||
| /* | ||||
|  * offsets into stackframe | ||||
|  * SP_	= offsets into stack sie64 is called with | ||||
|  * SPI_ = offsets into irq stack | ||||
|  */ | ||||
| SP_GREGS = __SF_EMPTY | ||||
| SP_HOOK  = __SF_EMPTY+8 | ||||
| SP_GPP	 = __SF_EMPTY+16 | ||||
| SPI_PSW  = STACK_FRAME_OVERHEAD + __PT_PSW | ||||
| 
 | ||||
| 
 | ||||
| 	.macro SPP newpp | ||||
| #ifdef CONFIG_KVM_AWARE_CMF | ||||
| 	tm	__LC_MACHINE_FLAGS+6,0x20	# MACHINE_FLAG_SPP | ||||
| 	jz	0f | ||||
| 	.insn	s,0xb2800000,\newpp | ||||
| 	0: | ||||
| #endif | ||||
| 	.endm | ||||
| 
 | ||||
| sie_irq_handler: | ||||
| 	SPP	__LC_CMF_HPP			# set host id | ||||
| 	larl	%r2,sie_inst | ||||
| 	clg	%r2,SPI_PSW+8(0,%r15)		# intercepted sie | ||||
| 	jne	1f | ||||
| 	xc	__LC_SIE_HOOK(8),__LC_SIE_HOOK | ||||
| 	lg	%r2,__LC_THREAD_INFO		# pointer thread_info struct | ||||
| 	tm	__TI_flags+7(%r2),_TIF_EXIT_SIE | ||||
| 	jz	0f | ||||
| 	larl	%r2,sie_exit			# work pending, leave sie | ||||
| 	stg	%r2,__LC_RETURN_PSW+8 | ||||
| 	br	%r14 | ||||
| 0:	larl	%r2,sie_reenter			# re-enter with guest id | ||||
| 	stg	%r2,__LC_RETURN_PSW+8 | ||||
| 1:	br	%r14 | ||||
| 
 | ||||
| /* | ||||
|  * sie64a calling convention: | ||||
| @ -23,23 +63,34 @@ SP_R6 =	6 * 8 | ||||
|  */ | ||||
| 	.globl	sie64a
 | ||||
| sie64a: | ||||
| 	lgr	%r5,%r3 | ||||
| 	stmg	%r5,%r14,SP_R5(%r15)	# save register on entry | ||||
| 	lgr	%r14,%r2		# pointer to sie control block | ||||
| 	lmg	%r0,%r13,0(%r3)		# load guest gprs 0-13 | ||||
| 	stg	%r3,SP_GREGS(%r15)		# save guest register save area | ||||
| 	stmg	%r6,%r14,__SF_GPRS(%r15)	# save registers on entry | ||||
| 	lgr	%r14,%r2			# pointer to sie control block | ||||
| 	larl	%r5,sie_irq_handler | ||||
| 	stg	%r2,SP_GPP(%r15) | ||||
| 	stg	%r5,SP_HOOK(%r15)		# save hook target | ||||
| 	lmg	%r0,%r13,0(%r3)			# load guest gprs 0-13 | ||||
| sie_reenter: | ||||
| 	mvc	__LC_SIE_HOOK(8),SP_HOOK(%r15) | ||||
| 	SPP	SP_GPP(%r15)			# set guest id | ||||
| sie_inst: | ||||
| 	sie	0(%r14) | ||||
| 	lg	%r14,SP_R5(%r15) | ||||
| 	stmg	%r0,%r13,0(%r14)	# save guest gprs 0-13 | ||||
| 	xc	__LC_SIE_HOOK(8),__LC_SIE_HOOK | ||||
| 	SPP	__LC_CMF_HPP			# set host id | ||||
| sie_exit: | ||||
| 	lg	%r14,SP_GREGS(%r15) | ||||
| 	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13 | ||||
| 	lghi	%r2,0 | ||||
| 	lmg	%r6,%r14,SP_R6(%r15) | ||||
| 	lmg	%r6,%r14,__SF_GPRS(%r15) | ||||
| 	br	%r14 | ||||
| 
 | ||||
| sie_err: | ||||
| 	lg	%r14,SP_R5(%r15) | ||||
| 	stmg	%r0,%r13,0(%r14)	# save guest gprs 0-13 | ||||
| 	xc	__LC_SIE_HOOK(8),__LC_SIE_HOOK | ||||
| 	SPP	__LC_CMF_HPP			# set host id | ||||
| 	lg	%r14,SP_GREGS(%r15) | ||||
| 	stmg	%r0,%r13,0(%r14)		# save guest gprs 0-13 | ||||
| 	lghi	%r2,-EFAULT | ||||
| 	lmg	%r6,%r14,SP_R6(%r15) | ||||
| 	lmg	%r6,%r14,__SF_GPRS(%r15) | ||||
| 	br	%r14 | ||||
| 
 | ||||
| 	.section __ex_table,"a" | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user