[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-ia64-devel] Re: [patch 05/12] Kexec: Save the MADT ACPI tables so that they can be restored
On Thu, 2007-09-27 at 17:17 +0900, Simon Horman wrote: > plain text document attachment (ia64-xen-kexec-save-acpi.patch) > 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. Hi Simon, I made an attempt to re-write this one. The most obvious reason for virtualizing the id/eid is for indexing into the domain vcpu array. Even if we made use of the real id/eid for that lookup, there are a couple other places where we're disabling bits of ACPI for dom0. So, it seems like we're stuck with backing up tables before dom0 is built and restoring them on kexec. I took a little bit more surgical approach in the implementation below (only backing up tables we mangle) and kept the changes in architecture specific code. This is a little more space efficient, but does require that we explicitly backup tables before we mangle them. Let me know what you think (or if it works - I can't seem to get a kexec to happen, no console output after machine_shutdown). Thanks, Alex Signed-off-by: Alex Williamson <alex.williamson@xxxxxx> -- diff -r 3165e43ce734 xen/arch/ia64/xen/dom_fw_dom0.c --- a/xen/arch/ia64/xen/dom_fw_dom0.c Tue Oct 02 11:31:55 2007 -0600 +++ b/xen/arch/ia64/xen/dom_fw_dom0.c Wed Oct 03 10:54:50 2007 -0600 @@ -28,6 +28,7 @@ #include <xen/acpi.h> #include <xen/errno.h> #include <xen/sched.h> +#include <xen/list.h> #include <asm/dom_fw.h> #include <asm/dom_fw_common.h> @@ -35,6 +36,15 @@ #include <asm/dom_fw_utils.h> #include <linux/sort.h> + +struct acpi_backup_table_entry { + struct list_head list; + unsigned long pa; + unsigned long size; + unsigned char data[0]; +}; + +static LIST_HEAD(acpi_backup_table_list); static u32 lsapic_nbr; @@ -100,11 +110,67 @@ acpi_update_madt_checksum(unsigned long return 0; } +static int __init +acpi_backup_table(unsigned long phys_addr, unsigned long size) +{ + struct acpi_backup_table_entry *entry; + void *vaddr = __va(phys_addr); + + if (!phys_addr || !size) + return -EINVAL; + + entry = xmalloc_bytes(sizeof(*entry) + size); + if (!entry) { + dprintk(XENLOG_WARNING, "Failed to allocate memory for " + "%.4s table backup\n", + ((struct acpi_table_header *)vaddr)->signature); + return -ENOMEM; + } + + entry->pa = phys_addr; + entry->size = size; + + memcpy(entry->data, vaddr, size); + + list_add(&entry->list, &acpi_backup_table_list); + + printk(XENLOG_INFO "Backup %.4s table stored @0x%p\n", + ((struct acpi_table_header *)entry->data)->signature, + entry->data); + + return 0; +} + +void +acpi_restore_tables() +{ + struct acpi_backup_table_entry *entry; + + list_for_each_entry(entry, &acpi_backup_table_list, list) { + printk(XENLOG_INFO "Restoring backup %.4s table @0x%p\n", + ((struct acpi_table_header *)entry->data)->signature, + entry->data); + + memcpy(__va(entry->pa), entry->data, entry->size); + /* Only called from kexec path, no need to free entries */ + } +} + /* base is physical address of acpi table */ static void __init touch_acpi_table(void) { int result; lsapic_nbr = 0; + + /* + * Modify dom0 MADT: + * - Disable CPUs that would exceed max vCPUs for the domain + * - Virtualize id/eid for indexing into domain vCPU array + * - Hide CPEI interrupt source + * + * ACPI tables must be backed-up before modification! + */ + acpi_table_parse(ACPI_APIC, acpi_backup_table); if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, 0) < 0) printk("Error parsing MADT - no LAPIC entries\n"); @@ -112,6 +178,17 @@ static void __init touch_acpi_table(void acpi_patch_plat_int_src, 0) < 0) printk("Error parsing MADT - no PLAT_INT_SRC entries\n"); + acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum); + + /* + * SRAT & SLIT tables aren't useful for Dom0 until + * we support more NUMA configuration information in Xen. + * + * NB - backup ACPI tables first. + */ + acpi_table_parse(ACPI_SRAT, acpi_backup_table); + acpi_table_parse(ACPI_SLIT, acpi_backup_table); + result = acpi_table_disable(ACPI_SRAT); if ( result == 0 ) printk("Success Disabling SRAT\n"); @@ -124,8 +201,6 @@ static void __init touch_acpi_table(void else if ( result != -ENOENT ) printk("ERROR: Failed Disabling SLIT\n"); - acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum); - return; } @@ -133,9 +208,9 @@ void __init efi_systable_init_dom0(struc { int i = 1; + touch_acpi_table(); + /* Write messages to the console. */ - touch_acpi_table(); - printk("Domain0 EFI passthrough:"); if (efi.mps) { tables->efi_tables[i].guid = MPS_TABLE_GUID; diff -r 3165e43ce734 xen/arch/ia64/xen/machine_kexec.c --- a/xen/arch/ia64/xen/machine_kexec.c Tue Oct 02 11:31:55 2007 -0600 +++ b/xen/arch/ia64/xen/machine_kexec.c Tue Oct 02 15:41:59 2007 -0600 @@ -23,6 +23,7 @@ #include <linux/cpu.h> #include <linux/cpu.h> #include <linux/notifier.h> +#include <asm/dom_fw_dom0.h> typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)( unsigned long indirection_page, @@ -149,6 +150,7 @@ static void machine_shutdown(void) } #endif kexec_disable_iosapic(); + acpi_restore_tables(); } void machine_kexec(xen_kexec_image_t *image) diff -r 3165e43ce734 xen/include/asm-ia64/dom_fw_dom0.h --- a/xen/include/asm-ia64/dom_fw_dom0.h Tue Oct 02 11:31:55 2007 -0600 +++ b/xen/include/asm-ia64/dom_fw_dom0.h Tue Oct 02 15:41:32 2007 -0600 @@ -26,6 +26,7 @@ struct domain; void efi_systable_init_dom0(struct fw_tables *tables); int complete_dom0_memmap(struct domain *d, struct fw_tables *tables); +void acpi_restore_tables(void); #endif /* __ASM_IA64_DOM_FW_DOM0_H__ */ /* _______________________________________________ Xen-ia64-devel mailing list Xen-ia64-devel@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-ia64-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |