Commit e3de3a1c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull powerpc fixes from Michael Ellerman:

 - Fix the DWARF CFI in our VDSO time functions, allowing gdb to
   backtrace through them correctly.

 - Fix a buffer overflow in the papr_scm driver, only triggerable by
   hypervisor input.

 - A fix in the recently added QoS handling for VAS (used for
   communicating with coprocessors).

Thanks to Alan Modra, Haren Myneni, Kajol Jain, and Segher Boessenkool.

* tag 'powerpc-5.18-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux:
  powerpc/papr_scm: Fix buffer overflow issue with CONFIG_FORTIFY_SOURCE
  powerpc/vdso: Fix incorrect CFI in gettimeofday.S
  powerpc/pseries/vas: Use QoS credits from the userspace
parents 27b5d61c 348c7134
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -22,12 +22,15 @@
.macro cvdso_call funct call_time=0
  .cfi_startproc
	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
  .cfi_adjust_cfa_offset PPC_MIN_STKFRM
	mflr		r0
  .cfi_register lr, r0
	PPC_STLU	r1, -PPC_MIN_STKFRM(r1)
  .cfi_adjust_cfa_offset PPC_MIN_STKFRM
	PPC_STL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
  .cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF
#ifdef __powerpc64__
	PPC_STL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
  .cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
#endif
	get_datapage	r5
	.ifeq	\call_time
@@ -39,13 +42,15 @@
	PPC_LL		r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
#ifdef __powerpc64__
	PPC_LL		r2, PPC_MIN_STKFRM + STK_GOT(r1)
  .cfi_restore r2
#endif
	.ifeq	\call_time
	cmpwi		r3, 0
	.endif
	mtlr		r0
  .cfi_restore lr
	addi		r1, r1, 2 * PPC_MIN_STKFRM
  .cfi_restore lr
  .cfi_def_cfa_offset 0
	crclr		so
	.ifeq	\call_time
	beqlr+
+2 −5
Original line number Diff line number Diff line
@@ -462,7 +462,6 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu
{
	struct papr_scm_perf_stat *stat;
	struct papr_scm_perf_stats *stats;
	char *statid;
	int index, rc, count;
	u32 available_events;

@@ -493,14 +492,12 @@ static int papr_scm_pmu_check_events(struct papr_scm_priv *p, struct nvdimm_pmu

	for (index = 0, stat = stats->scm_statistic, count = 0;
		     index < available_events; index++, ++stat) {
		statid = kzalloc(strlen(stat->stat_id) + 1, GFP_KERNEL);
		if (!statid) {
		p->nvdimm_events_map[count] = kmemdup_nul(stat->stat_id, 8, GFP_KERNEL);
		if (!p->nvdimm_events_map[count]) {
			rc = -ENOMEM;
			goto out_nvdimm_events_map;
		}

		strcpy(statid, stat->stat_id);
		p->nvdimm_events_map[count] = statid;
		count++;
	}
	p->nvdimm_events_map[count] = NULL;
+14 −5
Original line number Diff line number Diff line
@@ -27,22 +27,31 @@ struct vas_caps_entry {

/*
 * This function is used to get the notification from the drmgr when
 * QoS credits are changed. Though receiving the target total QoS
 * credits here, get the official QoS capabilities from the hypervisor.
 * QoS credits are changed.
 */
static ssize_t update_total_credits_trigger(struct vas_cop_feat_caps *caps,
static ssize_t update_total_credits_store(struct vas_cop_feat_caps *caps,
						const char *buf, size_t count)
{
	int err;
	u16 creds;

	err = kstrtou16(buf, 0, &creds);
	/*
	 * The user space interface from the management console
	 * notifies OS with the new QoS credits and then the
	 * hypervisor. So OS has to use this new credits value
	 * and reconfigure VAS windows (close or reopen depends
	 * on the credits available) instead of depending on VAS
	 * QoS capabilities from the hypervisor.
	 */
	if (!err)
		err = vas_reconfig_capabilties(caps->win_type);
		err = vas_reconfig_capabilties(caps->win_type, creds);

	if (err)
		return -EINVAL;

	pr_info("Set QoS total credits %u\n", creds);

	return count;
}

@@ -92,7 +101,7 @@ VAS_ATTR_RO(nr_total_credits);
VAS_ATTR_RO(nr_used_credits);

static struct vas_sysfs_entry update_total_credits_attribute =
	__ATTR(update_total_credits, 0200, NULL, update_total_credits_trigger);
	__ATTR(update_total_credits, 0200, NULL, update_total_credits_store);

static struct attribute *vas_def_capab_attrs[] = {
	&nr_total_credits_attribute.attr,
+12 −11
Original line number Diff line number Diff line
@@ -779,10 +779,10 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds,
 * changes. Reconfig window configurations based on the credits
 * availability from this new capabilities.
 */
int vas_reconfig_capabilties(u8 type)
int vas_reconfig_capabilties(u8 type, int new_nr_creds)
{
	struct vas_cop_feat_caps *caps;
	int old_nr_creds, new_nr_creds;
	int old_nr_creds;
	struct vas_caps *vcaps;
	int rc = 0, nr_active_wins;

@@ -795,12 +795,6 @@ int vas_reconfig_capabilties(u8 type)
	caps = &vcaps->caps;

	mutex_lock(&vas_pseries_mutex);
	rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES, vcaps->feat,
				      (u64)virt_to_phys(&hv_cop_caps));
	if (rc)
		goto out;

	new_nr_creds = be16_to_cpu(hv_cop_caps.target_lpar_creds);

	old_nr_creds = atomic_read(&caps->nr_total_credits);

@@ -832,7 +826,6 @@ int vas_reconfig_capabilties(u8 type)
					false);
	}

out:
	mutex_unlock(&vas_pseries_mutex);
	return rc;
}
@@ -850,7 +843,7 @@ static int pseries_vas_notifier(struct notifier_block *nb,
	struct of_reconfig_data *rd = data;
	struct device_node *dn = rd->dn;
	const __be32 *intserv = NULL;
	int len, rc = 0;
	int new_nr_creds, len, rc = 0;

	if ((action == OF_RECONFIG_ATTACH_NODE) ||
		(action == OF_RECONFIG_DETACH_NODE))
@@ -862,7 +855,15 @@ static int pseries_vas_notifier(struct notifier_block *nb,
	if (!intserv)
		return NOTIFY_OK;

	rc = vas_reconfig_capabilties(VAS_GZIP_DEF_FEAT_TYPE);
	rc = h_query_vas_capabilities(H_QUERY_VAS_CAPABILITIES,
					vascaps[VAS_GZIP_DEF_FEAT_TYPE].feat,
					(u64)virt_to_phys(&hv_cop_caps));
	if (!rc) {
		new_nr_creds = be16_to_cpu(hv_cop_caps.target_lpar_creds);
		rc = vas_reconfig_capabilties(VAS_GZIP_DEF_FEAT_TYPE,
						new_nr_creds);
	}

	if (rc)
		pr_err("Failed reconfig VAS capabilities with DLPAR\n");

+1 −1
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ struct pseries_vas_window {
};

int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps);
int vas_reconfig_capabilties(u8 type);
int vas_reconfig_capabilties(u8 type, int new_nr_creds);
int __init sysfs_pseries_vas_init(struct vas_all_caps *vas_caps);

#ifdef CONFIG_PPC_VAS