Subject: ACPI: fix processor limit set error
From: Yi Yang <[EMAIL PROTECTED]>

when echo some invalid values to /proc/acpi/processor/CPU*/limit,
it doesn't return any error info, on the contrary, it successes
and sets some other values, for example:

[EMAIL PROTECTED] /]# echo "0:0A" >/proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] /]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T0
user limit:              P0:T0
thermal limit:           P0:T0
[EMAIL PROTECTED] /]# echo "0:0F" >/proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] /]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T0
user limit:              P0:T0
thermal limit:           P0:T0
[EMAIL PROTECTED] /]# echo "0:0 0:1 0:2" >/proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] /]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T0
user limit:              P0:T0
thermal limit:           P0:T0
[EMAIL PROTECTED] /]#

A correct way is that it should fail and return error info.

This patch fixed this issue, it accepts not only such inputs as "*:*",
but also accepts such inputs as "p*:t*" or "P*:T*" or "p*:*" or "*:t*",
the former "*" in inputs means the allowed processor performance state,
currently it is only a stub and not set to the processor limit data
structure, the latter "*" means the allowed processor throttling state
which rages from 0 to 7 generally. This patch strictly limits inputs to
meet the above conditions, any input which can't meet the above conditions
is considered as invalid input.

Before applying this patch, the test result is below:

[EMAIL PROTECTED] /]# echo "0:0A" >/proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] /]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T0
user limit:              P0:T0
thermal limit:           P0:T0
[EMAIL PROTECTED] /]# echo "0:0F" >/proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] /]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T0
user limit:              P0:T0
thermal limit:           P0:T0
[EMAIL PROTECTED] /]# echo "10:2F" >/proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] /]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T2
user limit:              P0:T2
thermal limit:           P0:T0
[EMAIL PROTECTED] /]# echo "0:0 0:1 0:2" >/proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] /]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T0
user limit:              P0:T0
thermal limit:           P0:T0
[EMAIL PROTECTED] /]#

After applying this patch, the test result is below:

[EMAIL PROTECTED] ~]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T0
user limit:              P0:T0
thermal limit:           P0:T0
[EMAIL PROTECTED] ~]# echo "0:0A" > /proc/acpi/processor/CPU0/limit
-bash: echo: write error: Invalid argument
[EMAIL PROTECTED] ~]# echo "0:0F" > /proc/acpi/processor/CPU0/limit
-bash: echo: write error: Invalid argument
[EMAIL PROTECTED] ~]# echo "P0:T1" > /proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] ~]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T1
user limit:              P0:T1
thermal limit:           P0:T0
[EMAIL PROTECTED] ~]# echo "p0:t1" > /proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] ~]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T1
user limit:              P0:T1
thermal limit:           P0:T0
[EMAIL PROTECTED] ~]# echo "p0:x1" > /proc/acpi/processor/CPU0/limit
-bash: echo: write error: Invalid argument
[EMAIL PROTECTED] ~]# echo "q0:x1" > /proc/acpi/processor/CPU0/limit
-bash: echo: write error: Invalid argument
[EMAIL PROTECTED] ~]# echo "p0:1" > /proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] ~]# echo "q0:x1" > /proc/acpi/processor/CPU0/limit
-bash: echo: write error: Invalid argument
[EMAIL PROTECTED] ~]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T1
user limit:              P0:T1
thermal limit:           P0:T0
[EMAIL PROTECTED] ~]# echo "0:t1" > /proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] ~]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T1
user limit:              P0:T1
thermal limit:           P0:T0
[EMAIL PROTECTED] ~]# echo "0:t1F" > /proc/acpi/processor/CPU0/limit
-bash: echo: write error: Invalid argument
[EMAIL PROTECTED] ~]# echo "" > /proc/acpi/processor/CPU0/limit
-bash: echo: write error: Invalid argument
[EMAIL PROTECTED] ~]# echo "0:0 0:0 0:2 " > /proc/acpi/processor/CPU0/limit
-bash: echo: write error: Invalid argument
[EMAIL PROTECTED] ~]# echo "P0:T1" > /proc/acpi/processor/CPU0/limit
[EMAIL PROTECTED] ~]# cat /proc/acpi/processor/CPU0/limit
active limit:            P0:T1
user limit:              P0:T1
thermal limit:           P0:T0
[EMAIL PROTECTED] ~]#


Signed-off-by: Yi Yang <[EMAIL PROTECTED]>
---
 processor_thermal.c |   42 +++++++++++++++++++++++++++++++-----------
 1 file changed, 31 insertions(+), 11 deletions(-)

diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 06e6f3f..262d56e 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -349,9 +349,11 @@ static ssize_t acpi_processor_write_limit(struct file * 
file,
        int result = 0;
        struct seq_file *m = file->private_data;
        struct acpi_processor *pr = m->private;
-       char limit_string[25] = { '\0' };
+       char limit_string[10] = "";
        int px = 0;
        int tx = 0;
+       char *tmpp = NULL;
+       char tmpstring[10] = "";
 
 
        if (!pr || (count > sizeof(limit_string) - 1)) {
@@ -363,21 +365,39 @@ static ssize_t acpi_processor_write_limit(struct file * 
file,
        }
 
        limit_string[count] = '\0';
+       if ((count > 0) && (limit_string[count-1] == '\n'))
+               limit_string[count-1] = '\0';
 
-       if (sscanf(limit_string, "%d:%d", &px, &tx) != 2) {
-               printk(KERN_ERR PREFIX "Invalid data format\n");
+       tmpp = memchr(limit_string, ':', count);
+       if (tmpp == NULL)
+               return -EINVAL;
+
+       *tmpp = '\0';
+       tmpp = limit_string;
+       if ((limit_string[0] == 'p') || (limit_string[0] == 'P'))
+               tmpp++;
+       px = simple_strtoul(tmpp, NULL, 0);
+       snprintf(tmpstring, 10, "%d", px);
+       if (strcmp(tmpp, tmpstring) != 0)
+               return -EINVAL;
+
+       tmpp += strlen(tmpp) + 1;
+       if ((tmpp[0] == 't') || (tmpp[0] == 'T'))
+               tmpp++;
+       tx = simple_strtoul(tmpp, NULL, 0);
+       if (tx > (pr->throttling.state_count - 1))
+               return -EINVAL;
+       snprintf(tmpstring, 10, "%d", tx);
+       if (strcmp(tmpp, tmpstring) != 0)
                return -EINVAL;
-       }
 
        if (pr->flags.throttling) {
-               if ((tx < 0) || (tx > (pr->throttling.state_count - 1))) {
-                       printk(KERN_ERR PREFIX "Invalid tx\n");
-                       return -EINVAL;
-               }
                pr->limit.user.tx = tx;
-       }
-
-       result = acpi_processor_apply_limit(pr);
+               result = acpi_processor_apply_limit(pr);
+               if (result != 0)
+                       return result;
+       } else
+               return -ENODEV;
 
        return count;
 }


--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to