Xen mangles the MADT tables on boot up. But the pristine tables are needed
on kexec. So save the tables and restore them on kexec.
Note that this saves all the tables. A trimmed down save could
be done if prefered.
Signed-off-by: Simon Horman <horms@xxxxxxxxxxxx>
Index: xen-ia64-unstable.hg/xen/arch/ia64/xen/dom_fw_dom0.c
===================================================================
--- xen-ia64-unstable.hg.orig/xen/arch/ia64/xen/dom_fw_dom0.c 2007-06-28
15:07:12.000000000 +0900
+++ xen-ia64-unstable.hg/xen/arch/ia64/xen/dom_fw_dom0.c 2007-06-28
15:10:13.000000000 +0900
@@ -121,6 +121,7 @@ void __init efi_systable_init_dom0(struc
int i = 1;
/* Write messages to the console. */
+ acpi_table_save();
touch_acpi_table();
printk("Domain0 EFI passthrough:");
Index: xen-ia64-unstable.hg/xen/drivers/acpi/tables.c
===================================================================
--- xen-ia64-unstable.hg.orig/xen/drivers/acpi/tables.c 2007-06-28
15:07:12.000000000 +0900
+++ xen-ia64-unstable.hg/xen/drivers/acpi/tables.c 2007-06-28
15:10:13.000000000 +0900
@@ -74,7 +74,8 @@ struct acpi_table_sdt {
static unsigned long sdt_pa; /* Physical Address */
static unsigned long sdt_count; /* Table count */
-static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES] __initdata;
+static struct acpi_table_sdt sdt_entry[ACPI_MAX_TABLES];
+static struct acpi_table_sdt sdt_entry_backup[ACPI_MAX_TABLES];
void acpi_table_print(struct acpi_table_header *header, unsigned long
phys_addr)
{
@@ -377,6 +378,50 @@ acpi_table_parse_madt(enum acpi_madt_ent
handler, max_entries);
}
+/* Xen does unspeakable things to the ACPI table,
+ * so save it so it can be restored before kexecing */
+void __init
+acpi_table_save(void)
+{
+ unsigned int i;
+ void *in, *out;
+
+ BUG_ON(sdt_entry_backup[0].pa);
+
+ for (i = 0; i < sdt_count; i++) {
+ in = __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
+ BUG_ON(!in);
+
+ /* XXX: Is this the right way to grab some memory? */
+ out = xmalloc_bytes(sdt_entry[i].size);
+ BUG_ON(!out);
+
+ sdt_entry_backup[i].size = sdt_entry[i].size;
+ sdt_entry_backup[i].id = sdt_entry[i].id;
+ sdt_entry_backup[i].pa = __pa(out);
+ memcpy(out, in, sdt_entry[i].size);
+ }
+}
+
+void
+acpi_table_restore(void)
+{
+ unsigned int i;
+ void *in, *out;
+
+ BUG_ON(!sdt_entry_backup[0].pa);
+
+ for (i = 0; i < sdt_count; i++) {
+ out = __acpi_map_table(sdt_entry[i].pa, sdt_entry[i].size);
+ BUG_ON(!out);
+
+ sdt_entry[i].size = sdt_entry_backup[i].size;
+ sdt_entry[i].id = sdt_entry_backup[i].id;
+ in = __va(sdt_entry_backup[i].pa);
+ memcpy(out, in, sdt_entry_backup[i].size);
+ }
+}
+
int __init acpi_table_parse(enum acpi_table_id id, acpi_table_handler handler)
{
int count = 0;
Index: xen-ia64-unstable.hg/xen/include/xen/acpi.h
===================================================================
--- xen-ia64-unstable.hg.orig/xen/include/xen/acpi.h 2007-06-28
15:07:12.000000000 +0900
+++ xen-ia64-unstable.hg/xen/include/xen/acpi.h 2007-06-28 15:10:13.000000000
+0900
@@ -386,6 +386,8 @@ int acpi_table_init (void);
int acpi_table_parse (enum acpi_table_id id, acpi_table_handler handler);
int acpi_get_table_header_early (enum acpi_table_id id, struct
acpi_table_header **header);
int acpi_table_parse_madt (enum acpi_madt_entry_id id, acpi_madt_entry_handler
handler, unsigned int max_entries);
+void acpi_table_save(void);
+void acpi_table_restore(void);
int acpi_table_parse_srat (enum acpi_srat_entry_id id, acpi_madt_entry_handler
handler, unsigned int max_entries);
void acpi_table_print (struct acpi_table_header *header, unsigned long
phys_addr);
void acpi_table_print_madt_entry (acpi_table_entry_header *madt);
Index: xen-ia64-unstable.hg/xen/arch/ia64/xen/machine_kexec.c
===================================================================
--- xen-ia64-unstable.hg.orig/xen/arch/ia64/xen/machine_kexec.c 2007-06-28
15:10:27.000000000 +0900
+++ xen-ia64-unstable.hg/xen/arch/ia64/xen/machine_kexec.c 2007-06-28
15:10:42.000000000 +0900
@@ -185,6 +185,7 @@ static void machine_shutdown(void)
}
#endif
kexec_disable_iosapic();
+ acpi_table_restore();
}
void machine_kexec(xen_kexec_image_t *image)
--
--
Horms
H: http://www.vergenet.net/~horms/
W: http://www.valinux.co.jp/en/
_______________________________________________
Xen-ia64-devel mailing list
Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-ia64-devel
|