powerpc fixes for 5.18 #4
- 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, Segher Boessenkool. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAmJ3r7kTHG1wZUBlbGxl cm1hbi5pZC5hdQAKCRBR6+o8yOGlgM1LEACU87gXiSJJW99qD5IvoPncR1nRjd+3 zTAch9Dk70Kt/1Zkn0bEGjkua6YwcOdlA7QXiHBR2HAYli85VWK/w9Vz/TLTbL9/ SrDvSfzwmqbvU61A2ZppvH487z8pfEBmviv3SCrmB3xZWtttYkatEj4A1EjdBJUI +xq0JgrXj8rAayRpkJS5XEUpkw8eXJ85X1WXdx+peIGvcRKB+n46HyCYhsl3/YVv pAn6jcnNnPqYzXeE0sQ4ZpybzCkzqVHC4SyCemkp8PWfqyL8LqgIvz2qtCvXAzij SJikxmHUN3XvHCF4aOgJG6OTkMEz92cpH0hGsb59c4usPCNlRFMuqhJxuYYmNGT3 FtDUrrptsQ5ZRdWttQzi0RFjK0klro5VKvMJRv7uDWIlaPwl3Vi8DxvSrzCSdQPE Q1XsJS7B/io1JCCzrhrJyRQkIt+Z9e1/3xm618ide1UKQkqVYApZcImJDk7DlDCV QL1mtqHgasQjDLRkQq/fil/vyt2byw2uzCy6j0X/WQYrKJlUmbXKlcbdbbeCH2qZ 8NndD96wlw+dd/q2u/ZdngQ8f/68n6+a/Zxv7eAbb01JY04VFsCXgdgGHpzhBiJ5 YWqp5qzzuTcvhSYhyfdqFd9KCxxGRIag6jmhs6vbfQbMlZMoo9Jr4vaVm1aIW27t MRhuEwi2KzQI2A== =sVeX -----END PGP SIGNATURE----- Merge tag 'powerpc-5.18-4' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux 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
This commit is contained in:
commit
e3de3a1cda
|
@ -22,12 +22,15 @@
|
||||||
.macro cvdso_call funct call_time=0
|
.macro cvdso_call funct call_time=0
|
||||||
.cfi_startproc
|
.cfi_startproc
|
||||||
PPC_STLU r1, -PPC_MIN_STKFRM(r1)
|
PPC_STLU r1, -PPC_MIN_STKFRM(r1)
|
||||||
|
.cfi_adjust_cfa_offset PPC_MIN_STKFRM
|
||||||
mflr r0
|
mflr r0
|
||||||
.cfi_register lr, r0
|
|
||||||
PPC_STLU r1, -PPC_MIN_STKFRM(r1)
|
PPC_STLU r1, -PPC_MIN_STKFRM(r1)
|
||||||
|
.cfi_adjust_cfa_offset PPC_MIN_STKFRM
|
||||||
PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
|
PPC_STL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
|
||||||
|
.cfi_rel_offset lr, PPC_MIN_STKFRM + PPC_LR_STKOFF
|
||||||
#ifdef __powerpc64__
|
#ifdef __powerpc64__
|
||||||
PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1)
|
PPC_STL r2, PPC_MIN_STKFRM + STK_GOT(r1)
|
||||||
|
.cfi_rel_offset r2, PPC_MIN_STKFRM + STK_GOT
|
||||||
#endif
|
#endif
|
||||||
get_datapage r5
|
get_datapage r5
|
||||||
.ifeq \call_time
|
.ifeq \call_time
|
||||||
|
@ -39,13 +42,15 @@
|
||||||
PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
|
PPC_LL r0, PPC_MIN_STKFRM + PPC_LR_STKOFF(r1)
|
||||||
#ifdef __powerpc64__
|
#ifdef __powerpc64__
|
||||||
PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1)
|
PPC_LL r2, PPC_MIN_STKFRM + STK_GOT(r1)
|
||||||
|
.cfi_restore r2
|
||||||
#endif
|
#endif
|
||||||
.ifeq \call_time
|
.ifeq \call_time
|
||||||
cmpwi r3, 0
|
cmpwi r3, 0
|
||||||
.endif
|
.endif
|
||||||
mtlr r0
|
mtlr r0
|
||||||
.cfi_restore lr
|
|
||||||
addi r1, r1, 2 * PPC_MIN_STKFRM
|
addi r1, r1, 2 * PPC_MIN_STKFRM
|
||||||
|
.cfi_restore lr
|
||||||
|
.cfi_def_cfa_offset 0
|
||||||
crclr so
|
crclr so
|
||||||
.ifeq \call_time
|
.ifeq \call_time
|
||||||
beqlr+
|
beqlr+
|
||||||
|
|
|
@ -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_stat *stat;
|
||||||
struct papr_scm_perf_stats *stats;
|
struct papr_scm_perf_stats *stats;
|
||||||
char *statid;
|
|
||||||
int index, rc, count;
|
int index, rc, count;
|
||||||
u32 available_events;
|
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;
|
for (index = 0, stat = stats->scm_statistic, count = 0;
|
||||||
index < available_events; index++, ++stat) {
|
index < available_events; index++, ++stat) {
|
||||||
statid = kzalloc(strlen(stat->stat_id) + 1, GFP_KERNEL);
|
p->nvdimm_events_map[count] = kmemdup_nul(stat->stat_id, 8, GFP_KERNEL);
|
||||||
if (!statid) {
|
if (!p->nvdimm_events_map[count]) {
|
||||||
rc = -ENOMEM;
|
rc = -ENOMEM;
|
||||||
goto out_nvdimm_events_map;
|
goto out_nvdimm_events_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
strcpy(statid, stat->stat_id);
|
|
||||||
p->nvdimm_events_map[count] = statid;
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
p->nvdimm_events_map[count] = NULL;
|
p->nvdimm_events_map[count] = NULL;
|
||||||
|
|
|
@ -27,22 +27,31 @@ struct vas_caps_entry {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This function is used to get the notification from the drmgr when
|
* This function is used to get the notification from the drmgr when
|
||||||
* QoS credits are changed. Though receiving the target total QoS
|
* QoS credits are changed.
|
||||||
* credits here, get the official QoS capabilities from the hypervisor.
|
|
||||||
*/
|
*/
|
||||||
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)
|
const char *buf, size_t count)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
u16 creds;
|
u16 creds;
|
||||||
|
|
||||||
err = kstrtou16(buf, 0, &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)
|
if (!err)
|
||||||
err = vas_reconfig_capabilties(caps->win_type);
|
err = vas_reconfig_capabilties(caps->win_type, creds);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
pr_info("Set QoS total credits %u\n", creds);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,7 +101,7 @@ VAS_ATTR_RO(nr_total_credits);
|
||||||
VAS_ATTR_RO(nr_used_credits);
|
VAS_ATTR_RO(nr_used_credits);
|
||||||
|
|
||||||
static struct vas_sysfs_entry update_total_credits_attribute =
|
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[] = {
|
static struct attribute *vas_def_capab_attrs[] = {
|
||||||
&nr_total_credits_attribute.attr,
|
&nr_total_credits_attribute.attr,
|
||||||
|
|
|
@ -779,10 +779,10 @@ static int reconfig_close_windows(struct vas_caps *vcap, int excess_creds,
|
||||||
* changes. Reconfig window configurations based on the credits
|
* changes. Reconfig window configurations based on the credits
|
||||||
* availability from this new capabilities.
|
* 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;
|
struct vas_cop_feat_caps *caps;
|
||||||
int old_nr_creds, new_nr_creds;
|
int old_nr_creds;
|
||||||
struct vas_caps *vcaps;
|
struct vas_caps *vcaps;
|
||||||
int rc = 0, nr_active_wins;
|
int rc = 0, nr_active_wins;
|
||||||
|
|
||||||
|
@ -795,12 +795,6 @@ int vas_reconfig_capabilties(u8 type)
|
||||||
caps = &vcaps->caps;
|
caps = &vcaps->caps;
|
||||||
|
|
||||||
mutex_lock(&vas_pseries_mutex);
|
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);
|
old_nr_creds = atomic_read(&caps->nr_total_credits);
|
||||||
|
|
||||||
|
@ -832,7 +826,6 @@ int vas_reconfig_capabilties(u8 type)
|
||||||
false);
|
false);
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
|
||||||
mutex_unlock(&vas_pseries_mutex);
|
mutex_unlock(&vas_pseries_mutex);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
@ -850,7 +843,7 @@ static int pseries_vas_notifier(struct notifier_block *nb,
|
||||||
struct of_reconfig_data *rd = data;
|
struct of_reconfig_data *rd = data;
|
||||||
struct device_node *dn = rd->dn;
|
struct device_node *dn = rd->dn;
|
||||||
const __be32 *intserv = NULL;
|
const __be32 *intserv = NULL;
|
||||||
int len, rc = 0;
|
int new_nr_creds, len, rc = 0;
|
||||||
|
|
||||||
if ((action == OF_RECONFIG_ATTACH_NODE) ||
|
if ((action == OF_RECONFIG_ATTACH_NODE) ||
|
||||||
(action == OF_RECONFIG_DETACH_NODE))
|
(action == OF_RECONFIG_DETACH_NODE))
|
||||||
|
@ -862,7 +855,15 @@ static int pseries_vas_notifier(struct notifier_block *nb,
|
||||||
if (!intserv)
|
if (!intserv)
|
||||||
return NOTIFY_OK;
|
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)
|
if (rc)
|
||||||
pr_err("Failed reconfig VAS capabilities with DLPAR\n");
|
pr_err("Failed reconfig VAS capabilities with DLPAR\n");
|
||||||
|
|
||||||
|
|
|
@ -135,7 +135,7 @@ struct pseries_vas_window {
|
||||||
};
|
};
|
||||||
|
|
||||||
int sysfs_add_vas_caps(struct vas_cop_feat_caps *caps);
|
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);
|
int __init sysfs_pseries_vas_init(struct vas_all_caps *vas_caps);
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_VAS
|
#ifdef CONFIG_PPC_VAS
|
||||||
|
|
Loading…
Reference in New Issue