diff mbox series

[22/22] firmware: arm_scmi: Add SCMIv3.1 PERFORMANCE_LIMITS_SET checks

Message ID 20220330150551.2573938-23-cristian.marussi@arm.com (mailing list archive)
State New, archived
Headers show
Series SCMIv3.1 Miscellaneous changes | expand

Commit Message

Cristian Marussi March 30, 2022, 3:05 p.m. UTC
Starting with SCMIv3.1, the PERFORMANCE_LIMITS_SET command allows a user
to request only one between max and min ranges to be changed, while leaving
the other untouched if set to zero in the request; anyway SCMIv3.1 states
also explicitly that you cannot leave both of those unchanged (zeroed) when
issuing such command: add a proper check for this condition.

Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
---
 drivers/firmware/arm_scmi/perf.c | 3 +++
 1 file changed, 3 insertions(+)

Comments

Sudeep Holla April 28, 2022, 1:13 p.m. UTC | #1
On Wed, Mar 30, 2022 at 04:05:51PM +0100, Cristian Marussi wrote:
> Starting with SCMIv3.1, the PERFORMANCE_LIMITS_SET command allows a user
> to request only one between max and min ranges to be changed, while leaving
> the other untouched if set to zero in the request; anyway SCMIv3.1 states
> also explicitly that you cannot leave both of those unchanged (zeroed) when
> issuing such command: add a proper check for this condition.
> 
> Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> ---
>  drivers/firmware/arm_scmi/perf.c | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
> index 65ffda5495d6..8f4051aca220 100644
> --- a/drivers/firmware/arm_scmi/perf.c
> +++ b/drivers/firmware/arm_scmi/perf.c
> @@ -423,6 +423,9 @@ static int scmi_perf_limits_set(const struct scmi_protocol_handle *ph,
>  	struct scmi_perf_info *pi = ph->get_priv(ph);
>  	struct perf_dom_info *dom = pi->dom_info + domain;
>  
> +	if (PROTOCOL_REV_MAJOR(pi->version) >= 0x3 && !max_perf && !min_perf)
> +		return -EINVAL;
> +

Do we really need the version check here ? I agree it was explicitly added
in v3.1, but it makes sense on any version really. No ?
Cristian Marussi April 28, 2022, 1:49 p.m. UTC | #2
On Thu, Apr 28, 2022 at 02:13:57PM +0100, Sudeep Holla wrote:
> On Wed, Mar 30, 2022 at 04:05:51PM +0100, Cristian Marussi wrote:
> > Starting with SCMIv3.1, the PERFORMANCE_LIMITS_SET command allows a user
> > to request only one between max and min ranges to be changed, while leaving
> > the other untouched if set to zero in the request; anyway SCMIv3.1 states
> > also explicitly that you cannot leave both of those unchanged (zeroed) when
> > issuing such command: add a proper check for this condition.
> > 
> > Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> > ---
> >  drivers/firmware/arm_scmi/perf.c | 3 +++
> >  1 file changed, 3 insertions(+)
> > 
> > diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
> > index 65ffda5495d6..8f4051aca220 100644
> > --- a/drivers/firmware/arm_scmi/perf.c
> > +++ b/drivers/firmware/arm_scmi/perf.c
> > @@ -423,6 +423,9 @@ static int scmi_perf_limits_set(const struct scmi_protocol_handle *ph,
> >  	struct scmi_perf_info *pi = ph->get_priv(ph);
> >  	struct perf_dom_info *dom = pi->dom_info + domain;
> >  
> > +	if (PROTOCOL_REV_MAJOR(pi->version) >= 0x3 && !max_perf && !min_perf)
> > +		return -EINVAL;
> > +
> 
> Do we really need the version check here ? I agree it was explicitly added
> in v3.1, but it makes sense on any version really. No ?

Indeed seemed a silly patch also to me but given that only in v3.1 it is
explicitly stated that you cannot issue this command with both min and
max ZEROED I though this could have broken older fw that allowed
setting PERF_LIMITS_SET max=0 min=0

....maybe overthought ...

Thanks,
Cristian
Sudeep Holla April 28, 2022, 1:52 p.m. UTC | #3
On Thu, Apr 28, 2022 at 02:49:48PM +0100, Cristian Marussi wrote:
> On Thu, Apr 28, 2022 at 02:13:57PM +0100, Sudeep Holla wrote:
> > On Wed, Mar 30, 2022 at 04:05:51PM +0100, Cristian Marussi wrote:
> > > Starting with SCMIv3.1, the PERFORMANCE_LIMITS_SET command allows a user
> > > to request only one between max and min ranges to be changed, while leaving
> > > the other untouched if set to zero in the request; anyway SCMIv3.1 states
> > > also explicitly that you cannot leave both of those unchanged (zeroed) when
> > > issuing such command: add a proper check for this condition.
> > > 
> > > Signed-off-by: Cristian Marussi <cristian.marussi@arm.com>
> > > ---
> > >  drivers/firmware/arm_scmi/perf.c | 3 +++
> > >  1 file changed, 3 insertions(+)
> > > 
> > > diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
> > > index 65ffda5495d6..8f4051aca220 100644
> > > --- a/drivers/firmware/arm_scmi/perf.c
> > > +++ b/drivers/firmware/arm_scmi/perf.c
> > > @@ -423,6 +423,9 @@ static int scmi_perf_limits_set(const struct scmi_protocol_handle *ph,
> > >  	struct scmi_perf_info *pi = ph->get_priv(ph);
> > >  	struct perf_dom_info *dom = pi->dom_info + domain;
> > >  
> > > +	if (PROTOCOL_REV_MAJOR(pi->version) >= 0x3 && !max_perf && !min_perf)
> > > +		return -EINVAL;
> > > +
> > 
> > Do we really need the version check here ? I agree it was explicitly added
> > in v3.1, but it makes sense on any version really. No ?
> 
> Indeed seemed a silly patch also to me but given that only in v3.1 it is
> explicitly stated that you cannot issue this command with both min and
> max ZEROED I though this could have broken older fw that allowed
> setting PERF_LIMITS_SET max=0 min=0
> 
> ....maybe overthought ...

Hmm, let's keep it unconditional for now. We can add if someone reports
broken firmware. BTW there are no users in the kernel 
diff mbox series

Patch

diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c
index 65ffda5495d6..8f4051aca220 100644
--- a/drivers/firmware/arm_scmi/perf.c
+++ b/drivers/firmware/arm_scmi/perf.c
@@ -423,6 +423,9 @@  static int scmi_perf_limits_set(const struct scmi_protocol_handle *ph,
 	struct scmi_perf_info *pi = ph->get_priv(ph);
 	struct perf_dom_info *dom = pi->dom_info + domain;
 
+	if (PROTOCOL_REV_MAJOR(pi->version) >= 0x3 && !max_perf && !min_perf)
+		return -EINVAL;
+
 	if (dom->fc_info && dom->fc_info->limit_set_addr) {
 		iowrite32(max_perf, dom->fc_info->limit_set_addr);
 		iowrite32(min_perf, dom->fc_info->limit_set_addr + 4);