From: Thomas Renninger <trenn@suse.de>
To: Myron Stowe <myron.stowe@redhat.com>,
Len Brown <len.brown@intel.com>,
bondd@us.ibm.com
Cc: lenb@kernel.org, linux-acpi@vger.kernel.org, rjw@sisk.pl,
ying.huang@intel.com, bhelgaas@google.com
Subject: Re: [PATCH 0/2] ACPI: Re-factor and remove ./drivers/acpi/atomicio.[ch]
Date: Fri, 28 Oct 2011 03:49:25 +0200 [thread overview]
Message-ID: <201110280349.26410.trenn@suse.de> (raw)
In-Reply-To: <20110929215907.21126.24480.stgit@amt.stowe>
On Thursday 29 September 2011 23:59:08 Myron Stowe wrote:
..
> Myron Stowe (2):
> ACPI: Convert acpi_pre_map_gar()/acpi_atomic_read() and remove ./drivers/acpi/atomicio.[ch]
> ACPI: Export interfaces for ioremapping/iounmapping ACPI registers
Would be great to know whether these are going to be accepted.
If yes, this check should get removed as well:
drivers/acpi/acpica/hwregs.c:
acpi_status
acpi_hw_validate_register(struct acpi_generic_address *reg,
u8 max_bit_width, u64 *address)
{
...
if (reg->bit_offset != 0) {
ACPI_WARNING((AE_INFO,
"Unsupported register bit offset: 0x%X",
reg->bit_offset));
}
because APEI GAR declarations do use bit_offset != 0.
There is another problem. Would be great to get some opinions/feedback
on it already:
APEI GAR entries seem to have invalid bit_width entries on some platforms.
After looking at several tables, I expect that with APEI tables access width
(in bytes) should get used instead, Windows seem to ignore bit width fields,
at least for APEI tables.
I have patches but I need to know whether your patches are accepted.
There also is a problem with modifying GAR bit_width field to be able to
pass it to the generic acpica functions (what your patches are doing).
The problem is that the structures are located in reserved BIOS areas and
they should be const and not get modified.
I have 2 solutions for this:
1) Make apei_check_gar() pass 2 struct acpi_generic_address:
int apei_check_gar(struct acpi_generic_address *reg,
const struct acpi_generic_address *orig, u64 *paddr)
orig -> is the one located in reserved mem area, mapped to virtual addr space
reg -> will be a copy of it, possibly with bit_width adjusted which then
can be passed to acpi_memory_read/write and friends.
2) Allocate memory and copy whole APEI tables
1. Should have the advantage of less memory waste
2. Should have the advantage of a bit nicer code (kalloc and memcpy per table) and
if more things like this happen, tables could get adjusted easily.
It also has the advantage that GAR structures do not need to get double
checked and eventually adjusted at runtime again.
Below is the first patch which goes for 1. More patches may be needed, but I
as said, I need to know whether your patches get accepted.
What do you think?
Thanks,
Thomas
----
ACPI APEI: Adjust GAR checking code to what exists out there
Comparing different Generic Adress Register definitions of
different vendors it came out that bit width (at least in APEI
tables) is sometimes wrong or used different compared to older
ACPI BIOS definitions (e.g. older FACP tables).
It looks like Windows ignores the bit width field in
latest implementations. Either in APEI table parts only
(I'd say more likely) or in other ACPI parts as well.
Worst case is that an address value to be read from a GAR structure
can have a 8 bit width definition resulting in:
ERST: Can not request iomem region <0x 3f-0x 3f>
while the access width is correct:
[1B0h 0432 1] Action : 0D (Get Error Address Range)
[1B4h 0436 12] Register Region : <Generic Address Structure>
[1B4h 0436 1] Space ID : 00 (SystemMemory)
[1B5h 0437 1] Bit Width : 08
[1B6h 0438 1] Bit Offset : 00
[1B7h 0439 1] Encoded Access Width : 04 (QWord Access:64)
[1B8h 0440 8] Address : 000000007F8A8032
-> Ignore bit width field in APEI GAR checking code.
Correct bit width value if needed (derived from access width)
in the GAR structure, so that generic acpi read/write functions
can still be used.
Signed-off-by: Thomas Renninger <trenn@suse.de>
---
drivers/acpi/apei/apei-base.c | 63 +++++++++++++++++++++++++++++-------
drivers/acpi/apei/apei-internal.h | 2 +
2 files changed, 52 insertions(+), 13 deletions(-)
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c
index 6154036..d05f084 100644
--- a/drivers/acpi/apei/apei-base.c
+++ b/drivers/acpi/apei/apei-base.c
@@ -520,25 +520,53 @@ void apei_resources_release(struct apei_resources *resources)
}
EXPORT_SYMBOL_GPL(apei_resources_release);
-static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr)
+int apei_check_gar(struct acpi_generic_address *reg,
+ const struct acpi_generic_address *orig, u64 *paddr)
{
- u32 width, space_id;
+ int bit_width, space_id, acc_width, acc_width_bits;
- width = reg->bit_width;
+ memcpy(reg, orig, sizeof(struct acpi_generic_address));
+ bit_width = reg->bit_width;
space_id = reg->space_id;
+ acc_width = reg->access_width;
+
/* Handle possible alignment issues */
memcpy(paddr, ®->address, sizeof(*paddr));
if (!*paddr) {
pr_warning(FW_BUG APEI_PFX
"Invalid physical address in GAR [0x%llx/%u/%u]\n",
- *paddr, width, space_id);
+ *paddr, bit_width, space_id);
return -EINVAL;
}
- if ((width != 8) && (width != 16) && (width != 32) && (width != 64)) {
+ switch (acc_width) {
+ case 1:
+ acc_width_bits = 8;
+ break;
+ case 2:
+ acc_width_bits = 16;
+ break;
+ case 3:
+ acc_width_bits = 32;
+ break;
+ case 4:
+ acc_width_bits = 64;
+ break;
+ case 0:
+ /* Never seen this, acc_width should always be correct */
+ if ((bit_width == 8) || (bit_width == 16) ||
+ (bit_width == 32) || (bit_width == 64)) {
+ pr_warning(FW_BUG APEI_PFX
+ "Incorrect acc width, using bit width"
+ "[%d]\n", bit_width);
+ acc_width = bit_width / 8;
+ acc_width_bits = bit_width;
+ break;
+ }
+ default:
pr_warning(FW_BUG APEI_PFX
- "Invalid bit width in GAR [0x%llx/%u/%u]\n",
- *paddr, width, space_id);
+ "Invalid access width in GAR [0x%llx/%u/%u]\n",
+ *paddr, bit_width, space_id);
return -EINVAL;
}
@@ -546,19 +574,28 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr)
space_id != ACPI_ADR_SPACE_SYSTEM_IO) {
pr_warning(FW_BUG APEI_PFX
"Invalid address space type in GAR [0x%llx/%u/%u]\n",
- *paddr, width, space_id);
+ *paddr, bit_width, space_id);
return -EINVAL;
}
+ /* bit width is not much worth in APEI GAR structures */
+ if (acc_width_bits != bit_width) {
+ pr_debug(FW_INFO APEI_PFX
+ "Correcting bit width value 0x%x -> 0x%x\n",
+ reg->bit_width, acc_width_bits);
+ reg->bit_width = acc_width_bits;
+ }
return 0;
}
+EXPORT_SYMBOL_GPL(apei_check_gar);
static int collect_res_callback(struct apei_exec_context *ctx,
struct acpi_whea_header *entry,
void *data)
{
struct apei_resources *resources = data;
- struct acpi_generic_address *reg = &entry->register_region;
+ struct acpi_generic_address reg;
+ const struct acpi_generic_address *orig = &entry->register_region;
u8 ins = entry->instruction;
u64 paddr;
int rc;
@@ -566,17 +603,17 @@ static int collect_res_callback(struct apei_exec_context *ctx,
if (!(ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER))
return 0;
- rc = apei_check_gar(reg, &paddr);
+ rc = apei_check_gar(®, orig, &paddr);
if (rc)
return rc;
- switch (reg->space_id) {
+ switch (reg.space_id) {
case ACPI_ADR_SPACE_SYSTEM_MEMORY:
return apei_res_add(&resources->iomem, paddr,
- reg->bit_width / 8);
+ reg.bit_width / 8);
case ACPI_ADR_SPACE_SYSTEM_IO:
return apei_res_add(&resources->ioport, paddr,
- reg->bit_width / 8);
+ reg.bit_width / 8);
default:
return -EINVAL;
}
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h
index f57050e..63d43d8 100644
--- a/drivers/acpi/apei/apei-internal.h
+++ b/drivers/acpi/apei/apei-internal.h
@@ -82,6 +82,8 @@ int apei_exec_noop(struct apei_exec_context *ctx,
struct acpi_whea_header *entry);
int apei_exec_pre_map_gars(struct apei_exec_context *ctx);
int apei_exec_post_unmap_gars(struct apei_exec_context *ctx);
+int apei_check_gar(struct acpi_generic_address *reg,
+ const struct acpi_generic_address *orig, u64 *paddr);
struct apei_resources {
struct list_head iomem;
next prev parent reply other threads:[~2011-10-28 1:49 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-09-29 21:59 [PATCH 0/2] ACPI: Re-factor and remove ./drivers/acpi/atomicio.[ch] Myron Stowe
2011-09-29 21:59 ` [PATCH 1/2] ACPI: Export interfaces for ioremapping/iounmapping ACPI registers Myron Stowe
2011-11-06 12:49 ` Rafael J. Wysocki
2011-09-29 21:59 ` [PATCH 2/2] ACPI: Convert acpi_pre_map_gar()/acpi_atomic_read() and remove ./drivers/acpi/atomicio.[ch] Myron Stowe
2011-11-06 13:05 ` Rafael J. Wysocki
2011-10-28 1:49 ` Thomas Renninger [this message]
2011-10-28 15:03 ` [PATCH 0/2] ACPI: Re-factor " Bjorn Helgaas
2011-10-31 10:47 ` Thomas Renninger
2011-11-03 1:42 ` Myron Stowe
2011-11-06 13:30 ` Rafael J. Wysocki
2011-11-04 23:54 ` Myron Stowe
2011-11-05 2:42 ` Thomas Renninger
2011-11-06 13:42 ` Rafael J. Wysocki
2011-11-15 18:45 ` Bjorn Helgaas
2011-11-06 13:25 ` Rafael J. Wysocki
2011-11-06 13:23 ` Rafael J. Wysocki
2011-10-28 15:14 ` Bjorn Helgaas
2011-10-31 10:33 ` Thomas Renninger
2011-10-31 15:51 ` Bjorn Helgaas
2011-11-03 9:16 ` Thomas Renninger
2011-11-03 13:53 ` Bjorn Helgaas
2011-11-03 16:18 ` Thomas Renninger
2011-11-03 16:44 ` Myron Stowe
2011-11-04 2:16 ` Thomas Renninger
2011-11-04 1:55 ` Myron Stowe
2011-10-28 22:40 ` Myron Stowe
2011-11-06 13:19 ` Rafael J. Wysocki
2011-11-03 16:31 ` Thomas Renninger
2011-11-04 0:56 ` Huang Ying
2011-11-04 2:24 ` Thomas Renninger
2011-11-04 1:32 ` Huang Ying
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201110280349.26410.trenn@suse.de \
--to=trenn@suse.de \
--cc=bhelgaas@google.com \
--cc=bondd@us.ibm.com \
--cc=len.brown@intel.com \
--cc=lenb@kernel.org \
--cc=linux-acpi@vger.kernel.org \
--cc=myron.stowe@redhat.com \
--cc=rjw@sisk.pl \
--cc=ying.huang@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox