Received: by 10.213.65.68 with SMTP id h4csp156158imn; Tue, 3 Apr 2018 17:45:58 -0700 (PDT) X-Google-Smtp-Source: AIpwx48INcPDKv7wGih8bxqQcrQPr0UuNtW3szV0cxA+AXXORbBfIUFRBrp+vyz7g6I/wClQXkA4 X-Received: by 10.99.128.67 with SMTP id j64mr10254707pgd.55.1522802758300; Tue, 03 Apr 2018 17:45:58 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1522802758; cv=none; d=google.com; s=arc-20160816; b=AI/kJEzkoijekAiPqGpC1W5xGoTY0wWZMSHg8Oc9fhm2Avy0lwqLbA+Cp9lwbZtQxe 7WnKumBVYrnYoZDRJEBNvjlXWRMIpR7SYhQMD2OwkLA3C4jzYhc3r7nw5f8Zd2Qrijhz B6oHZy+1HTwze2FuqQO6r80QxnAAONyiv9+Ms65Qj0IC7JStRG9/LoiTzu9im9JNYkSs nT3UBzxUfszl9/0OyY8VXasaIZHRo6+yY/7YYOEsDBwH+I9+sQE90fFKjZdpBmyGT2Xs AMtwZ49jy1I1bpKumD37LuqdoWORQsms1vu3HC4ClgKOCjm2jUmV8/giQj9atrntF40l n1GQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=26N+J2BYOoEVnjYzyHZTh/ldP4j4qtH+cDIA10FS9uk=; b=UNp/xL2x+Ut2PyKNMdSODon5e4kv8VxlMGvbkCSfVoBkRA0tUV0Ni9+G4kO88LNito 9XXhqt/sj0CNyrrsfNF6nlCEZGgoVtSj1vWgkCqQcDzZ68Nu6/yE8Z58NhFdsSl3AttM Ijx5Wb9i/sCY6B7MOviZlpnRt6l7mhLVFDVeRhlF9Da/K9VxiZPo9AYa/CekbdopfAcE CGLvpVN/EC4R/rJKBNtz84799FiZwBBBzw/xXrq34FQ0spjv0GdRQ+D5Lo/SbGcRSi7z XaghbCXFidsecGIFtZfTcJiYCkZ0NLDd3mI2KRo1cTlVC/Y405HqqQI7JOesA9OZbwcu 8qow== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id s9-v6si1753349plr.493.2018.04.03.17.45.44; Tue, 03 Apr 2018 17:45:58 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754810AbeDDAol (ORCPT + 99 others); Tue, 3 Apr 2018 20:44:41 -0400 Received: from mx1.redhat.com ([209.132.183.28]:60436 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754032AbeDDAmY (ORCPT ); Tue, 3 Apr 2018 20:42:24 -0400 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7C7337FEA3; Wed, 4 Apr 2018 00:42:24 +0000 (UTC) Received: from fidelio.ahs3.com (ovpn-116-126.phx2.redhat.com [10.3.116.126]) by smtp.corp.redhat.com (Postfix) with ESMTP id 14F4A17BA1; Wed, 4 Apr 2018 00:42:24 +0000 (UTC) From: Al Stone To: linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Al Stone , Jassi Brar , "Rafael J . Wysocki" , Len Brown Subject: [PATCH 3/3] mailbox: ACPI: erroneous error message when parsing the ACPI PCCT Date: Tue, 3 Apr 2018 18:42:11 -0600 Message-Id: <20180404004211.6141-4-ahs3@redhat.com> In-Reply-To: <20180404004211.6141-1-ahs3@redhat.com> References: <20180404004211.6141-1-ahs3@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Wed, 04 Apr 2018 00:42:24 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 Cc: Jassi Brar Cc: Rafael J. Wysocki Cc: Len Brown --- 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..c6294476acc1 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c @@ -372,6 +372,36 @@ 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_GENERIC_SUBSPACE) && + (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