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: <20220824142229.RFT.v2.2.I6f77860e5cd98bf5c67208fa9edda4a08847c304@changeid>
Date:   Wed, 24 Aug 2022 14:22:57 -0700
From:   Douglas Anderson <dianders@...omium.org>
To:     Mark Brown <broonie@...nel.org>
Cc:     Andrew Halaney <ahalaney@...hat.com>,
        Douglas Anderson <dianders@...omium.org>,
        Liam Girdwood <lgirdwood@...il.com>,
        linux-kernel@...r.kernel.org
Subject: [RFT PATCH v2 2/2] regulator: core: Don't err if allow-set-load but no allowed-modes

Apparently the device trees of some boards have the property
"regulator-allow-set-load" for some of their regulators but then they
don't specify anything for "regulator-allowed-modes". That's not
really legit, but...

...before commit efb0cb50c427 ("regulator: qcom-rpmh: Implement
get_optimum_mode(), not set_load()") they used to get away with it, at
least on boards using RPMH regulators. That's because when a regulator
driver implements set_load() then the core doesn't look at
"regulator-allowed-modes" when trying to automatically adjust things
in response to the regulator's load. The core doesn't know what mode
we'll end up in, so how could it validate it?

Said another way: before commit efb0cb50c427 ("regulator: qcom-rpmh:
Implement get_optimum_mode(), not set_load()") some boards _were_
having the regulator mode adjusted despite listing no allowed
modes. After commit efb0cb50c427 ("regulator: qcom-rpmh: Implement
get_optimum_mode(), not set_load()") these same boards were now
getting an error returned when trying to use their regulators, since
simply enabling a regulator tries to update its load and that was
failing.

We don't really want to go back to the behavior from before commit
efb0cb50c427 ("regulator: qcom-rpmh: Implement get_optimum_mode(), not
set_load()"). Boards shouldn't have been changing modes if no allowed
modes were listed. However, the behavior after commit efb0cb50c427
("regulator: qcom-rpmh: Implement get_optimum_mode(), not set_load()")
isn't the best because now boards can't even turn their regulators on.

Let's choose to detect this case and return "no error" from
drms_uA_update(). The net-result will be _different_ behavior than we
had before commit efb0cb50c427 ("regulator: qcom-rpmh: Implement
get_optimum_mode(), not set_load()"), but this new behavior seems more
correct. If a board truly needed the mode switched then its device
tree should be updated to list the allowed modes.

Reported-by: Andrew Halaney <ahalaney@...hat.com>
Fixes: efb0cb50c427 ("regulator: qcom-rpmh: Implement get_optimum_mode(), not set_load()")
Signed-off-by: Douglas Anderson <dianders@...omium.org>
---

Changes in v2:
- Added ("Don't err if allow-set-load but no allowed-modes").

 drivers/regulator/core.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
index 0bc4b9b0a885..1d030831aeae 100644
--- a/drivers/regulator/core.c
+++ b/drivers/regulator/core.c
@@ -977,6 +977,18 @@ static int drms_uA_update(struct regulator_dev *rdev)
 			rdev_err(rdev, "failed to set load %d: %pe\n",
 				 current_uA, ERR_PTR(err));
 	} else {
+		/*
+		 * Unfortunately in some cases the constraints->valid_ops has
+		 * REGULATOR_CHANGE_DRMS but there are no valid modes listed.
+		 * That's not really legit but we won't consider it a fatal
+		 * error here. We'll treat it as if REGULATOR_CHANGE_DRMS
+		 * wasn't set.
+		 */
+		if (!rdev->constraints->valid_modes_mask) {
+			rdev_dbg(rdev, "Can change modes; but no valid mode\n");
+			return 0;
+		}
+
 		/* get output voltage */
 		output_uV = regulator_get_voltage_rdev(rdev);
 
-- 
2.37.2.672.g94769d06f0-goog

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ