Commit e59a0391 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull s390 fixes from Alexander Gordeev:

 - ptep_modify_prot_start() may be called in a loop, which might lead to
   the preempt_count overflow due to the unnecessary preemption
   disabling. Do not disable preemption to prevent the overflow

 - Events of type PERF_TYPE_HARDWARE are not tested for sampling and
   return -EOPNOTSUPP eventually.

   Instead, deny all sampling events by CPUMF counter facility and
   return -ENOENT to allow other PMUs to be tried

 - The PAI PMU driver returns -EINVAL if an event out of its range. That
   aborts a search for an alternative PMU driver.

   Instead, return -ENOENT to allow other PMUs to be tried

* tag 's390-6.17-4' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux:
  s390/cpum_cf: Deny all sampling events by counter PMU
  s390/pai: Deny all events not handled by this PMU
  s390/mm: Prevent possible preempt_count overflow
parents a1228f04 ce971233
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -760,8 +760,6 @@ static int __hw_perf_event_init(struct perf_event *event, unsigned int type)
		break;

	case PERF_TYPE_HARDWARE:
		if (is_sampling_event(event))	/* No sampling support */
			return -ENOENT;
		ev = attr->config;
		if (!attr->exclude_user && attr->exclude_kernel) {
			/*
@@ -859,6 +857,8 @@ static int cpumf_pmu_event_init(struct perf_event *event)
	unsigned int type = event->attr.type;
	int err = -ENOENT;

	if (is_sampling_event(event))	/* No sampling support */
		return err;
	if (type == PERF_TYPE_HARDWARE || type == PERF_TYPE_RAW)
		err = __hw_perf_event_init(event, type);
	else if (event->pmu->type == type)
+2 −2
Original line number Diff line number Diff line
@@ -285,10 +285,10 @@ static int paicrypt_event_init(struct perf_event *event)
	/* PAI crypto PMU registered as PERF_TYPE_RAW, check event type */
	if (a->type != PERF_TYPE_RAW && event->pmu->type != a->type)
		return -ENOENT;
	/* PAI crypto event must be in valid range */
	/* PAI crypto event must be in valid range, try others if not */
	if (a->config < PAI_CRYPTO_BASE ||
	    a->config > PAI_CRYPTO_BASE + paicrypt_cnt)
		return -EINVAL;
		return -ENOENT;
	/* Allow only CRYPTO_ALL for sampling */
	if (a->sample_period && a->config != PAI_CRYPTO_BASE)
		return -EINVAL;
+1 −1
Original line number Diff line number Diff line
@@ -265,7 +265,7 @@ static int paiext_event_valid(struct perf_event *event)
		event->hw.config_base = offsetof(struct paiext_cb, acc);
		return 0;
	}
	return -EINVAL;
	return -ENOENT;
}

/* Might be called on different CPU than the one the event is intended for. */
+0 −2
Original line number Diff line number Diff line
@@ -335,7 +335,6 @@ pte_t ptep_modify_prot_start(struct vm_area_struct *vma, unsigned long addr,
	int nodat;
	struct mm_struct *mm = vma->vm_mm;

	preempt_disable();
	pgste = ptep_xchg_start(mm, addr, ptep);
	nodat = !!(pgste_val(pgste) & _PGSTE_GPS_NODAT);
	old = ptep_flush_lazy(mm, addr, ptep, nodat);
@@ -360,7 +359,6 @@ void ptep_modify_prot_commit(struct vm_area_struct *vma, unsigned long addr,
	} else {
		set_pte(ptep, pte);
	}
	preempt_enable();
}

static inline void pmdp_idte_local(struct mm_struct *mm,