From patchwork Mon Mar 20 00:09:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Haozhong Zhang X-Patchwork-Id: 9632869 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 39DD56020B for ; Mon, 20 Mar 2017 00:15:43 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 2CDE827F8C for ; Mon, 20 Mar 2017 00:15:43 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 21B4727FBC; Mon, 20 Mar 2017 00:15:43 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 2907427F8C for ; Mon, 20 Mar 2017 00:15:42 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cpkx0-0006vm-1G; Mon, 20 Mar 2017 00:13:30 +0000 Received: from mail6.bemta3.messagelabs.com ([195.245.230.39]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cpkwy-0006sJ-P3 for xen-devel@lists.xen.org; Mon, 20 Mar 2017 00:13:28 +0000 Received: from [85.158.137.68] by server-7.bemta-3.messagelabs.com id EC/B9-23854-8AE1FC85; Mon, 20 Mar 2017 00:13:28 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrFLMWRWlGSWpSXmKPExsVywNykWHe53Pk Ig3O7OS2WfFzM4sDocXT3b6YAxijWzLyk/IoE1owZnZPZCjZMYqy41C3RwHgvu4uRi4NF4BaT xOuZW9hAHCGB6YwSa97eZ+pi5OSQEOCVOLJsBiuE7Sfx4OgqqKJeRokVn98wgiTYBPQlVjw+C FYkIiAtce3zZbA4s8BsJon7jSEgtrBAiMSmGy1AcQ6gdaoSfedNQExeATuJr615EOPlJS5cPc UCYnMChddcus0OYgsJ2ErsvzWNbQIj3wJGhlWMGsWpRWWpRbqGJnpJRZnpGSW5iZk5uoYGxnq 5qcXFiempOYlJxXrJ+bmbGIFhwgAEOxhXbPc8xCjJwaQkylv+40SEEF9SfkplRmJxRnxRaU5q 8SFGGQ4OJQneI0onI4QEi1LTUyvSMnOAAQuTluDgURLhzQVJ8xYXJOYWZ6ZDpE4xKkqJ814AS QiAJDJK8+DaYFFyiVFWSpiXEegQIZ6C1KLczBJU+VeM4hyMSsK8m0Gm8GTmlcBNfwW0mAlo8d sPJ0AWlyQipKQaGG3TXxbeffQsUj9J+6L6n+5CqZr6591PJmV7fX0XFLXkY+6LG5d3pQgI8om 83u8cUd0byb5uTum6pHNmsjlHY3auYizaKW3x3+ZKQYIJh9O5F8veLbDR+bJx8cPb6b++vl3y RnfFnMJFr9Us3j8KWqPc47dNJ3h3AvuZu7lPb6/14twZzLrhx1slluKMREMt5qLiRAAugbotj QIAAA== X-Env-Sender: haozhong.zhang@intel.com X-Msg-Ref: server-8.tower-31.messagelabs.com!1489968802!91050058!2 X-Originating-IP: [192.55.52.115] X-SpamReason: No, hits=0.0 required=7.0 tests= X-StarScan-Received: X-StarScan-Version: 9.2.3; banners=-,-,- X-VirusChecked: Checked Received: (qmail 57149 invoked from network); 20 Mar 2017 00:13:26 -0000 Received: from mga14.intel.com (HELO mga14.intel.com) (192.55.52.115) by server-8.tower-31.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 20 Mar 2017 00:13:26 -0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=intel.com; i=@intel.com; q=dns/txt; s=intel; t=1489968806; x=1521504806; h=from:to:cc:subject:date:message-id:in-reply-to: references; bh=DATMVt7QH/E6ZCMxeoaEHkQrEAyXw0cOclwfObbJTu4=; b=qcYm2z3KBOVZd3KZnau2QvfD6EkCumWl0blRC0Nb7QrEzz7+BDCY4ngL sXXorwfQJ2BlgUxdvOlT3Qxcd5ZB/Q==; Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 19 Mar 2017 17:13:26 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.36,191,1486454400"; d="scan'208";a="78799225" Received: from hz-desktop.sh.intel.com (HELO localhost) ([10.239.159.153]) by fmsmga006.fm.intel.com with ESMTP; 19 Mar 2017 17:13:24 -0700 From: Haozhong Zhang To: xen-devel@lists.xen.org Date: Mon, 20 Mar 2017 08:09:45 +0800 Message-Id: <20170320000949.24675-12-haozhong.zhang@intel.com> X-Mailer: git-send-email 2.10.1 In-Reply-To: <20170320000949.24675-1-haozhong.zhang@intel.com> References: <20170320000949.24675-1-haozhong.zhang@intel.com> Cc: Haozhong Zhang , Wei Liu , Andrew Cooper , Ian Jackson , Jan Beulich , Konrad Rzeszutek Wilk , Dan Williams Subject: [Xen-devel] [RFC XEN PATCH v2 11/15] tools/libacpi: load ACPI built by the device model X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP ACPI tables built by the device model, whose signatures do not conflict with tables built by Xen (except SSDT), are loaded after ACPI tables built by Xen. ACPI namespace devices built by the device model, whose names do not conflict with devices built by Xen, are assembled and placed in SSDTs after ACPI tables built by Xen. Signed-off-by: Haozhong Zhang --- Cc: Jan Beulich Cc: Andrew Cooper Cc: Ian Jackson Cc: Wei Liu Changes in v2: * Add dm_acpi_{signature, devname}_blacklist_register() to let each acpi construct function register tables and namespace devices that should not be loaded from DM ACPI. --- tools/firmware/hvmloader/util.c | 15 ++ tools/libacpi/acpi2_0.h | 2 + tools/libacpi/build.c | 311 ++++++++++++++++++++++++++++++++++++++++ tools/libacpi/libacpi.h | 8 ++ 4 files changed, 336 insertions(+) diff --git a/tools/firmware/hvmloader/util.c b/tools/firmware/hvmloader/util.c index ec0de711c2..295b748829 100644 --- a/tools/firmware/hvmloader/util.c +++ b/tools/firmware/hvmloader/util.c @@ -1000,6 +1000,21 @@ void hvmloader_acpi_build_tables(struct acpi_config *config, if ( !strncmp(xenstore_read("platform/acpi_s4", "1"), "1", 1) ) config->table_flags |= ACPI_HAS_SSDT_S4; + s = xenstore_read(HVM_XS_DM_ACPI_ADDRESS, NULL); + if ( s ) + { + config->dm.addr = strtoll(s, NULL, 0); + + s = xenstore_read(HVM_XS_DM_ACPI_LENGTH, NULL); + if ( s ) + { + config->dm.length = strtoll(s, NULL, 0); + config->table_flags |= ACPI_HAS_DM; + } + else + config->dm.addr = 0; + } + config->table_flags |= (ACPI_HAS_TCPA | ACPI_HAS_IOAPIC | ACPI_HAS_WAET | ACPI_HAS_PMTIMER | ACPI_HAS_BUTTONS | ACPI_HAS_VGA | diff --git a/tools/libacpi/acpi2_0.h b/tools/libacpi/acpi2_0.h index 2619ba32db..365825e6bc 100644 --- a/tools/libacpi/acpi2_0.h +++ b/tools/libacpi/acpi2_0.h @@ -435,6 +435,7 @@ struct acpi_20_slit { #define ACPI_2_0_WAET_SIGNATURE ASCII32('W','A','E','T') #define ACPI_2_0_SRAT_SIGNATURE ASCII32('S','R','A','T') #define ACPI_2_0_SLIT_SIGNATURE ASCII32('S','L','I','T') +#define ACPI_2_0_SSDT_SIGNATURE ASCII32('S','S','D','T') /* * Table revision numbers. @@ -449,6 +450,7 @@ struct acpi_20_slit { #define ACPI_1_0_FADT_REVISION 0x01 #define ACPI_2_0_SRAT_REVISION 0x01 #define ACPI_2_0_SLIT_REVISION 0x01 +#define ACPI_2_0_SSDT_REVISION 0x02 #pragma pack () diff --git a/tools/libacpi/build.c b/tools/libacpi/build.c index a02ffbf43c..62c2570b7d 100644 --- a/tools/libacpi/build.c +++ b/tools/libacpi/build.c @@ -15,6 +15,7 @@ #include LIBACPI_STDUTILS #include "acpi2_0.h" +#include "aml_build.h" #include "libacpi.h" #include "ssdt_s3.h" #include "ssdt_s4.h" @@ -55,6 +56,14 @@ struct acpi_info { uint64_t pci_hi_min, pci_hi_len; /* 24, 32 - PCI I/O hole boundaries */ }; +#define DM_ACPI_BLOB_TYPE_TABLE 0 /* ACPI table */ +#define DM_ACPI_BLOB_TYPE_NSDEV 1 /* AML of an ACPI namespace device */ + +/* ACPI tables of following signatures should not appear in DM ACPI */ +static uint64_t dm_acpi_signature_blacklist[64]; +/* ACPI namespace devices of following names should not appear in DM ACPI */ +static const char *dm_acpi_devname_blacklist[64]; + static void set_checksum( void *table, uint32_t checksum_offset, uint32_t length) { @@ -339,6 +348,281 @@ static int construct_passthrough_tables(struct acpi_ctxt *ctxt, return nr_added; } +static bool has_dm_tables(struct acpi_ctxt *ctxt, + const struct acpi_config *config) +{ + char **dir; + unsigned int num; + + if ( !(config->table_flags & ACPI_HAS_DM) || !config->dm.addr ) + return false; + + dir = ctxt->xs_ops.directory(ctxt, HVM_XS_DM_ACPI_ROOT, &num); + if ( !dir || !num ) + return false; + + return true; +} + +static int dm_acpi_signature_blacklist_register(const struct acpi_config *config, + uint64_t sig) +{ + unsigned int i, nr = ARRAY_SIZE(dm_acpi_signature_blacklist); + + if ( !(config->table_flags & ACPI_HAS_DM) ) + return 0; + + for ( i = 0; i < nr; i++ ) + { + uint64_t entry = dm_acpi_signature_blacklist[i]; + if ( entry == sig ) + return 0; + else if ( entry == 0 ) + break; + } + + if ( i >= nr ) + return -ENOSPC; + + dm_acpi_signature_blacklist[i] = sig; + return 0; +} + +static int dm_acpi_devname_blacklist_register(const struct acpi_config *config, + const char *devname) +{ + unsigned int i, nr = ARRAY_SIZE(dm_acpi_devname_blacklist); + + if ( !(config->table_flags & ACPI_HAS_DM) ) + return 0; + + for ( i = 0; i < nr; i++ ) + { + const char *entry = dm_acpi_devname_blacklist[i]; + if ( !entry ) + break; + if ( !strncmp(entry, devname, 4) ) + return 0; + } + + if ( i > nr ) + return -ENOSPC; + + dm_acpi_devname_blacklist[i] = devname; + return 0; +} + +/* Return true if no collision is found. */ +static bool check_signature_collision(uint64_t sig) +{ + unsigned int i; + for ( i = 0; i < ARRAY_SIZE(dm_acpi_signature_blacklist); i++ ) + { + if ( sig == dm_acpi_signature_blacklist[i] ) + return false; + } + return true; +} + +/* Return true if no collision is found. */ +static int check_devname_collision(const char *name) +{ + unsigned int i; + for ( i = 0; i < ARRAY_SIZE(dm_acpi_devname_blacklist); i++ ) + { + if ( !strncmp(name, dm_acpi_devname_blacklist[i], 4) ) + return false; + } + return true; +} + +static const char *xs_read_dm_acpi_blob_key(struct acpi_ctxt *ctxt, + const char *name, const char *key) +{ +/* + * name is supposed to be 4 characters at most, and the longest @key + * so far is 'address' (7), so 30 characters is enough to hold the + * longest path HVM_XS_DM_ACPI_ROOT/name/key. + */ +#define DM_ACPI_BLOB_PATH_MAX_LENGTH 30 + char path[DM_ACPI_BLOB_PATH_MAX_LENGTH]; + snprintf(path, DM_ACPI_BLOB_PATH_MAX_LENGTH, HVM_XS_DM_ACPI_ROOT"/%s/%s", + name, key); + return ctxt->xs_ops.read(ctxt, path); +} + +static bool construct_dm_table(struct acpi_ctxt *ctxt, + unsigned long *table_ptrs, + unsigned int nr_tables, + const void *blob, uint32_t length) +{ + const struct acpi_header *header = blob; + uint8_t *buffer; + + if ( !check_signature_collision(header->signature) ) + return false; + + if ( header->length > length || header->length == 0 ) + return false; + + buffer = ctxt->mem_ops.alloc(ctxt, header->length, 16); + if ( !buffer ) + return false; + memcpy(buffer, header, header->length); + + /* some device models (e.g. QEMU) does not set checksum */ + set_checksum(buffer, offsetof(struct acpi_header, checksum), + header->length); + + table_ptrs[nr_tables++] = ctxt->mem_ops.v2p(ctxt, buffer); + + return true; +} + +static bool construct_dm_nsdev(struct acpi_ctxt *ctxt, + unsigned long *table_ptrs, + unsigned int nr_tables, + const char *dev_name, + const void *blob, uint32_t blob_length) +{ + struct acpi_header ssdt, *header; + uint8_t *buffer; + int rc; + + if ( !check_devname_collision(dev_name) ) + return false; + +#define AML_BUILD(STMT) \ + do { \ + rc = STMT; \ + if ( rc ) \ + goto out; \ + } while (0) + + /* built ACPI namespace device from [name, blob] */ + buffer = aml_build_begin(ctxt); + if ( !buffer ) + return false; + + AML_BUILD(aml_prepend_blob(buffer, blob, blob_length)); + AML_BUILD(aml_prepend_device(buffer, dev_name)); + AML_BUILD((aml_prepend_scope(buffer, "\\_SB"))); + + /* build SSDT header */ + ssdt.signature = ACPI_2_0_SSDT_SIGNATURE; + ssdt.revision = ACPI_2_0_SSDT_REVISION; + fixed_strcpy(ssdt.oem_id, ACPI_OEM_ID); + fixed_strcpy(ssdt.oem_table_id, ACPI_OEM_TABLE_ID); + ssdt.oem_revision = ACPI_OEM_REVISION; + ssdt.creator_id = ACPI_CREATOR_ID; + ssdt.creator_revision = ACPI_CREATOR_REVISION; + + /* prepend SSDT header to ACPI namespace device */ + AML_BUILD(aml_prepend_blob(buffer, &ssdt, sizeof(ssdt))); + header = (struct acpi_header *) buffer; + +out: + header->length = aml_build_end(); + + if ( rc ) + return false; + + /* calculate checksum of SSDT */ + set_checksum(header, offsetof(struct acpi_header, checksum), + header->length); + + table_ptrs[nr_tables++] = ctxt->mem_ops.v2p(ctxt, buffer); + + return true; +} + +/* + * All ACPI stuffs built by the device model are placed in the guest + * buffer whose address and size are specified by config->dm.{addr, length}, + * or XenStore keys HVM_XS_DM_ACPI_{ADDRESS, LENGTH}. + * + * The data layout within the buffer is further specified by XenStore + * directories under HVM_XS_DM_ACPI_ROOT. Each directory specifies a + * data blob and contains following XenStore keys: + * + * - "type": + * * DM_ACPI_BLOB_TYPE_TABLE + * The data blob specified by this directory is an ACPI table. + * * DM_ACPI_BLOB_TYPE_NSDEV + * The data blob specified by this directory is an ACPI namespace device. + * Its name is specified by the directory name, while the AML code of the + * body of the AML device structure is in the data blob. + * + * - "length": the number of bytes in this data blob. + * + * - "offset": the offset in bytes of this data blob from the beginning of buffer + */ +static int construct_dm_tables(struct acpi_ctxt *ctxt, + unsigned long *table_ptrs, + unsigned int nr_tables, + struct acpi_config *config) +{ + const char *s; + char **dir; + uint8_t type; + void *blob; + unsigned int num, length, offset, i, nr_added = 0; + + if ( !config->dm.addr ) + return 0; + + dir = ctxt->xs_ops.directory(ctxt, HVM_XS_DM_ACPI_ROOT, &num); + if ( !dir || !num ) + return 0; + + if ( num > ACPI_MAX_SECONDARY_TABLES - nr_tables ) + return 0; + + for ( i = 0; i < num; i++, dir++ ) + { + if ( *dir == NULL ) + continue; + + s = xs_read_dm_acpi_blob_key(ctxt, *dir, "type"); + if ( !s ) + continue; + type = (uint8_t)strtoll(s, NULL, 0); + + s = xs_read_dm_acpi_blob_key(ctxt, *dir, "length"); + if ( !s ) + continue; + length = (uint32_t)strtoll(s, NULL, 0); + + s = xs_read_dm_acpi_blob_key(ctxt, *dir, "offset"); + if ( !s ) + continue; + offset = (uint32_t)strtoll(s, NULL, 0); + + blob = ctxt->mem_ops.p2v(ctxt, config->dm.addr + offset); + + switch ( type ) + { + case DM_ACPI_BLOB_TYPE_TABLE: + nr_added += construct_dm_table(ctxt, + table_ptrs, nr_tables + nr_added, + blob, length); + break; + + case DM_ACPI_BLOB_TYPE_NSDEV: + nr_added += construct_dm_nsdev(ctxt, + table_ptrs, nr_tables + nr_added, + *dir, blob, length); + break; + + default: + /* skip blobs of unknown types */ + continue; + } + } + + return nr_added; +} + static int construct_secondary_tables(struct acpi_ctxt *ctxt, unsigned long *table_ptrs, struct acpi_config *config, @@ -359,6 +643,7 @@ static int construct_secondary_tables(struct acpi_ctxt *ctxt, madt = construct_madt(ctxt, config, info); if (!madt) return -1; table_ptrs[nr_tables++] = ctxt->mem_ops.v2p(ctxt, madt); + dm_acpi_signature_blacklist_register(config, madt->header.signature); } /* HPET. */ @@ -367,6 +652,7 @@ static int construct_secondary_tables(struct acpi_ctxt *ctxt, hpet = construct_hpet(ctxt, config); if (!hpet) return -1; table_ptrs[nr_tables++] = ctxt->mem_ops.v2p(ctxt, hpet); + dm_acpi_signature_blacklist_register(config, hpet->header.signature); } /* WAET. */ @@ -376,6 +662,7 @@ static int construct_secondary_tables(struct acpi_ctxt *ctxt, if ( !waet ) return -1; table_ptrs[nr_tables++] = ctxt->mem_ops.v2p(ctxt, waet); + dm_acpi_signature_blacklist_register(config, waet->header.signature); } if ( config->table_flags & ACPI_HAS_SSDT_PM ) @@ -384,6 +671,9 @@ static int construct_secondary_tables(struct acpi_ctxt *ctxt, if (!ssdt) return -1; memcpy(ssdt, ssdt_pm, sizeof(ssdt_pm)); table_ptrs[nr_tables++] = ctxt->mem_ops.v2p(ctxt, ssdt); + dm_acpi_devname_blacklist_register(config, "AC"); + dm_acpi_devname_blacklist_register(config, "BAT0"); + dm_acpi_devname_blacklist_register(config, "BAT1"); } if ( config->table_flags & ACPI_HAS_SSDT_S3 ) @@ -439,6 +729,8 @@ static int construct_secondary_tables(struct acpi_ctxt *ctxt, offsetof(struct acpi_header, checksum), tcpa->header.length); } + dm_acpi_signature_blacklist_register(config, tcpa->header.signature); + dm_acpi_devname_blacklist_register(config, "TPM"); } /* SRAT and SLIT */ @@ -448,11 +740,17 @@ static int construct_secondary_tables(struct acpi_ctxt *ctxt, struct acpi_20_slit *slit = construct_slit(ctxt, config); if ( srat ) + { table_ptrs[nr_tables++] = ctxt->mem_ops.v2p(ctxt, srat); + dm_acpi_signature_blacklist_register(config, srat->header.signature); + } else printf("Failed to build SRAT, skipping...\n"); if ( slit ) + { table_ptrs[nr_tables++] = ctxt->mem_ops.v2p(ctxt, slit); + dm_acpi_signature_blacklist_register(config, slit->header.signature); + } else printf("Failed to build SLIT, skipping...\n"); } @@ -461,6 +759,9 @@ static int construct_secondary_tables(struct acpi_ctxt *ctxt, nr_tables += construct_passthrough_tables(ctxt, table_ptrs, nr_tables, config); + /* Load any additional tables passed from device model (e.g. QEMU). */ + nr_tables += construct_dm_tables(ctxt, table_ptrs, nr_tables, config); + table_ptrs[nr_tables] = 0; return nr_tables; } @@ -525,6 +826,9 @@ int acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) acpi_info->pci_hi_len = config->pci_hi_len; } + if ( !has_dm_tables(ctxt, config) ) + config->table_flags &= ~ACPI_HAS_DM; + /* * Fill in high-memory data structures, starting at @buf. */ @@ -532,6 +836,7 @@ int acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) facs = ctxt->mem_ops.alloc(ctxt, sizeof(struct acpi_20_facs), 16); if (!facs) goto oom; memcpy(facs, &Facs, sizeof(struct acpi_20_facs)); + dm_acpi_signature_blacklist_register(config, facs->signature); /* * Alternative DSDTs we get linked against. A cover-all DSDT for up to the @@ -553,6 +858,8 @@ int acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) if (!dsdt) goto oom; memcpy(dsdt, config->dsdt_anycpu, config->dsdt_anycpu_len); } + dm_acpi_devname_blacklist_register(config, "MEM0"); + dm_acpi_devname_blacklist_register(config, "PCI0"); /* * N.B. ACPI 1.0 operating systems may not handle FADT with revision 2 @@ -623,6 +930,7 @@ int acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) fadt->iapc_boot_arch |= ACPI_FADT_NO_CMOS_RTC; } set_checksum(fadt, offsetof(struct acpi_header, checksum), fadt_size); + dm_acpi_signature_blacklist_register(config, fadt->header.signature); nr_secondaries = construct_secondary_tables(ctxt, secondary_tables, config, acpi_info); @@ -641,6 +949,7 @@ int acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) set_checksum(xsdt, offsetof(struct acpi_header, checksum), xsdt->header.length); + dm_acpi_signature_blacklist_register(config, xsdt->header.signature); rsdt = ctxt->mem_ops.alloc(ctxt, sizeof(struct acpi_20_rsdt) + sizeof(uint32_t) * nr_secondaries, @@ -654,6 +963,7 @@ int acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) set_checksum(rsdt, offsetof(struct acpi_header, checksum), rsdt->header.length); + dm_acpi_signature_blacklist_register(config, rsdt->header.signature); /* * Fill in low-memory data structures: acpi_info and RSDP. @@ -669,6 +979,7 @@ int acpi_build_tables(struct acpi_ctxt *ctxt, struct acpi_config *config) set_checksum(rsdp, offsetof(struct acpi_20_rsdp, extended_checksum), sizeof(struct acpi_20_rsdp)); + dm_acpi_signature_blacklist_register(config, rsdp->signature); if ( !new_vm_gid(ctxt, config, acpi_info) ) goto oom; diff --git a/tools/libacpi/libacpi.h b/tools/libacpi/libacpi.h index 645e091f68..b41113ff3f 100644 --- a/tools/libacpi/libacpi.h +++ b/tools/libacpi/libacpi.h @@ -20,6 +20,8 @@ #ifndef __LIBACPI_H__ #define __LIBACPI_H__ +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) + #define ACPI_HAS_COM1 (1<<0) #define ACPI_HAS_COM2 (1<<1) #define ACPI_HAS_LPT1 (1<<2) @@ -35,6 +37,7 @@ #define ACPI_HAS_VGA (1<<12) #define ACPI_HAS_8042 (1<<13) #define ACPI_HAS_CMOS_RTC (1<<14) +#define ACPI_HAS_DM (1<<15) struct xen_vmemrange; struct acpi_numa { @@ -87,6 +90,11 @@ struct acpi_config { uint32_t length; } pt; + struct { + uint32_t addr; + uint32_t length; + } dm; + struct acpi_numa numa; const struct hvm_info_table *hvminfo;