aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/geode-aes.c
diff options
context:
space:
mode:
authorMagnus Damm <magnus@valinux.co.jp>2007-03-06 05:34:26 -0500
committerTony Luck <tony.luck@intel.com>2007-03-06 17:50:33 -0500
commitcee87af2a5f75713b98d3e65e43872e547122cd5 (patch)
tree1b5e4778d66cab374e333b4a327d28b0e037ab3f /drivers/crypto/geode-aes.c
parent41d5e5d73ecef4ef56b7b4cde962929a712689b4 (diff)
[IA64] kexec: Use EFI_LOADER_DATA for ELF core header
The address where the ELF core header is stored is passed to the secondary kernel as a kernel command line option. The memory area for this header is also marked as a separate EFI memory descriptor on ia64. The separate EFI memory descriptor is at the moment of the type EFI_UNUSABLE_MEMORY. With such a type the secondary kernel skips over the entire memory granule (config option, 16M or 64M) when detecting memory. If we are lucky we will just lose some memory, but if we happen to have data in the same granule (such as an initramfs image), then this data will never get mapped and the kernel bombs out when trying to access it. So this is an attempt to fix this by changing the EFI memory descriptor type into EFI_LOADER_DATA. This type is the same type used for the kernel data and for initramfs. In the secondary kernel we then handle the ELF core header data the same way as we handle the initramfs image. This patch contains the kernel changes to make this happen. Pretty straightforward, we reserve the area in reserve_memory(). The address for the area comes from the kernel command line and the size comes from the specialized EFI parsing function vmcore_find_descriptor_size(). The kexec-tools-testing code for this can be found here: http://lists.osdl.org/pipermail/fastboot/2007-February/005983.html Signed-off-by: Magnus Damm <magnus@valinux.co.jp> Cc: Simon Horman <horms@verge.net.au> Cc: Vivek Goyal <vgoyal@in.ibm.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'drivers/crypto/geode-aes.c')
0 files changed, 0 insertions, 0 deletions
ot"); module_param(debug, bool, 0644); #define _COMPONENT ACPI_PCI_COMPONENT ACPI_MODULE_NAME("pci_slot"); #define MY_NAME "pci_slot" #define err(format, arg...) pr_err("%s: " format , MY_NAME , ## arg) #define info(format, arg...) pr_info("%s: " format , MY_NAME , ## arg) #define dbg(format, arg...) \ do { \ if (debug) \ pr_debug("%s: " format, MY_NAME , ## arg); \ } while (0) #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ struct acpi_pci_slot { struct pci_slot *pci_slot; /* corresponding pci_slot */ struct list_head list; /* node in the list of slots */ }; static LIST_HEAD(slot_list); static DEFINE_MUTEX(slot_list_lock); static int check_slot(acpi_handle handle, unsigned long long *sun) { int device = -1; unsigned long long adr, sta; acpi_status status; struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); dbg("Checking slot on path: %s\n", (char *)buffer.pointer); if (check_sta_before_sun) { /* If SxFy doesn't have _STA, we just assume it's there */ status = acpi_evaluate_integer(handle, "_STA", NULL, &sta); if (ACPI_SUCCESS(status) && !(sta & ACPI_STA_DEVICE_PRESENT)) goto out; } status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); if (ACPI_FAILURE(status)) { dbg("_ADR returned %d on %s\n", status, (char *)buffer.pointer); goto out; } /* No _SUN == not a slot == bail */ status = acpi_evaluate_integer(handle, "_SUN", NULL, sun); if (ACPI_FAILURE(status)) { dbg("_SUN returned %d on %s\n", status, (char *)buffer.pointer); goto out; } device = (adr >> 16) & 0xffff; out: kfree(buffer.pointer); return device; } /* * Check whether handle has an associated slot and create PCI slot if it has. */ static acpi_status register_slot(acpi_handle handle, u32 lvl, void *context, void **rv) { int device; unsigned long long sun; char name[SLOT_NAME_SIZE]; struct acpi_pci_slot *slot; struct pci_slot *pci_slot; struct pci_bus *pci_bus = context; device = check_slot(handle, &sun); if (device < 0) return AE_OK; /* * There may be multiple PCI functions associated with the same slot. * Check whether PCI slot has already been created for this PCI device. */ list_for_each_entry(slot, &slot_list, list) { pci_slot = slot->pci_slot; if (pci_slot->bus == pci_bus && pci_slot->number == device) return AE_OK; } slot = kmalloc(sizeof(*slot), GFP_KERNEL); if (!slot) { err("%s: cannot allocate memory\n", __func__); return AE_OK; } snprintf(name, sizeof(name), "%llu", sun); pci_slot = pci_create_slot(pci_bus, device, name, NULL); if (IS_ERR(pci_slot)) { err("pci_create_slot returned %ld\n", PTR_ERR(pci_slot)); kfree(slot); return AE_OK; } slot->pci_slot = pci_slot; list_add(&slot->list, &slot_list); get_device(&pci_bus->dev); dbg("pci_slot: %p, pci_bus: %x, device: %d, name: %s\n", pci_slot, pci_bus->number, device, name); return AE_OK; } void acpi_pci_slot_enumerate(struct pci_bus *bus) { acpi_handle handle = ACPI_HANDLE(bus->bridge); if (handle) { mutex_lock(&slot_list_lock); acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, 1, register_slot, NULL, bus, NULL); mutex_unlock(&slot_list_lock); } } void acpi_pci_slot_remove(struct pci_bus *bus) { struct acpi_pci_slot *slot, *tmp; mutex_lock(&slot_list_lock); list_for_each_entry_safe(slot, tmp, &slot_list, list) { if (slot->pci_slot->bus == bus) { list_del(&slot->list); pci_destroy_slot(slot->pci_slot); put_device(&bus->dev); kfree(slot); } } mutex_unlock(&slot_list_lock); } static int do_sta_before_sun(const struct dmi_system_id *d) { info("%s detected: will evaluate _STA before calling _SUN\n", d->ident); check_sta_before_sun = 1; return 0; } static struct dmi_system_id acpi_pci_slot_dmi_table[] __initdata = { /* * Fujitsu Primequest machines will return 1023 to indicate an * error if the _SUN method is evaluated on SxFy objects that * are not present (as indicated by _STA), so for those machines, * we want to check _STA before evaluating _SUN. */ { .callback = do_sta_before_sun, .ident = "Fujitsu PRIMEQUEST", .matches = { DMI_MATCH(DMI_BIOS_VENDOR, "FUJITSU LIMITED"), DMI_MATCH(DMI_BIOS_VERSION, "PRIMEQUEST"), }, }, {} }; void __init acpi_pci_slot_init(void) { dmi_check_system(acpi_pci_slot_dmi_table); }