Skip to content

Commit e22cf8c

Browse files
borntraegerMartin Schwidefsky
authored and
Martin Schwidefsky
committed
s390/cpumf: rework program parameter setting to detect guest samples
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. [[email protected]]: 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 <[email protected]> Signed-off-by: Hendrik Brueckner <[email protected]> Reviewed-by: Heiko Carstens <[email protected]> Signed-off-by: Martin Schwidefsky <[email protected]>
1 parent 6a62b48 commit e22cf8c

File tree

8 files changed

+40
-24
lines changed

8 files changed

+40
-24
lines changed

arch/s390/include/asm/lowcore.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,14 @@ struct _lowcore {
132132
/* Address space pointer. */
133133
__u64 kernel_asce; /* 0x0358 */
134134
__u64 user_asce; /* 0x0360 */
135-
__u64 current_pid; /* 0x0368 */
135+
136+
/*
137+
* The lpp and current_pid fields form a
138+
* 64-bit value that is set as program
139+
* parameter with the LPP instruction.
140+
*/
141+
__u32 lpp; /* 0x0368 */
142+
__u32 current_pid; /* 0x036c */
136143

137144
/* SMP info area */
138145
__u32 cpu_nr; /* 0x0370 */

arch/s390/include/asm/setup.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,9 @@
3434
#define MACHINE_FLAG_VX _BITUL(18)
3535
#define MACHINE_FLAG_CAD _BITUL(19)
3636

37+
#define LPP_MAGIC _BITUL(31)
38+
#define LPP_PFAULT_PID_MASK _AC(0xffffffff, UL)
39+
3740
#ifndef __ASSEMBLY__
3841

3942
#include <asm/lowcore.h>

arch/s390/kernel/asm-offsets.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ int main(void)
163163
OFFSET(__LC_RESTART_DATA, _lowcore, restart_data);
164164
OFFSET(__LC_RESTART_SOURCE, _lowcore, restart_source);
165165
OFFSET(__LC_USER_ASCE, _lowcore, user_asce);
166+
OFFSET(__LC_LPP, _lowcore, lpp);
166167
OFFSET(__LC_CURRENT_PID, _lowcore, current_pid);
167168
OFFSET(__LC_PERCPU_OFFSET, _lowcore, percpu_offset);
168169
OFFSET(__LC_VDSO_PER_CPU, _lowcore, vdso_per_cpu_data);

arch/s390/kernel/entry.S

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -187,8 +187,11 @@ ENTRY(__switch_to)
187187
stg %r15,__LC_KERNEL_STACK # store end of kernel stack
188188
lg %r15,__THREAD_ksp(%r1) # load kernel stack of next
189189
lctl %c4,%c4,__TASK_pid(%r3) # load pid to control reg. 4
190-
mvc __LC_CURRENT_PID+4(4,%r0),__TASK_pid(%r3) # store pid of next
190+
mvc __LC_CURRENT_PID(4,%r0),__TASK_pid(%r3) # store pid of next
191191
lmg %r6,%r15,__SF_GPRS(%r15) # load gprs of next task
192+
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
193+
bzr %r14
194+
.insn s,0xb2800000,__LC_LPP # set program parameter
192195
br %r14
193196

194197
.L__critical_start:
@@ -203,7 +206,7 @@ ENTRY(sie64a)
203206
stmg %r6,%r14,__SF_GPRS(%r15) # save kernel registers
204207
stg %r2,__SF_EMPTY(%r15) # save control block pointer
205208
stg %r3,__SF_EMPTY+8(%r15) # save guest register save area
206-
xc __SF_EMPTY+16(16,%r15),__SF_EMPTY+16(%r15) # host id & reason
209+
xc __SF_EMPTY+16(8,%r15),__SF_EMPTY+16(%r15) # reason code = 0
207210
TSTMSK __LC_CPU_FLAGS,_CIF_FPU # load guest fp/vx registers ?
208211
jno .Lsie_load_guest_gprs
209212
brasl %r14,load_fpu_regs # load guest fp/vx regs
@@ -220,14 +223,7 @@ ENTRY(sie64a)
220223
jnz .Lsie_skip
221224
TSTMSK __LC_CPU_FLAGS,_CIF_FPU
222225
jo .Lsie_skip # exit if fp/vx regs changed
223-
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
224-
jz .Lsie_enter
225-
.insn s,0xb2800000,__LC_CURRENT_PID # set guest id to pid
226-
.Lsie_enter:
227226
sie 0(%r14)
228-
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
229-
jz .Lsie_skip
230-
.insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id
231227
.Lsie_skip:
232228
ni __SIE_PROG0C+3(%r14),0xfe # no longer in SIE
233229
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
@@ -244,11 +240,11 @@ sie_exit:
244240
lg %r14,__SF_EMPTY+8(%r15) # load guest register save area
245241
stmg %r0,%r13,0(%r14) # save guest gprs 0-13
246242
lmg %r6,%r14,__SF_GPRS(%r15) # restore kernel registers
247-
lg %r2,__SF_EMPTY+24(%r15) # return exit reason code
243+
lg %r2,__SF_EMPTY+16(%r15) # return exit reason code
248244
br %r14
249245
.Lsie_fault:
250246
lghi %r14,-EFAULT
251-
stg %r14,__SF_EMPTY+24(%r15) # set exit reason code
247+
stg %r14,__SF_EMPTY+16(%r15) # set exit reason code
252248
j sie_exit
253249

254250
EX_TABLE(.Lrewind_pad,.Lsie_fault)
@@ -938,7 +934,10 @@ ENTRY(mcck_int_handler)
938934
# PSW restart interrupt handler
939935
#
940936
ENTRY(restart_int_handler)
941-
stg %r15,__LC_SAVE_AREA_RESTART
937+
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
938+
jz 0f
939+
.insn s,0xb2800000,__LC_LPP
940+
0: stg %r15,__LC_SAVE_AREA_RESTART
942941
lg %r15,__LC_RESTART_STACK
943942
aghi %r15,-__PT_SIZE # create pt_regs on stack
944943
xc 0(__PT_SIZE,%r15),0(%r15)
@@ -1042,10 +1041,7 @@ cleanup_critical:
10421041

10431042
.Lcleanup_sie:
10441043
lg %r9,__SF_EMPTY(%r15) # get control block pointer
1045-
TSTMSK __LC_MACHINE_FLAGS,MACHINE_FLAG_LPP
1046-
jz 0f
1047-
.insn s,0xb2800000,__SF_EMPTY+16(%r15)# set host id
1048-
0: ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
1044+
ni __SIE_PROG0C+3(%r9),0xfe # no longer in SIE
10491045
lctlg %c1,%c1,__LC_USER_ASCE # load primary asce
10501046
larl %r9,sie_exit # skip forward to sie_exit
10511047
br %r14

arch/s390/kernel/head64.S

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616

1717
__HEAD
1818
ENTRY(startup_continue)
19-
larl %r1,sched_clock_base_cc
19+
tm __LC_STFL_FAC_LIST+6,0x80 # LPP available ?
20+
jz 0f
21+
xc __LC_LPP+1(7,0),__LC_LPP+1 # clear lpp and current_pid
22+
mvi __LC_LPP,0x80 # and set LPP_MAGIC
23+
.insn s,0xb2800000,__LC_LPP # load program parameter
24+
0: larl %r1,sched_clock_base_cc
2025
mvc 0(8,%r1),__LC_LAST_UPDATE_CLOCK
2126
larl %r13,.LPG1 # get base
2227
lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers

arch/s390/kernel/perf_cpum_sf.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,11 +1019,13 @@ static int perf_push_sample(struct perf_event *event, struct sf_raw_sample *sfr)
10191019
break;
10201020
}
10211021

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

10291031
overflow = 0;

arch/s390/kernel/smp.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,8 @@ static void pcpu_attach_task(struct pcpu *pcpu, struct task_struct *tsk)
262262
+ THREAD_SIZE - STACK_FRAME_OVERHEAD - sizeof(struct pt_regs);
263263
lc->thread_info = (unsigned long) task_thread_info(tsk);
264264
lc->current_task = (unsigned long) tsk;
265+
lc->lpp = LPP_MAGIC;
266+
lc->current_pid = tsk->pid;
265267
lc->user_timer = ti->user_timer;
266268
lc->system_timer = ti->system_timer;
267269
lc->steal_timer = 0;

arch/s390/mm/fault.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ int pfault_init(void)
590590
.reffcode = 0,
591591
.refdwlen = 5,
592592
.refversn = 2,
593-
.refgaddr = __LC_CURRENT_PID,
593+
.refgaddr = __LC_LPP,
594594
.refselmk = 1ULL << 48,
595595
.refcmpmk = 1ULL << 48,
596596
.reserved = __PF_RES_FIELD };
@@ -649,7 +649,7 @@ static void pfault_interrupt(struct ext_code ext_code,
649649
return;
650650
inc_irq_stat(IRQEXT_PFL);
651651
/* Get the token (= pid of the affected task). */
652-
pid = param64;
652+
pid = param64 & LPP_PFAULT_PID_MASK;
653653
rcu_read_lock();
654654
tsk = find_task_by_pid_ns(pid, &init_pid_ns);
655655
if (tsk)

0 commit comments

Comments
 (0)