ia64/xen-unstable

changeset 16120:3f6e855d218b

[IA64] Backup/restore ACPI tables

We modify some of the ACPI tables for dom0 (limiting available CPUs,
modifying id/eid, and hiding SLIT/SRAT tables). This causes problems
when we try to kexec with different dom0 CPU counts or from Xen to
Linux. This introduces a mechanism to save ACPI tables before
modification and restoring them before kexec.

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
Acked-by: Simon Horman <horms@verge.net.au>
author Alex Williamson <alex.williamson@hp.com>
date Wed Oct 17 10:36:31 2007 -0600 (2007-10-17)
parents 31959a65fe7c
children 328dcc446f9e
files xen/arch/ia64/xen/dom_fw_dom0.c xen/arch/ia64/xen/machine_kexec.c xen/include/asm-ia64/dom_fw_dom0.h
line diff
     1.1 --- a/xen/arch/ia64/xen/dom_fw_dom0.c	Wed Oct 17 10:29:31 2007 -0600
     1.2 +++ b/xen/arch/ia64/xen/dom_fw_dom0.c	Wed Oct 17 10:36:31 2007 -0600
     1.3 @@ -28,6 +28,7 @@
     1.4  #include <xen/acpi.h>
     1.5  #include <xen/errno.h>
     1.6  #include <xen/sched.h>
     1.7 +#include <xen/list.h>
     1.8  
     1.9  #include <asm/dom_fw.h>
    1.10  #include <asm/dom_fw_common.h>
    1.11 @@ -36,6 +37,15 @@
    1.12  
    1.13  #include <linux/sort.h>
    1.14  
    1.15 +struct acpi_backup_table_entry {
    1.16 +	struct list_head list;
    1.17 +	unsigned long pa;
    1.18 +	unsigned long size;
    1.19 +	unsigned char data[0];
    1.20 +};
    1.21 +
    1.22 +static LIST_HEAD(acpi_backup_table_list);
    1.23 +
    1.24  static u32 lsapic_nbr;
    1.25  
    1.26  /* Modify lsapic table.  Provides LPs.  */
    1.27 @@ -100,18 +110,85 @@ acpi_update_madt_checksum(unsigned long 
    1.28  	return 0;
    1.29  }
    1.30  
    1.31 +static int __init
    1.32 +acpi_backup_table(unsigned long phys_addr, unsigned long size)
    1.33 +{
    1.34 +	struct acpi_backup_table_entry *entry;
    1.35 +	void *vaddr = __va(phys_addr);
    1.36 +
    1.37 +	if (!phys_addr || !size)
    1.38 +		return -EINVAL;
    1.39 +
    1.40 +	entry = xmalloc_bytes(sizeof(*entry) + size);
    1.41 +	if (!entry) {
    1.42 +		dprintk(XENLOG_WARNING, "Failed to allocate memory for "
    1.43 +		        "%.4s table backup\n",
    1.44 +			((struct acpi_table_header *)vaddr)->signature);
    1.45 +		return -ENOMEM;
    1.46 +	}
    1.47 +
    1.48 +	entry->pa = phys_addr;
    1.49 +	entry->size = size;
    1.50 +
    1.51 +	memcpy(entry->data, vaddr, size);
    1.52 +
    1.53 +	list_add(&entry->list, &acpi_backup_table_list);
    1.54 +
    1.55 +	printk(XENLOG_INFO "Backup %.4s table stored @0x%p\n",
    1.56 +	       ((struct acpi_table_header *)entry->data)->signature,
    1.57 +	       entry->data);
    1.58 +
    1.59 +	return 0;
    1.60 +}
    1.61 +
    1.62 +void
    1.63 +acpi_restore_tables()
    1.64 +{
    1.65 +	struct acpi_backup_table_entry *entry;
    1.66 +
    1.67 +	list_for_each_entry(entry, &acpi_backup_table_list, list) {
    1.68 +		printk(XENLOG_INFO "Restoring backup %.4s table @0x%p\n",
    1.69 +		       ((struct acpi_table_header *)entry->data)->signature,
    1.70 +		       entry->data);
    1.71 +
    1.72 +		memcpy(__va(entry->pa), entry->data, entry->size);
    1.73 +		/* Only called from kexec path, no need to free entries */
    1.74 +	}
    1.75 +}
    1.76 +
    1.77  /* base is physical address of acpi table */
    1.78  static void __init touch_acpi_table(void)
    1.79  {
    1.80  	int result;
    1.81  	lsapic_nbr = 0;
    1.82  
    1.83 +	/*
    1.84 +	 * Modify dom0 MADT:
    1.85 +	 *  - Disable CPUs that would exceed max vCPUs for the domain
    1.86 +	 *  - Virtualize id/eid for indexing into domain vCPU array
    1.87 +	 *  - Hide CPEI interrupt source
    1.88 +	 *
    1.89 +	 * ACPI tables must be backed-up before modification!
    1.90 +	 */
    1.91 +	acpi_table_parse(ACPI_APIC, acpi_backup_table);
    1.92 +
    1.93  	if (acpi_table_parse_madt(ACPI_MADT_LSAPIC, acpi_update_lsapic, 0) < 0)
    1.94  		printk("Error parsing MADT - no LAPIC entries\n");
    1.95  	if (acpi_table_parse_madt(ACPI_MADT_PLAT_INT_SRC,
    1.96  				  acpi_patch_plat_int_src, 0) < 0)
    1.97  		printk("Error parsing MADT - no PLAT_INT_SRC entries\n");
    1.98  
    1.99 +	acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum);
   1.100 +
   1.101 +	/*
   1.102 +	 * SRAT & SLIT tables aren't useful for Dom0 until
   1.103 +	 * we support more NUMA configuration information in Xen.
   1.104 +	 *
   1.105 +	 * NB - backup ACPI tables first.
   1.106 +	 */
   1.107 +	acpi_table_parse(ACPI_SRAT, acpi_backup_table);
   1.108 +	acpi_table_parse(ACPI_SLIT, acpi_backup_table);
   1.109 +
   1.110  	result = acpi_table_disable(ACPI_SRAT);
   1.111  	if ( result == 0 )
   1.112  		printk("Success Disabling SRAT\n");
   1.113 @@ -124,8 +201,6 @@ static void __init touch_acpi_table(void
   1.114  	else if ( result != -ENOENT )
   1.115  		printk("ERROR: Failed Disabling SLIT\n");
   1.116  
   1.117 -	acpi_table_parse(ACPI_APIC, acpi_update_madt_checksum);
   1.118 -
   1.119  	return;
   1.120  }
   1.121  
   1.122 @@ -133,9 +208,9 @@ void __init efi_systable_init_dom0(struc
   1.123  {
   1.124  	int i = 1;
   1.125  
   1.126 -	/* Write messages to the console.  */
   1.127  	touch_acpi_table();
   1.128  
   1.129 +	/* Write messages to the console.  */
   1.130  	printk("Domain0 EFI passthrough:");
   1.131  	if (efi.mps) {
   1.132  		tables->efi_tables[i].guid = MPS_TABLE_GUID;
     2.1 --- a/xen/arch/ia64/xen/machine_kexec.c	Wed Oct 17 10:29:31 2007 -0600
     2.2 +++ b/xen/arch/ia64/xen/machine_kexec.c	Wed Oct 17 10:36:31 2007 -0600
     2.3 @@ -23,6 +23,7 @@
     2.4  #include <linux/cpu.h>
     2.5  #include <linux/cpu.h>
     2.6  #include <linux/notifier.h>
     2.7 +#include <asm/dom_fw_dom0.h>
     2.8  
     2.9  typedef asmlinkage NORET_TYPE void (*relocate_new_kernel_t)(
    2.10  					unsigned long indirection_page,
    2.11 @@ -149,6 +150,7 @@ static void machine_shutdown(void)
    2.12  	}
    2.13  #endif
    2.14  	kexec_disable_iosapic();
    2.15 +	acpi_restore_tables();
    2.16  }
    2.17  
    2.18  void machine_kexec(xen_kexec_image_t *image)
     3.1 --- a/xen/include/asm-ia64/dom_fw_dom0.h	Wed Oct 17 10:29:31 2007 -0600
     3.2 +++ b/xen/include/asm-ia64/dom_fw_dom0.h	Wed Oct 17 10:36:31 2007 -0600
     3.3 @@ -26,6 +26,7 @@ struct domain;
     3.4  
     3.5  void efi_systable_init_dom0(struct fw_tables *tables);
     3.6  int complete_dom0_memmap(struct domain *d, struct fw_tables *tables);
     3.7 +void acpi_restore_tables(void);
     3.8  
     3.9  #endif /* __ASM_IA64_DOM_FW_DOM0_H__ */
    3.10  /*