linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/3] mailbox: ACPI: Remove incorrect error message about parsing PCCT
@ 2018-04-24 19:35 Al Stone
  2018-04-24 19:35 ` [PATCH v2 1/3] ACPI: improve function documentation for acpi_parse_entries_array() Al Stone
                   ` (2 more replies)
  0 siblings, 3 replies; 10+ messages in thread
From: Al Stone @ 2018-04-24 19:35 UTC (permalink / raw)
  To: linux-acpi, linux-kernel; +Cc: Al Stone

This set of patches provide some cleanup in ACPI for minor issues
found while correcting a bogus error message (the first two patches),
and the correction for the error message itself (patch 3/3).  Note
that patches 1/3 and 2/3 are not required for 3/3 to work: 1/3 only
changes a comment and 2/3 makes an ACPI table parsing loop a wee bit
more robust.

For patch 3/3, many systems on boot have been reporting "Error parsing
PCC subspaces from PCCT" which turns out to not be an error at all.
The issue is that the probe for ACPI mailboxes defined in the PCCT
(Platform Communications Channel Table) makes a faulty assumption about
the content of the PCCT.  What's more, when the error is reported, no
further PCC mailboxes are set up, even when they have been defined
in the PCCT.  So, in the reported cases, there was no error and the
data in the PCCT was being ignored.  This is described in more detail
in patch 3/3.

Since these patches primarily involve ACPI usages, it may make
sense for all of them to go through the linux-acpi tree; clearly,
this is up to the maintainers, though.

v2:
  -- removed one extraneous '+' in a comment in patch 3/3
  -- fixed an if test that had a predicate that kbuild pointed out would
     always be zero

Al Stone (3):
  ACPI: improve function documentation for acpi_parse_entries_array()
  ACPI: ensure acpi_parse_entries_array() does not access non-existent
    table data
  mailbox: ACPI: erroneous error message when parsing the ACPI PCCT

 drivers/acpi/tables.c |  9 ++---
 drivers/mailbox/pcc.c | 99 +++++++++++++++++++++++++++++++++++++--------------
 2 files changed, 78 insertions(+), 30 deletions(-)

-- 
2.14.3

^ permalink raw reply	[flat|nested] 10+ messages in thread

* [PATCH v2 1/3] ACPI: improve function documentation for acpi_parse_entries_array()
  2018-04-24 19:35 [PATCH v2 0/3] mailbox: ACPI: Remove incorrect error message about parsing PCCT Al Stone
@ 2018-04-24 19:35 ` Al Stone
  2018-04-27 11:04   ` Rafael J. Wysocki
  2018-04-24 19:35 ` [PATCH v2 2/3] ACPI: ensure acpi_parse_entries_array() does not access non-existent table data Al Stone
  2018-04-24 19:35 ` [PATCH v2 3/3] mailbox: ACPI: erroneous error message when parsing the ACPI PCCT Al Stone
  2 siblings, 1 reply; 10+ messages in thread
From: Al Stone @ 2018-04-24 19:35 UTC (permalink / raw)
  To: linux-acpi, linux-kernel; +Cc: Al Stone, Rafael J . Wysocki, Len Brown

I found the description of the table_size argument to the function
acpi_parse_entries_array() unclear and ambiguous.  This is a minor
documentation change to improve that description so I don't misuse
the argument again in the future, and it is hopefully clearer to
other future users.

Signed-off-by: Al Stone <ahs3@redhat.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Len Brown <lenb@kernel.org>
---
 drivers/acpi/tables.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 849c4fb19b03..21535762b890 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -222,7 +222,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
  * acpi_parse_entries_array - for each proc_num find a suitable subtable
  *
  * @id: table id (for debugging purposes)
- * @table_size: single entry size
+ * @table_size: size of the root table; i.e., the offset from the very
+ *              first byte of the complete ACPI table, to the first byte
+ *              of the first subtable
  * @table_header: where does the table start?
  * @proc: array of acpi_subtable_proc struct containing entry id
  *        and associated handler with it
@@ -400,7 +402,7 @@ int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
 		return -ENODEV;
 }
 
-/* 
+/*
  * The BIOS is supposed to supply a single APIC/MADT,
  * but some report two.  Provide a knob to use either.
  * (don't you wish instance 0 and 1 were not the same?)
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 2/3] ACPI: ensure acpi_parse_entries_array() does not access non-existent table data
  2018-04-24 19:35 [PATCH v2 0/3] mailbox: ACPI: Remove incorrect error message about parsing PCCT Al Stone
  2018-04-24 19:35 ` [PATCH v2 1/3] ACPI: improve function documentation for acpi_parse_entries_array() Al Stone
@ 2018-04-24 19:35 ` Al Stone
  2018-04-27 11:05   ` Rafael J. Wysocki
  2018-04-24 19:35 ` [PATCH v2 3/3] mailbox: ACPI: erroneous error message when parsing the ACPI PCCT Al Stone
  2 siblings, 1 reply; 10+ messages in thread
From: Al Stone @ 2018-04-24 19:35 UTC (permalink / raw)
  To: linux-acpi, linux-kernel; +Cc: Al Stone, Rafael J . Wysocki, Len Brown

For ACPI tables that have subtables, acpi_parse_entries_array() gets used
to step through each of the subtables in memory.  The primary loop for this
was checking that the beginning location of the subtable being examined
plus the length of struct acpi_subtable_header was not beyond the end of
the complete ACPI table; if it wasn't, the subtable could be examined, but
if it was the loop would terminate as it should.

In the middle of this subtable loop, a callback is used to examine the
subtable in detail.

Should the callback function try to examine elements of the subtable that
are located past the subtable header, and the ACPI table containing this
subtable has an incorrect length, it is possible to access either invalid
or protected memory and cause a fault.  And, the length of struct
acpi_subtable_header will always be smaller than the length of the actual
subtable.

To fix this, we make the main loop check that the beginning of the
subtable being examined plus the actual length of the subtable does
not go past the end of the enclosing ACPI table.  While this cannot
protect us from malicious callback functions, it can prevent us from
failing because of some poorly constructed ACPI tables.

Found by inspection.  There is no functional change to existing code
that is known to work when calling acpi_parse_entries_array().

Signed-off-by: Al Stone <ahs3@redhat.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Len Brown <lenb@kernel.org>
---
 drivers/acpi/tables.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 21535762b890..c7b028f231a6 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -271,8 +271,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
 	entry = (struct acpi_subtable_header *)
 	    ((unsigned long)table_header + table_size);
 
-	while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
-	       table_end) {
+	while (((unsigned long)entry + entry->length) <= table_end) {
 		if (max_entries && count >= max_entries)
 			break;
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* [PATCH v2 3/3] mailbox: ACPI: erroneous error message when parsing the ACPI PCCT
  2018-04-24 19:35 [PATCH v2 0/3] mailbox: ACPI: Remove incorrect error message about parsing PCCT Al Stone
  2018-04-24 19:35 ` [PATCH v2 1/3] ACPI: improve function documentation for acpi_parse_entries_array() Al Stone
  2018-04-24 19:35 ` [PATCH v2 2/3] ACPI: ensure acpi_parse_entries_array() does not access non-existent table data Al Stone
@ 2018-04-24 19:35 ` Al Stone
  2018-04-27 11:16   ` Rafael J. Wysocki
  2 siblings, 1 reply; 10+ messages in thread
From: Al Stone @ 2018-04-24 19:35 UTC (permalink / raw)
  To: linux-acpi, linux-kernel
  Cc: Al Stone, Jassi Brar, Rafael J . Wysocki, Len Brown

There have been multiple reports of the following error message:

[    0.068293] Error parsing PCC subspaces from PCCT

This error message is not correct.  In multiple cases examined, the PCCT
(Platform Communications Channel Table) concerned is actually properly
constructed; the problem is that acpi_pcc_probe() which reads the PCCT
is making the assumption that the only valid PCCT is one that contains
subtables of one of two types: ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE or
ACPI_PCCT_TYPE_HW_REDUCED_TYPE2.  The number of subtables of these
types are counted and as long as there is at least one of the desired
types, the acpi_pcc_probe() succeeds.  When no subtables of these types
are found, regardless of whether or not any other subtable types are
present, the error mentioned above is reported.

In the cases reported to me personally, the PCCT contains exactly one
subtable of type ACPI_PCCT_TYPE_GENERIC_SUBSPACE.  The function
acpi_pcc_probe() does not count it as a valid subtable, so believes
there to be no valid subtables, and hence outputs the error message.

An example of the PCCT being reported as erroneous yet perfectly fine
is the following:

                    Signature : "PCCT"
                 Table Length : 0000006E
                     Revision : 05
                     Checksum : A9
                       Oem ID : "XXXXXX"
                 Oem Table ID : "XXXXX   "
                 Oem Revision : 00002280
              Asl Compiler ID : "XXXX"
        Asl Compiler Revision : 00000002

        Flags (decoded below) : 00000001
                     Platform : 1
                     Reserved : 0000000000000000

                Subtable Type : 00 [Generic Communications Subspace]
                       Length : 3E

                     Reserved : 000000000000
                 Base Address : 00000000DCE43018
               Address Length : 0000000000001000

            Doorbell Register : [Generic Address Structure]
                     Space ID : 01 [SystemIO]
                    Bit Width : 08
                   Bit Offset : 00
         Encoded Access Width : 01 [Byte Access:8]
                      Address : 0000000000001842

                Preserve Mask : 00000000000000FD
                   Write Mask : 0000000000000002
              Command Latency : 00001388
          Maximum Access Rate : 00000000
      Minimum Turnaround Time : 0000

To fix this, we count up all of the possible subtable types for the
PCCT, and only report an error when there are none (which could mean
either no subtables, or no valid subtables), or there are too many.
We also change the logic so that if there is a valid subtable, we
do try to initialize it per the PCCT subtable contents.  This is a
change in functionality; previously, the probe would have returned
right after the error message and would not have tried to use any
other subtable definition.

Tested on my personal laptop which showed the error previously; the
error message no longer appears and the laptop appears to operate
normally.

Signed-off-by: Al Stone <ahs3@redhat.com>
Cc: Jassi Brar <jassisinghbrar@gmail.com>
Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
Cc: Len Brown <lenb@kernel.org>
---
 drivers/mailbox/pcc.c | 99 +++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 73 insertions(+), 26 deletions(-)

diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
index 3ef7f036ceea..cc77a2f1694f 100644
--- a/drivers/mailbox/pcc.c
+++ b/drivers/mailbox/pcc.c
@@ -372,6 +372,35 @@ static const struct mbox_chan_ops pcc_chan_ops = {
 	.send_data = pcc_send_data,
 };
 
+/*
+ *
+ * count_pcc_subspaces -- Count the PCC subspaces that are not used in
+ *		reduced hardware systems.
+ * @header: Pointer to the ACPI subtable header under the PCCT.
+ * @end: End of subtable entry.
+ *
+ * Return: 0 for Success, else errno.
+ *
+ * This gets called for each entry in the PCC table.
+ */
+static int count_pcc_subspaces(struct acpi_subtable_header *header,
+		const unsigned long end)
+{
+	struct acpi_pcct_subspace *pcct_ss =
+				(struct acpi_pcct_subspace *) header;
+
+	if ((pcct_ss->header.type <= ACPI_PCCT_TYPE_RESERVED) &&
+	    (pcct_ss->header.type != ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) &&
+	    (pcct_ss->header.type !=
+				ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) {
+		pr_warn("PCCT count: useful subtype = %d\n",
+			pcct_ss->header.type);
+		return 0;
+	}
+	pr_warn("PCCT count: unwanted subtype = %d\n", pcct_ss->header.type);
+	return -EINVAL;
+}
+
 /**
  * parse_pcc_subspace - Parse the PCC table and verify PCC subspace
  *		entries. There should be one entry per PCC client.
@@ -395,10 +424,14 @@ static int parse_pcc_subspace(struct acpi_subtable_header *header,
 		    && (pcct_ss->header.type !=
 				ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) {
 			pr_err("Incorrect PCC Subspace type detected\n");
+			pr_warn("PCCT parse: unwanted subtype = %d\n",
+				pcct_ss->header.type);
 			return -EINVAL;
 		}
 	}
 
+	pcct_ss = (struct acpi_pcct_hw_reduced *) header;
+	pr_warn("PCCT parse: useful subtype = %d\n", pcct_ss->header.type);
 	return 0;
 }
 
@@ -449,8 +482,8 @@ static int __init acpi_pcc_probe(void)
 	struct acpi_table_header *pcct_tbl;
 	struct acpi_subtable_header *pcct_entry;
 	struct acpi_table_pcct *acpi_pcct_tbl;
+	struct acpi_subtable_proc proc[ACPI_PCCT_TYPE_RESERVED];
 	int count, i, rc;
-	int sum = 0;
 	acpi_status status = AE_OK;
 
 	/* Search for PCCT */
@@ -459,43 +492,50 @@ static int __init acpi_pcc_probe(void)
 	if (ACPI_FAILURE(status) || !pcct_tbl)
 		return -ENODEV;
 
-	count = acpi_table_parse_entries(ACPI_SIG_PCCT,
-			sizeof(struct acpi_table_pcct),
-			ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE,
-			parse_pcc_subspace, MAX_PCC_SUBSPACES);
-	sum += (count > 0) ? count : 0;
-
-	count = acpi_table_parse_entries(ACPI_SIG_PCCT,
-			sizeof(struct acpi_table_pcct),
-			ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2,
-			parse_pcc_subspace, MAX_PCC_SUBSPACES);
-	sum += (count > 0) ? count : 0;
+	/* Set up the subtable handlers */
+	for (i = ACPI_PCCT_TYPE_GENERIC_SUBSPACE;
+	     i < ACPI_PCCT_TYPE_RESERVED;
+	     i++) {
+		proc[i].id = i;
+		if (i == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
+		    i == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)
+			proc[i].handler = parse_pcc_subspace;
+		else
+			proc[i].handler = count_pcc_subspaces;
+		proc[i].count = 0;
+	}
 
-	if (sum == 0 || sum >= MAX_PCC_SUBSPACES) {
-		pr_err("Error parsing PCC subspaces from PCCT\n");
+	count = acpi_table_parse_entries_array(ACPI_SIG_PCCT,
+			sizeof(struct acpi_table_pcct), proc,
+			ACPI_PCCT_TYPE_RESERVED, MAX_PCC_SUBSPACES);
+	if (count == 0) {
+		pr_warn("PCCT provided but has no subspaces defined\n");
+		return -EINVAL;
+	} else if (count > MAX_PCC_SUBSPACES) {
+		pr_warn("Too many PCC subspaces defined in PCCT\n");
 		return -EINVAL;
 	}
 
 	pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) *
-			sum, GFP_KERNEL);
+			count, GFP_KERNEL);
 	if (!pcc_mbox_channels) {
 		pr_err("Could not allocate space for PCC mbox channels\n");
 		return -ENOMEM;
 	}
 
-	pcc_doorbell_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL);
+	pcc_doorbell_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL);
 	if (!pcc_doorbell_vaddr) {
 		rc = -ENOMEM;
 		goto err_free_mbox;
 	}
 
-	pcc_doorbell_ack_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL);
+	pcc_doorbell_ack_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL);
 	if (!pcc_doorbell_ack_vaddr) {
 		rc = -ENOMEM;
 		goto err_free_db_vaddr;
 	}
 
-	pcc_doorbell_irq = kcalloc(sum, sizeof(int), GFP_KERNEL);
+	pcc_doorbell_irq = kcalloc(count, sizeof(int), GFP_KERNEL);
 	if (!pcc_doorbell_irq) {
 		rc = -ENOMEM;
 		goto err_free_db_ack_vaddr;
@@ -509,18 +549,25 @@ static int __init acpi_pcc_probe(void)
 	if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL)
 		pcc_mbox_ctrl.txdone_irq = true;
 
-	for (i = 0; i < sum; i++) {
+	for (i = 0; i < count; i++) {
 		struct acpi_generic_address *db_reg;
-		struct acpi_pcct_hw_reduced *pcct_ss;
+		struct acpi_pcct_subspace *pcct_ss;
 		pcc_mbox_channels[i].con_priv = pcct_entry;
 
-		pcct_ss = (struct acpi_pcct_hw_reduced *) pcct_entry;
+		if (pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
+		    pcct_entry->type ==
+				ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
+			struct acpi_pcct_hw_reduced *pcct_hrss;
+
+			pcct_hrss = (struct acpi_pcct_hw_reduced *) pcct_entry;
 
-		if (pcc_mbox_ctrl.txdone_irq) {
-			rc = pcc_parse_subspace_irq(i, pcct_ss);
-			if (rc < 0)
-				goto err;
+			if (pcc_mbox_ctrl.txdone_irq) {
+				rc = pcc_parse_subspace_irq(i, pcct_hrss);
+				if (rc < 0)
+					goto err;
+			}
 		}
+		pcct_ss = (struct acpi_pcct_subspace *) pcct_entry;
 
 		/* If doorbell is in system memory cache the virt address */
 		db_reg = &pcct_ss->doorbell_register;
@@ -531,7 +578,7 @@ static int __init acpi_pcc_probe(void)
 			((unsigned long) pcct_entry + pcct_entry->length);
 	}
 
-	pcc_mbox_ctrl.num_chans = sum;
+	pcc_mbox_ctrl.num_chans = count;
 
 	pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans);
 
-- 
2.14.3

^ permalink raw reply related	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/3] ACPI: improve function documentation for acpi_parse_entries_array()
  2018-04-24 19:35 ` [PATCH v2 1/3] ACPI: improve function documentation for acpi_parse_entries_array() Al Stone
@ 2018-04-27 11:04   ` Rafael J. Wysocki
  2018-04-30 23:27     ` Al Stone
  0 siblings, 1 reply; 10+ messages in thread
From: Rafael J. Wysocki @ 2018-04-27 11:04 UTC (permalink / raw)
  To: Al Stone
  Cc: ACPI Devel Maling List, Linux Kernel Mailing List,
	Rafael J . Wysocki, Len Brown

On Tue, Apr 24, 2018 at 9:35 PM, Al Stone <ahs3@redhat.com> wrote:
> I found the description of the table_size argument to the function
> acpi_parse_entries_array() unclear and ambiguous.  This is a minor
> documentation change to improve that description so I don't misuse
> the argument again in the future, and it is hopefully clearer to
> other future users.
>
> Signed-off-by: Al Stone <ahs3@redhat.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Len Brown <lenb@kernel.org>
> ---
>  drivers/acpi/tables.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
> index 849c4fb19b03..21535762b890 100644
> --- a/drivers/acpi/tables.c
> +++ b/drivers/acpi/tables.c
> @@ -222,7 +222,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>   * acpi_parse_entries_array - for each proc_num find a suitable subtable
>   *
>   * @id: table id (for debugging purposes)
> - * @table_size: single entry size
> + * @table_size: size of the root table; i.e., the offset from the very
> + *              first byte of the complete ACPI table, to the first byte
> + *              of the first subtable

But alas this needs to be one line.

You can add more details in the comment body below.

>   * @table_header: where does the table start?
>   * @proc: array of acpi_subtable_proc struct containing entry id
>   *        and associated handler with it
> @@ -400,7 +402,7 @@ int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
>                 return -ENODEV;
>  }

Thanks,
Rafael

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/3] ACPI: ensure acpi_parse_entries_array() does not access non-existent table data
  2018-04-24 19:35 ` [PATCH v2 2/3] ACPI: ensure acpi_parse_entries_array() does not access non-existent table data Al Stone
@ 2018-04-27 11:05   ` Rafael J. Wysocki
  2018-04-30 23:28     ` Al Stone
  0 siblings, 1 reply; 10+ messages in thread
From: Rafael J. Wysocki @ 2018-04-27 11:05 UTC (permalink / raw)
  To: Al Stone
  Cc: ACPI Devel Maling List, Linux Kernel Mailing List,
	Rafael J . Wysocki, Len Brown

On Tue, Apr 24, 2018 at 9:35 PM, Al Stone <ahs3@redhat.com> wrote:
> For ACPI tables that have subtables, acpi_parse_entries_array() gets used
> to step through each of the subtables in memory.  The primary loop for this
> was checking that the beginning location of the subtable being examined
> plus the length of struct acpi_subtable_header was not beyond the end of
> the complete ACPI table; if it wasn't, the subtable could be examined, but
> if it was the loop would terminate as it should.
>
> In the middle of this subtable loop, a callback is used to examine the
> subtable in detail.
>
> Should the callback function try to examine elements of the subtable that
> are located past the subtable header, and the ACPI table containing this
> subtable has an incorrect length, it is possible to access either invalid
> or protected memory and cause a fault.  And, the length of struct
> acpi_subtable_header will always be smaller than the length of the actual
> subtable.
>
> To fix this, we make the main loop check that the beginning of the
> subtable being examined plus the actual length of the subtable does
> not go past the end of the enclosing ACPI table.  While this cannot
> protect us from malicious callback functions, it can prevent us from
> failing because of some poorly constructed ACPI tables.
>
> Found by inspection.  There is no functional change to existing code
> that is known to work when calling acpi_parse_entries_array().
>
> Signed-off-by: Al Stone <ahs3@redhat.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Len Brown <lenb@kernel.org>
> ---
>  drivers/acpi/tables.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
> index 21535762b890..c7b028f231a6 100644
> --- a/drivers/acpi/tables.c
> +++ b/drivers/acpi/tables.c
> @@ -271,8 +271,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
>         entry = (struct acpi_subtable_header *)
>             ((unsigned long)table_header + table_size);
>
> -       while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
> -              table_end) {
> +       while (((unsigned long)entry + entry->length) <= table_end) {

The inner parens are not needed.

>                 if (max_entries && count >= max_entries)
>                         break;
>
> --

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 3/3] mailbox: ACPI: erroneous error message when parsing the ACPI PCCT
  2018-04-24 19:35 ` [PATCH v2 3/3] mailbox: ACPI: erroneous error message when parsing the ACPI PCCT Al Stone
@ 2018-04-27 11:16   ` Rafael J. Wysocki
  2018-04-30 23:39     ` Al Stone
  0 siblings, 1 reply; 10+ messages in thread
From: Rafael J. Wysocki @ 2018-04-27 11:16 UTC (permalink / raw)
  To: Al Stone
  Cc: ACPI Devel Maling List, Linux Kernel Mailing List, Jassi Brar,
	Rafael J . Wysocki, Len Brown

On Tue, Apr 24, 2018 at 9:35 PM, Al Stone <ahs3@redhat.com> wrote:
> There have been multiple reports of the following error message:
>
> [    0.068293] Error parsing PCC subspaces from PCCT
>

[cut]

>
> Tested on my personal laptop which showed the error previously; the
> error message no longer appears and the laptop appears to operate
> normally.
>
> Signed-off-by: Al Stone <ahs3@redhat.com>
> Cc: Jassi Brar <jassisinghbrar@gmail.com>
> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
> Cc: Len Brown <lenb@kernel.org>
> ---
>  drivers/mailbox/pcc.c | 99 +++++++++++++++++++++++++++++++++++++--------------
>  1 file changed, 73 insertions(+), 26 deletions(-)
>
> diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
> index 3ef7f036ceea..cc77a2f1694f 100644
> --- a/drivers/mailbox/pcc.c
> +++ b/drivers/mailbox/pcc.c
> @@ -372,6 +372,35 @@ static const struct mbox_chan_ops pcc_chan_ops = {
>         .send_data = pcc_send_data,
>  };
>
> +/*
> + *
> + * count_pcc_subspaces -- Count the PCC subspaces that are not used in
> + *             reduced hardware systems.

One line here, please.

> + * @header: Pointer to the ACPI subtable header under the PCCT.
> + * @end: End of subtable entry.
> + *
> + * Return: 0 for Success, else errno.

The only errno returned appears to be -EINVAL, so maybe say when that
is returned and then "or 0 otherwise".

> + *
> + * This gets called for each entry in the PCC table.
> + */
> +static int count_pcc_subspaces(struct acpi_subtable_header *header,
> +               const unsigned long end)
> +{
> +       struct acpi_pcct_subspace *pcct_ss =
> +                               (struct acpi_pcct_subspace *) header;

This can be one line (ignore warnings from checkpatch about that).

> +
> +       if ((pcct_ss->header.type <= ACPI_PCCT_TYPE_RESERVED) &&
> +           (pcct_ss->header.type != ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) &&
> +           (pcct_ss->header.type !=
> +                               ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) {

This can be one line too.

> +               pr_warn("PCCT count: useful subtype = %d\n",
> +                       pcct_ss->header.type);

Why pr_warn()?

> +               return 0;
> +       }
> +       pr_warn("PCCT count: unwanted subtype = %d\n", pcct_ss->header.type);
> +       return -EINVAL;
> +}
> +
>  /**
>   * parse_pcc_subspace - Parse the PCC table and verify PCC subspace
>   *             entries. There should be one entry per PCC client.
> @@ -395,10 +424,14 @@ static int parse_pcc_subspace(struct acpi_subtable_header *header,
>                     && (pcct_ss->header.type !=
>                                 ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) {
>                         pr_err("Incorrect PCC Subspace type detected\n");
> +                       pr_warn("PCCT parse: unwanted subtype = %d\n",
> +                               pcct_ss->header.type);

Maybe merge the two messages?

>                         return -EINVAL;
>                 }
>         }
>
> +       pcct_ss = (struct acpi_pcct_hw_reduced *) header;
> +       pr_warn("PCCT parse: useful subtype = %d\n", pcct_ss->header.type);
>         return 0;
>  }
>
> @@ -449,8 +482,8 @@ static int __init acpi_pcc_probe(void)
>         struct acpi_table_header *pcct_tbl;
>         struct acpi_subtable_header *pcct_entry;
>         struct acpi_table_pcct *acpi_pcct_tbl;
> +       struct acpi_subtable_proc proc[ACPI_PCCT_TYPE_RESERVED];
>         int count, i, rc;
> -       int sum = 0;
>         acpi_status status = AE_OK;
>
>         /* Search for PCCT */
> @@ -459,43 +492,50 @@ static int __init acpi_pcc_probe(void)
>         if (ACPI_FAILURE(status) || !pcct_tbl)
>                 return -ENODEV;
>
> -       count = acpi_table_parse_entries(ACPI_SIG_PCCT,
> -                       sizeof(struct acpi_table_pcct),
> -                       ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE,
> -                       parse_pcc_subspace, MAX_PCC_SUBSPACES);
> -       sum += (count > 0) ? count : 0;
> -
> -       count = acpi_table_parse_entries(ACPI_SIG_PCCT,
> -                       sizeof(struct acpi_table_pcct),
> -                       ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2,
> -                       parse_pcc_subspace, MAX_PCC_SUBSPACES);
> -       sum += (count > 0) ? count : 0;
> +       /* Set up the subtable handlers */
> +       for (i = ACPI_PCCT_TYPE_GENERIC_SUBSPACE;
> +            i < ACPI_PCCT_TYPE_RESERVED;

I would append the line below to this one.

> +            i++) {
> +               proc[i].id = i;
> +               if (i == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
> +                   i == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)
> +                       proc[i].handler = parse_pcc_subspace;
> +               else
> +                       proc[i].handler = count_pcc_subspaces;
> +               proc[i].count = 0;

Why don't you move the count initialization above the if ()?

> +       }
>
> -       if (sum == 0 || sum >= MAX_PCC_SUBSPACES) {
> -               pr_err("Error parsing PCC subspaces from PCCT\n");
> +       count = acpi_table_parse_entries_array(ACPI_SIG_PCCT,
> +                       sizeof(struct acpi_table_pcct), proc,
> +                       ACPI_PCCT_TYPE_RESERVED, MAX_PCC_SUBSPACES);
> +       if (count == 0) {
> +               pr_warn("PCCT provided but has no subspaces defined\n");
> +               return -EINVAL;
> +       } else if (count > MAX_PCC_SUBSPACES) {
> +               pr_warn("Too many PCC subspaces defined in PCCT\n");

Do we need such detailed information to be printed here?  If you said
something like "Invalid PCCT format", you could merge the two if ()
branches.

>                 return -EINVAL;
>         }
>
>         pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) *
> -                       sum, GFP_KERNEL);
> +                       count, GFP_KERNEL);

One line, please.

>         if (!pcc_mbox_channels) {
>                 pr_err("Could not allocate space for PCC mbox channels\n");
>                 return -ENOMEM;
>         }
>
> -       pcc_doorbell_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL);
> +       pcc_doorbell_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL);
>         if (!pcc_doorbell_vaddr) {
>                 rc = -ENOMEM;
>                 goto err_free_mbox;
>         }
>
> -       pcc_doorbell_ack_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL);
> +       pcc_doorbell_ack_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL);
>         if (!pcc_doorbell_ack_vaddr) {
>                 rc = -ENOMEM;
>                 goto err_free_db_vaddr;
>         }
>
> -       pcc_doorbell_irq = kcalloc(sum, sizeof(int), GFP_KERNEL);
> +       pcc_doorbell_irq = kcalloc(count, sizeof(int), GFP_KERNEL);
>         if (!pcc_doorbell_irq) {
>                 rc = -ENOMEM;
>                 goto err_free_db_ack_vaddr;
> @@ -509,18 +549,25 @@ static int __init acpi_pcc_probe(void)
>         if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL)
>                 pcc_mbox_ctrl.txdone_irq = true;
>
> -       for (i = 0; i < sum; i++) {
> +       for (i = 0; i < count; i++) {
>                 struct acpi_generic_address *db_reg;
> -               struct acpi_pcct_hw_reduced *pcct_ss;
> +               struct acpi_pcct_subspace *pcct_ss;
>                 pcc_mbox_channels[i].con_priv = pcct_entry;
>
> -               pcct_ss = (struct acpi_pcct_hw_reduced *) pcct_entry;
> +               if (pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
> +                   pcct_entry->type ==
> +                               ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {

Again, please merge the two lines above.

> +                       struct acpi_pcct_hw_reduced *pcct_hrss;
> +
> +                       pcct_hrss = (struct acpi_pcct_hw_reduced *) pcct_entry;
>
> -               if (pcc_mbox_ctrl.txdone_irq) {
> -                       rc = pcc_parse_subspace_irq(i, pcct_ss);
> -                       if (rc < 0)
> -                               goto err;
> +                       if (pcc_mbox_ctrl.txdone_irq) {
> +                               rc = pcc_parse_subspace_irq(i, pcct_hrss);
> +                               if (rc < 0)
> +                                       goto err;
> +                       }
>                 }
> +               pcct_ss = (struct acpi_pcct_subspace *) pcct_entry;
>
>                 /* If doorbell is in system memory cache the virt address */
>                 db_reg = &pcct_ss->doorbell_register;
> @@ -531,7 +578,7 @@ static int __init acpi_pcc_probe(void)
>                         ((unsigned long) pcct_entry + pcct_entry->length);
>         }
>
> -       pcc_mbox_ctrl.num_chans = sum;
> +       pcc_mbox_ctrl.num_chans = count;
>
>         pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans);
>
> --

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 1/3] ACPI: improve function documentation for acpi_parse_entries_array()
  2018-04-27 11:04   ` Rafael J. Wysocki
@ 2018-04-30 23:27     ` Al Stone
  0 siblings, 0 replies; 10+ messages in thread
From: Al Stone @ 2018-04-30 23:27 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: ACPI Devel Maling List, Linux Kernel Mailing List,
	Rafael J . Wysocki, Len Brown

On 04/27/2018 05:04 AM, Rafael J. Wysocki wrote:
> On Tue, Apr 24, 2018 at 9:35 PM, Al Stone <ahs3@redhat.com> wrote:
>> I found the description of the table_size argument to the function
>> acpi_parse_entries_array() unclear and ambiguous.  This is a minor
>> documentation change to improve that description so I don't misuse
>> the argument again in the future, and it is hopefully clearer to
>> other future users.
>>
>> Signed-off-by: Al Stone <ahs3@redhat.com>
>> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
>> Cc: Len Brown <lenb@kernel.org>
>> ---
>>  drivers/acpi/tables.c | 6 ++++--
>>  1 file changed, 4 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
>> index 849c4fb19b03..21535762b890 100644
>> --- a/drivers/acpi/tables.c
>> +++ b/drivers/acpi/tables.c
>> @@ -222,7 +222,9 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header *header)
>>   * acpi_parse_entries_array - for each proc_num find a suitable subtable
>>   *
>>   * @id: table id (for debugging purposes)
>> - * @table_size: single entry size
>> + * @table_size: size of the root table; i.e., the offset from the very
>> + *              first byte of the complete ACPI table, to the first byte
>> + *              of the first subtable
> 
> But alas this needs to be one line.
> 
> You can add more details in the comment body below.

Whups.  Right.  Will do.

>>   * @table_header: where does the table start?
>>   * @proc: array of acpi_subtable_proc struct containing entry id
>>   *        and associated handler with it
>> @@ -400,7 +402,7 @@ int __init acpi_table_parse(char *id, acpi_tbl_table_handler handler)
>>                 return -ENODEV;
>>  }
> 
> Thanks,
> Rafael
> 


-- 
ciao,
al
-----------------------------------
Al Stone
Software Engineer
Red Hat, Inc.
ahs3@redhat.com
-----------------------------------

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 2/3] ACPI: ensure acpi_parse_entries_array() does not access non-existent table data
  2018-04-27 11:05   ` Rafael J. Wysocki
@ 2018-04-30 23:28     ` Al Stone
  0 siblings, 0 replies; 10+ messages in thread
From: Al Stone @ 2018-04-30 23:28 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: ACPI Devel Maling List, Linux Kernel Mailing List,
	Rafael J . Wysocki, Len Brown

On 04/27/2018 05:05 AM, Rafael J. Wysocki wrote:
> On Tue, Apr 24, 2018 at 9:35 PM, Al Stone <ahs3@redhat.com> wrote:
>> For ACPI tables that have subtables, acpi_parse_entries_array() gets used
>> to step through each of the subtables in memory.  The primary loop for this
>> was checking that the beginning location of the subtable being examined
>> plus the length of struct acpi_subtable_header was not beyond the end of
>> the complete ACPI table; if it wasn't, the subtable could be examined, but
>> if it was the loop would terminate as it should.
>>
>> In the middle of this subtable loop, a callback is used to examine the
>> subtable in detail.
>>
>> Should the callback function try to examine elements of the subtable that
>> are located past the subtable header, and the ACPI table containing this
>> subtable has an incorrect length, it is possible to access either invalid
>> or protected memory and cause a fault.  And, the length of struct
>> acpi_subtable_header will always be smaller than the length of the actual
>> subtable.
>>
>> To fix this, we make the main loop check that the beginning of the
>> subtable being examined plus the actual length of the subtable does
>> not go past the end of the enclosing ACPI table.  While this cannot
>> protect us from malicious callback functions, it can prevent us from
>> failing because of some poorly constructed ACPI tables.
>>
>> Found by inspection.  There is no functional change to existing code
>> that is known to work when calling acpi_parse_entries_array().
>>
>> Signed-off-by: Al Stone <ahs3@redhat.com>
>> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
>> Cc: Len Brown <lenb@kernel.org>
>> ---
>>  drivers/acpi/tables.c | 3 +--
>>  1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
>> index 21535762b890..c7b028f231a6 100644
>> --- a/drivers/acpi/tables.c
>> +++ b/drivers/acpi/tables.c
>> @@ -271,8 +271,7 @@ acpi_parse_entries_array(char *id, unsigned long table_size,
>>         entry = (struct acpi_subtable_header *)
>>             ((unsigned long)table_header + table_size);
>>
>> -       while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
>> -              table_end) {
>> +       while (((unsigned long)entry + entry->length) <= table_end) {
> 
> The inner parens are not needed.

Pure paranoia on my part.  Will fix.

>>                 if (max_entries && count >= max_entries)
>>                         break;
>>
>> --


-- 
ciao,
al
-----------------------------------
Al Stone
Software Engineer
Red Hat, Inc.
ahs3@redhat.com
-----------------------------------

^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: [PATCH v2 3/3] mailbox: ACPI: erroneous error message when parsing the ACPI PCCT
  2018-04-27 11:16   ` Rafael J. Wysocki
@ 2018-04-30 23:39     ` Al Stone
  0 siblings, 0 replies; 10+ messages in thread
From: Al Stone @ 2018-04-30 23:39 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: ACPI Devel Maling List, Linux Kernel Mailing List, Jassi Brar,
	Rafael J . Wysocki, Len Brown

On 04/27/2018 05:16 AM, Rafael J. Wysocki wrote:
> On Tue, Apr 24, 2018 at 9:35 PM, Al Stone <ahs3@redhat.com> wrote:
>> There have been multiple reports of the following error message:
>>
>> [    0.068293] Error parsing PCC subspaces from PCCT
>>
> 
> [cut]
> 
>>
>> Tested on my personal laptop which showed the error previously; the
>> error message no longer appears and the laptop appears to operate
>> normally.
>>
>> Signed-off-by: Al Stone <ahs3@redhat.com>
>> Cc: Jassi Brar <jassisinghbrar@gmail.com>
>> Cc: Rafael J. Wysocki <rjw@rjwysocki.net>
>> Cc: Len Brown <lenb@kernel.org>
>> ---
>>  drivers/mailbox/pcc.c | 99 +++++++++++++++++++++++++++++++++++++--------------
>>  1 file changed, 73 insertions(+), 26 deletions(-)
>>
>> diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c
>> index 3ef7f036ceea..cc77a2f1694f 100644
>> --- a/drivers/mailbox/pcc.c
>> +++ b/drivers/mailbox/pcc.c
>> @@ -372,6 +372,35 @@ static const struct mbox_chan_ops pcc_chan_ops = {
>>         .send_data = pcc_send_data,
>>  };
>>
>> +/*
>> + *
>> + * count_pcc_subspaces -- Count the PCC subspaces that are not used in
>> + *             reduced hardware systems.
> 
> One line here, please.

Ack.

>> + * @header: Pointer to the ACPI subtable header under the PCCT.
>> + * @end: End of subtable entry.
>> + *
>> + * Return: 0 for Success, else errno.
> 
> The only errno returned appears to be -EINVAL, so maybe say when that
> is returned and then "or 0 otherwise".

Okay.

>> + *
>> + * This gets called for each entry in the PCC table.
>> + */
>> +static int count_pcc_subspaces(struct acpi_subtable_header *header,
>> +               const unsigned long end)
>> +{
>> +       struct acpi_pcct_subspace *pcct_ss =
>> +                               (struct acpi_pcct_subspace *) header;
> 
> This can be one line (ignore warnings from checkpatch about that).

Okay.  That's always a bit of a judgment call with checkpatch.

>> +
>> +       if ((pcct_ss->header.type <= ACPI_PCCT_TYPE_RESERVED) &&
>> +           (pcct_ss->header.type != ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE) &&
>> +           (pcct_ss->header.type !=
>> +                               ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) {
> 
> This can be one line too.

Okay.

>> +               pr_warn("PCCT count: useful subtype = %d\n",
>> +                       pcct_ss->header.type);
> 
> Why pr_warn()?
> 
>> +               return 0;
>> +       }
>> +       pr_warn("PCCT count: unwanted subtype = %d\n", pcct_ss->header.type);
>> +       return -EINVAL;
>> +}
>> +

Oh, bugger.  I inadvertently left some debug noise in here.  Both of the above
pr_warn() calls should go away since they don't actually provide any value.

>>  /**
>>   * parse_pcc_subspace - Parse the PCC table and verify PCC subspace
>>   *             entries. There should be one entry per PCC client.
>> @@ -395,10 +424,14 @@ static int parse_pcc_subspace(struct acpi_subtable_header *header,
>>                     && (pcct_ss->header.type !=
>>                                 ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)) {
>>                         pr_err("Incorrect PCC Subspace type detected\n");
>> +                       pr_warn("PCCT parse: unwanted subtype = %d\n",
>> +                               pcct_ss->header.type);
> 
> Maybe merge the two messages?

Yup, or remove the pr_warn(); that's really just extra debug info I had put in
to check results.

> 
>>                         return -EINVAL;
>>                 }
>>         }
>>
>> +       pcct_ss = (struct acpi_pcct_hw_reduced *) header;
>> +       pr_warn("PCCT parse: useful subtype = %d\n", pcct_ss->header.type);

...and same here -- the pr_warn() is extraneous, really.

>>         return 0;
>>  }
>>
>> @@ -449,8 +482,8 @@ static int __init acpi_pcc_probe(void)
>>         struct acpi_table_header *pcct_tbl;
>>         struct acpi_subtable_header *pcct_entry;
>>         struct acpi_table_pcct *acpi_pcct_tbl;
>> +       struct acpi_subtable_proc proc[ACPI_PCCT_TYPE_RESERVED];
>>         int count, i, rc;
>> -       int sum = 0;
>>         acpi_status status = AE_OK;
>>
>>         /* Search for PCCT */
>> @@ -459,43 +492,50 @@ static int __init acpi_pcc_probe(void)
>>         if (ACPI_FAILURE(status) || !pcct_tbl)
>>                 return -ENODEV;
>>
>> -       count = acpi_table_parse_entries(ACPI_SIG_PCCT,
>> -                       sizeof(struct acpi_table_pcct),
>> -                       ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE,
>> -                       parse_pcc_subspace, MAX_PCC_SUBSPACES);
>> -       sum += (count > 0) ? count : 0;
>> -
>> -       count = acpi_table_parse_entries(ACPI_SIG_PCCT,
>> -                       sizeof(struct acpi_table_pcct),
>> -                       ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2,
>> -                       parse_pcc_subspace, MAX_PCC_SUBSPACES);
>> -       sum += (count > 0) ? count : 0;
>> +       /* Set up the subtable handlers */
>> +       for (i = ACPI_PCCT_TYPE_GENERIC_SUBSPACE;
>> +            i < ACPI_PCCT_TYPE_RESERVED;
> 
> I would append the line below to this one.

Okay.

>> +            i++) {
>> +               proc[i].id = i;
>> +               if (i == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
>> +                   i == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2)
>> +                       proc[i].handler = parse_pcc_subspace;
>> +               else
>> +                       proc[i].handler = count_pcc_subspaces;
>> +               proc[i].count = 0;
> 
> Why don't you move the count initialization above the if ()?

Sure.

>> +       }
>>
>> -       if (sum == 0 || sum >= MAX_PCC_SUBSPACES) {
>> -               pr_err("Error parsing PCC subspaces from PCCT\n");
>> +       count = acpi_table_parse_entries_array(ACPI_SIG_PCCT,
>> +                       sizeof(struct acpi_table_pcct), proc,
>> +                       ACPI_PCCT_TYPE_RESERVED, MAX_PCC_SUBSPACES);
>> +       if (count == 0) {
>> +               pr_warn("PCCT provided but has no subspaces defined\n");
>> +               return -EINVAL;
>> +       } else if (count > MAX_PCC_SUBSPACES) {
>> +               pr_warn("Too many PCC subspaces defined in PCCT\n");
> 
> Do we need such detailed information to be printed here?  If you said
> something like "Invalid PCCT format", you could merge the two if ()
> branches.

Yeah, let me re-do these and simplify them.

>>                 return -EINVAL;
>>         }
>>
>>         pcc_mbox_channels = kzalloc(sizeof(struct mbox_chan) *
>> -                       sum, GFP_KERNEL);
>> +                       count, GFP_KERNEL);
> 
> One line, please.

Okay.

>>         if (!pcc_mbox_channels) {
>>                 pr_err("Could not allocate space for PCC mbox channels\n");
>>                 return -ENOMEM;
>>         }
>>
>> -       pcc_doorbell_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL);
>> +       pcc_doorbell_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL);
>>         if (!pcc_doorbell_vaddr) {
>>                 rc = -ENOMEM;
>>                 goto err_free_mbox;
>>         }
>>
>> -       pcc_doorbell_ack_vaddr = kcalloc(sum, sizeof(void *), GFP_KERNEL);
>> +       pcc_doorbell_ack_vaddr = kcalloc(count, sizeof(void *), GFP_KERNEL);
>>         if (!pcc_doorbell_ack_vaddr) {
>>                 rc = -ENOMEM;
>>                 goto err_free_db_vaddr;
>>         }
>>
>> -       pcc_doorbell_irq = kcalloc(sum, sizeof(int), GFP_KERNEL);
>> +       pcc_doorbell_irq = kcalloc(count, sizeof(int), GFP_KERNEL);
>>         if (!pcc_doorbell_irq) {
>>                 rc = -ENOMEM;
>>                 goto err_free_db_ack_vaddr;
>> @@ -509,18 +549,25 @@ static int __init acpi_pcc_probe(void)
>>         if (acpi_pcct_tbl->flags & ACPI_PCCT_DOORBELL)
>>                 pcc_mbox_ctrl.txdone_irq = true;
>>
>> -       for (i = 0; i < sum; i++) {
>> +       for (i = 0; i < count; i++) {
>>                 struct acpi_generic_address *db_reg;
>> -               struct acpi_pcct_hw_reduced *pcct_ss;
>> +               struct acpi_pcct_subspace *pcct_ss;
>>                 pcc_mbox_channels[i].con_priv = pcct_entry;
>>
>> -               pcct_ss = (struct acpi_pcct_hw_reduced *) pcct_entry;
>> +               if (pcct_entry->type == ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE ||
>> +                   pcct_entry->type ==
>> +                               ACPI_PCCT_TYPE_HW_REDUCED_SUBSPACE_TYPE2) {
> 
> Again, please merge the two lines above.

Okay.

>> +                       struct acpi_pcct_hw_reduced *pcct_hrss;
>> +
>> +                       pcct_hrss = (struct acpi_pcct_hw_reduced *) pcct_entry;
>>
>> -               if (pcc_mbox_ctrl.txdone_irq) {
>> -                       rc = pcc_parse_subspace_irq(i, pcct_ss);
>> -                       if (rc < 0)
>> -                               goto err;
>> +                       if (pcc_mbox_ctrl.txdone_irq) {
>> +                               rc = pcc_parse_subspace_irq(i, pcct_hrss);
>> +                               if (rc < 0)
>> +                                       goto err;
>> +                       }
>>                 }
>> +               pcct_ss = (struct acpi_pcct_subspace *) pcct_entry;
>>
>>                 /* If doorbell is in system memory cache the virt address */
>>                 db_reg = &pcct_ss->doorbell_register;
>> @@ -531,7 +578,7 @@ static int __init acpi_pcc_probe(void)
>>                         ((unsigned long) pcct_entry + pcct_entry->length);
>>         }
>>
>> -       pcc_mbox_ctrl.num_chans = sum;
>> +       pcc_mbox_ctrl.num_chans = count;
>>
>>         pr_info("Detected %d PCC Subspaces\n", pcc_mbox_ctrl.num_chans);
>>
>> --

Thanks for the review, Rafael.

-- 
ciao,
al
-----------------------------------
Al Stone
Software Engineer
Red Hat, Inc.
ahs3@redhat.com
-----------------------------------

^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2018-04-30 23:39 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-24 19:35 [PATCH v2 0/3] mailbox: ACPI: Remove incorrect error message about parsing PCCT Al Stone
2018-04-24 19:35 ` [PATCH v2 1/3] ACPI: improve function documentation for acpi_parse_entries_array() Al Stone
2018-04-27 11:04   ` Rafael J. Wysocki
2018-04-30 23:27     ` Al Stone
2018-04-24 19:35 ` [PATCH v2 2/3] ACPI: ensure acpi_parse_entries_array() does not access non-existent table data Al Stone
2018-04-27 11:05   ` Rafael J. Wysocki
2018-04-30 23:28     ` Al Stone
2018-04-24 19:35 ` [PATCH v2 3/3] mailbox: ACPI: erroneous error message when parsing the ACPI PCCT Al Stone
2018-04-27 11:16   ` Rafael J. Wysocki
2018-04-30 23:39     ` Al Stone

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).