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: <1503538979-22693-7-git-send-email-cw00.choi@samsung.com>
Date:   Thu, 24 Aug 2017 10:42:53 +0900
From:   Chanwoo Choi <cw00.choi@...sung.com>
To:     myungjoo.ham@...sung.com, kyungmin.park@...sung.com,
        cw00.choi@...sung.com
Cc:     rafael.j.wysocki@...el.com, chanwoo@...nel.org,
        inki.dae@...sung.com, linux-kernel@...r.kernel.org,
        linux-pm@...r.kernel.org
Subject: [PATCH 06/12] PM / devfreq: Check the entered min/max_freq is
 supported or not

The existing {min|max}_freq_store() only check the range of
entered frequency. If the unsupported frequency is entered
and the entered frequency is within the ranges, {min|max}_freq_store()
will store it to devfreq->{min|max}_freq. And then when some user
try to read the {min|max}_freq, the devfreq show the unsupported
frequency value.

In order to fix this issue, this patch checks whether the entered
frequency is supported or not by OPP interface.

Signed-off-by: Chanwoo Choi <cw00.choi@...sung.com>
---
 drivers/devfreq/devfreq.c | 35 +++++++++++++++++++++++++++++++----
 1 file changed, 31 insertions(+), 4 deletions(-)

diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c
index 56f8a0473834..f10017fe400f 100644
--- a/drivers/devfreq/devfreq.c
+++ b/drivers/devfreq/devfreq.c
@@ -97,6 +97,25 @@ static unsigned long find_available_max_freq(struct devfreq *devfreq)
 	return max_freq;
 }
 
+static int is_supported_freq(struct devfreq *devfreq, unsigned long freq)
+{
+	struct device *dev = devfreq->dev.parent;
+	struct dev_pm_opp *opp;
+	int ret = 0;
+
+	/* Check whether entered frequency is supported or not */
+	opp = dev_pm_opp_find_freq_exact(dev, freq, true);
+	if (PTR_ERR(opp) == -ERANGE)
+		opp = dev_pm_opp_find_freq_exact(dev, freq, false);
+
+	if (IS_ERR(opp))
+		ret = PTR_ERR(opp);
+
+	dev_pm_opp_put(opp);
+
+	return ret;
+}
+
 /**
  * devfreq_get_freq_level() - Lookup freq_table for the frequency
  * @devfreq:	the devfreq instance
@@ -1099,9 +1118,8 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
 			      const char *buf, size_t count)
 {
 	struct devfreq *df = to_devfreq(dev);
-	unsigned long value;
+	unsigned long value, max;
 	int ret;
-	unsigned long max;
 
 	ret = sscanf(buf, "%lu", &value);
 	if (ret != 1)
@@ -1114,6 +1132,11 @@ static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr,
 		goto unlock;
 	}
 
+	/* Check whether entered frequency is supported or not */
+	ret = is_supported_freq(df, value);
+	if (ret < 0)
+		goto unlock;
+
 	df->min_freq = value;
 	update_devfreq(df);
 	ret = count;
@@ -1126,9 +1149,8 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
 			      const char *buf, size_t count)
 {
 	struct devfreq *df = to_devfreq(dev);
-	unsigned long value;
+	unsigned long value, min;
 	int ret;
-	unsigned long min;
 
 	ret = sscanf(buf, "%lu", &value);
 	if (ret != 1)
@@ -1141,6 +1163,11 @@ static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr,
 		goto unlock;
 	}
 
+	/* Check whether entered frequency is supported or not */
+	ret = is_supported_freq(df, value);
+	if (ret < 0)
+		goto unlock;
+
 	df->max_freq = value;
 	update_devfreq(df);
 	ret = count;
-- 
1.9.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ