Skip to content

Commit

Permalink
s390/cpumf: rework program parameter setting to detect guest samples
Browse files Browse the repository at this point in the history
The program parameter can be used to mark hardware samples with
some token.  Previously, it was used to mark guest samples only.

Improve the program parameter doubleword by combining two parts,
the leftmost LPP part and the rightmost PID part.  Set the PID
part for processes by using the task PID.
To distinguish host and guest samples for the kernel (PID part
is zero), the guest must always set the program paramater to a
non-zero value.  Use the leftmost bit in the LPP part of the
program parameter to be able to detect guest kernel samples.

[brueckner@linux.vnet.ibm.com]: Split __LC_CURRENT and introduced
__LC_LPP. Corrected __LC_CURRENT users and adjusted assembler parts.
And updated the commit message accordingly.

Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Reviewed-by: Heiko Carstens <heiko.carstens@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
  • Loading branch information
Christian Borntraeger authored and Martin Schwidefsky committed Oct 14, 2015
1 parent 6a62b48 commit e22cf8c
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 24 deletions.
9 changes: 8 additions & 1 deletion arch/s390/include/asm/lowcore.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,14 @@ struct _lowcore {
/* Address space pointer. */
__u64 kernel_asce; /* 0x0358 */
__u64 user_asce; /* 0x0360 */
__u64 current_pid; /* 0x0368 */

/*
* The lpp and current_pid fields form a
* 64-bit value that is set as program
* parameter with the LPP instruction.
*/
__u32 lpp; /* 0x0368 */
__u32 current_pid; /* 0x036c */

/* SMP info area */
__u32 cpu_nr; /* 0x0370 */
Expand Down
3 changes: 3 additions & 0 deletions arch/s390/include/asm/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
#define MACHINE_FLAG_VX _BITUL(18)
#define MACHINE_FLAG_CAD _BITUL(19)

#define LPP_MAGIC _BITUL(31)
#define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL)

#ifndef __ASSEMBLY__

#include <asm/lowcore.h>
Expand Down
1 change: 1 addition & 0 deletions arch/s390/kernel/asm-offsets.c
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ int main(void)
OFFSET(__LC_RESTART_DATA, _lowcore, restart_data);
OFFSET(__LC_RESTART_SOURCE, _lowcore, restart_source);
OFFSET(__LC_USER_ASCE, _lowcore, user_asce);
OFFSET(__LC_LPP, _lowcore, lpp);
OFFSET(__LC_CURRENT_PID, _lowcore, current_pid);
OFFSET(__LC_PERCPU_OFFSET, _lowcore, percpu_offset);
OFFSET(__LC_VDSO_PER_CPU, _lowcore, vdso_per_cpu_data);
Expand Down
28 changes: 12 additions & 16 deletions arch/s390/kernel/entry.S
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,11 @@ ENTRY(__switch_to)
stg %r15,__LC_KERNEL_STACK # store end of kernel stack
lg %r15,__THREAD_ksp(%r1) # load kernel stack of next
lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next
mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next
lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
bzr %r14
.insn s,0xb2800000,__LC_LPP # set program parameter
br %r14

.L__critical_start:
Expand All @@ -203,7 +206,7 @@ ENTRY(sie64a)
stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
stg %r2,__SF_EMPTY(%r15) # save control block pointer
stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
xc __SF_EMPTY+16(16,%r15),__SF_EMPTY+16(%r15) # host id & reason
xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # reason code = 0
TSTMSK __LC_CPU_FLAGS,_CIF_FPU # load guest fp/vx registers ?
jno .Lsie_load_guest_gprs
brasl %r14,load_fpu_regs # load guest fp/vx regs
Expand All @@ -220,14 +223,7 @@ ENTRY(sie64a)
jnz .Lsie_skip
TSTMSK __LC_CPU_FLAGS,_CIF_FPU
jo .Lsie_skip # exit if fp/vx regs changed
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
jz .Lsie_enter
.insn s,0xb2800000,__LC_CURRENT_PID # set guest id to pid
.Lsie_enter:
sie 0(%r14)
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
jz .Lsie_skip
.insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id
.Lsie_skip:
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
Expand All @@ -244,11 +240,11 @@ sie_exit:
lg %r14,__SF_EMPTY+8(%r15) # load guest register save area
stmg %r0,%r13,0(%r14) # save guest gprs 0-13
lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
lg %r2,__SF_EMPTY+24(%r15) # return exit reason code
lg %r2,__SF_EMPTY+16(%r15) # return exit reason code
br %r14
.Lsie_fault:
lghi %r14,-EFAULT
stg %r14,__SF_EMPTY+24(%r15) # set exit reason code
stg %r14,__SF_EMPTY+16(%r15) # set exit reason code
j sie_exit

EX_TABLE(.Lrewind_pad,.Lsie_fault)
Expand Down Expand Up @@ -938,7 +934,10 @@ ENTRY(mcck_int_handler)
# PSW restart interrupt handler
#
ENTRY(restart_int_handler)
stg %r15,__LC_SAVE_AREA_RESTART
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
jz 0f
.insn s,0xb2800000,__LC_LPP
0: stg %r15,__LC_SAVE_AREA_RESTART
lg %r15,__LC_RESTART_STACK
aghi %r15,-__PT_SIZE # create pt_regs on stack
xc 0(__PT_SIZE,%r15),0(%r15)
Expand Down Expand Up @@ -1042,10 +1041,7 @@ cleanup_critical:

.Lcleanup_sie:
lg %r9,__SF_EMPTY(%r15) # get control block pointer
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
jz 0f
.insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id
0: ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
larl %r9,sie_exit # skip forward to sie_exit
br %r14
Expand Down
7 changes: 6 additions & 1 deletion arch/s390/kernel/head64.S
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@

__HEAD
ENTRY(startup_continue)
larl %r1,sched_clock_base_cc
tm __LC_STFL_FAC_LIST+6,0x80 # LPP available ?
jz 0f
xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid
mvi __LC_LPP,0x80 # and set LPP_MAGIC
.insn s,0xb2800000,__LC_LPP # load program parameter
0: larl %r1,sched_clock_base_cc
mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
larl %r13,.LPG1 # get base
lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers
Expand Down
10 changes: 6 additions & 4 deletions arch/s390/kernel/perf_cpum_sf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1019,11 +1019,13 @@ static int perf_push_sample(struct perf_event *event, struct sf_raw_sample *sfr)
break;
}

/* The host-program-parameter (hpp) contains the pid of
* the CPU thread as set by sie64a() in entry.S.
* If non-zero assume a guest sample.
/*
* A non-zero guest program parameter indicates a guest
* sample.
* Note that some early samples might be misaccounted to
* the host.
*/
if (sfr->basic.hpp)
if (sfr->basic.gpp)
sde_regs->in_guest = 1;

overflow = 0;
Expand Down
2 changes: 2 additions & 0 deletions arch/s390/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,8 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
+ THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
lc->thread_info = (unsigned long) task_thread_info(tsk);
lc->current_task = (unsigned long) tsk;
lc->lpp = LPP_MAGIC;
lc->current_pid = tsk->pid;
lc->user_timer = ti->user_timer;
lc->system_timer = ti->system_timer;
lc->steal_timer = 0;
Expand Down
4 changes: 2 additions & 2 deletions arch/s390/mm/fault.c
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,7 @@ int pfault_init(void)
.reffcode = 0,
.refdwlen = 5,
.refversn = 2,
.refgaddr = __LC_CURRENT_PID,
.refgaddr = __LC_LPP,
.refselmk = 1ULL << 48,
.refcmpmk = 1ULL << 48,
.reserved = __PF_RES_FIELD };
Expand Down Expand Up @@ -649,7 +649,7 @@ static void pfault_interrupt(struct ext_code ext_code,
return;
inc_irq_stat(IRQEXT_PFL);
/* Get the token (= pid of the affected task). */
pid = param64;
pid = param64 & LPP_PFAULT_PID_MASK;
rcu_read_lock();
tsk = find_task_by_pid_ns(pid, &init_pid_ns);
if (tsk)
Expand Down

0 comments on commit e22cf8c

Please sign in to comment.