lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20250303095809.x2mmd52znicl7roy@lcpd911>
Date: Mon, 3 Mar 2025 15:28:09 +0530
From: Dhruva Gole <d-gole@...com>
To: Ulf Hansson <ulf.hansson@...aro.org>
CC: Kamlesh Gurudasani <kamlesh@...com>, <vigneshr@...com>,
        <linux-pm@...r.kernel.org>, <linux-kernel@...r.kernel.org>,
        <khilman@...libre.com>
Subject: Re: [PATCH RFC] pmdomain: core: add support for writeble power
 domain state

Ulf,

On Feb 28, 2025 at 13:39:44 +0100, Ulf Hansson wrote:
> On Fri, 21 Feb 2025 at 14:48, Kamlesh Gurudasani <kamlesh@...com> wrote:
> >
> > Add support for writeable power domain states from debugfs.
> >
> > Defining GENPD_ALLOW_WRITE_DEBUGFS will enable writeable pd_state
> > node in debugfs.
> >
> > Signed-off-by: Kamlesh Gurudasani <kamlesh@...com>
> > ---
> > This has turn out to be really helpful when debugging SCMI protocol
> > for power domain management.
> >
> > Reference has been taken from clock framework which provides similar
> > CLOCK_ALLOW_WRITE_DEBUGFS, which helps to test clocks from debugfs.
> > ---
> >  drivers/pmdomain/core.c | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 77 insertions(+)
> >
> > diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c
> > index 9b2f28b34bb5..6aba0c672da0 100644
> > --- a/drivers/pmdomain/core.c
> > +++ b/drivers/pmdomain/core.c
> > @@ -1298,6 +1298,60 @@ late_initcall_sync(genpd_power_off_unused);
> >
> >  #ifdef CONFIG_PM_SLEEP
> >
> > +#ifdef GENPD_ALLOW_WRITE_DEBUGFS
> > +/*
> > + * This can be dangerous, therefore don't provide any real compile time
> > + * configuration option for this feature.
> > + * People who want to use this will need to modify the source code directly.
> > + */
> > +static int genpd_state_set(void *data, u64 val)
> > +{
> > +
> > +       struct generic_pm_domain *genpd = data;
> > +       int ret = 0;
> > +
> > +       ret = genpd_lock_interruptible(genpd);
> > +       if (ret)
> > +               return -ERESTARTSYS;
> > +
> > +       if (val == 1) {
> > +               genpd->power_on(genpd);
> > +               genpd->status = GENPD_STATE_ON;
> > +       } else if (val == 0) {
> > +               genpd->power_off(genpd);
> > +               genpd->status = GENPD_STATE_OFF;
> > +       }
> > +
> > +       genpd_unlock(genpd);
> > +       return 0;
> 
> This makes the behaviour in genpd inconsistent and I am worried about
> that, even if it's for debugging/development.
> 
> For example, what if there is a device hooked up to the genpd which
> requires its PM domain to stay on? And what about child domains?

Thanks for taking a look.

Agreed that there maybe some paths in genpd that this patch maybe
ignoring and thus could break something fundamental while debugging.

Perhaps we can split this patch up and remove the state_set part till we
figure out the right way of doing it without breaking genPD

BUT, as I said in my previous response I feel that if one is enabling
DEBUG config then anyway they are literally aware of the risk that they
are taking, by exposing raw PD on/off operations from user space.
Perhaps we can continue our debate on the reply I gave earlier on this
thread...

> 
> > +}
> > +
> > +#define pd_state_mode  0644
> > +
> > +static int genpd_state_get(void *data, u64 *val)
> > +{
> > +
> > +       struct generic_pm_domain *genpd = data;
> > +       int ret = 0;
> > +
> > +       ret = genpd_lock_interruptible(genpd);
> > +       if (ret)
> > +               return -ERESTARTSYS;
> > +
> > +       if (genpd->status == GENPD_STATE_OFF)
> > +               *val = 0;
> > +       else
> > +               *val = 1;
> > +
> > +       genpd_unlock(genpd);
> > +       return ret;
> > +}
> > +
> > +DEFINE_DEBUGFS_ATTRIBUTE(pd_state_fops, genpd_state_get,
> > +                        genpd_state_set, "%llu\n");
> > +
> > +#endif /* GENPD_ALLOW_WRITE_DEBUGFS */
> > +
> >  /**
> >   * genpd_sync_power_off - Synchronously power off a PM domain and its parents.
> >   * @genpd: PM domain to power off, if possible.
> > @@ -3639,6 +3693,11 @@ static void genpd_debug_add(struct generic_pm_domain *genpd)
> >         if (genpd->set_performance_state)
> >                 debugfs_create_file("perf_state", 0444,
> >                                     d, genpd, &perf_state_fops);
> > +#ifdef GENPD_ALLOW_WRITE_DEBUGFS
> > +       debugfs_create_file("pd_state", 0644, d, genpd,
> > +                           &pd_state_fops);
> > +#endif /* GENPD_ALLOW_WRITE_DEBUGFS */
> > +
> >  }
> >
> >  static int __init genpd_debug_init(void)
> > @@ -3653,6 +3712,24 @@ static int __init genpd_debug_init(void)
> >         list_for_each_entry(genpd, &gpd_list, gpd_list_node)
> >                 genpd_debug_add(genpd);
> >
> > +#ifdef GENPD_ALLOW_WRITE_DEBUGFS
> > +       pr_warn("\n");
> > +       pr_warn("********************************************************************\n");
> > +       pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
> > +       pr_warn("**                                                                **\n");
> > +       pr_warn("**  WRITEABLE POWER DOMAIN STATE DEBUGFS SUPPORT HAS BEEN ENABLED **\n");
> > +       pr_warn("**  IN THIS KERNEL                                                **\n");
> > +       pr_warn("** This means that this kernel is built to expose pd operations   **\n");
> > +       pr_warn("** such as enabling, disabling, etc.                              **\n");
> > +       pr_warn("** to userspace, which may compromise security on your system.    **\n");
> > +       pr_warn("**                                                                **\n");
> > +       pr_warn("** If you see this message and you are not debugging the          **\n");
> > +       pr_warn("** kernel, report this immediately to your vendor!                **\n");
> > +       pr_warn("**                                                                **\n");
> > +       pr_warn("**     NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE           **\n");
> > +       pr_warn("********************************************************************\n");
> > +#endif /* GENPD_ALLOW_WRITE_DEBUGFS */
> > +
> >         return 0;
> >  }
> >  late_initcall(genpd_debug_init);
> >
> > ---
> > base-commit: d4b0fd87ff0d4338b259dc79b2b3c6f7e70e8afa
> > change-id: 20250221-pm-debug-0824da30890f
> >
> > Best regards,
> > --
> > Kamlesh Gurudasani <kamlesh@...com>
> >
> 
> When working with genpd and SCMI PM domains, a more robust way to
> debug things would be to implement a slim skeleton driver for a
> consumer device. In principle it just needs some basic runtime PM
> support and the corresponding device hooked up to the SCMI PM domain
> in DT. In this way, we can use the existing sysfs interface for

But this will just be a per-device limited solution right? It still
won't allow us a generic way of dealing with all possible scmi IDs  without
having to rebuild the system... Or maybe I am misunderstanding/ missing
something...

> runtime PM, to control and debug the behaviour of the genpd/SCMI PM
> domain.

If I were to come from a user's perspective, then they will want to be able
to get a full view of the system's power status at a glance. Today, I am
not aware of a way how we can do that from genpd. This makes debugging
what is _actually_ ON/OFF in the system a bit tricky..

Users may not even care much for example about the kernel drivers for
certain controllers but still want to ensure that those controller's registers are
accessible to them to use via something like devmem2.
Another application for the get_status part of this patch is for
studying the overall power draw of the system by judging which all IDs
are on/off at a glance.

Hence, if you feel that for now the state_get part of this patch makes
sense it will still help users query the status of all the pd id's in
the system.

Thinking of it... What if we modify the existing status_show() itself
with another column that shows current status similar to runtime status?
status_show today only does a print based off of genpd->status ... and
never really goes and queries the firmware again if by any chance some
other event or activity in the system may have turned ON the device.

For eg. if we have another remote processor request a resource
but genPD was unaware of this request so it just assumes that resource is still
off-0... That's just wrong IMO.

What I am proposing is can we have a get_state callback in genPD which
would be = something like power_ops->state_get in scmi pmdomains
today.
This will help the core pmdomains get an up-to-date view of the system
in the debugFS. Whether genPD decides to update it's internal
genpd->status based on the query is another issue.
But from what it looks like, we definitely have a requirement here to
make sure pm_genpd_summary shows a true-to life status of the power
domains. Not just rely on linux runtime pm or assume that linux is the
only real software who knows and does it all.

> 
> I have a bunch of local code/drivers for this already. Even for
> testing the SCMI perf domain with OPPs. I can share them with you, if
> you are interested?

Yes, please do share. We would love to see your ideas on this so we can
come up with a better solutions together.

-- 
Best regards,
Dhruva Gole
Texas Instruments Incorporated


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ