From mboxrd@z Thu Jan 1 00:00:00 1970 From: Tomasz Wroblewski Subject: [PATCH v3] Fix acpi_dmar_zap/reinstate() (fixes S3 regression) Date: Tue, 22 Jan 2013 18:22:18 +0100 Message-ID: <50FECACA.7020809@citrix.com> References: <50FE8126.8080005@citrix.com> <50FE9B1802000078000B84A1@nat28.tlf.novell.com> <50FEAFE4.1030303@citrix.com> <50FEC46B02000078000B8622@nat28.tlf.novell.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------060900040309080404070601" Return-path: In-Reply-To: <50FEC46B02000078000B8622@nat28.tlf.novell.com> List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xen.org Errors-To: xen-devel-bounces@lists.xen.org To: Jan Beulich Cc: "xen-devel@lists.xen.org" List-Id: xen-devel@lists.xenproject.org --------------060900040309080404070601 Content-Type: text/plain; charset="ISO-8859-1"; format=flowed Content-Transfer-Encoding: 7bit Thanks, attaching version 3 of the patch using your suggestions, which simplify it considerably. This one uses map_pages_to_xen in favour of ioremap, so it works on both tip as well as older trees from before ioremap() rework (tested both). Changes from v2/v1: - keeping global dmar_table pointer and initializing it in acpi_dmar_init() - use map_pages_to_xen to add a static mapping (instead of ioremap) - moved acpi_get_table_physical_location to tbxface.c. Added instance argument to make it symmetric with acpi_get_table. - coding convention fixes Commit message: Fix S3 regression introduced by cs 23013:65d26504e843 (ACPI: large cleanup). The dmar virtual pointer returned from acpi_get_table cannot be safely stored away and used later, as the underlying acpi_os_map_memory / __acpi_map_table functions overwrite the mapping causing it to point to different tables than dmar (last fetched table is used). This subsequently causes acpi_dmar_reinstate() and acpi_dmar_zap() to write data to wrong table, causing its corruption and problems with consecutive s3 resumes. Added a new function to fetch ACPI table physical address, and establishing separate static mapping for dmar_table pointer instead of using acpi_get_table(). Signed-off-by: Tomasz Wroblewski --------------060900040309080404070601 Content-Type: text/x-patch; name="fix-dmar-zap-reinstate-v3.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="fix-dmar-zap-reinstate-v3.patch" diff -r 4b476378fc35 xen/drivers/acpi/tables/tbxface.c --- a/xen/drivers/acpi/tables/tbxface.c Mon Jan 21 17:03:10 2013 +0000 +++ b/xen/drivers/acpi/tables/tbxface.c Tue Jan 22 17:13:06 2013 +0000 @@ -205,3 +205,44 @@ return (AE_NOT_FOUND); } + +/******************************************************************************* + * + * FUNCTION: acpi_get_table_physical_location + * + * PARAMETERS: Signature - ACPI signature of needed table + * Instance - Which instance (for SSDTs) + * out_addr - Where the table's physical address is returned + * out_len - Where the length of table is returned + * + * RETURN: Status, pointer and length of table + * + * DESCRIPTION: Finds physical address and length of ACPI table + * + *****************************************************************************/ +acpi_status __init +acpi_get_table_physical_location(char *signature, + acpi_native_uint instance, + acpi_physical_address *out_addr, u32 *out_len) +{ + acpi_native_uint i; + acpi_native_uint j; + + if (!signature || !out_addr || !out_len) { + return (AE_BAD_PARAMETER); + } + + for (i = 0, j=0; i < acpi_gbl_root_table_list.count; i++) { + if (!ACPI_COMPARE_NAME(&(acpi_gbl_root_table_list.tables[i].signature), signature)) { + continue; + } + if (++j < instance) { + continue; + } + *out_addr = acpi_gbl_root_table_list.tables[i].address; + *out_len = acpi_gbl_root_table_list.tables[i].length; + return AE_OK; + } + + return AE_NOT_FOUND; +} diff -r 4b476378fc35 xen/drivers/passthrough/vtd/dmar.c --- a/xen/drivers/passthrough/vtd/dmar.c Mon Jan 21 17:03:10 2013 +0000 +++ b/xen/drivers/passthrough/vtd/dmar.c Tue Jan 22 17:13:06 2013 +0000 @@ -823,7 +823,17 @@ int __init acpi_dmar_init(void) { - acpi_get_table(ACPI_SIG_DMAR, 0, &dmar_table); + acpi_physical_address dmar_addr; + u32 dmar_len; + if ( !acpi_get_table_physical_location( + ACPI_SIG_DMAR, 0, &dmar_addr, &dmar_len) ) + { + map_pages_to_xen((unsigned long)__va(dmar_addr), PFN_DOWN(dmar_addr), + PFN_UP(dmar_addr) - PFN_DOWN(dmar_addr) + 1, + PAGE_HYPERVISOR); + dmar_table = (struct acpi_table_header*) __va(dmar_addr); + } + return parse_dmar_table(acpi_parse_dmar); } diff -r 4b476378fc35 xen/include/acpi/acpixf.h --- a/xen/include/acpi/acpixf.h Mon Jan 21 17:03:10 2013 +0000 +++ b/xen/include/acpi/acpixf.h Tue Jan 22 17:13:06 2013 +0000 @@ -77,6 +77,10 @@ acpi_get_table(acpi_string signature, acpi_native_uint instance, struct acpi_table_header **out_table); +acpi_status +acpi_get_table_physical_location(char *signature, + acpi_native_uint instance, + acpi_physical_address *out_addr, u32 *out_len); /* * Namespace and name interfaces */ --------------060900040309080404070601 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xen.org http://lists.xen.org/xen-devel --------------060900040309080404070601--