Skip to content

Commit f6e9d01

Browse files
committed
Merge tag 's390-5.19-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
Pull s390 fixes from Alexander Gordeev: - Fix perf stat accounting for cryptography counters when multiple events are installed concurrently. - Prevent installation of unsupported perf events for cryptography counters. - Treat perf events cpum_cf/CPU_CYCLES/ and cpu_cf/INSTRUCTIONS/ identical to basic events CPU_CYCLES" and INSTRUCTIONS, since they address the same hardware. - Restore kcrash operation which was broken by commit 5d8de29 ("vmcore: convert copy_oldmem_page() to take an iov_iter"). * tag 's390-5.19-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux: s390/pai: Fix multiple concurrent event installation s390/pai: Prevent invalid event number for pai_crypto PMU s390/cpumf: Handle events cycles and instructions identical s390/crash: make copy_oldmem_page() return number of bytes copied s390/crash: add missing iterator advance in copy_oldmem_page()
2 parents 2c39d61 + 21e8764 commit f6e9d01

File tree

3 files changed

+45
-7
lines changed

3 files changed

+45
-7
lines changed

arch/s390/kernel/crash_dump.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,11 @@ ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize,
219219
unsigned long src;
220220
int rc;
221221

222+
if (!(iter_is_iovec(iter) || iov_iter_is_kvec(iter)))
223+
return -EINVAL;
224+
/* Multi-segment iterators are not supported */
225+
if (iter->nr_segs > 1)
226+
return -EINVAL;
222227
if (!csize)
223228
return 0;
224229
src = pfn_to_phys(pfn) + offset;
@@ -228,7 +233,10 @@ ssize_t copy_oldmem_page(struct iov_iter *iter, unsigned long pfn, size_t csize,
228233
rc = copy_oldmem_user(iter->iov->iov_base, src, csize);
229234
else
230235
rc = copy_oldmem_kernel(iter->kvec->iov_base, src, csize);
231-
return rc;
236+
if (rc < 0)
237+
return rc;
238+
iov_iter_advance(iter, csize);
239+
return csize;
232240
}
233241

234242
/*

arch/s390/kernel/perf_cpum_cf.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,26 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type)
516516
return err;
517517
}
518518

519+
/* Events CPU_CYLCES and INSTRUCTIONS can be submitted with two different
520+
* attribute::type values:
521+
* - PERF_TYPE_HARDWARE:
522+
* - pmu->type:
523+
* Handle both type of invocations identical. They address the same hardware.
524+
* The result is different when event modifiers exclude_kernel and/or
525+
* exclude_user are also set.
526+
*/
527+
static int cpumf_pmu_event_type(struct perf_event *event)
528+
{
529+
u64 ev = event->attr.config;
530+
531+
if (cpumf_generic_events_basic[PERF_COUNT_HW_CPU_CYCLES] == ev ||
532+
cpumf_generic_events_basic[PERF_COUNT_HW_INSTRUCTIONS] == ev ||
533+
cpumf_generic_events_user[PERF_COUNT_HW_CPU_CYCLES] == ev ||
534+
cpumf_generic_events_user[PERF_COUNT_HW_INSTRUCTIONS] == ev)
535+
return PERF_TYPE_HARDWARE;
536+
return PERF_TYPE_RAW;
537+
}
538+
519539
static int cpumf_pmu_event_init(struct perf_event *event)
520540
{
521541
unsigned int type = event->attr.type;
@@ -525,7 +545,7 @@ static int cpumf_pmu_event_init(struct perf_event *event)
525545
err = __hw_perf_event_init(event, type);
526546
else if (event->pmu->type == type)
527547
/* Registered as unknown PMU */
528-
err = __hw_perf_event_init(event, PERF_TYPE_RAW);
548+
err = __hw_perf_event_init(event, cpumf_pmu_event_type(event));
529549
else
530550
return -ENOENT;
531551

arch/s390/kernel/perf_pai_crypto.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -193,8 +193,9 @@ static int paicrypt_event_init(struct perf_event *event)
193193
/* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */
194194
if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type)
195195
return -ENOENT;
196-
/* PAI crypto event must be valid */
197-
if (a->config > PAI_CRYPTO_BASE + paicrypt_cnt)
196+
/* PAI crypto event must be in valid range */
197+
if (a->config < PAI_CRYPTO_BASE ||
198+
a->config > PAI_CRYPTO_BASE + paicrypt_cnt)
198199
return -EINVAL;
199200
/* Allow only CPU wide operation, no process context for now. */
200201
if (event->hw.target || event->cpu == -1)
@@ -208,6 +209,12 @@ static int paicrypt_event_init(struct perf_event *event)
208209
if (rc)
209210
return rc;
210211

212+
/* Event initialization sets last_tag to 0. When later on the events
213+
* are deleted and re-added, do not reset the event count value to zero.
214+
* Events are added, deleted and re-added when 2 or more events
215+
* are active at the same time.
216+
*/
217+
event->hw.last_tag = 0;
211218
cpump->event = event;
212219
event->destroy = paicrypt_event_destroy;
213220

@@ -242,9 +249,12 @@ static void paicrypt_start(struct perf_event *event, int flags)
242249
{
243250
u64 sum;
244251

245-
sum = paicrypt_getall(event); /* Get current value */
246-
local64_set(&event->hw.prev_count, sum);
247-
local64_set(&event->count, 0);
252+
if (!event->hw.last_tag) {
253+
event->hw.last_tag = 1;
254+
sum = paicrypt_getall(event); /* Get current value */
255+
local64_set(&event->count, 0);
256+
local64_set(&event->hw.prev_count, sum);
257+
}
248258
}
249259

250260
static int paicrypt_add(struct perf_event *event, int flags)

0 commit comments

Comments
 (0)