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]
Date:   Thu, 5 Oct 2023 01:10:03 +0200
From:   Sebastian Reichel <sre@...nel.org>
To:     Mario Limonciello <mario.limonciello@....com>
Cc:     amd-gfx@...ts.freedesktop.org,
        Alex Deucher <alexander.deucher@....com>,
        linux-pm@...r.kernel.org, linux-kernel@...r.kernel.org,
        Jun.ma2@....com
Subject: Re: [PATCH 2/3] power: supply: Don't count 'unknown' scope power
 supplies

Hi,

On Sun, Oct 01, 2023 at 07:00:11PM -0500, Mario Limonciello wrote:
> Let me try to add more detail.
> 
> This is an OEM system that has 3 USB type C ports.  It's an Intel system,
> but this doesn't matter for the issue.
> * when ucsi_acpi is not loaded there are no power supplies in the system and
> it reports power_supply_is_system_supplied() as AC.
> * When ucsi_acpi is loaded 3 power supplies will be registered.
> power_supply_is_system_supplied() reports as DC.
> 
> Now when you add in a Navi3x AMD dGPU to the system the power supplies don't
> change.  This particular dGPU model doesn't contain a USB-C port, so there
> is no UCSI power supply registered.
> 
> As amdgpu is loaded it looks at device initialization whether the system is
> powered by AC or DC.  Here is how it looks:
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c?h=linux-6.5.y#n3834
> 
> On the OEM system if amdgpu loads before the ucsi_acpi driver (such as in
> the initramfs) then the right value is returned for
> power_supply_is_system_supplied() - AC.
> 
> If amdgpu is loaded after the ucsi_acpi driver, the wrong value is returned
> for power_supply_is_system_supplied() - DC.
> 
> This value is very important to set up the dGPU properly.  If the wrong
> value is returned, the wrong value will be notified to the hardware and the
> hardware will not behave properly.  On the OEM system this is a "black
> screen" at bootup along with RAS errors emitted by the dGPU.
> 
> With no changes to a malfunctioning kernel or initramfs binaries I can add
> modprobe.blacklist=ucsi_acpi to kernel command line avoid registering those
> 3 power supplies and the system behaves properly.
> 
> So I think it's inappropriate for "UNKNOWN" scope power supplies to be
> registered and treated as system supplies, at least as it pertains to
> power_supply_is_system_supplied().

So the main issue is, that the ucsi_acpi registers a bunch of
power-supply chargers with unknown scope on a desktop systems
and that results in the system assumed to be supplied from battery.

The problem with your change is, that many of the charger drivers
don't set a scope at all (and thus report unknown scope). Those
obviously should not be skipped. Probably most of these drivers
could be changed to properly set the scope, but it needs to be
checked on a case-by-case basis. With your current patch they would
regress in the oposite direction of your use-case.

Ideally ucsi is changed to properly describe the scope, but I
suppose this information is not available in ACPI?

Assuming that the above are not solvable easily, my idea would be to
only count the number of POWER_SUPPLY_TYPE_BATTERY device, which have
!POWER_SUPPLY_SCOPE_DEVICE and exit early if there are none.
Basically change __power_supply_is_system_supplied(), so that it
looks like this:

...
	if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret))
		if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE)
			return 0;

	if (psy->desc->type == POWER_SUPPLY_TYPE_BATTERY)
			(*count)++;
    else
		if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_ONLINE,
					&ret))
			return ret.intval;
...

That should work in both cases.

-- Sebastian

> > >   drivers/power/supply/power_supply_core.c | 2 +-
> > >   1 file changed, 1 insertion(+), 1 deletion(-)
> > > 
> > > diff --git a/drivers/power/supply/power_supply_core.c b/drivers/power/supply/power_supply_core.c
> > > index d325e6dbc770..3de6e6d00815 100644
> > > --- a/drivers/power/supply/power_supply_core.c
> > > +++ b/drivers/power/supply/power_supply_core.c
> > > @@ -349,7 +349,7 @@ static int __power_supply_is_system_supplied(struct device *dev, void *data)
> > >   	unsigned int *count = data;
> > >   	if (!psy->desc->get_property(psy, POWER_SUPPLY_PROP_SCOPE, &ret))
> > > -		if (ret.intval == POWER_SUPPLY_SCOPE_DEVICE)
> > > +		if (ret.intval != POWER_SUPPLY_SCOPE_SYSTEM)
> > >   			return 0;
> > >   	(*count)++;
> > > -- 
> > > 2.34.1
> > > 
> 

Download attachment "signature.asc" of type "application/pgp-signature" (834 bytes)

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ