From 6e9a5f08d6e87d6cb9ed8b64d2b5001b21baa74f Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 13 Dec 2006 11:08:40 -0700 Subject: [PATCH 001/570] [IA64] new files from Linux 2.6.19 required for SN2 and machvec support Signed-off-by: Jes Sorensen --- xen/arch/ia64/linux-xen/sn/Makefile | 1 + xen/arch/ia64/linux-xen/sn/kernel/Makefile | 5 + .../ia64/linux-xen/sn/kernel/README.origin | 12 + xen/arch/ia64/linux-xen/sn/kernel/io_init.c | 740 ++++ xen/arch/ia64/linux-xen/sn/kernel/iomv.c | 76 + xen/arch/ia64/linux-xen/sn/kernel/irq.c | 444 +++ xen/arch/ia64/linux-xen/sn/kernel/setup.c | 755 ++++ xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c | 489 +++ xen/arch/ia64/linux/Makefile | 1 + xen/arch/ia64/linux/README.origin | 3 + xen/arch/ia64/linux/dig/Makefile | 1 + xen/arch/ia64/linux/dig/README.origin | 7 + xen/arch/ia64/linux/dig/machvec.c | 3 + xen/arch/ia64/linux/hp/Makefile | 1 + xen/arch/ia64/linux/hp/zx1/Makefile | 1 + xen/arch/ia64/linux/hp/zx1/README.origin | 7 + xen/arch/ia64/linux/hp/zx1/hpzx1_machvec.c | 3 + xen/arch/ia64/linux/io.c | 164 + xen/arch/ia64/linux/sn/Makefile | 2 + xen/arch/ia64/linux/sn/kernel/Makefile | 3 + xen/arch/ia64/linux/sn/kernel/README.origin | 9 + xen/arch/ia64/linux/sn/kernel/machvec.c | 11 + xen/arch/ia64/linux/sn/kernel/pio_phys.S | 71 + xen/arch/ia64/linux/sn/kernel/ptc_deadlock.S | 92 + xen/arch/ia64/linux/sn/pci/Makefile | 1 + xen/arch/ia64/linux/sn/pci/pcibr/Makefile | 1 + .../ia64/linux/sn/pci/pcibr/README.origin | 7 + xen/arch/ia64/linux/sn/pci/pcibr/pcibr_reg.c | 285 ++ .../asm-ia64/linux-null/linux/ioport.h | 1 - .../asm-ia64/linux-xen/asm/README.origin | 6 + .../asm-ia64/linux-xen/asm/machvec_dig.h | 16 + .../asm-ia64/linux-xen/asm/machvec_hpzx1.h | 37 + .../asm-ia64/linux-xen/asm/machvec_sn2.h | 133 + xen/include/asm-ia64/linux-xen/asm/pci.h | 174 + .../asm-ia64/linux-xen/asm/sn/README.origin | 16 + xen/include/asm-ia64/linux-xen/asm/sn/addrs.h | 299 ++ xen/include/asm-ia64/linux-xen/asm/sn/arch.h | 85 + .../asm-ia64/linux-xen/asm/sn/hubdev.h | 91 + xen/include/asm-ia64/linux-xen/asm/sn/intr.h | 67 + xen/include/asm-ia64/linux-xen/asm/sn/io.h | 274 ++ .../asm-ia64/linux-xen/asm/sn/nodepda.h | 83 + .../linux-xen/asm/sn/pcibr_provider.h | 149 + .../asm-ia64/linux-xen/asm/sn/rw_mmr.h | 28 + xen/include/asm-ia64/linux-xen/asm/sn/types.h | 26 + .../asm-ia64/linux-xen/linux/README.origin | 5 + xen/include/asm-ia64/linux-xen/linux/device.h | 473 +++ .../asm-ia64/linux-xen/linux/kobject.h | 282 ++ xen/include/asm-ia64/linux-xen/linux/pci.h | 817 ++++ xen/include/asm-ia64/linux/README.origin | 12 + xen/include/asm-ia64/linux/asm/README.origin | 3 + xen/include/asm-ia64/linux/asm/machvec_init.h | 32 + .../asm-ia64/linux/asm/sn/README.origin | 23 + xen/include/asm-ia64/linux/asm/sn/geo.h | 132 + xen/include/asm-ia64/linux/asm/sn/klconfig.h | 246 ++ xen/include/asm-ia64/linux/asm/sn/l1.h | 51 + xen/include/asm-ia64/linux/asm/sn/leds.h | 33 + xen/include/asm-ia64/linux/asm/sn/module.h | 127 + .../linux/asm/sn/pcibus_provider_defs.h | 68 + xen/include/asm-ia64/linux/asm/sn/pcidev.h | 83 + xen/include/asm-ia64/linux/asm/sn/pda.h | 69 + xen/include/asm-ia64/linux/asm/sn/pic.h | 261 ++ xen/include/asm-ia64/linux/asm/sn/shub_mmr.h | 502 +++ xen/include/asm-ia64/linux/asm/sn/shubio.h | 3358 +++++++++++++++++ xen/include/asm-ia64/linux/asm/sn/simulator.h | 20 + xen/include/asm-ia64/linux/asm/sn/sn_cpuid.h | 132 + .../asm-ia64/linux/asm/sn/sn_feature_sets.h | 51 + xen/include/asm-ia64/linux/asm/sn/tiocp.h | 257 ++ xen/include/asm-ia64/linux/asm/sn/xbow.h | 301 ++ .../asm-ia64/linux/asm/sn/xwidgetdev.h | 70 + xen/include/asm-ia64/linux/completion.h | 57 + xen/include/asm-ia64/linux/ioport.h | 136 + xen/include/asm-ia64/linux/klist.h | 61 + xen/include/asm-ia64/linux/kref.h | 32 + xen/include/asm-ia64/linux/mod_devicetable.h | 323 ++ xen/include/asm-ia64/linux/pci_ids.h | 2356 ++++++++++++ xen/include/asm-ia64/linux/pci_regs.h | 488 +++ xen/include/asm-ia64/linux/pm.h | 279 ++ xen/include/asm-ia64/linux/sysfs.h | 206 + 78 files changed, 16025 insertions(+), 1 deletion(-) create mode 100644 xen/arch/ia64/linux-xen/sn/Makefile create mode 100644 xen/arch/ia64/linux-xen/sn/kernel/Makefile create mode 100644 xen/arch/ia64/linux-xen/sn/kernel/README.origin create mode 100644 xen/arch/ia64/linux-xen/sn/kernel/io_init.c create mode 100644 xen/arch/ia64/linux-xen/sn/kernel/iomv.c create mode 100644 xen/arch/ia64/linux-xen/sn/kernel/irq.c create mode 100644 xen/arch/ia64/linux-xen/sn/kernel/setup.c create mode 100644 xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c create mode 100644 xen/arch/ia64/linux/dig/Makefile create mode 100644 xen/arch/ia64/linux/dig/README.origin create mode 100644 xen/arch/ia64/linux/dig/machvec.c create mode 100644 xen/arch/ia64/linux/hp/Makefile create mode 100644 xen/arch/ia64/linux/hp/zx1/Makefile create mode 100644 xen/arch/ia64/linux/hp/zx1/README.origin create mode 100644 xen/arch/ia64/linux/hp/zx1/hpzx1_machvec.c create mode 100644 xen/arch/ia64/linux/io.c create mode 100644 xen/arch/ia64/linux/sn/Makefile create mode 100644 xen/arch/ia64/linux/sn/kernel/Makefile create mode 100644 xen/arch/ia64/linux/sn/kernel/README.origin create mode 100644 xen/arch/ia64/linux/sn/kernel/machvec.c create mode 100644 xen/arch/ia64/linux/sn/kernel/pio_phys.S create mode 100644 xen/arch/ia64/linux/sn/kernel/ptc_deadlock.S create mode 100644 xen/arch/ia64/linux/sn/pci/Makefile create mode 100644 xen/arch/ia64/linux/sn/pci/pcibr/Makefile create mode 100644 xen/arch/ia64/linux/sn/pci/pcibr/README.origin create mode 100644 xen/arch/ia64/linux/sn/pci/pcibr/pcibr_reg.c delete mode 100644 xen/include/asm-ia64/linux-null/linux/ioport.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/machvec_dig.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/pci.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/README.origin create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/addrs.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/arch.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/hubdev.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/intr.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/io.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/nodepda.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/pcibr_provider.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/rw_mmr.h create mode 100644 xen/include/asm-ia64/linux-xen/asm/sn/types.h create mode 100644 xen/include/asm-ia64/linux-xen/linux/device.h create mode 100644 xen/include/asm-ia64/linux-xen/linux/kobject.h create mode 100644 xen/include/asm-ia64/linux-xen/linux/pci.h create mode 100644 xen/include/asm-ia64/linux/asm/machvec_init.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/README.origin create mode 100644 xen/include/asm-ia64/linux/asm/sn/geo.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/klconfig.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/l1.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/leds.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/module.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/pcibus_provider_defs.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/pcidev.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/pda.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/pic.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/shub_mmr.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/shubio.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/simulator.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/sn_cpuid.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/sn_feature_sets.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/tiocp.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/xbow.h create mode 100644 xen/include/asm-ia64/linux/asm/sn/xwidgetdev.h create mode 100644 xen/include/asm-ia64/linux/completion.h create mode 100644 xen/include/asm-ia64/linux/ioport.h create mode 100644 xen/include/asm-ia64/linux/klist.h create mode 100644 xen/include/asm-ia64/linux/kref.h create mode 100644 xen/include/asm-ia64/linux/mod_devicetable.h create mode 100644 xen/include/asm-ia64/linux/pci_ids.h create mode 100644 xen/include/asm-ia64/linux/pci_regs.h create mode 100644 xen/include/asm-ia64/linux/pm.h create mode 100644 xen/include/asm-ia64/linux/sysfs.h diff --git a/xen/arch/ia64/linux-xen/sn/Makefile b/xen/arch/ia64/linux-xen/sn/Makefile new file mode 100644 index 0000000000..96dd76f238 --- /dev/null +++ b/xen/arch/ia64/linux-xen/sn/Makefile @@ -0,0 +1 @@ +subdir-y += kernel diff --git a/xen/arch/ia64/linux-xen/sn/kernel/Makefile b/xen/arch/ia64/linux-xen/sn/kernel/Makefile new file mode 100644 index 0000000000..dc0d142533 --- /dev/null +++ b/xen/arch/ia64/linux-xen/sn/kernel/Makefile @@ -0,0 +1,5 @@ +obj-y += sn2_smp.o +obj-y += setup.o +obj-y += iomv.o +obj-y += irq.o +obj-y += io_init.o diff --git a/xen/arch/ia64/linux-xen/sn/kernel/README.origin b/xen/arch/ia64/linux-xen/sn/kernel/README.origin new file mode 100644 index 0000000000..312a90add1 --- /dev/null +++ b/xen/arch/ia64/linux-xen/sn/kernel/README.origin @@ -0,0 +1,12 @@ +# Source files in this directory are near-identical copies of linux-2.6.19 +# files: + +# NOTE: ALL changes to these files should be clearly marked +# (e.g. with #ifdef XEN or XEN in a comment) so that they can be +# easily updated to future versions of the corresponding Linux files. + +io_init.c -> linux/arch/ia64/sn/kernel/io_init.c +iomv.c -> linux/arch/ia64/sn/kernel/iomv.c +irq.c -> linux/arch/ia64/sn/kernel/irq.c +setup.c -> linux/arch/ia64/sn/kernel/setup.c +sn2_smp.c -> linux/arch/ia64/sn/kernel/sn2/sn2_smp.c diff --git a/xen/arch/ia64/linux-xen/sn/kernel/io_init.c b/xen/arch/ia64/linux-xen/sn/kernel/io_init.c new file mode 100644 index 0000000000..dc09a6a28a --- /dev/null +++ b/xen/arch/ia64/linux-xen/sn/kernel/io_init.c @@ -0,0 +1,740 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xtalk/hubdev.h" +#include "xtalk/xwidgetdev.h" + + +extern void sn_init_cpei_timer(void); +extern void register_sn_procfs(void); + +static struct list_head sn_sysdata_list; + +/* sysdata list struct */ +struct sysdata_el { + struct list_head entry; + void *sysdata; +}; + +struct slab_info { + struct hubdev_info hubdev; +}; + +struct brick { + moduleid_t id; /* Module ID of this module */ + struct slab_info slab_info[MAX_SLABS + 1]; +}; + +int sn_ioif_inited; /* SN I/O infrastructure initialized? */ + +struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ + +static int max_segment_number; /* Default highest segment number */ +static int max_pcibus_number = 255; /* Default highest pci bus number */ + +/* + * Hooks and struct for unsupported pci providers + */ + +static dma_addr_t +sn_default_pci_map(struct pci_dev *pdev, unsigned long paddr, size_t size, int type) +{ + return 0; +} + +static void +sn_default_pci_unmap(struct pci_dev *pdev, dma_addr_t addr, int direction) +{ + return; +} + +static void * +sn_default_pci_bus_fixup(struct pcibus_bussoft *soft, struct pci_controller *controller) +{ + return NULL; +} + +static struct sn_pcibus_provider sn_pci_default_provider = { + .dma_map = sn_default_pci_map, + .dma_map_consistent = sn_default_pci_map, + .dma_unmap = sn_default_pci_unmap, + .bus_fixup = sn_default_pci_bus_fixup, +}; + +/* + * Retrieve the DMA Flush List given nasid, widget, and device. + * This list is needed to implement the WAR - Flush DMA data on PIO Reads. + */ +static inline u64 +sal_get_device_dmaflush_list(u64 nasid, u64 widget_num, u64 device_num, + u64 address) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST, + (u64) nasid, (u64) widget_num, + (u64) device_num, (u64) address, 0, 0, 0); + return ret_stuff.status; +} + +/* + * Retrieve the hub device info structure for the given nasid. + */ +static inline u64 sal_get_hubdev_info(u64 handle, u64 address) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_HUBDEV_INFO, + (u64) handle, (u64) address, 0, 0, 0, 0, 0); + return ret_stuff.v0; +} + +/* + * Retrieve the pci bus information given the bus number. + */ +static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_PCIBUS_INFO, + (u64) segment, (u64) busnum, (u64) address, 0, 0, 0, 0); + return ret_stuff.v0; +} + +/* + * Retrieve the pci device information given the bus and device|function number. + */ +static inline u64 +sal_get_pcidev_info(u64 segment, u64 bus_number, u64 devfn, u64 pci_dev, + u64 sn_irq_info) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, + (u64) SN_SAL_IOIF_GET_PCIDEV_INFO, + (u64) segment, (u64) bus_number, (u64) devfn, + (u64) pci_dev, + sn_irq_info, 0, 0); + return ret_stuff.v0; +} + +/* + * sn_pcidev_info_get() - Retrieve the pcidev_info struct for the specified + * device. + */ +inline struct pcidev_info * +sn_pcidev_info_get(struct pci_dev *dev) +{ + struct pcidev_info *pcidev; + + list_for_each_entry(pcidev, + &(SN_PCI_CONTROLLER(dev)->pcidev_info), pdi_list) { + if (pcidev->pdi_linux_pcidev == dev) { + return pcidev; + } + } + return NULL; +} + +/* Older PROM flush WAR + * + * 01/16/06 -- This war will be in place until a new official PROM is released. + * Additionally note that the struct sn_flush_device_war also has to be + * removed from arch/ia64/sn/include/xtalk/hubdev.h + */ +static u8 war_implemented = 0; + +static s64 sn_device_fixup_war(u64 nasid, u64 widget, int device, + struct sn_flush_device_common *common) +{ + struct sn_flush_device_war *war_list; + struct sn_flush_device_war *dev_entry; + struct ia64_sal_retval isrv = {0,0,0,0}; + + if (!war_implemented) { + printk(KERN_WARNING "PROM version < 4.50 -- implementing old " + "PROM flush WAR\n"); + war_implemented = 1; + } + + war_list = kzalloc(DEV_PER_WIDGET * sizeof(*war_list), GFP_KERNEL); + if (!war_list) + BUG(); + + SAL_CALL_NOLOCK(isrv, SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST, + nasid, widget, __pa(war_list), 0, 0, 0 ,0); + if (isrv.status) + panic("sn_device_fixup_war failed: %s\n", + ia64_sal_strerror(isrv.status)); + + dev_entry = war_list + device; + memcpy(common,dev_entry, sizeof(*common)); + kfree(war_list); + + return isrv.status; +} + +/* + * sn_fixup_ionodes() - This routine initializes the HUB data strcuture for + * each node in the system. + */ +static void __init sn_fixup_ionodes(void) +{ + struct sn_flush_device_kernel *sn_flush_device_kernel; + struct sn_flush_device_kernel *dev_entry; + struct hubdev_info *hubdev; + u64 status; + u64 nasid; + int i, widget, device, size; + + /* + * Get SGI Specific HUB chipset information. + * Inform Prom that this kernel can support domain bus numbering. + */ + for (i = 0; i < num_cnodes; i++) { + hubdev = (struct hubdev_info *)(NODEPDA(i)->pdinfo); + nasid = cnodeid_to_nasid(i); + hubdev->max_segment_number = 0xffffffff; + hubdev->max_pcibus_number = 0xff; + status = sal_get_hubdev_info(nasid, (u64) __pa(hubdev)); + if (status) + continue; + + /* Save the largest Domain and pcibus numbers found. */ + if (hubdev->max_segment_number) { + /* + * Dealing with a Prom that supports segments. + */ + max_segment_number = hubdev->max_segment_number; + max_pcibus_number = hubdev->max_pcibus_number; + } + + /* Attach the error interrupt handlers */ + if (nasid & 1) + ice_error_init(hubdev); + else + hub_error_init(hubdev); + + for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) + hubdev->hdi_xwidget_info[widget].xwi_hubinfo = hubdev; + + if (!hubdev->hdi_flush_nasid_list.widget_p) + continue; + + size = (HUB_WIDGET_ID_MAX + 1) * + sizeof(struct sn_flush_device_kernel *); + hubdev->hdi_flush_nasid_list.widget_p = + kzalloc(size, GFP_KERNEL); + if (!hubdev->hdi_flush_nasid_list.widget_p) + BUG(); + + for (widget = 0; widget <= HUB_WIDGET_ID_MAX; widget++) { + size = DEV_PER_WIDGET * + sizeof(struct sn_flush_device_kernel); + sn_flush_device_kernel = kzalloc(size, GFP_KERNEL); + if (!sn_flush_device_kernel) + BUG(); + + dev_entry = sn_flush_device_kernel; + for (device = 0; device < DEV_PER_WIDGET; + device++,dev_entry++) { + size = sizeof(struct sn_flush_device_common); + dev_entry->common = kzalloc(size, GFP_KERNEL); + if (!dev_entry->common) + BUG(); + + if (sn_prom_feature_available( + PRF_DEVICE_FLUSH_LIST)) + status = sal_get_device_dmaflush_list( + nasid, widget, device, + (u64)(dev_entry->common)); + else + status = sn_device_fixup_war(nasid, + widget, device, + dev_entry->common); + if (status != SALRET_OK) + panic("SAL call failed: %s\n", + ia64_sal_strerror(status)); + + spin_lock_init(&dev_entry->sfdl_flush_lock); + } + + if (sn_flush_device_kernel) + hubdev->hdi_flush_nasid_list.widget_p[widget] = + sn_flush_device_kernel; + } + } +} + +/* + * sn_pci_window_fixup() - Create a pci_window for each device resource. + * Until ACPI support is added, we need this code + * to setup pci_windows for use by + * pcibios_bus_to_resource(), + * pcibios_resource_to_bus(), etc. + */ +static void +sn_pci_window_fixup(struct pci_dev *dev, unsigned int count, + s64 * pci_addrs) +{ + struct pci_controller *controller = PCI_CONTROLLER(dev->bus); + unsigned int i; + unsigned int idx; + unsigned int new_count; + struct pci_window *new_window; + + if (count == 0) + return; + idx = controller->windows; + new_count = controller->windows + count; + new_window = kcalloc(new_count, sizeof(struct pci_window), GFP_KERNEL); + if (new_window == NULL) + BUG(); + if (controller->window) { + memcpy(new_window, controller->window, + sizeof(struct pci_window) * controller->windows); + kfree(controller->window); + } + + /* Setup a pci_window for each device resource. */ + for (i = 0; i <= PCI_ROM_RESOURCE; i++) { + if (pci_addrs[i] == -1) + continue; + + new_window[idx].offset = dev->resource[i].start - pci_addrs[i]; + new_window[idx].resource = dev->resource[i]; + idx++; + } + + controller->windows = new_count; + controller->window = new_window; +} + +void sn_pci_unfixup_slot(struct pci_dev *dev) +{ + struct pci_dev *host_pci_dev = SN_PCIDEV_INFO(dev)->host_pci_dev; + + sn_irq_unfixup(dev); + pci_dev_put(host_pci_dev); + pci_dev_put(dev); +} + +/* + * sn_pci_fixup_slot() - This routine sets up a slot's resources + * consistent with the Linux PCI abstraction layer. Resources acquired + * from our PCI provider include PIO maps to BAR space and interrupt + * objects. + */ +void sn_pci_fixup_slot(struct pci_dev *dev) +{ + unsigned int count = 0; + int idx; + int segment = pci_domain_nr(dev->bus); + int status = 0; + struct pcibus_bussoft *bs; + struct pci_bus *host_pci_bus; + struct pci_dev *host_pci_dev; + struct pcidev_info *pcidev_info; + s64 pci_addrs[PCI_ROM_RESOURCE + 1]; + struct sn_irq_info *sn_irq_info; + unsigned long size; + unsigned int bus_no, devfn; + + pci_dev_get(dev); /* for the sysdata pointer */ + pcidev_info = kzalloc(sizeof(struct pcidev_info), GFP_KERNEL); + if (!pcidev_info) + BUG(); /* Cannot afford to run out of memory */ + + sn_irq_info = kzalloc(sizeof(struct sn_irq_info), GFP_KERNEL); + if (!sn_irq_info) + BUG(); /* Cannot afford to run out of memory */ + + /* Call to retrieve pci device information needed by kernel. */ + status = sal_get_pcidev_info((u64) segment, (u64) dev->bus->number, + dev->devfn, + (u64) __pa(pcidev_info), + (u64) __pa(sn_irq_info)); + if (status) + BUG(); /* Cannot get platform pci device information */ + + /* Add pcidev_info to list in sn_pci_controller struct */ + list_add_tail(&pcidev_info->pdi_list, + &(SN_PCI_CONTROLLER(dev->bus)->pcidev_info)); + + /* Copy over PIO Mapped Addresses */ + for (idx = 0; idx <= PCI_ROM_RESOURCE; idx++) { + unsigned long start, end, addr; + + if (!pcidev_info->pdi_pio_mapped_addr[idx]) { + pci_addrs[idx] = -1; + continue; + } + + start = dev->resource[idx].start; + end = dev->resource[idx].end; + size = end - start; + if (size == 0) { + pci_addrs[idx] = -1; + continue; + } + pci_addrs[idx] = start; + count++; + addr = pcidev_info->pdi_pio_mapped_addr[idx]; + addr = ((addr << 4) >> 4) | __IA64_UNCACHED_OFFSET; + dev->resource[idx].start = addr; + dev->resource[idx].end = addr + size; + if (dev->resource[idx].flags & IORESOURCE_IO) + dev->resource[idx].parent = &ioport_resource; + else + dev->resource[idx].parent = &iomem_resource; + } + /* Create a pci_window in the pci_controller struct for + * each device resource. + */ + if (count > 0) + sn_pci_window_fixup(dev, count, pci_addrs); + + /* + * Using the PROMs values for the PCI host bus, get the Linux + * PCI host_pci_dev struct and set up host bus linkages + */ + + bus_no = (pcidev_info->pdi_slot_host_handle >> 32) & 0xff; + devfn = pcidev_info->pdi_slot_host_handle & 0xffffffff; + host_pci_bus = pci_find_bus(segment, bus_no); + host_pci_dev = pci_get_slot(host_pci_bus, devfn); + + pcidev_info->host_pci_dev = host_pci_dev; + pcidev_info->pdi_linux_pcidev = dev; + pcidev_info->pdi_host_pcidev_info = SN_PCIDEV_INFO(host_pci_dev); + bs = SN_PCIBUS_BUSSOFT(dev->bus); + pcidev_info->pdi_pcibus_info = bs; + + if (bs && bs->bs_asic_type < PCIIO_ASIC_MAX_TYPES) { + SN_PCIDEV_BUSPROVIDER(dev) = sn_pci_provider[bs->bs_asic_type]; + } else { + SN_PCIDEV_BUSPROVIDER(dev) = &sn_pci_default_provider; + } + + /* Only set up IRQ stuff if this device has a host bus context */ + if (bs && sn_irq_info->irq_irq) { + pcidev_info->pdi_sn_irq_info = sn_irq_info; + dev->irq = pcidev_info->pdi_sn_irq_info->irq_irq; + sn_irq_fixup(dev, sn_irq_info); + } else { + pcidev_info->pdi_sn_irq_info = NULL; + kfree(sn_irq_info); + } +} + +/* + * sn_pci_controller_fixup() - This routine sets up a bus's resources + * consistent with the Linux PCI abstraction layer. + */ +void sn_pci_controller_fixup(int segment, int busnum, struct pci_bus *bus) +{ + int status; + int nasid, cnode; + struct pci_controller *controller; + struct sn_pci_controller *sn_controller; + struct pcibus_bussoft *prom_bussoft_ptr; + struct hubdev_info *hubdev_info; + void *provider_soft; + struct sn_pcibus_provider *provider; + + status = sal_get_pcibus_info((u64) segment, (u64) busnum, + (u64) ia64_tpa(&prom_bussoft_ptr)); + if (status > 0) + return; /*bus # does not exist */ + prom_bussoft_ptr = __va(prom_bussoft_ptr); + + /* Allocate a sn_pci_controller, which has a pci_controller struct + * as the first member. + */ + sn_controller = kzalloc(sizeof(struct sn_pci_controller), GFP_KERNEL); + if (!sn_controller) + BUG(); + INIT_LIST_HEAD(&sn_controller->pcidev_info); + controller = &sn_controller->pci_controller; + controller->segment = segment; + + if (bus == NULL) { + bus = pci_scan_bus(busnum, &pci_root_ops, controller); + if (bus == NULL) + goto error_return; /* error, or bus already scanned */ + bus->sysdata = NULL; + } + + if (bus->sysdata) + goto error_return; /* sysdata already alloc'd */ + + /* + * Per-provider fixup. Copies the contents from prom to local + * area and links SN_PCIBUS_BUSSOFT(). + */ + + if (prom_bussoft_ptr->bs_asic_type >= PCIIO_ASIC_MAX_TYPES) + goto error_return; /* unsupported asic type */ + + if (prom_bussoft_ptr->bs_asic_type == PCIIO_ASIC_TYPE_PPB) + goto error_return; /* no further fixup necessary */ + + provider = sn_pci_provider[prom_bussoft_ptr->bs_asic_type]; + if (provider == NULL) + goto error_return; /* no provider registerd for this asic */ + + bus->sysdata = controller; + if (provider->bus_fixup) + provider_soft = (*provider->bus_fixup) (prom_bussoft_ptr, controller); + else + provider_soft = NULL; + + if (provider_soft == NULL) { + /* fixup failed or not applicable */ + bus->sysdata = NULL; + goto error_return; + } + + /* + * Setup pci_windows for legacy IO and MEM space. + * (Temporary until ACPI support is in place.) + */ + controller->window = kcalloc(2, sizeof(struct pci_window), GFP_KERNEL); + if (controller->window == NULL) + BUG(); + controller->window[0].offset = prom_bussoft_ptr->bs_legacy_io; + controller->window[0].resource.name = "legacy_io"; + controller->window[0].resource.flags = IORESOURCE_IO; + controller->window[0].resource.start = prom_bussoft_ptr->bs_legacy_io; + controller->window[0].resource.end = + controller->window[0].resource.start + 0xffff; + controller->window[0].resource.parent = &ioport_resource; + controller->window[1].offset = prom_bussoft_ptr->bs_legacy_mem; + controller->window[1].resource.name = "legacy_mem"; + controller->window[1].resource.flags = IORESOURCE_MEM; + controller->window[1].resource.start = prom_bussoft_ptr->bs_legacy_mem; + controller->window[1].resource.end = + controller->window[1].resource.start + (1024 * 1024) - 1; + controller->window[1].resource.parent = &iomem_resource; + controller->windows = 2; + + /* + * Generic bus fixup goes here. Don't reference prom_bussoft_ptr + * after this point. + */ + + PCI_CONTROLLER(bus)->platform_data = provider_soft; + nasid = NASID_GET(SN_PCIBUS_BUSSOFT(bus)->bs_base); + cnode = nasid_to_cnodeid(nasid); + hubdev_info = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); + SN_PCIBUS_BUSSOFT(bus)->bs_xwidget_info = + &(hubdev_info->hdi_xwidget_info[SN_PCIBUS_BUSSOFT(bus)->bs_xid]); + + /* + * If the node information we obtained during the fixup phase is invalid + * then set controller->node to -1 (undetermined) + */ + if (controller->node >= num_online_nodes()) { + struct pcibus_bussoft *b = SN_PCIBUS_BUSSOFT(bus); + + printk(KERN_WARNING "Device ASIC=%u XID=%u PBUSNUM=%u" + "L_IO=%lx L_MEM=%lx BASE=%lx\n", + b->bs_asic_type, b->bs_xid, b->bs_persist_busnum, + b->bs_legacy_io, b->bs_legacy_mem, b->bs_base); + printk(KERN_WARNING "on node %d but only %d nodes online." + "Association set to undetermined.\n", + controller->node, num_online_nodes()); + controller->node = -1; + } + return; + +error_return: + + kfree(sn_controller); + return; +} + +void sn_bus_store_sysdata(struct pci_dev *dev) +{ + struct sysdata_el *element; + + element = kzalloc(sizeof(struct sysdata_el), GFP_KERNEL); + if (!element) { + dev_dbg(dev, "%s: out of memory!\n", __FUNCTION__); + return; + } + element->sysdata = SN_PCIDEV_INFO(dev); + list_add(&element->entry, &sn_sysdata_list); +} + +void sn_bus_free_sysdata(void) +{ + struct sysdata_el *element; + struct list_head *list, *safe; + + list_for_each_safe(list, safe, &sn_sysdata_list) { + element = list_entry(list, struct sysdata_el, entry); + list_del(&element->entry); + list_del(&(((struct pcidev_info *) + (element->sysdata))->pdi_list)); + kfree(element->sysdata); + kfree(element); + } + return; +} + +/* + * Ugly hack to get PCI setup until we have a proper ACPI namespace. + */ + +#define PCI_BUSES_TO_SCAN 256 + +static int __init sn_pci_init(void) +{ + int i, j; + struct pci_dev *pci_dev = NULL; + + if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) + return 0; + + /* + * prime sn_pci_provider[]. Individial provider init routines will + * override their respective default entries. + */ + + for (i = 0; i < PCIIO_ASIC_MAX_TYPES; i++) + sn_pci_provider[i] = &sn_pci_default_provider; + + pcibr_init_provider(); + tioca_init_provider(); + tioce_init_provider(); + + /* + * This is needed to avoid bounce limit checks in the blk layer + */ + ia64_max_iommu_merge_mask = ~PAGE_MASK; + sn_fixup_ionodes(); + sn_irq_lh_init(); + INIT_LIST_HEAD(&sn_sysdata_list); + sn_init_cpei_timer(); + +#ifdef CONFIG_PROC_FS + register_sn_procfs(); +#endif + + /* busses are not known yet ... */ + for (i = 0; i <= max_segment_number; i++) + for (j = 0; j <= max_pcibus_number; j++) + sn_pci_controller_fixup(i, j, NULL); + + /* + * Generic Linux PCI Layer has created the pci_bus and pci_dev + * structures - time for us to add our SN PLatform specific + * information. + */ + + while ((pci_dev = + pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) + sn_pci_fixup_slot(pci_dev); + + sn_ioif_inited = 1; /* sn I/O infrastructure now initialized */ + + return 0; +} + +/* + * hubdev_init_node() - Creates the HUB data structure and link them to it's + * own NODE specific data area. + */ +void hubdev_init_node(nodepda_t * npda, cnodeid_t node) +{ + struct hubdev_info *hubdev_info; + int size; + pg_data_t *pg; + + size = sizeof(struct hubdev_info); + + if (node >= num_online_nodes()) /* Headless/memless IO nodes */ + pg = NODE_DATA(0); + else + pg = NODE_DATA(node); + + hubdev_info = (struct hubdev_info *)alloc_bootmem_node(pg, size); + + npda->pdinfo = (void *)hubdev_info; +} + +geoid_t +cnodeid_get_geoid(cnodeid_t cnode) +{ + struct hubdev_info *hubdev; + + hubdev = (struct hubdev_info *)(NODEPDA(cnode)->pdinfo); + return hubdev->hdi_geoid; +} + +void sn_generate_path(struct pci_bus *pci_bus, char *address) +{ + nasid_t nasid; + cnodeid_t cnode; + geoid_t geoid; + moduleid_t moduleid; + u16 bricktype; + + nasid = NASID_GET(SN_PCIBUS_BUSSOFT(pci_bus)->bs_base); + cnode = nasid_to_cnodeid(nasid); + geoid = cnodeid_get_geoid(cnode); + moduleid = geo_module(geoid); + + sprintf(address, "module_%c%c%c%c%.2d", + '0'+RACK_GET_CLASS(MODULE_GET_RACK(moduleid)), + '0'+RACK_GET_GROUP(MODULE_GET_RACK(moduleid)), + '0'+RACK_GET_NUM(MODULE_GET_RACK(moduleid)), + MODULE_GET_BTCHAR(moduleid), MODULE_GET_BPOS(moduleid)); + + /* Tollhouse requires slot id to be displayed */ + bricktype = MODULE_GET_BTYPE(moduleid); + if ((bricktype == L1_BRICKTYPE_191010) || + (bricktype == L1_BRICKTYPE_1932)) + sprintf(address, "%s^%d", address, geo_slot(geoid)); +} + +subsys_initcall(sn_pci_init); +EXPORT_SYMBOL(sn_pci_fixup_slot); +EXPORT_SYMBOL(sn_pci_unfixup_slot); +EXPORT_SYMBOL(sn_pci_controller_fixup); +EXPORT_SYMBOL(sn_bus_store_sysdata); +EXPORT_SYMBOL(sn_bus_free_sysdata); +EXPORT_SYMBOL(sn_generate_path); diff --git a/xen/arch/ia64/linux-xen/sn/kernel/iomv.c b/xen/arch/ia64/linux-xen/sn/kernel/iomv.c new file mode 100644 index 0000000000..7ce3cdad62 --- /dev/null +++ b/xen/arch/ia64/linux-xen/sn/kernel/iomv.c @@ -0,0 +1,76 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define IS_LEGACY_VGA_IOPORT(p) \ + (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df)) + +/** + * sn_io_addr - convert an in/out port to an i/o address + * @port: port to convert + * + * Legacy in/out instructions are converted to ld/st instructions + * on IA64. This routine will convert a port number into a valid + * SN i/o address. Used by sn_in*() and sn_out*(). + */ +void *sn_io_addr(unsigned long port) +{ + if (!IS_RUNNING_ON_SIMULATOR()) { + if (IS_LEGACY_VGA_IOPORT(port)) + port += vga_console_iobase; + /* On sn2, legacy I/O ports don't point at anything */ + if (port < (64 * 1024)) + return NULL; + return ((void *)(port | __IA64_UNCACHED_OFFSET)); + } else { + /* but the simulator uses them... */ + unsigned long addr; + + /* + * word align port, but need more than 10 bits + * for accessing registers in bedrock local block + * (so we don't do port&0xfff) + */ + addr = (is_shub2() ? 0xc00000028c000000UL : 0xc0000087cc000000UL) | ((port >> 2) << 12); + if ((port >= 0x1f0 && port <= 0x1f7) || port == 0x3f6 || port == 0x3f7) + addr |= port; + return (void *)addr; + } +} + +EXPORT_SYMBOL(sn_io_addr); + +/** + * __sn_mmiowb - I/O space memory barrier + * + * See include/asm-ia64/io.h and Documentation/DocBook/deviceiobook.tmpl + * for details. + * + * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear. + * See PV 871084 for details about the WAR about zero value. + * + */ +void __sn_mmiowb(void) +{ + volatile unsigned long *adr = pda->pio_write_status_addr; + unsigned long val = pda->pio_write_status_val; + + while ((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != val) + cpu_relax(); +} + +EXPORT_SYMBOL(__sn_mmiowb); diff --git a/xen/arch/ia64/linux-xen/sn/kernel/irq.c b/xen/arch/ia64/linux-xen/sn/kernel/irq.c new file mode 100644 index 0000000000..0b49459a87 --- /dev/null +++ b/xen/arch/ia64/linux-xen/sn/kernel/irq.c @@ -0,0 +1,444 @@ +/* + * Platform dependent support for SGI SN + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2000-2006 Silicon Graphics, Inc. All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static void force_interrupt(int irq); +static void register_intr_pda(struct sn_irq_info *sn_irq_info); +static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); + +int sn_force_interrupt_flag = 1; +extern int sn_ioif_inited; +struct list_head **sn_irq_lh; +static DEFINE_SPINLOCK(sn_irq_info_lock); /* non-IRQ lock */ + +u64 sn_intr_alloc(nasid_t local_nasid, int local_widget, + struct sn_irq_info *sn_irq_info, + int req_irq, nasid_t req_nasid, + int req_slice) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT, + (u64) SAL_INTR_ALLOC, (u64) local_nasid, + (u64) local_widget, __pa(sn_irq_info), (u64) req_irq, + (u64) req_nasid, (u64) req_slice); + + return ret_stuff.status; +} + +void sn_intr_free(nasid_t local_nasid, int local_widget, + struct sn_irq_info *sn_irq_info) +{ + struct ia64_sal_retval ret_stuff; + ret_stuff.status = 0; + ret_stuff.v0 = 0; + + SAL_CALL_NOLOCK(ret_stuff, (u64) SN_SAL_IOIF_INTERRUPT, + (u64) SAL_INTR_FREE, (u64) local_nasid, + (u64) local_widget, (u64) sn_irq_info->irq_irq, + (u64) sn_irq_info->irq_cookie, 0, 0); +} + +static unsigned int sn_startup_irq(unsigned int irq) +{ + return 0; +} + +static void sn_shutdown_irq(unsigned int irq) +{ +} + +static void sn_disable_irq(unsigned int irq) +{ +} + +static void sn_enable_irq(unsigned int irq) +{ +} + +static void sn_ack_irq(unsigned int irq) +{ + u64 event_occurred, mask; + + irq = irq & 0xff; + event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED)); + mask = event_occurred & SH_ALL_INT_MASK; + HUB_S((u64*)LOCAL_MMR_ADDR(SH_EVENT_OCCURRED_ALIAS), mask); + __set_bit(irq, (volatile void *)pda->sn_in_service_ivecs); + + move_native_irq(irq); +} + +static void sn_end_irq(unsigned int irq) +{ + int ivec; + u64 event_occurred; + + ivec = irq & 0xff; + if (ivec == SGI_UART_VECTOR) { + event_occurred = HUB_L((u64*)LOCAL_MMR_ADDR (SH_EVENT_OCCURRED)); + /* If the UART bit is set here, we may have received an + * interrupt from the UART that the driver missed. To + * make sure, we IPI ourselves to force us to look again. + */ + if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) { + platform_send_ipi(smp_processor_id(), SGI_UART_VECTOR, + IA64_IPI_DM_INT, 0); + } + } + __clear_bit(ivec, (volatile void *)pda->sn_in_service_ivecs); + if (sn_force_interrupt_flag) + force_interrupt(irq); +} + +static void sn_irq_info_free(struct rcu_head *head); + +struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, + nasid_t nasid, int slice) +{ + int vector; + int cpuphys; + int64_t bridge; + int local_widget, status; + nasid_t local_nasid; + struct sn_irq_info *new_irq_info; + struct sn_pcibus_provider *pci_provider; + + new_irq_info = kmalloc(sizeof(struct sn_irq_info), GFP_ATOMIC); + if (new_irq_info == NULL) + return NULL; + + memcpy(new_irq_info, sn_irq_info, sizeof(struct sn_irq_info)); + + bridge = (u64) new_irq_info->irq_bridge; + if (!bridge) { + kfree(new_irq_info); + return NULL; /* irq is not a device interrupt */ + } + + local_nasid = NASID_GET(bridge); + + if (local_nasid & 1) + local_widget = TIO_SWIN_WIDGETNUM(bridge); + else + local_widget = SWIN_WIDGETNUM(bridge); + + vector = sn_irq_info->irq_irq; + /* Free the old PROM new_irq_info structure */ + sn_intr_free(local_nasid, local_widget, new_irq_info); + /* Update kernels new_irq_info with new target info */ + unregister_intr_pda(new_irq_info); + + /* allocate a new PROM new_irq_info struct */ + status = sn_intr_alloc(local_nasid, local_widget, + new_irq_info, vector, + nasid, slice); + + /* SAL call failed */ + if (status) { + kfree(new_irq_info); + return NULL; + } + + cpuphys = nasid_slice_to_cpuid(nasid, slice); + new_irq_info->irq_cpuid = cpuphys; + register_intr_pda(new_irq_info); + + pci_provider = sn_pci_provider[new_irq_info->irq_bridge_type]; + + /* + * If this represents a line interrupt, target it. If it's + * an msi (irq_int_bit < 0), it's already targeted. + */ + if (new_irq_info->irq_int_bit >= 0 && + pci_provider && pci_provider->target_interrupt) + (pci_provider->target_interrupt)(new_irq_info); + + spin_lock(&sn_irq_info_lock); + list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); + spin_unlock(&sn_irq_info_lock); + call_rcu(&sn_irq_info->rcu, sn_irq_info_free); + +#ifdef CONFIG_SMP + set_irq_affinity_info((vector & 0xff), cpuphys, 0); +#endif + + return new_irq_info; +} + +static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) +{ + struct sn_irq_info *sn_irq_info, *sn_irq_info_safe; + nasid_t nasid; + int slice; + + nasid = cpuid_to_nasid(first_cpu(mask)); + slice = cpuid_to_slice(first_cpu(mask)); + + list_for_each_entry_safe(sn_irq_info, sn_irq_info_safe, + sn_irq_lh[irq], list) + (void)sn_retarget_vector(sn_irq_info, nasid, slice); +} + +struct hw_interrupt_type irq_type_sn = { + .name = "SN hub", + .startup = sn_startup_irq, + .shutdown = sn_shutdown_irq, + .enable = sn_enable_irq, + .disable = sn_disable_irq, + .ack = sn_ack_irq, + .end = sn_end_irq, + .set_affinity = sn_set_affinity_irq +}; + +unsigned int sn_local_vector_to_irq(u8 vector) +{ + return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector)); +} + +void sn_irq_init(void) +{ + int i; + irq_desc_t *base_desc = irq_desc; + + ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR; + ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; + + for (i = 0; i < NR_IRQS; i++) { + if (base_desc[i].chip == &no_irq_type) { + base_desc[i].chip = &irq_type_sn; + } + } +} + +static void register_intr_pda(struct sn_irq_info *sn_irq_info) +{ + int irq = sn_irq_info->irq_irq; + int cpu = sn_irq_info->irq_cpuid; + + if (pdacpu(cpu)->sn_last_irq < irq) { + pdacpu(cpu)->sn_last_irq = irq; + } + + if (pdacpu(cpu)->sn_first_irq == 0 || pdacpu(cpu)->sn_first_irq > irq) + pdacpu(cpu)->sn_first_irq = irq; +} + +static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) +{ + int irq = sn_irq_info->irq_irq; + int cpu = sn_irq_info->irq_cpuid; + struct sn_irq_info *tmp_irq_info; + int i, foundmatch; + + rcu_read_lock(); + if (pdacpu(cpu)->sn_last_irq == irq) { + foundmatch = 0; + for (i = pdacpu(cpu)->sn_last_irq - 1; + i && !foundmatch; i--) { + list_for_each_entry_rcu(tmp_irq_info, + sn_irq_lh[i], + list) { + if (tmp_irq_info->irq_cpuid == cpu) { + foundmatch = 1; + break; + } + } + } + pdacpu(cpu)->sn_last_irq = i; + } + + if (pdacpu(cpu)->sn_first_irq == irq) { + foundmatch = 0; + for (i = pdacpu(cpu)->sn_first_irq + 1; + i < NR_IRQS && !foundmatch; i++) { + list_for_each_entry_rcu(tmp_irq_info, + sn_irq_lh[i], + list) { + if (tmp_irq_info->irq_cpuid == cpu) { + foundmatch = 1; + break; + } + } + } + pdacpu(cpu)->sn_first_irq = ((i == NR_IRQS) ? 0 : i); + } + rcu_read_unlock(); +} + +static void sn_irq_info_free(struct rcu_head *head) +{ + struct sn_irq_info *sn_irq_info; + + sn_irq_info = container_of(head, struct sn_irq_info, rcu); + kfree(sn_irq_info); +} + +void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) +{ + nasid_t nasid = sn_irq_info->irq_nasid; + int slice = sn_irq_info->irq_slice; + int cpu = nasid_slice_to_cpuid(nasid, slice); + + pci_dev_get(pci_dev); + sn_irq_info->irq_cpuid = cpu; + sn_irq_info->irq_pciioinfo = SN_PCIDEV_INFO(pci_dev); + + /* link it into the sn_irq[irq] list */ + spin_lock(&sn_irq_info_lock); + list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); + reserve_irq_vector(sn_irq_info->irq_irq); + spin_unlock(&sn_irq_info_lock); + + register_intr_pda(sn_irq_info); +} + +void sn_irq_unfixup(struct pci_dev *pci_dev) +{ + struct sn_irq_info *sn_irq_info; + + /* Only cleanup IRQ stuff if this device has a host bus context */ + if (!SN_PCIDEV_BUSSOFT(pci_dev)) + return; + + sn_irq_info = SN_PCIDEV_INFO(pci_dev)->pdi_sn_irq_info; + if (!sn_irq_info) + return; + if (!sn_irq_info->irq_irq) { + kfree(sn_irq_info); + return; + } + + unregister_intr_pda(sn_irq_info); + spin_lock(&sn_irq_info_lock); + list_del_rcu(&sn_irq_info->list); + spin_unlock(&sn_irq_info_lock); + if (list_empty(sn_irq_lh[sn_irq_info->irq_irq])) + free_irq_vector(sn_irq_info->irq_irq); + call_rcu(&sn_irq_info->rcu, sn_irq_info_free); + pci_dev_put(pci_dev); + +} + +static inline void +sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info) +{ + struct sn_pcibus_provider *pci_provider; + + pci_provider = sn_pci_provider[sn_irq_info->irq_bridge_type]; + if (pci_provider && pci_provider->force_interrupt) + (*pci_provider->force_interrupt)(sn_irq_info); +} + +static void force_interrupt(int irq) +{ + struct sn_irq_info *sn_irq_info; + + if (!sn_ioif_inited) + return; + + rcu_read_lock(); + list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) + sn_call_force_intr_provider(sn_irq_info); + + rcu_read_unlock(); +} + +/* + * Check for lost interrupts. If the PIC int_status reg. says that + * an interrupt has been sent, but not handled, and the interrupt + * is not pending in either the cpu irr regs or in the soft irr regs, + * and the interrupt is not in service, then the interrupt may have + * been lost. Force an interrupt on that pin. It is possible that + * the interrupt is in flight, so we may generate a spurious interrupt, + * but we should never miss a real lost interrupt. + */ +static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) +{ + u64 regval; + struct pcidev_info *pcidev_info; + struct pcibus_info *pcibus_info; + + /* + * Bridge types attached to TIO (anything but PIC) do not need this WAR + * since they do not target Shub II interrupt registers. If that + * ever changes, this check needs to accomodate. + */ + if (sn_irq_info->irq_bridge_type != PCIIO_ASIC_TYPE_PIC) + return; + + pcidev_info = (struct pcidev_info *)sn_irq_info->irq_pciioinfo; + if (!pcidev_info) + return; + + pcibus_info = + (struct pcibus_info *)pcidev_info->pdi_host_pcidev_info-> + pdi_pcibus_info; + regval = pcireg_intr_status_get(pcibus_info); + + if (!ia64_get_irr(irq_to_vector(irq))) { + if (!test_bit(irq, pda->sn_in_service_ivecs)) { + regval &= 0xff; + if (sn_irq_info->irq_int_bit & regval & + sn_irq_info->irq_last_intr) { + regval &= ~(sn_irq_info->irq_int_bit & regval); + sn_call_force_intr_provider(sn_irq_info); + } + } + } + sn_irq_info->irq_last_intr = regval; +} + +void sn_lb_int_war_check(void) +{ + struct sn_irq_info *sn_irq_info; + int i; + + if (!sn_ioif_inited || pda->sn_first_irq == 0) + return; + + rcu_read_lock(); + for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) { + list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) { + sn_check_intr(i, sn_irq_info); + } + } + rcu_read_unlock(); +} + +void __init sn_irq_lh_init(void) +{ + int i; + + sn_irq_lh = kmalloc(sizeof(struct list_head *) * NR_IRQS, GFP_KERNEL); + if (!sn_irq_lh) + panic("SN PCI INIT: Failed to allocate memory for PCI init\n"); + + for (i = 0; i < NR_IRQS; i++) { + sn_irq_lh[i] = kmalloc(sizeof(struct list_head), GFP_KERNEL); + if (!sn_irq_lh[i]) + panic("SN PCI INIT: Failed IRQ memory allocation\n"); + + INIT_LIST_HEAD(sn_irq_lh[i]); + } +} diff --git a/xen/arch/ia64/linux-xen/sn/kernel/setup.c b/xen/arch/ia64/linux-xen/sn/kernel/setup.c new file mode 100644 index 0000000000..7a2d824c5c --- /dev/null +++ b/xen/arch/ia64/linux-xen/sn/kernel/setup.c @@ -0,0 +1,755 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999,2001-2006 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "xtalk/xwidgetdev.h" +#include "xtalk/hubdev.h" +#include + + +DEFINE_PER_CPU(struct pda_s, pda_percpu); + +#define MAX_PHYS_MEMORY (1UL << IA64_MAX_PHYS_BITS) /* Max physical address supported */ + +extern void bte_init_node(nodepda_t *, cnodeid_t); + +extern void sn_timer_init(void); +extern unsigned long last_time_offset; +extern void (*ia64_mark_idle) (int); +extern void snidle(int); +extern unsigned long long (*ia64_printk_clock)(void); + +unsigned long sn_rtc_cycles_per_second; +EXPORT_SYMBOL(sn_rtc_cycles_per_second); + +DEFINE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); +EXPORT_PER_CPU_SYMBOL(__sn_hub_info); + +DEFINE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]); +EXPORT_PER_CPU_SYMBOL(__sn_cnodeid_to_nasid); + +DEFINE_PER_CPU(struct nodepda_s *, __sn_nodepda); +EXPORT_PER_CPU_SYMBOL(__sn_nodepda); + +char sn_system_serial_number_string[128]; +EXPORT_SYMBOL(sn_system_serial_number_string); +u64 sn_partition_serial_number; +EXPORT_SYMBOL(sn_partition_serial_number); +u8 sn_partition_id; +EXPORT_SYMBOL(sn_partition_id); +u8 sn_system_size; +EXPORT_SYMBOL(sn_system_size); +u8 sn_sharing_domain_size; +EXPORT_SYMBOL(sn_sharing_domain_size); +u8 sn_coherency_id; +EXPORT_SYMBOL(sn_coherency_id); +u8 sn_region_size; +EXPORT_SYMBOL(sn_region_size); +int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ + +short physical_node_map[MAX_NUMALINK_NODES]; +static unsigned long sn_prom_features[MAX_PROM_FEATURE_SETS]; + +EXPORT_SYMBOL(physical_node_map); + +int num_cnodes; + +static void sn_init_pdas(char **); +static void build_cnode_tables(void); + +static nodepda_t *nodepdaindr[MAX_COMPACT_NODES]; + +/* + * The format of "screen_info" is strange, and due to early i386-setup + * code. This is just enough to make the console code think we're on a + * VGA color display. + */ +struct screen_info sn_screen_info = { + .orig_x = 0, + .orig_y = 0, + .orig_video_mode = 3, + .orig_video_cols = 80, + .orig_video_ega_bx = 3, + .orig_video_lines = 25, + .orig_video_isVGA = 1, + .orig_video_points = 16 +}; + +/* + * This routine can only be used during init, since + * smp_boot_data is an init data structure. + * We have to use smp_boot_data.cpu_phys_id to find + * the physical id of the processor because the normal + * cpu_physical_id() relies on data structures that + * may not be initialized yet. + */ + +static int __init pxm_to_nasid(int pxm) +{ + int i; + int nid; + + nid = pxm_to_node(pxm); + for (i = 0; i < num_node_memblks; i++) { + if (node_memblk[i].nid == nid) { + return NASID_GET(node_memblk[i].start_paddr); + } + } + return -1; +} + +/** + * early_sn_setup - early setup routine for SN platforms + * + * Sets up an initial console to aid debugging. Intended primarily + * for bringup. See start_kernel() in init/main.c. + */ + +void __init early_sn_setup(void) +{ + efi_system_table_t *efi_systab; + efi_config_table_t *config_tables; + struct ia64_sal_systab *sal_systab; + struct ia64_sal_desc_entry_point *ep; + char *p; + int i, j; + + /* + * Parse enough of the SAL tables to locate the SAL entry point. Since, console + * IO on SN2 is done via SAL calls, early_printk won't work without this. + * + * This code duplicates some of the ACPI table parsing that is in efi.c & sal.c. + * Any changes to those file may have to be made hereas well. + */ + efi_systab = (efi_system_table_t *) __va(ia64_boot_param->efi_systab); + config_tables = __va(efi_systab->tables); + for (i = 0; i < efi_systab->nr_tables; i++) { + if (efi_guidcmp(config_tables[i].guid, SAL_SYSTEM_TABLE_GUID) == + 0) { + sal_systab = __va(config_tables[i].table); + p = (char *)(sal_systab + 1); + for (j = 0; j < sal_systab->entry_count; j++) { + if (*p == SAL_DESC_ENTRY_POINT) { + ep = (struct ia64_sal_desc_entry_point + *)p; + ia64_sal_handler_init(__va + (ep->sal_proc), + __va(ep->gp)); + return; + } + p += SAL_DESC_SIZE(*p); + } + } + } + /* Uh-oh, SAL not available?? */ + printk(KERN_ERR "failed to find SAL entry point\n"); +} + +extern int platform_intr_list[]; +static int __initdata shub_1_1_found; + +/* + * sn_check_for_wars + * + * Set flag for enabling shub specific wars + */ + +static inline int __init is_shub_1_1(int nasid) +{ + unsigned long id; + int rev; + + if (is_shub2()) + return 0; + id = REMOTE_HUB_L(nasid, SH1_SHUB_ID); + rev = (id & SH1_SHUB_ID_REVISION_MASK) >> SH1_SHUB_ID_REVISION_SHFT; + return rev <= 2; +} + +static void __init sn_check_for_wars(void) +{ + int cnode; + + if (is_shub2()) { + /* none yet */ + } else { + for_each_online_node(cnode) { + if (is_shub_1_1(cnodeid_to_nasid(cnode))) + shub_1_1_found = 1; + } + } +} + +/* + * Scan the EFI PCDP table (if it exists) for an acceptable VGA console + * output device. If one exists, pick it and set sn_legacy_{io,mem} to + * reflect the bus offsets needed to address it. + * + * Since pcdp support in SN is not supported in the 2.4 kernel (or at least + * the one lbs is based on) just declare the needed structs here. + * + * Reference spec http://www.dig64.org/specifications/DIG64_PCDPv20.pdf + * + * Returns 0 if no acceptable vga is found, !0 otherwise. + * + * Note: This stuff is duped here because Altix requires the PCDP to + * locate a usable VGA device due to lack of proper ACPI support. Structures + * could be used from drivers/firmware/pcdp.h, but it was decided that moving + * this file to a more public location just for Altix use was undesireable. + */ + +struct hcdp_uart_desc { + u8 pad[45]; +}; + +struct pcdp { + u8 signature[4]; /* should be 'HCDP' */ + u32 length; + u8 rev; /* should be >=3 for pcdp, <3 for hcdp */ + u8 sum; + u8 oem_id[6]; + u64 oem_tableid; + u32 oem_rev; + u32 creator_id; + u32 creator_rev; + u32 num_type0; + struct hcdp_uart_desc uart[0]; /* num_type0 of these */ + /* pcdp descriptors follow */ +} __attribute__((packed)); + +struct pcdp_device_desc { + u8 type; + u8 primary; + u16 length; + u16 index; + /* interconnect specific structure follows */ + /* device specific structure follows that */ +} __attribute__((packed)); + +struct pcdp_interface_pci { + u8 type; /* 1 == pci */ + u8 reserved; + u16 length; + u8 segment; + u8 bus; + u8 dev; + u8 fun; + u16 devid; + u16 vendid; + u32 acpi_interrupt; + u64 mmio_tra; + u64 ioport_tra; + u8 flags; + u8 translation; +} __attribute__((packed)); + +struct pcdp_vga_device { + u8 num_eas_desc; + /* ACPI Extended Address Space Desc follows */ +} __attribute__((packed)); + +/* from pcdp_device_desc.primary */ +#define PCDP_PRIMARY_CONSOLE 0x01 + +/* from pcdp_device_desc.type */ +#define PCDP_CONSOLE_INOUT 0x0 +#define PCDP_CONSOLE_DEBUG 0x1 +#define PCDP_CONSOLE_OUT 0x2 +#define PCDP_CONSOLE_IN 0x3 +#define PCDP_CONSOLE_TYPE_VGA 0x8 + +#define PCDP_CONSOLE_VGA (PCDP_CONSOLE_TYPE_VGA | PCDP_CONSOLE_OUT) + +/* from pcdp_interface_pci.type */ +#define PCDP_IF_PCI 1 + +/* from pcdp_interface_pci.translation */ +#define PCDP_PCI_TRANS_IOPORT 0x02 +#define PCDP_PCI_TRANS_MMIO 0x01 + +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) +static void +sn_scan_pcdp(void) +{ + u8 *bp; + struct pcdp *pcdp; + struct pcdp_device_desc device; + struct pcdp_interface_pci if_pci; + extern struct efi efi; + + if (efi.hcdp == EFI_INVALID_TABLE_ADDR) + return; /* no hcdp/pcdp table */ + + pcdp = __va(efi.hcdp); + + if (pcdp->rev < 3) + return; /* only support PCDP (rev >= 3) */ + + for (bp = (u8 *)&pcdp->uart[pcdp->num_type0]; + bp < (u8 *)pcdp + pcdp->length; + bp += device.length) { + memcpy(&device, bp, sizeof(device)); + if (! (device.primary & PCDP_PRIMARY_CONSOLE)) + continue; /* not primary console */ + + if (device.type != PCDP_CONSOLE_VGA) + continue; /* not VGA descriptor */ + + memcpy(&if_pci, bp+sizeof(device), sizeof(if_pci)); + if (if_pci.type != PCDP_IF_PCI) + continue; /* not PCI interconnect */ + + if (if_pci.translation & PCDP_PCI_TRANS_IOPORT) + vga_console_iobase = + if_pci.ioport_tra | __IA64_UNCACHED_OFFSET; + + if (if_pci.translation & PCDP_PCI_TRANS_MMIO) + vga_console_membase = + if_pci.mmio_tra | __IA64_UNCACHED_OFFSET; + + break; /* once we find the primary, we're done */ + } +} +#endif + +static unsigned long sn2_rtc_initial; + +static unsigned long long ia64_sn2_printk_clock(void) +{ + unsigned long rtc_now = rtc_time(); + + return (rtc_now - sn2_rtc_initial) * + (1000000000 / sn_rtc_cycles_per_second); +} + +/** + * sn_setup - SN platform setup routine + * @cmdline_p: kernel command line + * + * Handles platform setup for SN machines. This includes determining + * the RTC frequency (via a SAL call), initializing secondary CPUs, and + * setting up per-node data areas. The console is also initialized here. + */ +void __init sn_setup(char **cmdline_p) +{ + long status, ticks_per_sec, drift; + u32 version = sn_sal_rev(); + extern void sn_cpu_init(void); + + sn2_rtc_initial = rtc_time(); + ia64_sn_plat_set_error_handling_features(); // obsolete + ia64_sn_set_os_feature(OSF_MCA_SLV_TO_OS_INIT_SLV); + ia64_sn_set_os_feature(OSF_FEAT_LOG_SBES); + + +#if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) + /* + * Handle SN vga console. + * + * SN systems do not have enough ACPI table information + * being passed from prom to identify VGA adapters and the legacy + * addresses to access them. Until that is done, SN systems rely + * on the PCDP table to identify the primary VGA console if one + * exists. + * + * However, kernel PCDP support is optional, and even if it is built + * into the kernel, it will not be used if the boot cmdline contains + * console= directives. + * + * So, to work around this mess, we duplicate some of the PCDP code + * here so that the primary VGA console (as defined by PCDP) will + * work on SN systems even if a different console (e.g. serial) is + * selected on the boot line (or CONFIG_EFI_PCDP is off). + */ + + if (! vga_console_membase) + sn_scan_pcdp(); + + if (vga_console_membase) { + /* usable vga ... make tty0 the preferred default console */ + if (!strstr(*cmdline_p, "console=")) + add_preferred_console("tty", 0, NULL); + } else { + printk(KERN_DEBUG "SGI: Disabling VGA console\n"); + if (!strstr(*cmdline_p, "console=")) + add_preferred_console("ttySG", 0, NULL); +#ifdef CONFIG_DUMMY_CONSOLE + conswitchp = &dummy_con; +#else + conswitchp = NULL; +#endif /* CONFIG_DUMMY_CONSOLE */ + } +#endif /* def(CONFIG_VT) && def(CONFIG_VGA_CONSOLE) */ + + MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY; + + /* + * Build the tables for managing cnodes. + */ + build_cnode_tables(); + + status = + ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, + &drift); + if (status != 0 || ticks_per_sec < 100000) { + printk(KERN_WARNING + "unable to determine platform RTC clock frequency, guessing.\n"); + /* PROM gives wrong value for clock freq. so guess */ + sn_rtc_cycles_per_second = 1000000000000UL / 30000UL; + } else + sn_rtc_cycles_per_second = ticks_per_sec; + + platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; + + ia64_printk_clock = ia64_sn2_printk_clock; + + printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); + + /* + * we set the default root device to /dev/hda + * to make simulation easy + */ + ROOT_DEV = Root_HDA1; + + /* + * Create the PDAs and NODEPDAs for all the cpus. + */ + sn_init_pdas(cmdline_p); + + ia64_mark_idle = &snidle; + + /* + * For the bootcpu, we do this here. All other cpus will make the + * call as part of cpu_init in slave cpu initialization. + */ + sn_cpu_init(); + +#ifdef CONFIG_SMP + init_smp_config(); +#endif + screen_info = sn_screen_info; + + sn_timer_init(); + + /* + * set pm_power_off to a SAL call to allow + * sn machines to power off. The SAL call can be replaced + * by an ACPI interface call when ACPI is fully implemented + * for sn. + */ + pm_power_off = ia64_sn_power_down; + current->thread.flags |= IA64_THREAD_MIGRATION; +} + +/** + * sn_init_pdas - setup node data areas + * + * One time setup for Node Data Area. Called by sn_setup(). + */ +static void __init sn_init_pdas(char **cmdline_p) +{ + cnodeid_t cnode; + + /* + * Allocate & initalize the nodepda for each node. + */ + for_each_online_node(cnode) { + nodepdaindr[cnode] = + alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t)); + memset(nodepdaindr[cnode], 0, sizeof(nodepda_t)); + memset(nodepdaindr[cnode]->phys_cpuid, -1, + sizeof(nodepdaindr[cnode]->phys_cpuid)); + spin_lock_init(&nodepdaindr[cnode]->ptc_lock); + } + + /* + * Allocate & initialize nodepda for TIOs. For now, put them on node 0. + */ + for (cnode = num_online_nodes(); cnode < num_cnodes; cnode++) { + nodepdaindr[cnode] = + alloc_bootmem_node(NODE_DATA(0), sizeof(nodepda_t)); + memset(nodepdaindr[cnode], 0, sizeof(nodepda_t)); + } + + /* + * Now copy the array of nodepda pointers to each nodepda. + */ + for (cnode = 0; cnode < num_cnodes; cnode++) + memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr, + sizeof(nodepdaindr)); + + /* + * Set up IO related platform-dependent nodepda fields. + * The following routine actually sets up the hubinfo struct + * in nodepda. + */ + for_each_online_node(cnode) { + bte_init_node(nodepdaindr[cnode], cnode); + } + + /* + * Initialize the per node hubdev. This includes IO Nodes and + * headless/memless nodes. + */ + for (cnode = 0; cnode < num_cnodes; cnode++) { + hubdev_init_node(nodepdaindr[cnode], cnode); + } +} + +/** + * sn_cpu_init - initialize per-cpu data areas + * @cpuid: cpuid of the caller + * + * Called during cpu initialization on each cpu as it starts. + * Currently, initializes the per-cpu data area for SNIA. + * Also sets up a few fields in the nodepda. Also known as + * platform_cpu_init() by the ia64 machvec code. + */ +void __cpuinit sn_cpu_init(void) +{ + int cpuid; + int cpuphyid; + int nasid; + int subnode; + int slice; + int cnode; + int i; + static int wars_have_been_checked; + + cpuid = smp_processor_id(); + if (cpuid == 0 && IS_MEDUSA()) { + if (ia64_sn_is_fake_prom()) + sn_prom_type = 2; + else + sn_prom_type = 1; + printk(KERN_INFO "Running on medusa with %s PROM\n", + (sn_prom_type == 1) ? "real" : "fake"); + } + + memset(pda, 0, sizeof(pda)); + if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, + &sn_hub_info->nasid_bitmask, + &sn_hub_info->nasid_shift, + &sn_system_size, &sn_sharing_domain_size, + &sn_partition_id, &sn_coherency_id, + &sn_region_size)) + BUG(); + sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2; + + /* + * Don't check status. The SAL call is not supported on all PROMs + * but a failure is harmless. + */ + (void) ia64_sn_set_cpu_number(cpuid); + + /* + * The boot cpu makes this call again after platform initialization is + * complete. + */ + if (nodepdaindr[0] == NULL) + return; + + for (i = 0; i < MAX_PROM_FEATURE_SETS; i++) + if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0) + break; + + cpuphyid = get_sapicid(); + + if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice)) + BUG(); + + for (i=0; i < MAX_NUMNODES; i++) { + if (nodepdaindr[i]) { + nodepdaindr[i]->phys_cpuid[cpuid].nasid = nasid; + nodepdaindr[i]->phys_cpuid[cpuid].slice = slice; + nodepdaindr[i]->phys_cpuid[cpuid].subnode = subnode; + } + } + + cnode = nasid_to_cnodeid(nasid); + + sn_nodepda = nodepdaindr[cnode]; + + pda->led_address = + (typeof(pda->led_address)) (LED0 + (slice << LED_CPU_SHIFT)); + pda->led_state = LED_ALWAYS_SET; + pda->hb_count = HZ / 2; + pda->hb_state = 0; + pda->idle_flag = 0; + + if (cpuid != 0) { + /* copy cpu 0's sn_cnodeid_to_nasid table to this cpu's */ + memcpy(sn_cnodeid_to_nasid, + (&per_cpu(__sn_cnodeid_to_nasid, 0)), + sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid))); + } + + /* + * Check for WARs. + * Only needs to be done once, on BSP. + * Has to be done after loop above, because it uses this cpu's + * sn_cnodeid_to_nasid table which was just initialized if this + * isn't cpu 0. + * Has to be done before assignment below. + */ + if (!wars_have_been_checked) { + sn_check_for_wars(); + wars_have_been_checked = 1; + } + sn_hub_info->shub_1_1_found = shub_1_1_found; + + /* + * Set up addresses of PIO/MEM write status registers. + */ + { + u64 pio1[] = {SH1_PIO_WRITE_STATUS_0, 0, SH1_PIO_WRITE_STATUS_1, 0}; + u64 pio2[] = {SH2_PIO_WRITE_STATUS_0, SH2_PIO_WRITE_STATUS_2, + SH2_PIO_WRITE_STATUS_1, SH2_PIO_WRITE_STATUS_3}; + u64 *pio; + pio = is_shub1() ? pio1 : pio2; + pda->pio_write_status_addr = + (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, pio[slice]); + pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0; + } + + /* + * WAR addresses for SHUB 1.x. + */ + if (local_node_data->active_cpu_count++ == 0 && is_shub1()) { + int buddy_nasid; + buddy_nasid = + cnodeid_to_nasid(numa_node_id() == + num_online_nodes() - 1 ? 0 : numa_node_id() + 1); + pda->pio_shub_war_cam_addr = + (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, + SH1_PI_CAM_CONTROL); + } +} + +/* + * Build tables for converting between NASIDs and cnodes. + */ +static inline int __init board_needs_cnode(int type) +{ + return (type == KLTYPE_SNIA || type == KLTYPE_TIO); +} + +void __init build_cnode_tables(void) +{ + int nasid; + int node; + lboard_t *brd; + + memset(physical_node_map, -1, sizeof(physical_node_map)); + memset(sn_cnodeid_to_nasid, -1, + sizeof(__ia64_per_cpu_var(__sn_cnodeid_to_nasid))); + + /* + * First populate the tables with C/M bricks. This ensures that + * cnode == node for all C & M bricks. + */ + for_each_online_node(node) { + nasid = pxm_to_nasid(node_to_pxm(node)); + sn_cnodeid_to_nasid[node] = nasid; + physical_node_map[nasid] = node; + } + + /* + * num_cnodes is total number of C/M/TIO bricks. Because of the 256 node + * limit on the number of nodes, we can't use the generic node numbers + * for this. Note that num_cnodes is incremented below as TIOs or + * headless/memoryless nodes are discovered. + */ + num_cnodes = num_online_nodes(); + + /* fakeprom does not support klgraph */ + if (IS_RUNNING_ON_FAKE_PROM()) + return; + + /* Find TIOs & headless/memoryless nodes and add them to the tables */ + for_each_online_node(node) { + kl_config_hdr_t *klgraph_header; + nasid = cnodeid_to_nasid(node); + klgraph_header = ia64_sn_get_klconfig_addr(nasid); + if (klgraph_header == NULL) + BUG(); + brd = NODE_OFFSET_TO_LBOARD(nasid, klgraph_header->ch_board_info); + while (brd) { + if (board_needs_cnode(brd->brd_type) && physical_node_map[brd->brd_nasid] < 0) { + sn_cnodeid_to_nasid[num_cnodes] = brd->brd_nasid; + physical_node_map[brd->brd_nasid] = num_cnodes++; + } + brd = find_lboard_next(brd); + } + } +} + +int +nasid_slice_to_cpuid(int nasid, int slice) +{ + long cpu; + + for (cpu = 0; cpu < NR_CPUS; cpu++) + if (cpuid_to_nasid(cpu) == nasid && + cpuid_to_slice(cpu) == slice) + return cpu; + + return -1; +} + +int sn_prom_feature_available(int id) +{ + if (id >= BITS_PER_LONG * MAX_PROM_FEATURE_SETS) + return 0; + return test_bit(id, sn_prom_features); +} +EXPORT_SYMBOL(sn_prom_feature_available); + diff --git a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c new file mode 100644 index 0000000000..d9d306c79f --- /dev/null +++ b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c @@ -0,0 +1,489 @@ +/* + * SN2 Platform specific SMP Support + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000-2006 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DEFINE_PER_CPU(struct ptc_stats, ptcstats); +DECLARE_PER_CPU(struct ptc_stats, ptcstats); + +static __cacheline_aligned DEFINE_SPINLOCK(sn2_global_ptc_lock); + +extern unsigned long +sn2_ptc_deadlock_recovery_core(volatile unsigned long *, unsigned long, + volatile unsigned long *, unsigned long, + volatile unsigned long *, unsigned long); +void +sn2_ptc_deadlock_recovery(short *, short, short, int, + volatile unsigned long *, unsigned long, + volatile unsigned long *, unsigned long); + +/* + * Note: some is the following is captured here to make degugging easier + * (the macros make more sense if you see the debug patch - not posted) + */ +#define sn2_ptctest 0 +#define local_node_uses_ptc_ga(sh1) ((sh1) ? 1 : 0) +#define max_active_pio(sh1) ((sh1) ? 32 : 7) +#define reset_max_active_on_deadlock() 1 +#define PTC_LOCK(sh1) ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock) + +struct ptc_stats { + unsigned long ptc_l; + unsigned long change_rid; + unsigned long shub_ptc_flushes; + unsigned long nodes_flushed; + unsigned long deadlocks; + unsigned long deadlocks2; + unsigned long lock_itc_clocks; + unsigned long shub_itc_clocks; + unsigned long shub_itc_clocks_max; + unsigned long shub_ptc_flushes_not_my_mm; +}; + +#define sn2_ptctest 0 + +static inline unsigned long wait_piowc(void) +{ + volatile unsigned long *piows; + unsigned long zeroval, ws; + + piows = pda->pio_write_status_addr; + zeroval = pda->pio_write_status_val; + do { + cpu_relax(); + } while (((ws = *piows) & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) != zeroval); + return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0; +} + +/** + * sn_migrate - SN-specific task migration actions + * @task: Task being migrated to new CPU + * + * SN2 PIO writes from separate CPUs are not guaranteed to arrive in order. + * Context switching user threads which have memory-mapped MMIO may cause + * PIOs to issue from seperate CPUs, thus the PIO writes must be drained + * from the previous CPU's Shub before execution resumes on the new CPU. + */ +void sn_migrate(struct task_struct *task) +{ + pda_t *last_pda = pdacpu(task_thread_info(task)->last_cpu); + volatile unsigned long *adr = last_pda->pio_write_status_addr; + unsigned long val = last_pda->pio_write_status_val; + + /* Drain PIO writes from old CPU's Shub */ + while (unlikely((*adr & SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK) + != val)) + cpu_relax(); +} + +void sn_tlb_migrate_finish(struct mm_struct *mm) +{ + /* flush_tlb_mm is inefficient if more than 1 users of mm */ + if (mm == current->mm && mm && atomic_read(&mm->mm_users) == 1) + flush_tlb_mm(mm); +} + +/** + * sn2_global_tlb_purge - globally purge translation cache of virtual address range + * @mm: mm_struct containing virtual address range + * @start: start of virtual address range + * @end: end of virtual address range + * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc)) + * + * Purges the translation caches of all processors of the given virtual address + * range. + * + * Note: + * - cpu_vm_mask is a bit mask that indicates which cpus have loaded the context. + * - cpu_vm_mask is converted into a nodemask of the nodes containing the + * cpus in cpu_vm_mask. + * - if only one bit is set in cpu_vm_mask & it is the current cpu & the + * process is purging its own virtual address range, then only the + * local TLB needs to be flushed. This flushing can be done using + * ptc.l. This is the common case & avoids the global spinlock. + * - if multiple cpus have loaded the context, then flushing has to be + * done with ptc.g/MMRs under protection of the global ptc_lock. + */ + +void +sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, + unsigned long end, unsigned long nbits) +{ + int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid; + int mymm = (mm == current->active_mm && mm == current->mm); + int use_cpu_ptcga; + volatile unsigned long *ptc0, *ptc1; + unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0; + short nasids[MAX_NUMNODES], nix; + nodemask_t nodes_flushed; + int active, max_active, deadlock; + + nodes_clear(nodes_flushed); + i = 0; + + for_each_cpu_mask(cpu, mm->cpu_vm_mask) { + cnode = cpu_to_node(cpu); + node_set(cnode, nodes_flushed); + lcpu = cpu; + i++; + } + + if (i == 0) + return; + + preempt_disable(); + + if (likely(i == 1 && lcpu == smp_processor_id() && mymm)) { + do { + ia64_ptcl(start, nbits << 2); + start += (1UL << nbits); + } while (start < end); + ia64_srlz_i(); + __get_cpu_var(ptcstats).ptc_l++; + preempt_enable(); + return; + } + + if (atomic_read(&mm->mm_users) == 1 && mymm) { + flush_tlb_mm(mm); + __get_cpu_var(ptcstats).change_rid++; + preempt_enable(); + return; + } + + itc = ia64_get_itc(); + nix = 0; + for_each_node_mask(cnode, nodes_flushed) + nasids[nix++] = cnodeid_to_nasid(cnode); + + rr_value = (mm->context << 3) | REGION_NUMBER(start); + + shub1 = is_shub1(); + if (shub1) { + data0 = (1UL << SH1_PTC_0_A_SHFT) | + (nbits << SH1_PTC_0_PS_SHFT) | + (rr_value << SH1_PTC_0_RID_SHFT) | + (1UL << SH1_PTC_0_START_SHFT); + ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0); + ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1); + } else { + data0 = (1UL << SH2_PTC_A_SHFT) | + (nbits << SH2_PTC_PS_SHFT) | + (1UL << SH2_PTC_START_SHFT); + ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH2_PTC + + (rr_value << SH2_PTC_RID_SHFT)); + ptc1 = NULL; + } + + + mynasid = get_nasid(); + use_cpu_ptcga = local_node_uses_ptc_ga(shub1); + max_active = max_active_pio(shub1); + + itc = ia64_get_itc(); + spin_lock_irqsave(PTC_LOCK(shub1), flags); + itc2 = ia64_get_itc(); + + __get_cpu_var(ptcstats).lock_itc_clocks += itc2 - itc; + __get_cpu_var(ptcstats).shub_ptc_flushes++; + __get_cpu_var(ptcstats).nodes_flushed += nix; + if (!mymm) + __get_cpu_var(ptcstats).shub_ptc_flushes_not_my_mm++; + + if (use_cpu_ptcga && !mymm) { + old_rr = ia64_get_rr(start); + ia64_set_rr(start, (old_rr & 0xff) | (rr_value << 8)); + ia64_srlz_d(); + } + + wait_piowc(); + do { + if (shub1) + data1 = start | (1UL << SH1_PTC_1_START_SHFT); + else + data0 = (data0 & ~SH2_PTC_ADDR_MASK) | (start & SH2_PTC_ADDR_MASK); + deadlock = 0; + active = 0; + for (ibegin = 0, i = 0; i < nix; i++) { + nasid = nasids[i]; + if (use_cpu_ptcga && unlikely(nasid == mynasid)) { + ia64_ptcga(start, nbits << 2); + ia64_srlz_i(); + } else { + ptc0 = CHANGE_NASID(nasid, ptc0); + if (ptc1) + ptc1 = CHANGE_NASID(nasid, ptc1); + pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1); + active++; + } + if (active >= max_active || i == (nix - 1)) { + if ((deadlock = wait_piowc())) { + sn2_ptc_deadlock_recovery(nasids, ibegin, i, mynasid, ptc0, data0, ptc1, data1); + if (reset_max_active_on_deadlock()) + max_active = 1; + } + active = 0; + ibegin = i + 1; + } + } + start += (1UL << nbits); + } while (start < end); + + itc2 = ia64_get_itc() - itc2; + __get_cpu_var(ptcstats).shub_itc_clocks += itc2; + if (itc2 > __get_cpu_var(ptcstats).shub_itc_clocks_max) + __get_cpu_var(ptcstats).shub_itc_clocks_max = itc2; + + if (old_rr) { + ia64_set_rr(start, old_rr); + ia64_srlz_d(); + } + + spin_unlock_irqrestore(PTC_LOCK(shub1), flags); + + preempt_enable(); +} + +/* + * sn2_ptc_deadlock_recovery + * + * Recover from PTC deadlocks conditions. Recovery requires stepping thru each + * TLB flush transaction. The recovery sequence is somewhat tricky & is + * coded in assembly language. + */ + +void +sn2_ptc_deadlock_recovery(short *nasids, short ib, short ie, int mynasid, + volatile unsigned long *ptc0, unsigned long data0, + volatile unsigned long *ptc1, unsigned long data1) +{ + short nasid, i; + unsigned long *piows, zeroval, n; + + __get_cpu_var(ptcstats).deadlocks++; + + piows = (unsigned long *) pda->pio_write_status_addr; + zeroval = pda->pio_write_status_val; + + + for (i=ib; i <= ie; i++) { + nasid = nasids[i]; + if (local_node_uses_ptc_ga(is_shub1()) && nasid == mynasid) + continue; + ptc0 = CHANGE_NASID(nasid, ptc0); + if (ptc1) + ptc1 = CHANGE_NASID(nasid, ptc1); + + n = sn2_ptc_deadlock_recovery_core(ptc0, data0, ptc1, data1, piows, zeroval); + __get_cpu_var(ptcstats).deadlocks2 += n; + } + +} + +/** + * sn_send_IPI_phys - send an IPI to a Nasid and slice + * @nasid: nasid to receive the interrupt (may be outside partition) + * @physid: physical cpuid to receive the interrupt. + * @vector: command to send + * @delivery_mode: delivery mechanism + * + * Sends an IPI (interprocessor interrupt) to the processor specified by + * @physid + * + * @delivery_mode can be one of the following + * + * %IA64_IPI_DM_INT - pend an interrupt + * %IA64_IPI_DM_PMI - pend a PMI + * %IA64_IPI_DM_NMI - pend an NMI + * %IA64_IPI_DM_INIT - pend an INIT interrupt + */ +void sn_send_IPI_phys(int nasid, long physid, int vector, int delivery_mode) +{ + long val; + unsigned long flags = 0; + volatile long *p; + + p = (long *)GLOBAL_MMR_PHYS_ADDR(nasid, SH_IPI_INT); + val = (1UL << SH_IPI_INT_SEND_SHFT) | + (physid << SH_IPI_INT_PID_SHFT) | + ((long)delivery_mode << SH_IPI_INT_TYPE_SHFT) | + ((long)vector << SH_IPI_INT_IDX_SHFT) | + (0x000feeUL << SH_IPI_INT_BASE_SHFT); + + mb(); + if (enable_shub_wars_1_1()) { + spin_lock_irqsave(&sn2_global_ptc_lock, flags); + } + pio_phys_write_mmr(p, val); + if (enable_shub_wars_1_1()) { + wait_piowc(); + spin_unlock_irqrestore(&sn2_global_ptc_lock, flags); + } + +} + +EXPORT_SYMBOL(sn_send_IPI_phys); + +/** + * sn2_send_IPI - send an IPI to a processor + * @cpuid: target of the IPI + * @vector: command to send + * @delivery_mode: delivery mechanism + * @redirect: redirect the IPI? + * + * Sends an IPI (InterProcessor Interrupt) to the processor specified by + * @cpuid. @vector specifies the command to send, while @delivery_mode can + * be one of the following + * + * %IA64_IPI_DM_INT - pend an interrupt + * %IA64_IPI_DM_PMI - pend a PMI + * %IA64_IPI_DM_NMI - pend an NMI + * %IA64_IPI_DM_INIT - pend an INIT interrupt + */ +void sn2_send_IPI(int cpuid, int vector, int delivery_mode, int redirect) +{ + long physid; + int nasid; + + physid = cpu_physical_id(cpuid); + nasid = cpuid_to_nasid(cpuid); + + /* the following is used only when starting cpus at boot time */ + if (unlikely(nasid == -1)) + ia64_sn_get_sapic_info(physid, &nasid, NULL, NULL); + + sn_send_IPI_phys(nasid, physid, vector, delivery_mode); +} + +#ifdef CONFIG_PROC_FS + +#define PTC_BASENAME "sgi_sn/ptc_statistics" + +static void *sn2_ptc_seq_start(struct seq_file *file, loff_t * offset) +{ + if (*offset < NR_CPUS) + return offset; + return NULL; +} + +static void *sn2_ptc_seq_next(struct seq_file *file, void *data, loff_t * offset) +{ + (*offset)++; + if (*offset < NR_CPUS) + return offset; + return NULL; +} + +static void sn2_ptc_seq_stop(struct seq_file *file, void *data) +{ +} + +static int sn2_ptc_seq_show(struct seq_file *file, void *data) +{ + struct ptc_stats *stat; + int cpu; + + cpu = *(loff_t *) data; + + if (!cpu) { + seq_printf(file, + "# cpu ptc_l newrid ptc_flushes nodes_flushed deadlocks lock_nsec shub_nsec shub_nsec_max not_my_mm deadlock2\n"); + seq_printf(file, "# ptctest %d\n", sn2_ptctest); + } + + if (cpu < NR_CPUS && cpu_online(cpu)) { + stat = &per_cpu(ptcstats, cpu); + seq_printf(file, "cpu %d %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld\n", cpu, stat->ptc_l, + stat->change_rid, stat->shub_ptc_flushes, stat->nodes_flushed, + stat->deadlocks, + 1000 * stat->lock_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, + 1000 * stat->shub_itc_clocks / per_cpu(cpu_info, cpu).cyc_per_usec, + 1000 * stat->shub_itc_clocks_max / per_cpu(cpu_info, cpu).cyc_per_usec, + stat->shub_ptc_flushes_not_my_mm, + stat->deadlocks2); + } + return 0; +} + +static struct seq_operations sn2_ptc_seq_ops = { + .start = sn2_ptc_seq_start, + .next = sn2_ptc_seq_next, + .stop = sn2_ptc_seq_stop, + .show = sn2_ptc_seq_show +}; + +static int sn2_ptc_proc_open(struct inode *inode, struct file *file) +{ + return seq_open(file, &sn2_ptc_seq_ops); +} + +static struct file_operations proc_sn2_ptc_operations = { + .open = sn2_ptc_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = seq_release, +}; + +static struct proc_dir_entry *proc_sn2_ptc; + +static int __init sn2_ptc_init(void) +{ + if (!ia64_platform_is("sn2")) + return 0; + + if (!(proc_sn2_ptc = create_proc_entry(PTC_BASENAME, 0444, NULL))) { + printk(KERN_ERR "unable to create %s proc entry", PTC_BASENAME); + return -EINVAL; + } + proc_sn2_ptc->proc_fops = &proc_sn2_ptc_operations; + spin_lock_init(&sn2_global_ptc_lock); + return 0; +} + +static void __exit sn2_ptc_exit(void) +{ + remove_proc_entry(PTC_BASENAME, NULL); +} + +module_init(sn2_ptc_init); +module_exit(sn2_ptc_exit); +#endif /* CONFIG_PROC_FS */ + diff --git a/xen/arch/ia64/linux/Makefile b/xen/arch/ia64/linux/Makefile index 6acc02583d..4f7cd5a83b 100644 --- a/xen/arch/ia64/linux/Makefile +++ b/xen/arch/ia64/linux/Makefile @@ -23,6 +23,7 @@ obj-y += __udivdi3.o obj-y += __moddi3.o obj-y += __umoddi3.o obj-y += carta_random.o +obj-y += io.o ## variants of divide/modulo ## see files in xen/arch/ia64/linux/lib (linux/arch/ia64/lib) diff --git a/xen/arch/ia64/linux/README.origin b/xen/arch/ia64/linux/README.origin index 87da72ac8f..9706a53502 100644 --- a/xen/arch/ia64/linux/README.origin +++ b/xen/arch/ia64/linux/README.origin @@ -27,3 +27,6 @@ strlen.S -> linux/arch/ia64/lib/strlen.S # The files below are from Linux-2.6.16.33 carta_random.S -> linux/arch/ia64/lib/carta_random.S + +# The files below are from Linux-2.6.19 +io.c -> linux/arch/ia64/lib/io.c diff --git a/xen/arch/ia64/linux/dig/Makefile b/xen/arch/ia64/linux/dig/Makefile new file mode 100644 index 0000000000..38f6b9375d --- /dev/null +++ b/xen/arch/ia64/linux/dig/Makefile @@ -0,0 +1 @@ +obj-y += machvec.o diff --git a/xen/arch/ia64/linux/dig/README.origin b/xen/arch/ia64/linux/dig/README.origin new file mode 100644 index 0000000000..0976d1dd60 --- /dev/null +++ b/xen/arch/ia64/linux/dig/README.origin @@ -0,0 +1,7 @@ +Source files in this directory are identical copies of linux-2.6.19 files: + +NOTE: DO NOT commit changes to these files! If a file +needs to be changed, move it to ../linux-xen and follow +the instructions in the README there. + +machvec.c -> linux/arch/ia64/dig/machvec.c diff --git a/xen/arch/ia64/linux/dig/machvec.c b/xen/arch/ia64/linux/dig/machvec.c new file mode 100644 index 0000000000..0c55bdafb4 --- /dev/null +++ b/xen/arch/ia64/linux/dig/machvec.c @@ -0,0 +1,3 @@ +#define MACHVEC_PLATFORM_NAME dig +#define MACHVEC_PLATFORM_HEADER +#include diff --git a/xen/arch/ia64/linux/hp/Makefile b/xen/arch/ia64/linux/hp/Makefile new file mode 100644 index 0000000000..fc712eb29b --- /dev/null +++ b/xen/arch/ia64/linux/hp/Makefile @@ -0,0 +1 @@ +subdir-y += zx1 diff --git a/xen/arch/ia64/linux/hp/zx1/Makefile b/xen/arch/ia64/linux/hp/zx1/Makefile new file mode 100644 index 0000000000..c80bcd4ed7 --- /dev/null +++ b/xen/arch/ia64/linux/hp/zx1/Makefile @@ -0,0 +1 @@ +obj-y += hpzx1_machvec.o diff --git a/xen/arch/ia64/linux/hp/zx1/README.origin b/xen/arch/ia64/linux/hp/zx1/README.origin new file mode 100644 index 0000000000..598e743752 --- /dev/null +++ b/xen/arch/ia64/linux/hp/zx1/README.origin @@ -0,0 +1,7 @@ +Source files in this directory are identical copies of linux-2.6.19 files: + +NOTE: DO NOT commit changes to these files! If a file +needs to be changed, move it to ../linux-xen and follow +the instructions in the README there. + +hpzx1_machvec.c -> linux/arch/ia64/hp/zx1/hpzx1_machvec.c diff --git a/xen/arch/ia64/linux/hp/zx1/hpzx1_machvec.c b/xen/arch/ia64/linux/hp/zx1/hpzx1_machvec.c new file mode 100644 index 0000000000..32518b0f92 --- /dev/null +++ b/xen/arch/ia64/linux/hp/zx1/hpzx1_machvec.c @@ -0,0 +1,3 @@ +#define MACHVEC_PLATFORM_NAME hpzx1 +#define MACHVEC_PLATFORM_HEADER +#include diff --git a/xen/arch/ia64/linux/io.c b/xen/arch/ia64/linux/io.c new file mode 100644 index 0000000000..bcd16f8ad9 --- /dev/null +++ b/xen/arch/ia64/linux/io.c @@ -0,0 +1,164 @@ +#include +#include + +#include + +/* + * Copy data from IO memory space to "real" memory space. + * This needs to be optimized. + */ +void memcpy_fromio(void *to, const volatile void __iomem *from, long count) +{ + char *dst = to; + + while (count) { + count--; + *dst++ = readb(from++); + } +} +EXPORT_SYMBOL(memcpy_fromio); + +/* + * Copy data from "real" memory space to IO memory space. + * This needs to be optimized. + */ +void memcpy_toio(volatile void __iomem *to, const void *from, long count) +{ + const char *src = from; + + while (count) { + count--; + writeb(*src++, to++); + } +} +EXPORT_SYMBOL(memcpy_toio); + +/* + * "memset" on IO memory space. + * This needs to be optimized. + */ +void memset_io(volatile void __iomem *dst, int c, long count) +{ + unsigned char ch = (char)(c & 0xff); + + while (count) { + count--; + writeb(ch, dst); + dst++; + } +} +EXPORT_SYMBOL(memset_io); + +#ifdef CONFIG_IA64_GENERIC + +#undef __ia64_inb +#undef __ia64_inw +#undef __ia64_inl +#undef __ia64_outb +#undef __ia64_outw +#undef __ia64_outl +#undef __ia64_readb +#undef __ia64_readw +#undef __ia64_readl +#undef __ia64_readq +#undef __ia64_readb_relaxed +#undef __ia64_readw_relaxed +#undef __ia64_readl_relaxed +#undef __ia64_readq_relaxed +#undef __ia64_writeb +#undef __ia64_writew +#undef __ia64_writel +#undef __ia64_writeq +#undef __ia64_mmiowb + +unsigned int +__ia64_inb (unsigned long port) +{ + return ___ia64_inb(port); +} + +unsigned int +__ia64_inw (unsigned long port) +{ + return ___ia64_inw(port); +} + +unsigned int +__ia64_inl (unsigned long port) +{ + return ___ia64_inl(port); +} + +void +__ia64_outb (unsigned char val, unsigned long port) +{ + ___ia64_outb(val, port); +} + +void +__ia64_outw (unsigned short val, unsigned long port) +{ + ___ia64_outw(val, port); +} + +void +__ia64_outl (unsigned int val, unsigned long port) +{ + ___ia64_outl(val, port); +} + +unsigned char +__ia64_readb (void __iomem *addr) +{ + return ___ia64_readb (addr); +} + +unsigned short +__ia64_readw (void __iomem *addr) +{ + return ___ia64_readw (addr); +} + +unsigned int +__ia64_readl (void __iomem *addr) +{ + return ___ia64_readl (addr); +} + +unsigned long +__ia64_readq (void __iomem *addr) +{ + return ___ia64_readq (addr); +} + +unsigned char +__ia64_readb_relaxed (void __iomem *addr) +{ + return ___ia64_readb (addr); +} + +unsigned short +__ia64_readw_relaxed (void __iomem *addr) +{ + return ___ia64_readw (addr); +} + +unsigned int +__ia64_readl_relaxed (void __iomem *addr) +{ + return ___ia64_readl (addr); +} + +unsigned long +__ia64_readq_relaxed (void __iomem *addr) +{ + return ___ia64_readq (addr); +} + +void +__ia64_mmiowb(void) +{ + ___ia64_mmiowb(); +} + +#endif /* CONFIG_IA64_GENERIC */ diff --git a/xen/arch/ia64/linux/sn/Makefile b/xen/arch/ia64/linux/sn/Makefile new file mode 100644 index 0000000000..24687f3086 --- /dev/null +++ b/xen/arch/ia64/linux/sn/Makefile @@ -0,0 +1,2 @@ +subdir-y += kernel +subdir-y += pci diff --git a/xen/arch/ia64/linux/sn/kernel/Makefile b/xen/arch/ia64/linux/sn/kernel/Makefile new file mode 100644 index 0000000000..54a9da7ca7 --- /dev/null +++ b/xen/arch/ia64/linux/sn/kernel/Makefile @@ -0,0 +1,3 @@ +obj-y += machvec.o +obj-y += pio_phys.o +obj-y += ptc_deadlock.o diff --git a/xen/arch/ia64/linux/sn/kernel/README.origin b/xen/arch/ia64/linux/sn/kernel/README.origin new file mode 100644 index 0000000000..9f77d132f9 --- /dev/null +++ b/xen/arch/ia64/linux/sn/kernel/README.origin @@ -0,0 +1,9 @@ +Source files in this directory are identical copies of linux-2.6.19 files: + +NOTE: DO NOT commit changes to these files! If a file +needs to be changed, move it to ../linux-xen and follow +the instructions in the README there. + +machvec.c -> linux/arch/ia64/sn/kernel/machvec.c +pio_phys.S -> linux/arch/ia64/sn/kernel/pio_phys.S +ptc_deadlock.S -> linux/arch/ia64/sn/kernel/sn2/ptc_deadlock.S diff --git a/xen/arch/ia64/linux/sn/kernel/machvec.c b/xen/arch/ia64/linux/sn/kernel/machvec.c new file mode 100644 index 0000000000..02bb915584 --- /dev/null +++ b/xen/arch/ia64/linux/sn/kernel/machvec.c @@ -0,0 +1,11 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2002-2003 Silicon Graphics, Inc. All Rights Reserved. + */ + +#define MACHVEC_PLATFORM_NAME sn2 +#define MACHVEC_PLATFORM_HEADER +#include diff --git a/xen/arch/ia64/linux/sn/kernel/pio_phys.S b/xen/arch/ia64/linux/sn/kernel/pio_phys.S new file mode 100644 index 0000000000..3c7d48d6ec --- /dev/null +++ b/xen/arch/ia64/linux/sn/kernel/pio_phys.S @@ -0,0 +1,71 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved. + * + * This file contains macros used to access MMR registers via + * uncached physical addresses. + * pio_phys_read_mmr - read an MMR + * pio_phys_write_mmr - write an MMR + * pio_atomic_phys_write_mmrs - atomically write 1 or 2 MMRs with psr.ic=0 + * Second MMR will be skipped if address is NULL + * + * Addresses passed to these routines should be uncached physical addresses + * ie., 0x80000.... + */ + + + +#include +#include + +GLOBAL_ENTRY(pio_phys_read_mmr) + .prologue + .regstk 1,0,0,0 + .body + mov r2=psr + rsm psr.i | psr.dt + ;; + srlz.d + ld8.acq r8=[r32] + ;; + mov psr.l=r2;; + srlz.d + br.ret.sptk.many rp +END(pio_phys_read_mmr) + +GLOBAL_ENTRY(pio_phys_write_mmr) + .prologue + .regstk 2,0,0,0 + .body + mov r2=psr + rsm psr.i | psr.dt + ;; + srlz.d + st8.rel [r32]=r33 + ;; + mov psr.l=r2;; + srlz.d + br.ret.sptk.many rp +END(pio_phys_write_mmr) + +GLOBAL_ENTRY(pio_atomic_phys_write_mmrs) + .prologue + .regstk 4,0,0,0 + .body + mov r2=psr + cmp.ne p9,p0=r34,r0; + rsm psr.i | psr.dt | psr.ic + ;; + srlz.d + st8.rel [r32]=r33 +(p9) st8.rel [r34]=r35 + ;; + mov psr.l=r2;; + srlz.d + br.ret.sptk.many rp +END(pio_atomic_phys_write_mmrs) + + diff --git a/xen/arch/ia64/linux/sn/kernel/ptc_deadlock.S b/xen/arch/ia64/linux/sn/kernel/ptc_deadlock.S new file mode 100644 index 0000000000..bebbcc4f8d --- /dev/null +++ b/xen/arch/ia64/linux/sn/kernel/ptc_deadlock.S @@ -0,0 +1,92 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include + +#define DEADLOCKBIT SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT +#define WRITECOUNTMASK SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK +#define ALIAS_OFFSET 8 + + + .global sn2_ptc_deadlock_recovery_core + .proc sn2_ptc_deadlock_recovery_core + +sn2_ptc_deadlock_recovery_core: + .regstk 6,0,0,0 + + ptc0 = in0 + data0 = in1 + ptc1 = in2 + data1 = in3 + piowc = in4 + zeroval = in5 + piowcphy = r30 + psrsave = r2 + scr1 = r16 + scr2 = r17 + mask = r18 + + + extr.u piowcphy=piowc,0,61;; // Convert piowc to uncached physical address + dep piowcphy=-1,piowcphy,63,1 + movl mask=WRITECOUNTMASK + mov r8=r0 + +1: + cmp.ne p8,p9=r0,ptc1 // Test for shub type (ptc1 non-null on shub1) + // p8 = 1 if shub1, p9 = 1 if shub2 + + add scr2=ALIAS_OFFSET,piowc // Address of WRITE_STATUS alias register + mov scr1=7;; // Clear DEADLOCK, WRITE_ERROR, MULTI_WRITE_ERROR +(p8) st8.rel [scr2]=scr1;; +(p9) ld8.acq scr1=[scr2];; + +5: ld8.acq scr1=[piowc];; // Wait for PIOs to complete. + hint @pause + and scr2=scr1,mask;; // mask of writecount bits + cmp.ne p6,p0=zeroval,scr2 +(p6) br.cond.sptk 5b + + + + ////////////// BEGIN PHYSICAL MODE //////////////////// + mov psrsave=psr // Disable IC (no PMIs) + rsm psr.i | psr.dt | psr.ic;; + srlz.i;; + + st8.rel [ptc0]=data0 // Write PTC0 & wait for completion. + +5: ld8.acq scr1=[piowcphy];; // Wait for PIOs to complete. + hint @pause + and scr2=scr1,mask;; // mask of writecount bits + cmp.ne p6,p0=zeroval,scr2 +(p6) br.cond.sptk 5b;; + + tbit.nz p8,p7=scr1,DEADLOCKBIT;;// Test for DEADLOCK +(p7) cmp.ne p7,p0=r0,ptc1;; // Test for non-null ptc1 + +(p7) st8.rel [ptc1]=data1;; // Now write PTC1. + +5: ld8.acq scr1=[piowcphy];; // Wait for PIOs to complete. + hint @pause + and scr2=scr1,mask;; // mask of writecount bits + cmp.ne p6,p0=zeroval,scr2 +(p6) br.cond.sptk 5b + + tbit.nz p8,p0=scr1,DEADLOCKBIT;;// Test for DEADLOCK + + mov psr.l=psrsave;; // Reenable IC + srlz.i;; + ////////////// END PHYSICAL MODE //////////////////// + +(p8) add r8=1,r8 +(p8) br.cond.spnt 1b;; // Repeat if DEADLOCK occurred. + + br.ret.sptk rp + .endp sn2_ptc_deadlock_recovery_core diff --git a/xen/arch/ia64/linux/sn/pci/Makefile b/xen/arch/ia64/linux/sn/pci/Makefile new file mode 100644 index 0000000000..4c866bc776 --- /dev/null +++ b/xen/arch/ia64/linux/sn/pci/Makefile @@ -0,0 +1 @@ +subdir-y += pcibr diff --git a/xen/arch/ia64/linux/sn/pci/pcibr/Makefile b/xen/arch/ia64/linux/sn/pci/pcibr/Makefile new file mode 100644 index 0000000000..4039c25ab4 --- /dev/null +++ b/xen/arch/ia64/linux/sn/pci/pcibr/Makefile @@ -0,0 +1 @@ +obj-y += pcibr_reg.o diff --git a/xen/arch/ia64/linux/sn/pci/pcibr/README.origin b/xen/arch/ia64/linux/sn/pci/pcibr/README.origin new file mode 100644 index 0000000000..45d03b049c --- /dev/null +++ b/xen/arch/ia64/linux/sn/pci/pcibr/README.origin @@ -0,0 +1,7 @@ +Source files in this directory are identical copies of linux-2.6.19 files: + +NOTE: DO NOT commit changes to these files! If a file +needs to be changed, move it to ../linux-xen and follow +the instructions in the README there. + +pcibr_reg.c -> linux/arch/ia64/sn/pci/pcibr/pcibr_reg.c diff --git a/xen/arch/ia64/linux/sn/pci/pcibr/pcibr_reg.c b/xen/arch/ia64/linux/sn/pci/pcibr/pcibr_reg.c new file mode 100644 index 0000000000..8b8bbd51d4 --- /dev/null +++ b/xen/arch/ia64/linux/sn/pci/pcibr/pcibr_reg.c @@ -0,0 +1,285 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2004 Silicon Graphics, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +union br_ptr { + struct tiocp tio; + struct pic pic; +}; + +/* + * Control Register Access -- Read/Write 0000_0020 + */ +void pcireg_control_bit_clr(struct pcibus_info *pcibus_info, u64 bits) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + __sn_clrq_relaxed(&ptr->tio.cp_control, bits); + break; + case PCIBR_BRIDGETYPE_PIC: + __sn_clrq_relaxed(&ptr->pic.p_wid_control, bits); + break; + default: + panic + ("pcireg_control_bit_clr: unknown bridgetype bridge 0x%p", + ptr); + } + } +} + +void pcireg_control_bit_set(struct pcibus_info *pcibus_info, u64 bits) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + __sn_setq_relaxed(&ptr->tio.cp_control, bits); + break; + case PCIBR_BRIDGETYPE_PIC: + __sn_setq_relaxed(&ptr->pic.p_wid_control, bits); + break; + default: + panic + ("pcireg_control_bit_set: unknown bridgetype bridge 0x%p", + ptr); + } + } +} + +/* + * PCI/PCIX Target Flush Register Access -- Read Only 0000_0050 + */ +u64 pcireg_tflush_get(struct pcibus_info *pcibus_info) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + u64 ret = 0; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + ret = __sn_readq_relaxed(&ptr->tio.cp_tflush); + break; + case PCIBR_BRIDGETYPE_PIC: + ret = __sn_readq_relaxed(&ptr->pic.p_wid_tflush); + break; + default: + panic + ("pcireg_tflush_get: unknown bridgetype bridge 0x%p", + ptr); + } + } + + /* Read of the Target Flush should always return zero */ + if (ret != 0) + panic("pcireg_tflush_get:Target Flush failed\n"); + + return ret; +} + +/* + * Interrupt Status Register Access -- Read Only 0000_0100 + */ +u64 pcireg_intr_status_get(struct pcibus_info * pcibus_info) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + u64 ret = 0; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + ret = __sn_readq_relaxed(&ptr->tio.cp_int_status); + break; + case PCIBR_BRIDGETYPE_PIC: + ret = __sn_readq_relaxed(&ptr->pic.p_int_status); + break; + default: + panic + ("pcireg_intr_status_get: unknown bridgetype bridge 0x%p", + ptr); + } + } + return ret; +} + +/* + * Interrupt Enable Register Access -- Read/Write 0000_0108 + */ +void pcireg_intr_enable_bit_clr(struct pcibus_info *pcibus_info, u64 bits) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + __sn_clrq_relaxed(&ptr->tio.cp_int_enable, bits); + break; + case PCIBR_BRIDGETYPE_PIC: + __sn_clrq_relaxed(&ptr->pic.p_int_enable, bits); + break; + default: + panic + ("pcireg_intr_enable_bit_clr: unknown bridgetype bridge 0x%p", + ptr); + } + } +} + +void pcireg_intr_enable_bit_set(struct pcibus_info *pcibus_info, u64 bits) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + __sn_setq_relaxed(&ptr->tio.cp_int_enable, bits); + break; + case PCIBR_BRIDGETYPE_PIC: + __sn_setq_relaxed(&ptr->pic.p_int_enable, bits); + break; + default: + panic + ("pcireg_intr_enable_bit_set: unknown bridgetype bridge 0x%p", + ptr); + } + } +} + +/* + * Intr Host Address Register (int_addr) -- Read/Write 0000_0130 - 0000_0168 + */ +void pcireg_intr_addr_addr_set(struct pcibus_info *pcibus_info, int int_n, + u64 addr) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + __sn_clrq_relaxed(&ptr->tio.cp_int_addr[int_n], + TIOCP_HOST_INTR_ADDR); + __sn_setq_relaxed(&ptr->tio.cp_int_addr[int_n], + (addr & TIOCP_HOST_INTR_ADDR)); + break; + case PCIBR_BRIDGETYPE_PIC: + __sn_clrq_relaxed(&ptr->pic.p_int_addr[int_n], + PIC_HOST_INTR_ADDR); + __sn_setq_relaxed(&ptr->pic.p_int_addr[int_n], + (addr & PIC_HOST_INTR_ADDR)); + break; + default: + panic + ("pcireg_intr_addr_addr_get: unknown bridgetype bridge 0x%p", + ptr); + } + } +} + +/* + * Force Interrupt Register Access -- Write Only 0000_01C0 - 0000_01F8 + */ +void pcireg_force_intr_set(struct pcibus_info *pcibus_info, int int_n) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + writeq(1, &ptr->tio.cp_force_pin[int_n]); + break; + case PCIBR_BRIDGETYPE_PIC: + writeq(1, &ptr->pic.p_force_pin[int_n]); + break; + default: + panic + ("pcireg_force_intr_set: unknown bridgetype bridge 0x%p", + ptr); + } + } +} + +/* + * Device(x) Write Buffer Flush Reg Access -- Read Only 0000_0240 - 0000_0258 + */ +u64 pcireg_wrb_flush_get(struct pcibus_info *pcibus_info, int device) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + u64 ret = 0; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + ret = + __sn_readq_relaxed(&ptr->tio.cp_wr_req_buf[device]); + break; + case PCIBR_BRIDGETYPE_PIC: + ret = + __sn_readq_relaxed(&ptr->pic.p_wr_req_buf[device]); + break; + default: + panic("pcireg_wrb_flush_get: unknown bridgetype bridge 0x%p", ptr); + } + + } + /* Read of the Write Buffer Flush should always return zero */ + return ret; +} + +void pcireg_int_ate_set(struct pcibus_info *pcibus_info, int ate_index, + u64 val) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + writeq(val, &ptr->tio.cp_int_ate_ram[ate_index]); + break; + case PCIBR_BRIDGETYPE_PIC: + writeq(val, &ptr->pic.p_int_ate_ram[ate_index]); + break; + default: + panic + ("pcireg_int_ate_set: unknown bridgetype bridge 0x%p", + ptr); + } + } +} + +u64 __iomem *pcireg_int_ate_addr(struct pcibus_info *pcibus_info, int ate_index) +{ + union br_ptr __iomem *ptr = (union br_ptr __iomem *)pcibus_info->pbi_buscommon.bs_base; + u64 __iomem *ret = NULL; + + if (pcibus_info) { + switch (pcibus_info->pbi_bridge_type) { + case PCIBR_BRIDGETYPE_TIOCP: + ret = &ptr->tio.cp_int_ate_ram[ate_index]; + break; + case PCIBR_BRIDGETYPE_PIC: + ret = &ptr->pic.p_int_ate_ram[ate_index]; + break; + default: + panic + ("pcireg_int_ate_addr: unknown bridgetype bridge 0x%p", + ptr); + } + } + return ret; +} diff --git a/xen/include/asm-ia64/linux-null/linux/ioport.h b/xen/include/asm-ia64/linux-null/linux/ioport.h deleted file mode 100644 index 29f4f4cd69..0000000000 --- a/xen/include/asm-ia64/linux-null/linux/ioport.h +++ /dev/null @@ -1 +0,0 @@ -/* This file is intentionally left empty. */ diff --git a/xen/include/asm-ia64/linux-xen/asm/README.origin b/xen/include/asm-ia64/linux-xen/asm/README.origin index f8d8375770..e3c092976c 100644 --- a/xen/include/asm-ia64/linux-xen/asm/README.origin +++ b/xen/include/asm-ia64/linux-xen/asm/README.origin @@ -34,3 +34,9 @@ iosapic.h -> linux/include/asm-ia64/iosapic.h # The files below are from Linux-2.6.16.33 perfmon.h -> linux/include/asm-ia64/perfmon.h perfmon_default_smpl.h -> linux/include/asm-ia64/perfmon_default_smpl.h + +# The files below are from Linux-2.6.19 +machvec_dig.h -> linux/include/asm-ia64/machvec_dig.h +machvec_sn2.h -> linux/include/asm-ia64/machvec_sn2.h +machvec_hpzx1.h -> linux/include/asm-ia64/machvec_hpzx1.h +machvec_pci.h -> linux/include/asm-ia64/pci.h diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h b/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h new file mode 100644 index 0000000000..8a0752f409 --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h @@ -0,0 +1,16 @@ +#ifndef _ASM_IA64_MACHVEC_DIG_h +#define _ASM_IA64_MACHVEC_DIG_h + +extern ia64_mv_setup_t dig_setup; + +/* + * This stuff has dual use! + * + * For a generic kernel, the macros are used to initialize the + * platform's machvec structure. When compiling a non-generic kernel, + * the macros are used directly. + */ +#define platform_name "dig" +#define platform_setup dig_setup + +#endif /* _ASM_IA64_MACHVEC_DIG_h */ diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h b/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h new file mode 100644 index 0000000000..e90daf9ce3 --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h @@ -0,0 +1,37 @@ +#ifndef _ASM_IA64_MACHVEC_HPZX1_h +#define _ASM_IA64_MACHVEC_HPZX1_h + +extern ia64_mv_setup_t dig_setup; +extern ia64_mv_dma_alloc_coherent sba_alloc_coherent; +extern ia64_mv_dma_free_coherent sba_free_coherent; +extern ia64_mv_dma_map_single sba_map_single; +extern ia64_mv_dma_unmap_single sba_unmap_single; +extern ia64_mv_dma_map_sg sba_map_sg; +extern ia64_mv_dma_unmap_sg sba_unmap_sg; +extern ia64_mv_dma_supported sba_dma_supported; +extern ia64_mv_dma_mapping_error sba_dma_mapping_error; + +/* + * This stuff has dual use! + * + * For a generic kernel, the macros are used to initialize the + * platform's machvec structure. When compiling a non-generic kernel, + * the macros are used directly. + */ +#define platform_name "hpzx1" +#define platform_setup dig_setup +#define platform_dma_init machvec_noop +#define platform_dma_alloc_coherent sba_alloc_coherent +#define platform_dma_free_coherent sba_free_coherent +#define platform_dma_map_single sba_map_single +#define platform_dma_unmap_single sba_unmap_single +#define platform_dma_map_sg sba_map_sg +#define platform_dma_unmap_sg sba_unmap_sg +#define platform_dma_sync_single_for_cpu machvec_dma_sync_single +#define platform_dma_sync_sg_for_cpu machvec_dma_sync_sg +#define platform_dma_sync_single_for_device machvec_dma_sync_single +#define platform_dma_sync_sg_for_device machvec_dma_sync_sg +#define platform_dma_supported sba_dma_supported +#define platform_dma_mapping_error sba_dma_mapping_error + +#endif /* _ASM_IA64_MACHVEC_HPZX1_h */ diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h b/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h new file mode 100644 index 0000000000..c54b165b1c --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2002-2003,2006 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/NoticeExplan + */ + +#ifndef _ASM_IA64_MACHVEC_SN2_H +#define _ASM_IA64_MACHVEC_SN2_H + +extern ia64_mv_setup_t sn_setup; +extern ia64_mv_cpu_init_t sn_cpu_init; +extern ia64_mv_irq_init_t sn_irq_init; +extern ia64_mv_send_ipi_t sn2_send_IPI; +extern ia64_mv_timer_interrupt_t sn_timer_interrupt; +extern ia64_mv_global_tlb_purge_t sn2_global_tlb_purge; +extern ia64_mv_tlb_migrate_finish_t sn_tlb_migrate_finish; +extern ia64_mv_local_vector_to_irq sn_local_vector_to_irq; +extern ia64_mv_pci_get_legacy_mem_t sn_pci_get_legacy_mem; +extern ia64_mv_pci_legacy_read_t sn_pci_legacy_read; +extern ia64_mv_pci_legacy_write_t sn_pci_legacy_write; +extern ia64_mv_inb_t __sn_inb; +extern ia64_mv_inw_t __sn_inw; +extern ia64_mv_inl_t __sn_inl; +extern ia64_mv_outb_t __sn_outb; +extern ia64_mv_outw_t __sn_outw; +extern ia64_mv_outl_t __sn_outl; +extern ia64_mv_mmiowb_t __sn_mmiowb; +extern ia64_mv_readb_t __sn_readb; +extern ia64_mv_readw_t __sn_readw; +extern ia64_mv_readl_t __sn_readl; +extern ia64_mv_readq_t __sn_readq; +extern ia64_mv_readb_t __sn_readb_relaxed; +extern ia64_mv_readw_t __sn_readw_relaxed; +extern ia64_mv_readl_t __sn_readl_relaxed; +extern ia64_mv_readq_t __sn_readq_relaxed; +extern ia64_mv_dma_alloc_coherent sn_dma_alloc_coherent; +extern ia64_mv_dma_free_coherent sn_dma_free_coherent; +extern ia64_mv_dma_map_single sn_dma_map_single; +extern ia64_mv_dma_unmap_single sn_dma_unmap_single; +extern ia64_mv_dma_map_sg sn_dma_map_sg; +extern ia64_mv_dma_unmap_sg sn_dma_unmap_sg; +extern ia64_mv_dma_sync_single_for_cpu sn_dma_sync_single_for_cpu; +extern ia64_mv_dma_sync_sg_for_cpu sn_dma_sync_sg_for_cpu; +extern ia64_mv_dma_sync_single_for_device sn_dma_sync_single_for_device; +extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device; +extern ia64_mv_dma_mapping_error sn_dma_mapping_error; +extern ia64_mv_dma_supported sn_dma_supported; +extern ia64_mv_migrate_t sn_migrate; +extern ia64_mv_setup_msi_irq_t sn_setup_msi_irq; +extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; + + +/* + * This stuff has dual use! + * + * For a generic kernel, the macros are used to initialize the + * platform's machvec structure. When compiling a non-generic kernel, + * the macros are used directly. + */ +#define platform_name "sn2" +#define platform_setup sn_setup +#define platform_cpu_init sn_cpu_init +#define platform_irq_init sn_irq_init +#define platform_send_ipi sn2_send_IPI +#define platform_timer_interrupt sn_timer_interrupt +#define platform_global_tlb_purge sn2_global_tlb_purge +#define platform_tlb_migrate_finish sn_tlb_migrate_finish +#define platform_pci_fixup sn_pci_fixup +#define platform_inb __sn_inb +#define platform_inw __sn_inw +#define platform_inl __sn_inl +#define platform_outb __sn_outb +#define platform_outw __sn_outw +#define platform_outl __sn_outl +#define platform_mmiowb __sn_mmiowb +#define platform_readb __sn_readb +#define platform_readw __sn_readw +#define platform_readl __sn_readl +#define platform_readq __sn_readq +#define platform_readb_relaxed __sn_readb_relaxed +#define platform_readw_relaxed __sn_readw_relaxed +#define platform_readl_relaxed __sn_readl_relaxed +#define platform_readq_relaxed __sn_readq_relaxed +#define platform_local_vector_to_irq sn_local_vector_to_irq +#define platform_pci_get_legacy_mem sn_pci_get_legacy_mem +#define platform_pci_legacy_read sn_pci_legacy_read +#define platform_pci_legacy_write sn_pci_legacy_write +#define platform_dma_init machvec_noop +#define platform_dma_alloc_coherent sn_dma_alloc_coherent +#define platform_dma_free_coherent sn_dma_free_coherent +#define platform_dma_map_single sn_dma_map_single +#define platform_dma_unmap_single sn_dma_unmap_single +#define platform_dma_map_sg sn_dma_map_sg +#define platform_dma_unmap_sg sn_dma_unmap_sg +#define platform_dma_sync_single_for_cpu sn_dma_sync_single_for_cpu +#define platform_dma_sync_sg_for_cpu sn_dma_sync_sg_for_cpu +#define platform_dma_sync_single_for_device sn_dma_sync_single_for_device +#define platform_dma_sync_sg_for_device sn_dma_sync_sg_for_device +#define platform_dma_mapping_error sn_dma_mapping_error +#define platform_dma_supported sn_dma_supported +#define platform_migrate sn_migrate +#ifdef CONFIG_PCI_MSI +#define platform_setup_msi_irq sn_setup_msi_irq +#define platform_teardown_msi_irq sn_teardown_msi_irq +#else +#define platform_setup_msi_irq ((ia64_mv_setup_msi_irq_t*)NULL) +#define platform_teardown_msi_irq ((ia64_mv_teardown_msi_irq_t*)NULL) +#endif + +#include + +#endif /* _ASM_IA64_MACHVEC_SN2_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/pci.h b/xen/include/asm-ia64/linux-xen/asm/pci.h new file mode 100644 index 0000000000..ef616fd4cb --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/pci.h @@ -0,0 +1,174 @@ +#ifndef _ASM_IA64_PCI_H +#define _ASM_IA64_PCI_H + +#include +#include +#include +#include +#include + +#include +#include + +/* + * Can be used to override the logic in pci_scan_bus for skipping already-configured bus + * numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the + * loader. + */ +#define pcibios_assign_all_busses() 0 +#define pcibios_scan_all_fns(a, b) 0 + +#define PCIBIOS_MIN_IO 0x1000 +#define PCIBIOS_MIN_MEM 0x10000000 + +void pcibios_config_init(void); + +struct pci_dev; + +/* + * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct correspondence + * between device bus addresses and CPU physical addresses. Platforms with a hardware I/O + * MMU _must_ turn this off to suppress the bounce buffer handling code in the block and + * network device layers. Platforms with separate bus address spaces _must_ turn this off + * and provide a device DMA mapping implementation that takes care of the necessary + * address translation. + * + * For now, the ia64 platforms which may have separate/multiple bus address spaces all + * have I/O MMUs which support the merging of physically discontiguous buffers, so we can + * use that as the sole factor to determine the setting of PCI_DMA_BUS_IS_PHYS. + */ +extern unsigned long ia64_max_iommu_merge_mask; +#define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL) + +static inline void +pcibios_set_master (struct pci_dev *dev) +{ + /* No special bus mastering setup handling */ +} + +static inline void +pcibios_penalize_isa_irq (int irq, int active) +{ + /* We don't do dynamic PCI IRQ allocation */ +} + +#define HAVE_ARCH_PCI_MWI 1 +extern int pcibios_prep_mwi (struct pci_dev *); + +#include + +/* pci_unmap_{single,page} is not a nop, thus... */ +#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ + dma_addr_t ADDR_NAME; +#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ + __u32 LEN_NAME; +#define pci_unmap_addr(PTR, ADDR_NAME) \ + ((PTR)->ADDR_NAME) +#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ + (((PTR)->ADDR_NAME) = (VAL)) +#define pci_unmap_len(PTR, LEN_NAME) \ + ((PTR)->LEN_NAME) +#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ + (((PTR)->LEN_NAME) = (VAL)) + +/* The ia64 platform always supports 64-bit addressing. */ +#define pci_dac_dma_supported(pci_dev, mask) (1) +#define pci_dac_page_to_dma(dev,pg,off,dir) ((dma_addr_t) page_to_bus(pg) + (off)) +#define pci_dac_dma_to_page(dev,dma_addr) (virt_to_page(bus_to_virt(dma_addr))) +#define pci_dac_dma_to_offset(dev,dma_addr) offset_in_page(dma_addr) +#define pci_dac_dma_sync_single_for_cpu(dev,dma_addr,len,dir) do { } while (0) +#define pci_dac_dma_sync_single_for_device(dev,dma_addr,len,dir) do { mb(); } while (0) + +#define sg_dma_len(sg) ((sg)->dma_length) +#define sg_dma_address(sg) ((sg)->dma_address) + +#ifdef CONFIG_PCI +static inline void pci_dma_burst_advice(struct pci_dev *pdev, + enum pci_dma_burst_strategy *strat, + unsigned long *strategy_parameter) +{ + unsigned long cacheline_size; + u8 byte; + + pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); + if (byte == 0) + cacheline_size = 1024; + else + cacheline_size = (int) byte * 4; + + *strat = PCI_DMA_BURST_MULTIPLE; + *strategy_parameter = cacheline_size; +} +#endif + +#define HAVE_PCI_MMAP +extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, + enum pci_mmap_state mmap_state, int write_combine); +#define HAVE_PCI_LEGACY +extern int pci_mmap_legacy_page_range(struct pci_bus *bus, + struct vm_area_struct *vma); +extern ssize_t pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, + size_t count); +extern ssize_t pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, + size_t count); +extern int pci_mmap_legacy_mem(struct kobject *kobj, + struct bin_attribute *attr, + struct vm_area_struct *vma); + +#define pci_get_legacy_mem platform_pci_get_legacy_mem +#define pci_legacy_read platform_pci_legacy_read +#define pci_legacy_write platform_pci_legacy_write + +struct pci_window { + struct resource resource; + u64 offset; +}; + +struct pci_controller { + void *acpi_handle; + void *iommu; + int segment; + int node; /* nearest node with memory or -1 for global allocation */ + + unsigned int windows; + struct pci_window *window; + + void *platform_data; +}; + +#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata) +#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment) + +extern struct pci_ops pci_root_ops; + +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return (pci_domain_nr(bus) != 0); +} + +static inline void pcibios_add_platform_entries(struct pci_dev *dev) +{ +} + +extern void pcibios_resource_to_bus(struct pci_dev *dev, + struct pci_bus_region *region, struct resource *res); + +extern void pcibios_bus_to_resource(struct pci_dev *dev, + struct resource *res, struct pci_bus_region *region); + +static inline struct resource * +pcibios_select_root(struct pci_dev *pdev, struct resource *res) +{ + struct resource *root = NULL; + + if (res->flags & IORESOURCE_IO) + root = &ioport_resource; + if (res->flags & IORESOURCE_MEM) + root = &iomem_resource; + + return root; +} + +#define pcibios_scan_all_fns(a, b) 0 + +#endif /* _ASM_IA64_PCI_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/README.origin b/xen/include/asm-ia64/linux-xen/asm/sn/README.origin new file mode 100644 index 0000000000..762d1f5a9c --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/README.origin @@ -0,0 +1,16 @@ +# Source files in this directory are near-identical copies of linux-2.6.19 +# files: + +# NOTE: ALL changes to these files should be clearly marked +# (e.g. with #ifdef XEN or XEN in a comment) so that they can be +# easily updated to future versions of the corresponding Linux files. + +addrs.h -> linux/include/asm-ia64/sn/addrs.h +arch.h -> linux/include/asm-ia64/sn/arch.h +hubdev.h -> linux/arch/ia64/sn/include/xtalk/hubdev.h +intr.h -> linux/include/asm-ia64/sn/intr.h +io.h -> linux/include/asm-ia64/sn/io.h +nodepda.h -> linux/include/asm-ia64/sn/nodepda.h +pcibr_provider.h -> linux/include/asm-ia64/sn/pcibr_provider.h +rw_mmr.h -> linux/include/asm-ia64/sn/rw_mmr.h +types.h -> linux/include/asm-ia64/sn/types.h diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/addrs.h b/xen/include/asm-ia64/linux-xen/asm/sn/addrs.h new file mode 100644 index 0000000000..e715c794b1 --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/addrs.h @@ -0,0 +1,299 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 1992-1999,2001-2005 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef _ASM_IA64_SN_ADDRS_H +#define _ASM_IA64_SN_ADDRS_H + +#include +#include +#include +#include + +/* + * Memory/SHUB Address Format: + * +-+---------+--+--------------+ + * |0| NASID |AS| NodeOffset | + * +-+---------+--+--------------+ + * + * NASID: (low NASID bit is 0) Memory and SHUB MMRs + * AS: 2-bit Address Space Identifier. Used only if low NASID bit is 0 + * 00: Local Resources and MMR space + * Top bit of NodeOffset + * 0: Local resources space + * node id: + * 0: IA64/NT compatibility space + * 2: Local MMR Space + * 4: Local memory, regardless of local node id + * 1: Global MMR space + * 01: GET space. + * 10: AMO space. + * 11: Cacheable memory space. + * + * NodeOffset: byte offset + * + * + * TIO address format: + * +-+----------+--+--------------+ + * |0| NASID |AS| Nodeoffset | + * +-+----------+--+--------------+ + * + * NASID: (low NASID bit is 1) TIO + * AS: 2-bit Chiplet Identifier + * 00: TIO LB (Indicates TIO MMR access.) + * 01: TIO ICE (indicates coretalk space access.) + * + * NodeOffset: top bit must be set. + * + * + * Note that in both of the above address formats, the low + * NASID bit indicates if the reference is to the SHUB or TIO MMRs. + */ + + +/* + * Define basic shift & mask constants for manipulating NASIDs and AS values. + */ +#define NASID_BITMASK (sn_hub_info->nasid_bitmask) +#define NASID_SHIFT (sn_hub_info->nasid_shift) +#define AS_SHIFT (sn_hub_info->as_shift) +#define AS_BITMASK 0x3UL + +#define NASID_MASK ((u64)NASID_BITMASK << NASID_SHIFT) +#define AS_MASK ((u64)AS_BITMASK << AS_SHIFT) + + +/* + * AS values. These are the same on both SHUB1 & SHUB2. + */ +#define AS_GET_VAL 1UL +#define AS_AMO_VAL 2UL +#define AS_CAC_VAL 3UL +#define AS_GET_SPACE (AS_GET_VAL << AS_SHIFT) +#define AS_AMO_SPACE (AS_AMO_VAL << AS_SHIFT) +#define AS_CAC_SPACE (AS_CAC_VAL << AS_SHIFT) + + +/* + * Virtual Mode Local & Global MMR space. + */ +#define SH1_LOCAL_MMR_OFFSET 0x8000000000UL +#define SH2_LOCAL_MMR_OFFSET 0x0200000000UL +#define LOCAL_MMR_OFFSET (is_shub2() ? SH2_LOCAL_MMR_OFFSET : SH1_LOCAL_MMR_OFFSET) +#define LOCAL_MMR_SPACE (__IA64_UNCACHED_OFFSET | LOCAL_MMR_OFFSET) +#define LOCAL_PHYS_MMR_SPACE (RGN_BASE(RGN_HPAGE) | LOCAL_MMR_OFFSET) + +#define SH1_GLOBAL_MMR_OFFSET 0x0800000000UL +#define SH2_GLOBAL_MMR_OFFSET 0x0300000000UL +#define GLOBAL_MMR_OFFSET (is_shub2() ? SH2_GLOBAL_MMR_OFFSET : SH1_GLOBAL_MMR_OFFSET) +#define GLOBAL_MMR_SPACE (__IA64_UNCACHED_OFFSET | GLOBAL_MMR_OFFSET) + +/* + * Physical mode addresses + */ +#define GLOBAL_PHYS_MMR_SPACE (RGN_BASE(RGN_HPAGE) | GLOBAL_MMR_OFFSET) + + +/* + * Clear region & AS bits. + */ +#define TO_PHYS_MASK (~(RGN_BITS | AS_MASK)) + + +/* + * Misc NASID manipulation. + */ +#define NASID_SPACE(n) ((u64)(n) << NASID_SHIFT) +#define REMOTE_ADDR(n,a) (NASID_SPACE(n) | (a)) +#define NODE_OFFSET(x) ((x) & (NODE_ADDRSPACE_SIZE - 1)) +#define NODE_ADDRSPACE_SIZE (1UL << AS_SHIFT) +#define NASID_GET(x) (int) (((u64) (x) >> NASID_SHIFT) & NASID_BITMASK) +#define LOCAL_MMR_ADDR(a) (LOCAL_MMR_SPACE | (a)) +#define GLOBAL_MMR_ADDR(n,a) (GLOBAL_MMR_SPACE | REMOTE_ADDR(n,a)) +#define GLOBAL_MMR_PHYS_ADDR(n,a) (GLOBAL_PHYS_MMR_SPACE | REMOTE_ADDR(n,a)) +#define GLOBAL_CAC_ADDR(n,a) (CAC_BASE | REMOTE_ADDR(n,a)) +#define CHANGE_NASID(n,x) ((void *)(((u64)(x) & ~NASID_MASK) | NASID_SPACE(n))) +#define IS_TIO_NASID(n) ((n) & 1) + + +/* non-II mmr's start at top of big window space (4G) */ +#define BWIN_TOP 0x0000000100000000UL + +/* + * general address defines + */ +#define CAC_BASE (PAGE_OFFSET | AS_CAC_SPACE) +#define AMO_BASE (__IA64_UNCACHED_OFFSET | AS_AMO_SPACE) +#define AMO_PHYS_BASE (RGN_BASE(RGN_HPAGE) | AS_AMO_SPACE) +#define GET_BASE (PAGE_OFFSET | AS_GET_SPACE) + +/* + * Convert Memory addresses between various addressing modes. + */ +#define TO_PHYS(x) (TO_PHYS_MASK & (x)) +#define TO_CAC(x) (CAC_BASE | TO_PHYS(x)) +#ifdef CONFIG_SGI_SN +#define TO_AMO(x) (AMO_BASE | TO_PHYS(x)) +#define TO_GET(x) (GET_BASE | TO_PHYS(x)) +#else +#define TO_AMO(x) ({ BUG(); x; }) +#define TO_GET(x) ({ BUG(); x; }) +#endif + +/* + * Covert from processor physical address to II/TIO physical address: + * II - squeeze out the AS bits + * TIO- requires a chiplet id in bits 38-39. For DMA to memory, + * the chiplet id is zero. If we implement TIO-TIO dma, we might need + * to insert a chiplet id into this macro. However, it is our belief + * right now that this chiplet id will be ICE, which is also zero. + */ +#define SH1_TIO_PHYS_TO_DMA(x) \ + ((((u64)(NASID_GET(x))) << 40) | NODE_OFFSET(x)) + +#define SH2_NETWORK_BANK_OFFSET(x) \ + ((u64)(x) & ((1UL << (sn_hub_info->nasid_shift - 4)) -1)) + +#define SH2_NETWORK_BANK_SELECT(x) \ + ((((u64)(x) & (0x3UL << (sn_hub_info->nasid_shift - 4))) \ + >> (sn_hub_info->nasid_shift - 4)) << 36) + +#define SH2_NETWORK_ADDRESS(x) \ + (SH2_NETWORK_BANK_OFFSET(x) | SH2_NETWORK_BANK_SELECT(x)) + +#define SH2_TIO_PHYS_TO_DMA(x) \ + (((u64)(NASID_GET(x)) << 40) | SH2_NETWORK_ADDRESS(x)) + +#define PHYS_TO_TIODMA(x) \ + (is_shub1() ? SH1_TIO_PHYS_TO_DMA(x) : SH2_TIO_PHYS_TO_DMA(x)) + +#define PHYS_TO_DMA(x) \ + ((((u64)(x) & NASID_MASK) >> 2) | NODE_OFFSET(x)) + + +/* + * Macros to test for address type. + */ +#define IS_AMO_ADDRESS(x) (((u64)(x) & (RGN_BITS | AS_MASK)) == AMO_BASE) +#define IS_AMO_PHYS_ADDRESS(x) (((u64)(x) & (RGN_BITS | AS_MASK)) == AMO_PHYS_BASE) + + +/* + * The following definitions pertain to the IO special address + * space. They define the location of the big and little windows + * of any given node. + */ +#define BWIN_SIZE_BITS 29 /* big window size: 512M */ +#define TIO_BWIN_SIZE_BITS 30 /* big window size: 1G */ +#define NODE_SWIN_BASE(n, w) ((w == 0) ? NODE_BWIN_BASE((n), SWIN0_BIGWIN) \ + : RAW_NODE_SWIN_BASE(n, w)) +#define TIO_SWIN_BASE(n, w) (TIO_IO_BASE(n) + \ + ((u64) (w) << TIO_SWIN_SIZE_BITS)) +#define NODE_IO_BASE(n) (GLOBAL_MMR_SPACE | NASID_SPACE(n)) +#define TIO_IO_BASE(n) (__IA64_UNCACHED_OFFSET | NASID_SPACE(n)) +#define BWIN_SIZE (1UL << BWIN_SIZE_BITS) +#define NODE_BWIN_BASE0(n) (NODE_IO_BASE(n) + BWIN_SIZE) +#define NODE_BWIN_BASE(n, w) (NODE_BWIN_BASE0(n) + ((u64) (w) << BWIN_SIZE_BITS)) +#define RAW_NODE_SWIN_BASE(n, w) (NODE_IO_BASE(n) + ((u64) (w) << SWIN_SIZE_BITS)) +#define BWIN_WIDGET_MASK 0x7 +#define BWIN_WINDOWNUM(x) (((x) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK) +#define SH1_IS_BIG_WINDOW_ADDR(x) ((x) & BWIN_TOP) + +#define TIO_BWIN_WINDOW_SELECT_MASK 0x7 +#define TIO_BWIN_WINDOWNUM(x) (((x) >> TIO_BWIN_SIZE_BITS) & TIO_BWIN_WINDOW_SELECT_MASK) + +#define TIO_HWIN_SHIFT_BITS 33 +#define TIO_HWIN(x) (NODE_OFFSET(x) >> TIO_HWIN_SHIFT_BITS) + +/* + * The following definitions pertain to the IO special address + * space. They define the location of the big and little windows + * of any given node. + */ + +#define SWIN_SIZE_BITS 24 +#define SWIN_WIDGET_MASK 0xF + +#define TIO_SWIN_SIZE_BITS 28 +#define TIO_SWIN_SIZE (1UL << TIO_SWIN_SIZE_BITS) +#define TIO_SWIN_WIDGET_MASK 0x3 + +/* + * Convert smallwindow address to xtalk address. + * + * 'addr' can be physical or virtual address, but will be converted + * to Xtalk address in the range 0 -> SWINZ_SIZEMASK + */ +#define SWIN_WIDGETNUM(x) (((x) >> SWIN_SIZE_BITS) & SWIN_WIDGET_MASK) +#define TIO_SWIN_WIDGETNUM(x) (((x) >> TIO_SWIN_SIZE_BITS) & TIO_SWIN_WIDGET_MASK) + + +/* + * The following macros produce the correct base virtual address for + * the hub registers. The REMOTE_HUB_* macro produce + * the address for the specified hub's registers. The intent is + * that the appropriate PI, MD, NI, or II register would be substituted + * for x. + * + * WARNING: + * When certain Hub chip workaround are defined, it's not sufficient + * to dereference the *_HUB_ADDR() macros. You should instead use + * HUB_L() and HUB_S() if you must deal with pointers to hub registers. + * Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S(). + * They're always safe. + */ +/* Shub1 TIO & MMR addressing macros */ +#define SH1_TIO_IOSPACE_ADDR(n,x) \ + GLOBAL_MMR_ADDR(n,x) + +#define SH1_REMOTE_BWIN_MMR(n,x) \ + GLOBAL_MMR_ADDR(n,x) + +#define SH1_REMOTE_SWIN_MMR(n,x) \ + (NODE_SWIN_BASE(n,1) + 0x800000UL + (x)) + +#define SH1_REMOTE_MMR(n,x) \ + (SH1_IS_BIG_WINDOW_ADDR(x) ? SH1_REMOTE_BWIN_MMR(n,x) : \ + SH1_REMOTE_SWIN_MMR(n,x)) + +/* Shub1 TIO & MMR addressing macros */ +#define SH2_TIO_IOSPACE_ADDR(n,x) \ + ((__IA64_UNCACHED_OFFSET | REMOTE_ADDR(n,x) | 1UL << (NASID_SHIFT - 2))) + +#define SH2_REMOTE_MMR(n,x) \ + GLOBAL_MMR_ADDR(n,x) + + +/* TIO & MMR addressing macros that work on both shub1 & shub2 */ +#define TIO_IOSPACE_ADDR(n,x) \ + ((u64 *)(is_shub1() ? SH1_TIO_IOSPACE_ADDR(n,x) : \ + SH2_TIO_IOSPACE_ADDR(n,x))) + +#define SH_REMOTE_MMR(n,x) \ + (is_shub1() ? SH1_REMOTE_MMR(n,x) : SH2_REMOTE_MMR(n,x)) + +#define REMOTE_HUB_ADDR(n,x) \ + (IS_TIO_NASID(n) ? ((volatile u64*)TIO_IOSPACE_ADDR(n,x)) : \ + ((volatile u64*)SH_REMOTE_MMR(n,x))) + + +#define HUB_L(x) (*((volatile typeof(*x) *)x)) +#define HUB_S(x,d) (*((volatile typeof(*x) *)x) = (d)) + +#define REMOTE_HUB_L(n, a) HUB_L(REMOTE_HUB_ADDR((n), (a))) +#define REMOTE_HUB_S(n, a, d) HUB_S(REMOTE_HUB_ADDR((n), (a)), (d)) + +/* + * Coretalk address breakdown + */ +#define CTALK_NASID_SHFT 40 +#define CTALK_NASID_MASK (0x3FFFULL << CTALK_NASID_SHFT) +#define CTALK_CID_SHFT 38 +#define CTALK_CID_MASK (0x3ULL << CTALK_CID_SHFT) +#define CTALK_NODE_OFFSET 0x3FFFFFFFFF + +#endif /* _ASM_IA64_SN_ADDRS_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/arch.h b/xen/include/asm-ia64/linux-xen/asm/sn/arch.h new file mode 100644 index 0000000000..16adc93d7a --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/arch.h @@ -0,0 +1,85 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * SGI specific setup. + * + * Copyright (C) 1995-1997,1999,2001-2005 Silicon Graphics, Inc. All rights reserved. + * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org) + */ +#ifndef _ASM_IA64_SN_ARCH_H +#define _ASM_IA64_SN_ARCH_H + +#include +#include +#include +#include +#include + +/* + * This is the maximum number of NUMALINK nodes that can be part of a single + * SSI kernel. This number includes C-brick, M-bricks, and TIOs. Nodes in + * remote partitions are NOT included in this number. + * The number of compact nodes cannot exceed size of a coherency domain. + * The purpose of this define is to specify a node count that includes + * all C/M/TIO nodes in an SSI system. + * + * SGI system can currently support up to 256 C/M nodes plus additional TIO nodes. + * + * Note: ACPI20 has an architectural limit of 256 nodes. When we upgrade + * to ACPI3.0, this limit will be removed. The notion of "compact nodes" + * should be deleted and TIOs should be included in MAX_NUMNODES. + */ +#define MAX_TIO_NODES MAX_NUMNODES +#define MAX_COMPACT_NODES (MAX_NUMNODES + MAX_TIO_NODES) + +/* + * Maximum number of nodes in all partitions and in all coherency domains. + * This is the total number of nodes accessible in the numalink fabric. It + * includes all C & M bricks, plus all TIOs. + * + * This value is also the value of the maximum number of NASIDs in the numalink + * fabric. + */ +#define MAX_NUMALINK_NODES 16384 + +/* + * The following defines attributes of the HUB chip. These attributes are + * frequently referenced. They are kept in the per-cpu data areas of each cpu. + * They are kept together in a struct to minimize cache misses. + */ +struct sn_hub_info_s { + u8 shub2; + u8 nasid_shift; + u8 as_shift; + u8 shub_1_1_found; + u16 nasid_bitmask; +}; +DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); +#define sn_hub_info (&__get_cpu_var(__sn_hub_info)) +#define is_shub2() (sn_hub_info->shub2) +#define is_shub1() (sn_hub_info->shub2 == 0) + +/* + * Use this macro to test if shub 1.1 wars should be enabled + */ +#define enable_shub_wars_1_1() (sn_hub_info->shub_1_1_found) + + +/* + * Compact node ID to nasid mappings kept in the per-cpu data areas of each + * cpu. + */ +DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]); +#define sn_cnodeid_to_nasid (&__get_cpu_var(__sn_cnodeid_to_nasid[0])) + + +extern u8 sn_partition_id; +extern u8 sn_system_size; +extern u8 sn_sharing_domain_size; +extern u8 sn_region_size; + +extern void sn_flush_all_caches(long addr, long bytes); + +#endif /* _ASM_IA64_SN_ARCH_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/hubdev.h b/xen/include/asm-ia64/linux-xen/asm/sn/hubdev.h new file mode 100644 index 0000000000..8182583c76 --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/hubdev.h @@ -0,0 +1,91 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved. + */ +#ifndef _ASM_IA64_SN_XTALK_HUBDEV_H +#define _ASM_IA64_SN_XTALK_HUBDEV_H + +#include "xtalk/xwidgetdev.h" + +#define HUB_WIDGET_ID_MAX 0xf +#define DEV_PER_WIDGET (2*2*8) +#define IIO_ITTE_WIDGET_BITS 4 /* size of widget field */ +#define IIO_ITTE_WIDGET_MASK ((1<> IIO_ITTE_WIDGET_SHIFT) & IIO_ITTE_WIDGET_MASK) + +/* + * Use the top big window as a surrogate for the first small window + */ +#define SWIN0_BIGWIN HUB_NUM_BIG_WINDOW +#define IIO_NUM_ITTES 7 +#define HUB_NUM_BIG_WINDOW (IIO_NUM_ITTES - 1) + +/* This struct is shared between the PROM and the kernel. + * Changes to this struct will require corresponding changes to the kernel. + */ +struct sn_flush_device_common { + int sfdl_bus; + int sfdl_slot; + int sfdl_pin; + struct common_bar_list { + unsigned long start; + unsigned long end; + } sfdl_bar_list[6]; + unsigned long sfdl_force_int_addr; + unsigned long sfdl_flush_value; + volatile unsigned long *sfdl_flush_addr; + u32 sfdl_persistent_busnum; + u32 sfdl_persistent_segment; + struct pcibus_info *sfdl_pcibus_info; +}; + +/* This struct is kernel only and is not used by the PROM */ +struct sn_flush_device_kernel { + spinlock_t sfdl_flush_lock; + struct sn_flush_device_common *common; +}; + +/* 01/16/06 This struct is the old PROM/kernel struct and needs to be included + * for older official PROMs to function on the new kernel base. This struct + * will be removed when the next official PROM release occurs. */ + +struct sn_flush_device_war { + struct sn_flush_device_common common; + u32 filler; /* older PROMs expect the default size of a spinlock_t */ +}; + +/* + * **widget_p - Used as an array[wid_num][device] of sn_flush_device_kernel. + */ +struct sn_flush_nasid_entry { + struct sn_flush_device_kernel **widget_p; // Used as an array of wid_num + u64 iio_itte[8]; +}; + +struct hubdev_info { + geoid_t hdi_geoid; + short hdi_nasid; + short hdi_peer_nasid; /* Dual Porting Peer */ + + struct sn_flush_nasid_entry hdi_flush_nasid_list; + struct xwidget_info hdi_xwidget_info[HUB_WIDGET_ID_MAX + 1]; + + + void *hdi_nodepda; + void *hdi_node_vertex; + u32 max_segment_number; + u32 max_pcibus_number; +}; + +extern void hubdev_init_node(nodepda_t *, cnodeid_t); +extern void hub_error_init(struct hubdev_info *); +extern void ice_error_init(struct hubdev_info *); + + +#endif /* _ASM_IA64_SN_XTALK_HUBDEV_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/intr.h b/xen/include/asm-ia64/linux-xen/asm/sn/intr.h new file mode 100644 index 0000000000..12b54ddb06 --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/intr.h @@ -0,0 +1,67 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2006 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef _ASM_IA64_SN_INTR_H +#define _ASM_IA64_SN_INTR_H + +#include +#include + +#define SGI_UART_VECTOR 0xe9 + +/* Reserved IRQs : Note, not to exceed IA64_SN2_FIRST_DEVICE_VECTOR */ +#define SGI_XPC_ACTIVATE 0x30 +#define SGI_II_ERROR 0x31 +#define SGI_XBOW_ERROR 0x32 +#define SGI_PCIASIC_ERROR 0x33 +#define SGI_ACPI_SCI_INT 0x34 +#define SGI_TIOCA_ERROR 0x35 +#define SGI_TIO_ERROR 0x36 +#define SGI_TIOCX_ERROR 0x37 +#define SGI_MMTIMER_VECTOR 0x38 +#define SGI_XPC_NOTIFY 0xe7 + +#define IA64_SN2_FIRST_DEVICE_VECTOR 0x3c +#define IA64_SN2_LAST_DEVICE_VECTOR 0xe6 + +#define SN2_IRQ_RESERVED 0x1 +#define SN2_IRQ_CONNECTED 0x2 +#define SN2_IRQ_SHARED 0x4 + +// The SN PROM irq struct +struct sn_irq_info { + struct sn_irq_info *irq_next; /* deprecated DO NOT USE */ + short irq_nasid; /* Nasid IRQ is assigned to */ + int irq_slice; /* slice IRQ is assigned to */ + int irq_cpuid; /* kernel logical cpuid */ + int irq_irq; /* the IRQ number */ + int irq_int_bit; /* Bridge interrupt pin */ + /* <0 means MSI */ + u64 irq_xtalkaddr; /* xtalkaddr IRQ is sent to */ + int irq_bridge_type;/* pciio asic type (pciio.h) */ + void *irq_bridge; /* bridge generating irq */ + void *irq_pciioinfo; /* associated pciio_info_t */ + int irq_last_intr; /* For Shub lb lost intr WAR */ + int irq_cookie; /* unique cookie */ + int irq_flags; /* flags */ + int irq_share_cnt; /* num devices sharing IRQ */ + struct list_head list; /* list of sn_irq_info structs */ + struct rcu_head rcu; /* rcu callback list */ +}; + +extern void sn_send_IPI_phys(int, long, int, int); +extern u64 sn_intr_alloc(nasid_t, int, + struct sn_irq_info *, + int, nasid_t, int); +extern void sn_intr_free(nasid_t, int, struct sn_irq_info *); +extern struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *, nasid_t, int); +extern struct list_head **sn_irq_lh; + +#define CPU_VECTOR_TO_IRQ(cpuid,vector) (vector) + +#endif /* _ASM_IA64_SN_INTR_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/io.h b/xen/include/asm-ia64/linux-xen/asm/sn/io.h new file mode 100644 index 0000000000..41c73a7356 --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/io.h @@ -0,0 +1,274 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef _ASM_SN_IO_H +#define _ASM_SN_IO_H +#include +#include + +extern void * sn_io_addr(unsigned long port) __attribute_const__; /* Forward definition */ +extern void __sn_mmiowb(void); /* Forward definition */ + +extern int num_cnodes; + +#define __sn_mf_a() ia64_mfa() + +extern void sn_dma_flush(unsigned long); + +#define __sn_inb ___sn_inb +#define __sn_inw ___sn_inw +#define __sn_inl ___sn_inl +#define __sn_outb ___sn_outb +#define __sn_outw ___sn_outw +#define __sn_outl ___sn_outl +#define __sn_readb ___sn_readb +#define __sn_readw ___sn_readw +#define __sn_readl ___sn_readl +#define __sn_readq ___sn_readq +#define __sn_readb_relaxed ___sn_readb_relaxed +#define __sn_readw_relaxed ___sn_readw_relaxed +#define __sn_readl_relaxed ___sn_readl_relaxed +#define __sn_readq_relaxed ___sn_readq_relaxed + +/* + * Convenience macros for setting/clearing bits using the above accessors + */ + +#define __sn_setq_relaxed(addr, val) \ + writeq((__sn_readq_relaxed(addr) | (val)), (addr)) +#define __sn_clrq_relaxed(addr, val) \ + writeq((__sn_readq_relaxed(addr) & ~(val)), (addr)) + +/* + * The following routines are SN Platform specific, called when + * a reference is made to inX/outX set macros. SN Platform + * inX set of macros ensures that Posted DMA writes on the + * Bridge is flushed. + * + * The routines should be self explainatory. + */ + +static inline unsigned int +___sn_inb (unsigned long port) +{ + volatile unsigned char *addr; + unsigned char ret = -1; + + if ((addr = sn_io_addr(port))) { + ret = *addr; + __sn_mf_a(); + sn_dma_flush((unsigned long)addr); + } + return ret; +} + +static inline unsigned int +___sn_inw (unsigned long port) +{ + volatile unsigned short *addr; + unsigned short ret = -1; + + if ((addr = sn_io_addr(port))) { + ret = *addr; + __sn_mf_a(); + sn_dma_flush((unsigned long)addr); + } + return ret; +} + +static inline unsigned int +___sn_inl (unsigned long port) +{ + volatile unsigned int *addr; + unsigned int ret = -1; + + if ((addr = sn_io_addr(port))) { + ret = *addr; + __sn_mf_a(); + sn_dma_flush((unsigned long)addr); + } + return ret; +} + +static inline void +___sn_outb (unsigned char val, unsigned long port) +{ + volatile unsigned char *addr; + + if ((addr = sn_io_addr(port))) { + *addr = val; + __sn_mmiowb(); + } +} + +static inline void +___sn_outw (unsigned short val, unsigned long port) +{ + volatile unsigned short *addr; + + if ((addr = sn_io_addr(port))) { + *addr = val; + __sn_mmiowb(); + } +} + +static inline void +___sn_outl (unsigned int val, unsigned long port) +{ + volatile unsigned int *addr; + + if ((addr = sn_io_addr(port))) { + *addr = val; + __sn_mmiowb(); + } +} + +/* + * The following routines are SN Platform specific, called when + * a reference is made to readX/writeX set macros. SN Platform + * readX set of macros ensures that Posted DMA writes on the + * Bridge is flushed. + * + * The routines should be self explainatory. + */ + +static inline unsigned char +___sn_readb (const volatile void __iomem *addr) +{ + unsigned char val; + + val = *(volatile unsigned char __force *)addr; + __sn_mf_a(); + sn_dma_flush((unsigned long)addr); + return val; +} + +static inline unsigned short +___sn_readw (const volatile void __iomem *addr) +{ + unsigned short val; + + val = *(volatile unsigned short __force *)addr; + __sn_mf_a(); + sn_dma_flush((unsigned long)addr); + return val; +} + +static inline unsigned int +___sn_readl (const volatile void __iomem *addr) +{ + unsigned int val; + + val = *(volatile unsigned int __force *)addr; + __sn_mf_a(); + sn_dma_flush((unsigned long)addr); + return val; +} + +static inline unsigned long +___sn_readq (const volatile void __iomem *addr) +{ + unsigned long val; + + val = *(volatile unsigned long __force *)addr; + __sn_mf_a(); + sn_dma_flush((unsigned long)addr); + return val; +} + +/* + * For generic and SN2 kernels, we have a set of fast access + * PIO macros. These macros are provided on SN Platform + * because the normal inX and readX macros perform an + * additional task of flushing Post DMA request on the Bridge. + * + * These routines should be self explainatory. + */ + +static inline unsigned int +sn_inb_fast (unsigned long port) +{ + volatile unsigned char *addr = (unsigned char *)port; + unsigned char ret; + + ret = *addr; + __sn_mf_a(); + return ret; +} + +static inline unsigned int +sn_inw_fast (unsigned long port) +{ + volatile unsigned short *addr = (unsigned short *)port; + unsigned short ret; + + ret = *addr; + __sn_mf_a(); + return ret; +} + +static inline unsigned int +sn_inl_fast (unsigned long port) +{ + volatile unsigned int *addr = (unsigned int *)port; + unsigned int ret; + + ret = *addr; + __sn_mf_a(); + return ret; +} + +static inline unsigned char +___sn_readb_relaxed (const volatile void __iomem *addr) +{ + return *(volatile unsigned char __force *)addr; +} + +static inline unsigned short +___sn_readw_relaxed (const volatile void __iomem *addr) +{ + return *(volatile unsigned short __force *)addr; +} + +static inline unsigned int +___sn_readl_relaxed (const volatile void __iomem *addr) +{ + return *(volatile unsigned int __force *) addr; +} + +static inline unsigned long +___sn_readq_relaxed (const volatile void __iomem *addr) +{ + return *(volatile unsigned long __force *) addr; +} + +struct pci_dev; + +static inline int +sn_pci_set_vchan(struct pci_dev *pci_dev, unsigned long *addr, int vchan) +{ + + if (vchan > 1) { + return -1; + } + + if (!(*addr >> 32)) /* Using a mask here would be cleaner */ + return 0; /* but this generates better code */ + + if (vchan == 1) { + /* Set Bit 57 */ + *addr |= (1UL << 57); + } else { + /* Clear Bit 57 */ + *addr &= ~(1UL << 57); + } + + return 0; +} + +#endif /* _ASM_SN_IO_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/nodepda.h b/xen/include/asm-ia64/linux-xen/asm/sn/nodepda.h new file mode 100644 index 0000000000..6f6d69e39f --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/nodepda.h @@ -0,0 +1,83 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved. + */ +#ifndef _ASM_IA64_SN_NODEPDA_H +#define _ASM_IA64_SN_NODEPDA_H + + +#include +#include +#include +#include +#include + +/* + * NUMA Node-Specific Data structures are defined in this file. + * In particular, this is the location of the node PDA. + * A pointer to the right node PDA is saved in each CPU PDA. + */ + +/* + * Node-specific data structure. + * + * One of these structures is allocated on each node of a NUMA system. + * + * This structure provides a convenient way of keeping together + * all per-node data structures. + */ +struct phys_cpuid { + short nasid; + char subnode; + char slice; +}; + +struct nodepda_s { + void *pdinfo; /* Platform-dependent per-node info */ + + /* + * The BTEs on this node are shared by the local cpus + */ + struct bteinfo_s bte_if[MAX_BTES_PER_NODE]; /* Virtual Interface */ + struct timer_list bte_recovery_timer; + spinlock_t bte_recovery_lock; + + /* + * Array of pointers to the nodepdas for each node. + */ + struct nodepda_s *pernode_pdaindr[MAX_COMPACT_NODES]; + + /* + * Array of physical cpu identifiers. Indexed by cpuid. + */ + struct phys_cpuid phys_cpuid[NR_CPUS]; + spinlock_t ptc_lock ____cacheline_aligned_in_smp; +}; + +typedef struct nodepda_s nodepda_t; + +/* + * Access Functions for node PDA. + * Since there is one nodepda for each node, we need a convenient mechanism + * to access these nodepdas without cluttering code with #ifdefs. + * The next set of definitions provides this. + * Routines are expected to use + * + * sn_nodepda - to access node PDA for the node on which code is running + * NODEPDA(cnodeid) - to access node PDA for cnodeid + */ + +DECLARE_PER_CPU(struct nodepda_s *, __sn_nodepda); +#define sn_nodepda (__get_cpu_var(__sn_nodepda)) +#define NODEPDA(cnodeid) (sn_nodepda->pernode_pdaindr[cnodeid]) + +/* + * Check if given a compact node id the corresponding node has all the + * cpus disabled. + */ +#define is_headless_node(cnodeid) (nr_cpus_node(cnodeid) == 0) + +#endif /* _ASM_IA64_SN_NODEPDA_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/pcibr_provider.h b/xen/include/asm-ia64/linux-xen/asm/sn/pcibr_provider.h new file mode 100644 index 0000000000..da3eade0ca --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/pcibr_provider.h @@ -0,0 +1,149 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992-1997,2000-2006 Silicon Graphics, Inc. All rights reserved. + */ +#ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H +#define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H + +#include +#include + +/* Workarounds */ +#define PV907516 (1 << 1) /* TIOCP: Don't write the write buffer flush reg */ + +#define BUSTYPE_MASK 0x1 + +/* Macros given a pcibus structure */ +#define IS_PCIX(ps) ((ps)->pbi_bridge_mode & BUSTYPE_MASK) +#define IS_PCI_BRIDGE_ASIC(asic) (asic == PCIIO_ASIC_TYPE_PIC || \ + asic == PCIIO_ASIC_TYPE_TIOCP) +#define IS_PIC_SOFT(ps) (ps->pbi_bridge_type == PCIBR_BRIDGETYPE_PIC) + + +/* + * The different PCI Bridge types supported on the SGI Altix platforms + */ +#define PCIBR_BRIDGETYPE_UNKNOWN -1 +#define PCIBR_BRIDGETYPE_PIC 2 +#define PCIBR_BRIDGETYPE_TIOCP 3 + +/* + * Bridge 64bit Direct Map Attributes + */ +#define PCI64_ATTR_PREF (1ull << 59) +#define PCI64_ATTR_PREC (1ull << 58) +#define PCI64_ATTR_VIRTUAL (1ull << 57) +#define PCI64_ATTR_BAR (1ull << 56) +#define PCI64_ATTR_SWAP (1ull << 55) +#define PCI64_ATTR_VIRTUAL1 (1ull << 54) + +#define PCI32_LOCAL_BASE 0 +#define PCI32_MAPPED_BASE 0x40000000 +#define PCI32_DIRECT_BASE 0x80000000 + +#define IS_PCI32_MAPPED(x) ((u64)(x) < PCI32_DIRECT_BASE && \ + (u64)(x) >= PCI32_MAPPED_BASE) +#define IS_PCI32_DIRECT(x) ((u64)(x) >= PCI32_MAPPED_BASE) + + +/* + * Bridge PMU Address Transaltion Entry Attibutes + */ +#define PCI32_ATE_V (0x1 << 0) +#define PCI32_ATE_CO (0x1 << 1) +#define PCI32_ATE_PREC (0x1 << 2) +#define PCI32_ATE_MSI (0x1 << 2) +#define PCI32_ATE_PREF (0x1 << 3) +#define PCI32_ATE_BAR (0x1 << 4) +#define PCI32_ATE_ADDR_SHFT 12 + +#define MINIMAL_ATES_REQUIRED(addr, size) \ + (IOPG(IOPGOFF(addr) + (size) - 1) == IOPG((size) - 1)) + +#define MINIMAL_ATE_FLAG(addr, size) \ + (MINIMAL_ATES_REQUIRED((u64)addr, size) ? 1 : 0) + +/* bit 29 of the pci address is the SWAP bit */ +#define ATE_SWAPSHIFT 29 +#define ATE_SWAP_ON(x) ((x) |= (1 << ATE_SWAPSHIFT)) +#define ATE_SWAP_OFF(x) ((x) &= ~(1 << ATE_SWAPSHIFT)) + +/* + * I/O page size + */ +#if PAGE_SIZE < 16384 +#define IOPFNSHIFT 12 /* 4K per mapped page */ +#else +#define IOPFNSHIFT 14 /* 16K per mapped page */ +#endif + +#define IOPGSIZE (1 << IOPFNSHIFT) +#define IOPG(x) ((x) >> IOPFNSHIFT) +#define IOPGOFF(x) ((x) & (IOPGSIZE-1)) + +#define PCIBR_DEV_SWAP_DIR (1ull << 19) +#define PCIBR_CTRL_PAGE_SIZE (0x1 << 21) + +/* + * PMU resources. + */ +struct ate_resource{ + u64 *ate; + u64 num_ate; + u64 lowest_free_index; +}; + +struct pcibus_info { + struct pcibus_bussoft pbi_buscommon; /* common header */ + u32 pbi_moduleid; + short pbi_bridge_type; + short pbi_bridge_mode; + + struct ate_resource pbi_int_ate_resource; + u64 pbi_int_ate_size; + + u64 pbi_dir_xbase; + char pbi_hub_xid; + + u64 pbi_devreg[8]; + + u32 pbi_valid_devices; + u32 pbi_enabled_devices; + + spinlock_t pbi_lock; +}; + +extern int pcibr_init_provider(void); +extern void *pcibr_bus_fixup(struct pcibus_bussoft *, struct pci_controller *); +extern dma_addr_t pcibr_dma_map(struct pci_dev *, unsigned long, size_t, int type); +extern dma_addr_t pcibr_dma_map_consistent(struct pci_dev *, unsigned long, size_t, int type); +extern void pcibr_dma_unmap(struct pci_dev *, dma_addr_t, int); + +/* + * prototypes for the bridge asic register access routines in pcibr_reg.c + */ +extern void pcireg_control_bit_clr(struct pcibus_info *, u64); +extern void pcireg_control_bit_set(struct pcibus_info *, u64); +extern u64 pcireg_tflush_get(struct pcibus_info *); +extern u64 pcireg_intr_status_get(struct pcibus_info *); +extern void pcireg_intr_enable_bit_clr(struct pcibus_info *, u64); +extern void pcireg_intr_enable_bit_set(struct pcibus_info *, u64); +extern void pcireg_intr_addr_addr_set(struct pcibus_info *, int, u64); +extern void pcireg_force_intr_set(struct pcibus_info *, int); +extern u64 pcireg_wrb_flush_get(struct pcibus_info *, int); +extern void pcireg_int_ate_set(struct pcibus_info *, int, u64); +extern u64 __iomem * pcireg_int_ate_addr(struct pcibus_info *, int); +extern void pcibr_force_interrupt(struct sn_irq_info *sn_irq_info); +extern void pcibr_change_devices_irq(struct sn_irq_info *sn_irq_info); +extern int pcibr_ate_alloc(struct pcibus_info *, int); +extern void pcibr_ate_free(struct pcibus_info *, int); +extern void ate_write(struct pcibus_info *, int, int, u64); +extern int sal_pcibr_slot_enable(struct pcibus_info *soft, int device, + void *resp); +extern int sal_pcibr_slot_disable(struct pcibus_info *soft, int device, + int action, void *resp); +extern u16 sn_ioboard_to_pci_bus(struct pci_bus *pci_bus); +#endif diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/rw_mmr.h b/xen/include/asm-ia64/linux-xen/asm/sn/rw_mmr.h new file mode 100644 index 0000000000..2d78f4c5a4 --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/rw_mmr.h @@ -0,0 +1,28 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2002-2006 Silicon Graphics, Inc. All Rights Reserved. + */ +#ifndef _ASM_IA64_SN_RW_MMR_H +#define _ASM_IA64_SN_RW_MMR_H + + +/* + * This file that access MMRs via uncached physical addresses. + * pio_phys_read_mmr - read an MMR + * pio_phys_write_mmr - write an MMR + * pio_atomic_phys_write_mmrs - atomically write 1 or 2 MMRs with psr.ic=0 + * Second MMR will be skipped if address is NULL + * + * Addresses passed to these routines should be uncached physical addresses + * ie., 0x80000.... + */ + + +extern long pio_phys_read_mmr(volatile long *mmr); +extern void pio_phys_write_mmr(volatile long *mmr, long val); +extern void pio_atomic_phys_write_mmrs(volatile long *mmr1, long val1, volatile long *mmr2, long val2); + +#endif /* _ASM_IA64_SN_RW_MMR_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/types.h b/xen/include/asm-ia64/linux-xen/asm/sn/types.h new file mode 100644 index 0000000000..8e04ee211e --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/asm/sn/types.h @@ -0,0 +1,26 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1999 by Ralf Baechle + */ +#ifndef _ASM_IA64_SN_TYPES_H +#define _ASM_IA64_SN_TYPES_H + +#include + +typedef unsigned long cpuid_t; +typedef signed short nasid_t; /* node id in numa-as-id space */ +typedef signed char partid_t; /* partition ID type */ +typedef unsigned int moduleid_t; /* user-visible module number type */ +typedef unsigned int cmoduleid_t; /* kernel compact module id type */ +typedef unsigned char slotid_t; /* slot (blade) within module */ +typedef unsigned char slabid_t; /* slab (asic) within slot */ +typedef u64 nic_t; +typedef unsigned long iopaddr_t; +typedef unsigned long paddr_t; +typedef short cnodeid_t; + +#endif /* _ASM_IA64_SN_TYPES_H */ diff --git a/xen/include/asm-ia64/linux-xen/linux/README.origin b/xen/include/asm-ia64/linux-xen/linux/README.origin index 6cc513be16..b46632953f 100644 --- a/xen/include/asm-ia64/linux-xen/linux/README.origin +++ b/xen/include/asm-ia64/linux-xen/linux/README.origin @@ -12,3 +12,8 @@ interrupt.h -> linux/include/linux/interrupt.h # The files below are from Linux-2.6.16.33 oprofile.h -> linux/include/linux/oprofile.h + +# The files below are from Linux-2.6.19 +pci.h -> linux/include/linux/pci.h +kobject.h -> linux/include/linux/kobject.h +device.h -> linux/include/linux/device.h diff --git a/xen/include/asm-ia64/linux-xen/linux/device.h b/xen/include/asm-ia64/linux-xen/linux/device.h new file mode 100644 index 0000000000..9d4f6a9639 --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/linux/device.h @@ -0,0 +1,473 @@ +/* + * device.h - generic, centralized driver model + * + * Copyright (c) 2001-2003 Patrick Mochel + * + * This file is released under the GPLv2 + * + * See Documentation/driver-model/ for more information. + */ + +#ifndef _DEVICE_H_ +#define _DEVICE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEVICE_NAME_SIZE 50 +#define DEVICE_NAME_HALF __stringify(20) /* Less than half to accommodate slop */ +#define DEVICE_ID_SIZE 32 +#define BUS_ID_SIZE KOBJ_NAME_LEN + + +struct device; +struct device_driver; +struct class; +struct class_device; + +struct bus_type { + const char * name; + + struct subsystem subsys; + struct kset drivers; + struct kset devices; + struct klist klist_devices; + struct klist klist_drivers; + + struct bus_attribute * bus_attrs; + struct device_attribute * dev_attrs; + struct driver_attribute * drv_attrs; + + int (*match)(struct device * dev, struct device_driver * drv); + int (*uevent)(struct device *dev, char **envp, + int num_envp, char *buffer, int buffer_size); + int (*probe)(struct device * dev); + int (*remove)(struct device * dev); + void (*shutdown)(struct device * dev); + + int (*suspend)(struct device * dev, pm_message_t state); + int (*suspend_late)(struct device * dev, pm_message_t state); + int (*resume_early)(struct device * dev); + int (*resume)(struct device * dev); +}; + +extern int __must_check bus_register(struct bus_type * bus); +extern void bus_unregister(struct bus_type * bus); + +extern int __must_check bus_rescan_devices(struct bus_type * bus); + +/* iterator helpers for buses */ + +int bus_for_each_dev(struct bus_type * bus, struct device * start, void * data, + int (*fn)(struct device *, void *)); +struct device * bus_find_device(struct bus_type *bus, struct device *start, + void *data, int (*match)(struct device *, void *)); + +int __must_check bus_for_each_drv(struct bus_type *bus, + struct device_driver *start, void *data, + int (*fn)(struct device_driver *, void *)); + +/* driverfs interface for exporting bus attributes */ + +struct bus_attribute { + struct attribute attr; + ssize_t (*show)(struct bus_type *, char * buf); + ssize_t (*store)(struct bus_type *, const char * buf, size_t count); +}; + +#define BUS_ATTR(_name,_mode,_show,_store) \ +struct bus_attribute bus_attr_##_name = __ATTR(_name,_mode,_show,_store) + +extern int __must_check bus_create_file(struct bus_type *, + struct bus_attribute *); +extern void bus_remove_file(struct bus_type *, struct bus_attribute *); + +struct device_driver { + const char * name; + struct bus_type * bus; + + struct completion unloaded; + struct kobject kobj; + struct klist klist_devices; + struct klist_node knode_bus; + + struct module * owner; + + int (*probe) (struct device * dev); + int (*remove) (struct device * dev); + void (*shutdown) (struct device * dev); + int (*suspend) (struct device * dev, pm_message_t state); + int (*resume) (struct device * dev); + + unsigned int multithread_probe:1; +}; + + +extern int __must_check driver_register(struct device_driver * drv); +extern void driver_unregister(struct device_driver * drv); + +extern struct device_driver * get_driver(struct device_driver * drv); +extern void put_driver(struct device_driver * drv); +extern struct device_driver *driver_find(const char *name, struct bus_type *bus); +extern int driver_probe_done(void); + +/* driverfs interface for exporting driver attributes */ + +struct driver_attribute { + struct attribute attr; + ssize_t (*show)(struct device_driver *, char * buf); + ssize_t (*store)(struct device_driver *, const char * buf, size_t count); +}; + +#define DRIVER_ATTR(_name,_mode,_show,_store) \ +struct driver_attribute driver_attr_##_name = __ATTR(_name,_mode,_show,_store) + +extern int __must_check driver_create_file(struct device_driver *, + struct driver_attribute *); +extern void driver_remove_file(struct device_driver *, struct driver_attribute *); + +extern int __must_check driver_for_each_device(struct device_driver * drv, + struct device *start, void *data, + int (*fn)(struct device *, void *)); +struct device * driver_find_device(struct device_driver *drv, + struct device *start, void *data, + int (*match)(struct device *, void *)); + +/* + * device classes + */ +struct class { + const char * name; + struct module * owner; + + struct subsystem subsys; + struct list_head children; + struct list_head devices; + struct list_head interfaces; + struct semaphore sem; /* locks both the children and interfaces lists */ + + struct kobject *virtual_dir; + + struct class_attribute * class_attrs; + struct class_device_attribute * class_dev_attrs; + struct device_attribute * dev_attrs; + + int (*uevent)(struct class_device *dev, char **envp, + int num_envp, char *buffer, int buffer_size); + int (*dev_uevent)(struct device *dev, char **envp, int num_envp, + char *buffer, int buffer_size); + + void (*release)(struct class_device *dev); + void (*class_release)(struct class *class); + void (*dev_release)(struct device *dev); + + int (*suspend)(struct device *, pm_message_t state); + int (*resume)(struct device *); +}; + +extern int __must_check class_register(struct class *); +extern void class_unregister(struct class *); + + +struct class_attribute { + struct attribute attr; + ssize_t (*show)(struct class *, char * buf); + ssize_t (*store)(struct class *, const char * buf, size_t count); +}; + +#define CLASS_ATTR(_name,_mode,_show,_store) \ +struct class_attribute class_attr_##_name = __ATTR(_name,_mode,_show,_store) + +extern int __must_check class_create_file(struct class *, + const struct class_attribute *); +extern void class_remove_file(struct class *, const struct class_attribute *); + +struct class_device_attribute { + struct attribute attr; + ssize_t (*show)(struct class_device *, char * buf); + ssize_t (*store)(struct class_device *, const char * buf, size_t count); +}; + +#define CLASS_DEVICE_ATTR(_name,_mode,_show,_store) \ +struct class_device_attribute class_device_attr_##_name = \ + __ATTR(_name,_mode,_show,_store) + +extern int __must_check class_device_create_file(struct class_device *, + const struct class_device_attribute *); + +/** + * struct class_device - class devices + * @class: pointer to the parent class for this class device. This is required. + * @devt: for internal use by the driver core only. + * @node: for internal use by the driver core only. + * @kobj: for internal use by the driver core only. + * @devt_attr: for internal use by the driver core only. + * @groups: optional additional groups to be created + * @dev: if set, a symlink to the struct device is created in the sysfs + * directory for this struct class device. + * @class_data: pointer to whatever you want to store here for this struct + * class_device. Use class_get_devdata() and class_set_devdata() to get and + * set this pointer. + * @parent: pointer to a struct class_device that is the parent of this struct + * class_device. If NULL, this class_device will show up at the root of the + * struct class in sysfs (which is probably what you want to have happen.) + * @release: pointer to a release function for this struct class_device. If + * set, this will be called instead of the class specific release function. + * Only use this if you want to override the default release function, like + * when you are nesting class_device structures. + * @uevent: pointer to a uevent function for this struct class_device. If + * set, this will be called instead of the class specific uevent function. + * Only use this if you want to override the default uevent function, like + * when you are nesting class_device structures. + */ +struct class_device { + struct list_head node; + + struct kobject kobj; + struct class * class; /* required */ + dev_t devt; /* dev_t, creates the sysfs "dev" */ + struct class_device_attribute *devt_attr; + struct class_device_attribute uevent_attr; + struct device * dev; /* not necessary, but nice to have */ + void * class_data; /* class-specific data */ + struct class_device *parent; /* parent of this child device, if there is one */ + struct attribute_group ** groups; /* optional groups */ + + void (*release)(struct class_device *dev); + int (*uevent)(struct class_device *dev, char **envp, + int num_envp, char *buffer, int buffer_size); + char class_id[BUS_ID_SIZE]; /* unique to this class */ +}; + +static inline void * +class_get_devdata (struct class_device *dev) +{ + return dev->class_data; +} + +static inline void +class_set_devdata (struct class_device *dev, void *data) +{ + dev->class_data = data; +} + + +extern int __must_check class_device_register(struct class_device *); +extern void class_device_unregister(struct class_device *); +extern void class_device_initialize(struct class_device *); +extern int __must_check class_device_add(struct class_device *); +extern void class_device_del(struct class_device *); + +extern int class_device_rename(struct class_device *, char *); + +extern struct class_device * class_device_get(struct class_device *); +extern void class_device_put(struct class_device *); + +extern void class_device_remove_file(struct class_device *, + const struct class_device_attribute *); +extern int __must_check class_device_create_bin_file(struct class_device *, + struct bin_attribute *); +extern void class_device_remove_bin_file(struct class_device *, + struct bin_attribute *); + +struct class_interface { + struct list_head node; + struct class *class; + + int (*add) (struct class_device *, struct class_interface *); + void (*remove) (struct class_device *, struct class_interface *); + int (*add_dev) (struct device *, struct class_interface *); + void (*remove_dev) (struct device *, struct class_interface *); +}; + +extern int __must_check class_interface_register(struct class_interface *); +extern void class_interface_unregister(struct class_interface *); + +extern struct class *class_create(struct module *owner, const char *name); +extern void class_destroy(struct class *cls); +extern struct class_device *class_device_create(struct class *cls, + struct class_device *parent, + dev_t devt, + struct device *device, + const char *fmt, ...) + __attribute__((format(printf,5,6))); +extern void class_device_destroy(struct class *cls, dev_t devt); + +/* interface for exporting device attributes */ +struct device_attribute { + struct attribute attr; + ssize_t (*show)(struct device *dev, struct device_attribute *attr, + char *buf); + ssize_t (*store)(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count); +}; + +#define DEVICE_ATTR(_name,_mode,_show,_store) \ +struct device_attribute dev_attr_##_name = __ATTR(_name,_mode,_show,_store) + +extern int __must_check device_create_file(struct device *device, + struct device_attribute * entry); +extern void device_remove_file(struct device * dev, struct device_attribute * attr); +extern int __must_check device_create_bin_file(struct device *dev, + struct bin_attribute *attr); +extern void device_remove_bin_file(struct device *dev, + struct bin_attribute *attr); +struct device { + struct klist klist_children; + struct klist_node knode_parent; /* node in sibling list */ + struct klist_node knode_driver; + struct klist_node knode_bus; + struct device * parent; + + struct kobject kobj; + char bus_id[BUS_ID_SIZE]; /* position on parent bus */ + unsigned is_registered:1; + struct device_attribute uevent_attr; + struct device_attribute *devt_attr; + + struct semaphore sem; /* semaphore to synchronize calls to + * its driver. + */ + + struct bus_type * bus; /* type of bus device is on */ + struct device_driver *driver; /* which driver has allocated this + device */ + void *driver_data; /* data private to the driver */ + void *platform_data; /* Platform specific data, device + core doesn't touch it */ + void *firmware_data; /* Firmware specific data (e.g. ACPI, + BIOS data),reserved for device core*/ + struct dev_pm_info power; + + u64 *dma_mask; /* dma mask (if dma'able device) */ + u64 coherent_dma_mask;/* Like dma_mask, but for + alloc_coherent mappings as + not all hardware supports + 64 bit addresses for consistent + allocations such descriptors. */ + + struct list_head dma_pools; /* dma pools (if dma'ble) */ + + struct dma_coherent_mem *dma_mem; /* internal for coherent mem + override */ + + /* class_device migration path */ + struct list_head node; + struct class *class; /* optional*/ + dev_t devt; /* dev_t, creates the sysfs "dev" */ + struct attribute_group **groups; /* optional groups */ + + void (*release)(struct device * dev); +}; + +static inline void * +dev_get_drvdata (struct device *dev) +{ + return dev->driver_data; +} + +static inline void +dev_set_drvdata (struct device *dev, void *data) +{ + dev->driver_data = data; +} + +static inline int device_is_registered(struct device *dev) +{ + return dev->is_registered; +} + +/* + * High level routines for use by the bus drivers + */ +extern int __must_check device_register(struct device * dev); +extern void device_unregister(struct device * dev); +extern void device_initialize(struct device * dev); +extern int __must_check device_add(struct device * dev); +extern void device_del(struct device * dev); +extern int device_for_each_child(struct device *, void *, + int (*fn)(struct device *, void *)); +extern int device_rename(struct device *dev, char *new_name); + +/* + * Manual binding of a device to driver. See drivers/base/bus.c + * for information on use. + */ +extern int __must_check device_bind_driver(struct device *dev); +extern void device_release_driver(struct device * dev); +extern int __must_check device_attach(struct device * dev); +extern int __must_check driver_attach(struct device_driver *drv); +extern int __must_check device_reprobe(struct device *dev); + +/* + * Easy functions for dynamically creating devices on the fly + */ +extern struct device *device_create(struct class *cls, struct device *parent, + dev_t devt, const char *fmt, ...) + __attribute__((format(printf,4,5))); +extern void device_destroy(struct class *cls, dev_t devt); + +extern int virtual_device_parent(struct device *dev); + +/* + * Platform "fixup" functions - allow the platform to have their say + * about devices and actions that the general device layer doesn't + * know about. + */ +/* Notify platform of device discovery */ +extern int (*platform_notify)(struct device * dev); + +extern int (*platform_notify_remove)(struct device * dev); + + +/** + * get_device - atomically increment the reference count for the device. + * + */ +extern struct device * get_device(struct device * dev); +extern void put_device(struct device * dev); + + +/* drivers/base/power/shutdown.c */ +extern void device_shutdown(void); + + +/* drivers/base/firmware.c */ +extern int __must_check firmware_register(struct subsystem *); +extern void firmware_unregister(struct subsystem *); + +/* debugging and troubleshooting/diagnostic helpers. */ +extern const char *dev_driver_string(struct device *dev); +#define dev_printk(level, dev, format, arg...) \ + printk(level "%s %s: " format , dev_driver_string(dev) , (dev)->bus_id , ## arg) + +#ifdef DEBUG +#define dev_dbg(dev, format, arg...) \ + dev_printk(KERN_DEBUG , dev , format , ## arg) +#else +#define dev_dbg(dev, format, arg...) do { (void)(dev); } while (0) +#endif + +#define dev_err(dev, format, arg...) \ + dev_printk(KERN_ERR , dev , format , ## arg) +#define dev_info(dev, format, arg...) \ + dev_printk(KERN_INFO , dev , format , ## arg) +#define dev_warn(dev, format, arg...) \ + dev_printk(KERN_WARNING , dev , format , ## arg) +#define dev_notice(dev, format, arg...) \ + dev_printk(KERN_NOTICE , dev , format , ## arg) + +/* Create alias, so I can be autoloaded. */ +#define MODULE_ALIAS_CHARDEV(major,minor) \ + MODULE_ALIAS("char-major-" __stringify(major) "-" __stringify(minor)) +#define MODULE_ALIAS_CHARDEV_MAJOR(major) \ + MODULE_ALIAS("char-major-" __stringify(major) "-*") +#endif /* _DEVICE_H_ */ diff --git a/xen/include/asm-ia64/linux-xen/linux/kobject.h b/xen/include/asm-ia64/linux-xen/linux/kobject.h new file mode 100644 index 0000000000..bcd9cd173c --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/linux/kobject.h @@ -0,0 +1,282 @@ +/* + * kobject.h - generic kernel object infrastructure. + * + * Copyright (c) 2002-2003 Patrick Mochel + * Copyright (c) 2002-2003 Open Source Development Labs + * + * This file is released under the GPLv2. + * + * + * Please read Documentation/kobject.txt before using the kobject + * interface, ESPECIALLY the parts about reference counts and object + * destructors. + */ + +#ifndef _KOBJECT_H_ +#define _KOBJECT_H_ + +#ifdef __KERNEL__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define KOBJ_NAME_LEN 20 +#define UEVENT_HELPER_PATH_LEN 256 + +/* path to the userspace helper executed on an event */ +extern char uevent_helper[]; + +/* counter to tag the uevent, read only except for the kobject core */ +extern u64 uevent_seqnum; + +/* the actions here must match the proper string in lib/kobject_uevent.c */ +typedef int __bitwise kobject_action_t; +enum kobject_action { + KOBJ_ADD = (__force kobject_action_t) 0x01, /* exclusive to core */ + KOBJ_REMOVE = (__force kobject_action_t) 0x02, /* exclusive to core */ + KOBJ_CHANGE = (__force kobject_action_t) 0x03, /* device state change */ + KOBJ_MOUNT = (__force kobject_action_t) 0x04, /* mount event for block devices (broken) */ + KOBJ_UMOUNT = (__force kobject_action_t) 0x05, /* umount event for block devices (broken) */ + KOBJ_OFFLINE = (__force kobject_action_t) 0x06, /* device offline */ + KOBJ_ONLINE = (__force kobject_action_t) 0x07, /* device online */ +}; + +struct kobject { + const char * k_name; + char name[KOBJ_NAME_LEN]; + struct kref kref; + struct list_head entry; + struct kobject * parent; + struct kset * kset; + struct kobj_type * ktype; + struct dentry * dentry; + wait_queue_head_t poll; +}; + +extern int kobject_set_name(struct kobject *, const char *, ...) + __attribute__((format(printf,2,3))); + +static inline const char * kobject_name(const struct kobject * kobj) +{ + return kobj->k_name; +} + +extern void kobject_init(struct kobject *); +extern void kobject_cleanup(struct kobject *); + +extern int __must_check kobject_add(struct kobject *); +extern void kobject_del(struct kobject *); + +extern int __must_check kobject_rename(struct kobject *, const char *new_name); + +extern int __must_check kobject_register(struct kobject *); +extern void kobject_unregister(struct kobject *); + +extern struct kobject * kobject_get(struct kobject *); +extern void kobject_put(struct kobject *); + +extern struct kobject *kobject_add_dir(struct kobject *, const char *); + +extern char * kobject_get_path(struct kobject *, gfp_t); + +struct kobj_type { + void (*release)(struct kobject *); + struct sysfs_ops * sysfs_ops; + struct attribute ** default_attrs; +}; + + +/** + * kset - a set of kobjects of a specific type, belonging + * to a specific subsystem. + * + * All kobjects of a kset should be embedded in an identical + * type. This type may have a descriptor, which the kset points + * to. This allows there to exist sets of objects of the same + * type in different subsystems. + * + * A subsystem does not have to be a list of only one type + * of object; multiple ksets can belong to one subsystem. All + * ksets of a subsystem share the subsystem's lock. + * + * Each kset can support specific event variables; it can + * supress the event generation or add subsystem specific + * variables carried with the event. + */ +struct kset_uevent_ops { + int (*filter)(struct kset *kset, struct kobject *kobj); + const char *(*name)(struct kset *kset, struct kobject *kobj); + int (*uevent)(struct kset *kset, struct kobject *kobj, char **envp, + int num_envp, char *buffer, int buffer_size); +}; + +struct kset { + struct subsystem * subsys; + struct kobj_type * ktype; + struct list_head list; + spinlock_t list_lock; + struct kobject kobj; + struct kset_uevent_ops * uevent_ops; +}; + + +extern void kset_init(struct kset * k); +extern int __must_check kset_add(struct kset * k); +extern int __must_check kset_register(struct kset * k); +extern void kset_unregister(struct kset * k); + +static inline struct kset * to_kset(struct kobject * kobj) +{ + return kobj ? container_of(kobj,struct kset,kobj) : NULL; +} + +static inline struct kset * kset_get(struct kset * k) +{ + return k ? to_kset(kobject_get(&k->kobj)) : NULL; +} + +static inline void kset_put(struct kset * k) +{ + kobject_put(&k->kobj); +} + +static inline struct kobj_type * get_ktype(struct kobject * k) +{ + if (k->kset && k->kset->ktype) + return k->kset->ktype; + else + return k->ktype; +} + +extern struct kobject * kset_find_obj(struct kset *, const char *); + + +/** + * Use this when initializing an embedded kset with no other + * fields to initialize. + */ +#define set_kset_name(str) .kset = { .kobj = { .name = str } } + + + +struct subsystem { + struct kset kset; + struct rw_semaphore rwsem; +}; + +#define decl_subsys(_name,_type,_uevent_ops) \ +struct subsystem _name##_subsys = { \ + .kset = { \ + .kobj = { .name = __stringify(_name) }, \ + .ktype = _type, \ + .uevent_ops =_uevent_ops, \ + } \ +} +#define decl_subsys_name(_varname,_name,_type,_uevent_ops) \ +struct subsystem _varname##_subsys = { \ + .kset = { \ + .kobj = { .name = __stringify(_name) }, \ + .ktype = _type, \ + .uevent_ops =_uevent_ops, \ + } \ +} + +/* The global /sys/kernel/ subsystem for people to chain off of */ +extern struct subsystem kernel_subsys; +/* The global /sys/hypervisor/ subsystem */ +extern struct subsystem hypervisor_subsys; + +/** + * Helpers for setting the kset of registered objects. + * Often, a registered object belongs to a kset embedded in a + * subsystem. These do no magic, just make the resulting code + * easier to follow. + */ + +/** + * kobj_set_kset_s(obj,subsys) - set kset for embedded kobject. + * @obj: ptr to some object type. + * @subsys: a subsystem object (not a ptr). + * + * Can be used for any object type with an embedded ->kobj. + */ + +#define kobj_set_kset_s(obj,subsys) \ + (obj)->kobj.kset = &(subsys).kset + +/** + * kset_set_kset_s(obj,subsys) - set kset for embedded kset. + * @obj: ptr to some object type. + * @subsys: a subsystem object (not a ptr). + * + * Can be used for any object type with an embedded ->kset. + * Sets the kset of @obj's embedded kobject (via its embedded + * kset) to @subsys.kset. This makes @obj a member of that + * kset. + */ + +#define kset_set_kset_s(obj,subsys) \ + (obj)->kset.kobj.kset = &(subsys).kset + +/** + * subsys_set_kset(obj,subsys) - set kset for subsystem + * @obj: ptr to some object type. + * @subsys: a subsystem object (not a ptr). + * + * Can be used for any object type with an embedded ->subsys. + * Sets the kset of @obj's kobject to @subsys.kset. This makes + * the object a member of that kset. + */ + +#define subsys_set_kset(obj,_subsys) \ + (obj)->subsys.kset.kobj.kset = &(_subsys).kset + +extern void subsystem_init(struct subsystem *); +extern int __must_check subsystem_register(struct subsystem *); +extern void subsystem_unregister(struct subsystem *); + +static inline struct subsystem * subsys_get(struct subsystem * s) +{ + return s ? container_of(kset_get(&s->kset),struct subsystem,kset) : NULL; +} + +static inline void subsys_put(struct subsystem * s) +{ + kset_put(&s->kset); +} + +struct subsys_attribute { + struct attribute attr; + ssize_t (*show)(struct subsystem *, char *); + ssize_t (*store)(struct subsystem *, const char *, size_t); +}; + +extern int __must_check subsys_create_file(struct subsystem * , + struct subsys_attribute *); + +#if defined(CONFIG_HOTPLUG) +void kobject_uevent(struct kobject *kobj, enum kobject_action action); + +int add_uevent_var(char **envp, int num_envp, int *cur_index, + char *buffer, int buffer_size, int *cur_len, + const char *format, ...) + __attribute__((format (printf, 7, 8))); +#else +static inline void kobject_uevent(struct kobject *kobj, enum kobject_action action) { } + +static inline int add_uevent_var(char **envp, int num_envp, int *cur_index, + char *buffer, int buffer_size, int *cur_len, + const char *format, ...) +{ return 0; } +#endif + +#endif /* __KERNEL__ */ +#endif /* _KOBJECT_H_ */ diff --git a/xen/include/asm-ia64/linux-xen/linux/pci.h b/xen/include/asm-ia64/linux-xen/linux/pci.h new file mode 100644 index 0000000000..09be0f81b2 --- /dev/null +++ b/xen/include/asm-ia64/linux-xen/linux/pci.h @@ -0,0 +1,817 @@ +/* + * pci.h + * + * PCI defines and function prototypes + * Copyright 1994, Drew Eckhardt + * Copyright 1997--1999 Martin Mares + * + * For more information, please consult the following manuals (look at + * http://www.pcisig.com/ for how to get them): + * + * PCI BIOS Specification + * PCI Local Bus Specification + * PCI to PCI Bridge Specification + * PCI System Design Guide + */ + +#ifndef LINUX_PCI_H +#define LINUX_PCI_H + +/* Include the pci register defines */ +#include + +/* Include the ID list */ +#include + +/* + * The PCI interface treats multi-function devices as independent + * devices. The slot/function address of each device is encoded + * in a single byte as follows: + * + * 7:3 = slot + * 2:0 = function + */ +#define PCI_DEVFN(slot,func) ((((slot) & 0x1f) << 3) | ((func) & 0x07)) +#define PCI_SLOT(devfn) (((devfn) >> 3) & 0x1f) +#define PCI_FUNC(devfn) ((devfn) & 0x07) + +/* Ioctls for /proc/bus/pci/X/Y nodes. */ +#define PCIIOC_BASE ('P' << 24 | 'C' << 16 | 'I' << 8) +#define PCIIOC_CONTROLLER (PCIIOC_BASE | 0x00) /* Get controller for PCI device. */ +#define PCIIOC_MMAP_IS_IO (PCIIOC_BASE | 0x01) /* Set mmap state to I/O space. */ +#define PCIIOC_MMAP_IS_MEM (PCIIOC_BASE | 0x02) /* Set mmap state to MEM space. */ +#define PCIIOC_WRITE_COMBINE (PCIIOC_BASE | 0x03) /* Enable/disable write-combining. */ + +#ifdef __KERNEL__ + +#include + +#include +#include +#include +#include +#include +#include + +/* File state for mmap()s on /proc/bus/pci/X/Y */ +enum pci_mmap_state { + pci_mmap_io, + pci_mmap_mem +}; + +/* This defines the direction arg to the DMA mapping routines. */ +#define PCI_DMA_BIDIRECTIONAL 0 +#define PCI_DMA_TODEVICE 1 +#define PCI_DMA_FROMDEVICE 2 +#define PCI_DMA_NONE 3 + +#define DEVICE_COUNT_COMPATIBLE 4 +#define DEVICE_COUNT_RESOURCE 12 + +typedef int __bitwise pci_power_t; + +#define PCI_D0 ((pci_power_t __force) 0) +#define PCI_D1 ((pci_power_t __force) 1) +#define PCI_D2 ((pci_power_t __force) 2) +#define PCI_D3hot ((pci_power_t __force) 3) +#define PCI_D3cold ((pci_power_t __force) 4) +#define PCI_UNKNOWN ((pci_power_t __force) 5) +#define PCI_POWER_ERROR ((pci_power_t __force) -1) + +/** The pci_channel state describes connectivity between the CPU and + * the pci device. If some PCI bus between here and the pci device + * has crashed or locked up, this info is reflected here. + */ +typedef unsigned int __bitwise pci_channel_state_t; + +enum pci_channel_state { + /* I/O channel is in normal state */ + pci_channel_io_normal = (__force pci_channel_state_t) 1, + + /* I/O to channel is blocked */ + pci_channel_io_frozen = (__force pci_channel_state_t) 2, + + /* PCI card is dead */ + pci_channel_io_perm_failure = (__force pci_channel_state_t) 3, +}; + +typedef unsigned short __bitwise pci_bus_flags_t; +enum pci_bus_flags { + PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, +}; + +struct pci_cap_saved_state { + struct hlist_node next; + char cap_nr; + u32 data[0]; +}; + +/* + * The pci_dev structure is used to describe PCI devices. + */ +struct pci_dev { + struct list_head global_list; /* node in list of all PCI devices */ + struct list_head bus_list; /* node in per-bus list */ + struct pci_bus *bus; /* bus this device is on */ + struct pci_bus *subordinate; /* bus this device bridges to */ + + void *sysdata; /* hook for sys-specific extension */ + struct proc_dir_entry *procent; /* device entry in /proc/bus/pci */ + + unsigned int devfn; /* encoded device & function index */ + unsigned short vendor; + unsigned short device; + unsigned short subsystem_vendor; + unsigned short subsystem_device; + unsigned int class; /* 3 bytes: (base,sub,prog-if) */ + u8 hdr_type; /* PCI header type (`multi' flag masked out) */ + u8 rom_base_reg; /* which config register controls the ROM */ + u8 pin; /* which interrupt pin this device uses */ + + struct pci_driver *driver; /* which driver has allocated this device */ + u64 dma_mask; /* Mask of the bits of bus address this + device implements. Normally this is + 0xffffffff. You only need to change + this if your device has broken DMA + or supports 64-bit transfers. */ + + pci_power_t current_state; /* Current operating state. In ACPI-speak, + this is D0-D3, D0 being fully functional, + and D3 being off. */ + + pci_channel_state_t error_state; /* current connectivity state */ + struct device dev; /* Generic device interface */ + + /* device is compatible with these IDs */ + unsigned short vendor_compatible[DEVICE_COUNT_COMPATIBLE]; + unsigned short device_compatible[DEVICE_COUNT_COMPATIBLE]; + + int cfg_size; /* Size of configuration space */ + + /* + * Instead of touching interrupt line and base address registers + * directly, use the values stored here. They might be different! + */ + unsigned int irq; + struct resource resource[DEVICE_COUNT_RESOURCE]; /* I/O and memory regions + expansion ROMs */ + + /* These fields are used by common fixups */ + unsigned int transparent:1; /* Transparent PCI bridge */ + unsigned int multifunction:1;/* Part of multi-function device */ + /* keep track of device state */ + unsigned int is_enabled:1; /* pci_enable_device has been called */ + unsigned int is_busmaster:1; /* device is busmaster */ + unsigned int no_msi:1; /* device may not use msi */ + unsigned int no_d1d2:1; /* only allow d0 or d3 */ + unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ + unsigned int broken_parity_status:1; /* Device generates false positive parity */ + unsigned int msi_enabled:1; + unsigned int msix_enabled:1; + + u32 saved_config_space[16]; /* config space saved at suspend time */ + struct hlist_head saved_cap_space; + struct bin_attribute *rom_attr; /* attribute descriptor for sysfs ROM entry */ + int rom_attr_enabled; /* has display of the rom attribute been enabled? */ + struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ +}; + +#define pci_dev_g(n) list_entry(n, struct pci_dev, global_list) +#define pci_dev_b(n) list_entry(n, struct pci_dev, bus_list) +#define to_pci_dev(n) container_of(n, struct pci_dev, dev) +#define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) + +static inline struct pci_cap_saved_state *pci_find_saved_cap( + struct pci_dev *pci_dev,char cap) +{ + struct pci_cap_saved_state *tmp; + struct hlist_node *pos; + + hlist_for_each_entry(tmp, pos, &pci_dev->saved_cap_space, next) { + if (tmp->cap_nr == cap) + return tmp; + } + return NULL; +} + +static inline void pci_add_saved_cap(struct pci_dev *pci_dev, + struct pci_cap_saved_state *new_cap) +{ + hlist_add_head(&new_cap->next, &pci_dev->saved_cap_space); +} + +static inline void pci_remove_saved_cap(struct pci_cap_saved_state *cap) +{ + hlist_del(&cap->next); +} + +/* + * For PCI devices, the region numbers are assigned this way: + * + * 0-5 standard PCI regions + * 6 expansion ROM + * 7-10 bridges: address space assigned to buses behind the bridge + */ + +#define PCI_ROM_RESOURCE 6 +#define PCI_BRIDGE_RESOURCES 7 +#define PCI_NUM_RESOURCES 11 + +#ifndef PCI_BUS_NUM_RESOURCES +#define PCI_BUS_NUM_RESOURCES 8 +#endif + +#define PCI_REGION_FLAG_MASK 0x0fU /* These bits of resource flags tell us the PCI region flags */ + +struct pci_bus { + struct list_head node; /* node in list of buses */ + struct pci_bus *parent; /* parent bus this bridge is on */ + struct list_head children; /* list of child buses */ + struct list_head devices; /* list of devices on this bus */ + struct pci_dev *self; /* bridge device as seen by parent */ + struct resource *resource[PCI_BUS_NUM_RESOURCES]; + /* address space routed to this bus */ + + struct pci_ops *ops; /* configuration access functions */ + void *sysdata; /* hook for sys-specific extension */ + struct proc_dir_entry *procdir; /* directory entry in /proc/bus/pci */ + + unsigned char number; /* bus number */ + unsigned char primary; /* number of primary bridge */ + unsigned char secondary; /* number of secondary bridge */ + unsigned char subordinate; /* max number of subordinate buses */ + + char name[48]; + + unsigned short bridge_ctl; /* manage NO_ISA/FBB/et al behaviors */ + pci_bus_flags_t bus_flags; /* Inherited by child busses */ + struct device *bridge; + struct class_device class_dev; + struct bin_attribute *legacy_io; /* legacy I/O for this bus */ + struct bin_attribute *legacy_mem; /* legacy mem */ +}; + +#define pci_bus_b(n) list_entry(n, struct pci_bus, node) +#define to_pci_bus(n) container_of(n, struct pci_bus, class_dev) + +/* + * Error values that may be returned by PCI functions. + */ +#define PCIBIOS_SUCCESSFUL 0x00 +#define PCIBIOS_FUNC_NOT_SUPPORTED 0x81 +#define PCIBIOS_BAD_VENDOR_ID 0x83 +#define PCIBIOS_DEVICE_NOT_FOUND 0x86 +#define PCIBIOS_BAD_REGISTER_NUMBER 0x87 +#define PCIBIOS_SET_FAILED 0x88 +#define PCIBIOS_BUFFER_TOO_SMALL 0x89 + +/* Low-level architecture-dependent routines */ + +struct pci_ops { + int (*read)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val); + int (*write)(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val); +}; + +struct pci_raw_ops { + int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, + int reg, int len, u32 *val); + int (*write)(unsigned int domain, unsigned int bus, unsigned int devfn, + int reg, int len, u32 val); +}; + +extern struct pci_raw_ops *raw_pci_ops; + +struct pci_bus_region { + unsigned long start; + unsigned long end; +}; + +struct pci_dynids { + spinlock_t lock; /* protects list, index */ + struct list_head list; /* for IDs added at runtime */ + unsigned int use_driver_data:1; /* pci_driver->driver_data is used */ +}; + +/* ---------------------------------------------------------------- */ +/** PCI Error Recovery System (PCI-ERS). If a PCI device driver provides + * a set fof callbacks in struct pci_error_handlers, then that device driver + * will be notified of PCI bus errors, and will be driven to recovery + * when an error occurs. + */ + +typedef unsigned int __bitwise pci_ers_result_t; + +enum pci_ers_result { + /* no result/none/not supported in device driver */ + PCI_ERS_RESULT_NONE = (__force pci_ers_result_t) 1, + + /* Device driver can recover without slot reset */ + PCI_ERS_RESULT_CAN_RECOVER = (__force pci_ers_result_t) 2, + + /* Device driver wants slot to be reset. */ + PCI_ERS_RESULT_NEED_RESET = (__force pci_ers_result_t) 3, + + /* Device has completely failed, is unrecoverable */ + PCI_ERS_RESULT_DISCONNECT = (__force pci_ers_result_t) 4, + + /* Device driver is fully recovered and operational */ + PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5, +}; + +/* PCI bus error event callbacks */ +struct pci_error_handlers +{ + /* PCI bus error detected on this device */ + pci_ers_result_t (*error_detected)(struct pci_dev *dev, + enum pci_channel_state error); + + /* MMIO has been re-enabled, but not DMA */ + pci_ers_result_t (*mmio_enabled)(struct pci_dev *dev); + + /* PCI Express link has been reset */ + pci_ers_result_t (*link_reset)(struct pci_dev *dev); + + /* PCI slot has been reset */ + pci_ers_result_t (*slot_reset)(struct pci_dev *dev); + + /* Device driver may resume normal operations */ + void (*resume)(struct pci_dev *dev); +}; + +/* ---------------------------------------------------------------- */ + +struct module; +struct pci_driver { + struct list_head node; + char *name; + const struct pci_device_id *id_table; /* must be non-NULL for probe to be called */ + int (*probe) (struct pci_dev *dev, const struct pci_device_id *id); /* New device inserted */ + void (*remove) (struct pci_dev *dev); /* Device removed (NULL if not a hot-plug capable driver) */ + int (*suspend) (struct pci_dev *dev, pm_message_t state); /* Device suspended */ + int (*suspend_late) (struct pci_dev *dev, pm_message_t state); + int (*resume_early) (struct pci_dev *dev); + int (*resume) (struct pci_dev *dev); /* Device woken up */ + int (*enable_wake) (struct pci_dev *dev, pci_power_t state, int enable); /* Enable wake event */ + void (*shutdown) (struct pci_dev *dev); + + struct pci_error_handlers *err_handler; + struct device_driver driver; + struct pci_dynids dynids; + + int multithread_probe; +}; + +#define to_pci_driver(drv) container_of(drv,struct pci_driver, driver) + +/** + * PCI_DEVICE - macro used to describe a specific pci device + * @vend: the 16 bit PCI Vendor ID + * @dev: the 16 bit PCI Device ID + * + * This macro is used to create a struct pci_device_id that matches a + * specific device. The subvendor and subdevice fields will be set to + * PCI_ANY_ID. + */ +#define PCI_DEVICE(vend,dev) \ + .vendor = (vend), .device = (dev), \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID + +/** + * PCI_DEVICE_CLASS - macro used to describe a specific pci device class + * @dev_class: the class, subclass, prog-if triple for this device + * @dev_class_mask: the class mask for this device + * + * This macro is used to create a struct pci_device_id that matches a + * specific PCI class. The vendor, device, subvendor, and subdevice + * fields will be set to PCI_ANY_ID. + */ +#define PCI_DEVICE_CLASS(dev_class,dev_class_mask) \ + .class = (dev_class), .class_mask = (dev_class_mask), \ + .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \ + .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID + +/* + * pci_module_init is obsolete, this stays here till we fix up all usages of it + * in the tree. + */ +#define pci_module_init pci_register_driver + +/* these external functions are only available when PCI support is enabled */ +#ifdef CONFIG_PCI + +extern struct bus_type pci_bus_type; + +/* Do NOT directly access these two variables, unless you are arch specific pci + * code, or pci core code. */ +extern struct list_head pci_root_buses; /* list of all known PCI buses */ +extern struct list_head pci_devices; /* list of all devices */ + +void pcibios_fixup_bus(struct pci_bus *); +int __must_check pcibios_enable_device(struct pci_dev *, int mask); +char *pcibios_setup (char *str); + +/* Used only when drivers/pci/setup.c is used */ +void pcibios_align_resource(void *, struct resource *, resource_size_t, + resource_size_t); +void pcibios_update_irq(struct pci_dev *, int irq); + +/* Generic PCI functions used internally */ + +extern struct pci_bus *pci_find_bus(int domain, int busnr); +void pci_bus_add_devices(struct pci_bus *bus); +struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); +static inline struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata) +{ + struct pci_bus *root_bus; + root_bus = pci_scan_bus_parented(NULL, bus, ops, sysdata); + if (root_bus) + pci_bus_add_devices(root_bus); + return root_bus; +} +struct pci_bus *pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata); +struct pci_bus * pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr); +int pci_scan_slot(struct pci_bus *bus, int devfn); +struct pci_dev * pci_scan_single_device(struct pci_bus *bus, int devfn); +void pci_device_add(struct pci_dev *dev, struct pci_bus *bus); +unsigned int pci_scan_child_bus(struct pci_bus *bus); +int __must_check pci_bus_add_device(struct pci_dev *dev); +void pci_read_bridge_bases(struct pci_bus *child); +struct resource *pci_find_parent_resource(const struct pci_dev *dev, struct resource *res); +int pci_get_interrupt_pin(struct pci_dev *dev, struct pci_dev **bridge); +extern struct pci_dev *pci_dev_get(struct pci_dev *dev); +extern void pci_dev_put(struct pci_dev *dev); +extern void pci_remove_bus(struct pci_bus *b); +extern void pci_remove_bus_device(struct pci_dev *dev); +extern void pci_stop_bus_device(struct pci_dev *dev); +void pci_setup_cardbus(struct pci_bus *bus); +extern void pci_sort_breadthfirst(void); + +/* Generic PCI functions exported to card drivers */ + +struct pci_dev *pci_find_device (unsigned int vendor, unsigned int device, const struct pci_dev *from); +struct pci_dev *pci_find_device_reverse (unsigned int vendor, unsigned int device, const struct pci_dev *from); +struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn); +int pci_find_capability (struct pci_dev *dev, int cap); +int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap); +int pci_find_ext_capability (struct pci_dev *dev, int cap); +struct pci_bus *pci_find_next_bus(const struct pci_bus *from); + +struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device, + struct pci_dev *from); +struct pci_dev *pci_get_device_reverse(unsigned int vendor, unsigned int device, + struct pci_dev *from); + +struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, + unsigned int ss_vendor, unsigned int ss_device, + struct pci_dev *from); +struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn); +struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn); +struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from); +int pci_dev_present(const struct pci_device_id *ids); + +int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val); +int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val); +int pci_bus_read_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 *val); +int pci_bus_write_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 val); +int pci_bus_write_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 val); +int pci_bus_write_config_dword (struct pci_bus *bus, unsigned int devfn, int where, u32 val); + +static inline int pci_read_config_byte(struct pci_dev *dev, int where, u8 *val) +{ + return pci_bus_read_config_byte (dev->bus, dev->devfn, where, val); +} +static inline int pci_read_config_word(struct pci_dev *dev, int where, u16 *val) +{ + return pci_bus_read_config_word (dev->bus, dev->devfn, where, val); +} +static inline int pci_read_config_dword(struct pci_dev *dev, int where, u32 *val) +{ + return pci_bus_read_config_dword (dev->bus, dev->devfn, where, val); +} +static inline int pci_write_config_byte(struct pci_dev *dev, int where, u8 val) +{ + return pci_bus_write_config_byte (dev->bus, dev->devfn, where, val); +} +static inline int pci_write_config_word(struct pci_dev *dev, int where, u16 val) +{ + return pci_bus_write_config_word (dev->bus, dev->devfn, where, val); +} +static inline int pci_write_config_dword(struct pci_dev *dev, int where, u32 val) +{ + return pci_bus_write_config_dword (dev->bus, dev->devfn, where, val); +} + +int __must_check pci_enable_device(struct pci_dev *dev); +int __must_check pci_enable_device_bars(struct pci_dev *dev, int mask); +void pci_disable_device(struct pci_dev *dev); +void pci_set_master(struct pci_dev *dev); +#define HAVE_PCI_SET_MWI +int __must_check pci_set_mwi(struct pci_dev *dev); +void pci_clear_mwi(struct pci_dev *dev); +void pci_intx(struct pci_dev *dev, int enable); +int pci_set_dma_mask(struct pci_dev *dev, u64 mask); +int pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask); +void pci_update_resource(struct pci_dev *dev, struct resource *res, int resno); +int __must_check pci_assign_resource(struct pci_dev *dev, int i); +int __must_check pci_assign_resource_fixed(struct pci_dev *dev, int i); +void pci_restore_bars(struct pci_dev *dev); + +/* ROM control related routines */ +void __iomem __must_check *pci_map_rom(struct pci_dev *pdev, size_t *size); +void __iomem __must_check *pci_map_rom_copy(struct pci_dev *pdev, size_t *size); +void pci_unmap_rom(struct pci_dev *pdev, void __iomem *rom); +void pci_remove_rom(struct pci_dev *pdev); + +/* Power management related routines */ +int pci_save_state(struct pci_dev *dev); +int pci_restore_state(struct pci_dev *dev); +int pci_set_power_state(struct pci_dev *dev, pci_power_t state); +pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); +int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable); + +/* Helper functions for low-level code (drivers/pci/setup-[bus,res].c) */ +void pci_bus_assign_resources(struct pci_bus *bus); +void pci_bus_size_bridges(struct pci_bus *bus); +int pci_claim_resource(struct pci_dev *, int); +void pci_assign_unassigned_resources(void); +void pdev_enable_device(struct pci_dev *); +void pdev_sort_resources(struct pci_dev *, struct resource_list *); +void pci_fixup_irqs(u8 (*)(struct pci_dev *, u8 *), + int (*)(struct pci_dev *, u8, u8)); +#define HAVE_PCI_REQ_REGIONS 2 +int __must_check pci_request_regions(struct pci_dev *, const char *); +void pci_release_regions(struct pci_dev *); +int __must_check pci_request_region(struct pci_dev *, int, const char *); +void pci_release_region(struct pci_dev *, int); + +/* drivers/pci/bus.c */ +int __must_check pci_bus_alloc_resource(struct pci_bus *bus, + struct resource *res, resource_size_t size, + resource_size_t align, resource_size_t min, + unsigned int type_mask, + void (*alignf)(void *, struct resource *, + resource_size_t, resource_size_t), + void *alignf_data); +void pci_enable_bridges(struct pci_bus *bus); + +/* Proper probing supporting hot-pluggable devices */ +int __must_check __pci_register_driver(struct pci_driver *, struct module *); +static inline int __must_check pci_register_driver(struct pci_driver *driver) +{ + return __pci_register_driver(driver, THIS_MODULE); +} + +void pci_unregister_driver(struct pci_driver *); +void pci_remove_behind_bridge(struct pci_dev *); +struct pci_driver *pci_dev_driver(const struct pci_dev *); +const struct pci_device_id *pci_match_device(struct pci_driver *drv, struct pci_dev *dev); +const struct pci_device_id *pci_match_id(const struct pci_device_id *ids, struct pci_dev *dev); +int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass); + +void pci_walk_bus(struct pci_bus *top, void (*cb)(struct pci_dev *, void *), + void *userdata); +int pci_cfg_space_size(struct pci_dev *dev); +unsigned char pci_bus_max_busnr(struct pci_bus* bus); + +/* kmem_cache style wrapper around pci_alloc_consistent() */ + +#include + +#define pci_pool dma_pool +#define pci_pool_create(name, pdev, size, align, allocation) \ + dma_pool_create(name, &pdev->dev, size, align, allocation) +#define pci_pool_destroy(pool) dma_pool_destroy(pool) +#define pci_pool_alloc(pool, flags, handle) dma_pool_alloc(pool, flags, handle) +#define pci_pool_free(pool, vaddr, addr) dma_pool_free(pool, vaddr, addr) + +enum pci_dma_burst_strategy { + PCI_DMA_BURST_INFINITY, /* make bursts as large as possible, + strategy_parameter is N/A */ + PCI_DMA_BURST_BOUNDARY, /* disconnect at every strategy_parameter + byte boundaries */ + PCI_DMA_BURST_MULTIPLE, /* disconnect at some multiple of + strategy_parameter byte boundaries */ +}; + +#if defined(CONFIG_ISA) || defined(CONFIG_EISA) +extern struct pci_dev *isa_bridge; +#endif + +struct msix_entry { + u16 vector; /* kernel uses to write allocated vector */ + u16 entry; /* driver uses to specify entry, OS writes */ +}; + + +#ifndef CONFIG_PCI_MSI +static inline void pci_scan_msi_device(struct pci_dev *dev) {} +static inline int pci_enable_msi(struct pci_dev *dev) {return -1;} +static inline void pci_disable_msi(struct pci_dev *dev) {} +static inline int pci_enable_msix(struct pci_dev* dev, + struct msix_entry *entries, int nvec) {return -1;} +static inline void pci_disable_msix(struct pci_dev *dev) {} +static inline void msi_remove_pci_irq_vectors(struct pci_dev *dev) {} +#else +extern void pci_scan_msi_device(struct pci_dev *dev); +extern int pci_enable_msi(struct pci_dev *dev); +extern void pci_disable_msi(struct pci_dev *dev); +extern int pci_enable_msix(struct pci_dev* dev, + struct msix_entry *entries, int nvec); +extern void pci_disable_msix(struct pci_dev *dev); +extern void msi_remove_pci_irq_vectors(struct pci_dev *dev); +#endif + +#ifdef CONFIG_HT_IRQ +/* The functions a driver should call */ +int ht_create_irq(struct pci_dev *dev, int idx); +void ht_destroy_irq(unsigned int irq); +#endif /* CONFIG_HT_IRQ */ + +extern void pci_block_user_cfg_access(struct pci_dev *dev); +extern void pci_unblock_user_cfg_access(struct pci_dev *dev); + +/* + * PCI domain support. Sometimes called PCI segment (eg by ACPI), + * a PCI domain is defined to be a set of PCI busses which share + * configuration space. + */ +#ifndef CONFIG_PCI_DOMAINS +static inline int pci_domain_nr(struct pci_bus *bus) { return 0; } +static inline int pci_proc_domain(struct pci_bus *bus) +{ + return 0; +} +#endif + +#else /* CONFIG_PCI is not enabled */ + +/* + * If the system does not have PCI, clearly these return errors. Define + * these as simple inline functions to avoid hair in drivers. + */ + +#define _PCI_NOP(o,s,t) \ + static inline int pci_##o##_config_##s (struct pci_dev *dev, int where, t val) \ + { return PCIBIOS_FUNC_NOT_SUPPORTED; } +#define _PCI_NOP_ALL(o,x) _PCI_NOP(o,byte,u8 x) \ + _PCI_NOP(o,word,u16 x) \ + _PCI_NOP(o,dword,u32 x) +_PCI_NOP_ALL(read, *) +_PCI_NOP_ALL(write,) + +static inline struct pci_dev *pci_find_device(unsigned int vendor, unsigned int device, const struct pci_dev *from) +{ return NULL; } + +static inline struct pci_dev *pci_find_slot(unsigned int bus, unsigned int devfn) +{ return NULL; } + +static inline struct pci_dev *pci_get_device(unsigned int vendor, + unsigned int device, struct pci_dev *from) +{ return NULL; } + +static inline struct pci_dev *pci_get_device_reverse(unsigned int vendor, + unsigned int device, struct pci_dev *from) +{ return NULL; } + +static inline struct pci_dev *pci_get_subsys (unsigned int vendor, unsigned int device, +unsigned int ss_vendor, unsigned int ss_device, struct pci_dev *from) +{ return NULL; } + +static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from) +{ return NULL; } + +#define pci_dev_present(ids) (0) +#define pci_dev_put(dev) do { } while (0) + +static inline void pci_set_master(struct pci_dev *dev) { } +static inline int pci_enable_device(struct pci_dev *dev) { return -EIO; } +static inline void pci_disable_device(struct pci_dev *dev) { } +static inline int pci_set_dma_mask(struct pci_dev *dev, u64 mask) { return -EIO; } +static inline int pci_assign_resource(struct pci_dev *dev, int i) { return -EBUSY;} +static inline int __pci_register_driver(struct pci_driver *drv, struct module *owner) { return 0;} +static inline int pci_register_driver(struct pci_driver *drv) { return 0;} +static inline void pci_unregister_driver(struct pci_driver *drv) { } +static inline int pci_find_capability (struct pci_dev *dev, int cap) {return 0; } +static inline int pci_find_next_capability (struct pci_dev *dev, u8 post, int cap) { return 0; } +static inline int pci_find_ext_capability (struct pci_dev *dev, int cap) {return 0; } +static inline const struct pci_device_id *pci_match_device(const struct pci_device_id *ids, const struct pci_dev *dev) { return NULL; } + +/* Power management related routines */ +static inline int pci_save_state(struct pci_dev *dev) { return 0; } +static inline int pci_restore_state(struct pci_dev *dev) { return 0; } +static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { return 0; } +static inline pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) { return PCI_D0; } +static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { return 0; } + +#define isa_bridge ((struct pci_dev *)NULL) + +#define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) + +static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } +static inline void pci_unblock_user_cfg_access(struct pci_dev *dev) { } + +#endif /* CONFIG_PCI */ + +/* Include architecture-dependent settings and functions */ + +#include + +/* these helpers provide future and backwards compatibility + * for accessing popular PCI BAR info */ +#define pci_resource_start(dev,bar) ((dev)->resource[(bar)].start) +#define pci_resource_end(dev,bar) ((dev)->resource[(bar)].end) +#define pci_resource_flags(dev,bar) ((dev)->resource[(bar)].flags) +#define pci_resource_len(dev,bar) \ + ((pci_resource_start((dev),(bar)) == 0 && \ + pci_resource_end((dev),(bar)) == \ + pci_resource_start((dev),(bar))) ? 0 : \ + \ + (pci_resource_end((dev),(bar)) - \ + pci_resource_start((dev),(bar)) + 1)) + +/* Similar to the helpers above, these manipulate per-pci_dev + * driver-specific data. They are really just a wrapper around + * the generic device structure functions of these calls. + */ +static inline void *pci_get_drvdata (struct pci_dev *pdev) +{ + return dev_get_drvdata(&pdev->dev); +} + +static inline void pci_set_drvdata (struct pci_dev *pdev, void *data) +{ + dev_set_drvdata(&pdev->dev, data); +} + +/* If you want to know what to call your pci_dev, ask this function. + * Again, it's a wrapper around the generic device. + */ +static inline char *pci_name(struct pci_dev *pdev) +{ + return pdev->dev.bus_id; +} + + +/* Some archs don't want to expose struct resource to userland as-is + * in sysfs and /proc + */ +#ifndef HAVE_ARCH_PCI_RESOURCE_TO_USER +static inline void pci_resource_to_user(const struct pci_dev *dev, int bar, + const struct resource *rsrc, resource_size_t *start, + resource_size_t *end) +{ + *start = rsrc->start; + *end = rsrc->end; +} +#endif /* HAVE_ARCH_PCI_RESOURCE_TO_USER */ + + +/* + * The world is not perfect and supplies us with broken PCI devices. + * For at least a part of these bugs we need a work-around, so both + * generic (drivers/pci/quirks.c) and per-architecture code can define + * fixup hooks to be called for particular buggy devices. + */ + +struct pci_fixup { + u16 vendor, device; /* You can use PCI_ANY_ID here of course */ + void (*hook)(struct pci_dev *dev); +}; + +enum pci_fixup_pass { + pci_fixup_early, /* Before probing BARs */ + pci_fixup_header, /* After reading configuration header */ + pci_fixup_final, /* Final phase of device fixups */ + pci_fixup_enable, /* pci_enable_device() time */ +}; + +/* Anonymous variables would be nice... */ +#define DECLARE_PCI_FIXUP_SECTION(section, name, vendor, device, hook) \ + static const struct pci_fixup __pci_fixup_##name __attribute_used__ \ + __attribute__((__section__(#section))) = { vendor, device, hook }; +#define DECLARE_PCI_FIXUP_EARLY(vendor, device, hook) \ + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_early, \ + vendor##device##hook, vendor, device, hook) +#define DECLARE_PCI_FIXUP_HEADER(vendor, device, hook) \ + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_header, \ + vendor##device##hook, vendor, device, hook) +#define DECLARE_PCI_FIXUP_FINAL(vendor, device, hook) \ + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_final, \ + vendor##device##hook, vendor, device, hook) +#define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \ + DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \ + vendor##device##hook, vendor, device, hook) + + +void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev); + +extern int pci_pci_problems; +#define PCIPCI_FAIL 1 /* No PCI PCI DMA */ +#define PCIPCI_TRITON 2 +#define PCIPCI_NATOMA 4 +#define PCIPCI_VIAETBF 8 +#define PCIPCI_VSFX 16 +#define PCIPCI_ALIMAGIK 32 /* Need low latency setting */ +#define PCIAGP_FAIL 64 /* No PCI to AGP DMA */ + +#endif /* __KERNEL__ */ +#endif /* LINUX_PCI_H */ diff --git a/xen/include/asm-ia64/linux/README.origin b/xen/include/asm-ia64/linux/README.origin index e364b52977..4b1ff51f30 100644 --- a/xen/include/asm-ia64/linux/README.origin +++ b/xen/include/asm-ia64/linux/README.origin @@ -24,3 +24,15 @@ time.h -> linux/include/linux/time.h timex.h -> linux/include/linux/timex.h topology.h -> linux/include/linux/topology.h wait.h -> linux/include/linux/wait.h + +# The files below are from Linux-2.6.19 +completion.h -> linux/include/linux/completion.h +ioport.h -> linux/include/linux/ioport.h +klist.h -> linux/include/linux/klist.h +kref.h -> linux/include/linux/kref.h +mod_devicetable.h -> linux/include/linux/mod_devicetable.h +pci_ids.h -> linux/include/linux/pci_ids.h +pci_regs.h -> linux/include/linux/pci_regs.h +pm.h -> linux/include/linux/pm.h +sysfs.h -> linux/include/linux/sysfs.h + diff --git a/xen/include/asm-ia64/linux/asm/README.origin b/xen/include/asm-ia64/linux/asm/README.origin index 863a538b04..b7228fae33 100644 --- a/xen/include/asm-ia64/linux/asm/README.origin +++ b/xen/include/asm-ia64/linux/asm/README.origin @@ -41,3 +41,6 @@ topology.h -> linux/include/asm-ia64/topology.h unaligned.h -> linux/include/asm-ia64/unaligned.h unistd.h -> linux/include/asm-ia64/unistd.h unwind.h -> linux/include/asm-ia64/unwind.h + +# The files below are from Linux-2.6.19 +machvec_init.h -> linux/include/asm-ia64/machvec_init.h diff --git a/xen/include/asm-ia64/linux/asm/machvec_init.h b/xen/include/asm-ia64/linux/asm/machvec_init.h new file mode 100644 index 0000000000..2d36f6840f --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/machvec_init.h @@ -0,0 +1,32 @@ +#include + +extern ia64_mv_send_ipi_t ia64_send_ipi; +extern ia64_mv_global_tlb_purge_t ia64_global_tlb_purge; +extern ia64_mv_local_vector_to_irq __ia64_local_vector_to_irq; +extern ia64_mv_pci_get_legacy_mem_t ia64_pci_get_legacy_mem; +extern ia64_mv_pci_legacy_read_t ia64_pci_legacy_read; +extern ia64_mv_pci_legacy_write_t ia64_pci_legacy_write; + +extern ia64_mv_inb_t __ia64_inb; +extern ia64_mv_inw_t __ia64_inw; +extern ia64_mv_inl_t __ia64_inl; +extern ia64_mv_outb_t __ia64_outb; +extern ia64_mv_outw_t __ia64_outw; +extern ia64_mv_outl_t __ia64_outl; +extern ia64_mv_mmiowb_t __ia64_mmiowb; +extern ia64_mv_readb_t __ia64_readb; +extern ia64_mv_readw_t __ia64_readw; +extern ia64_mv_readl_t __ia64_readl; +extern ia64_mv_readq_t __ia64_readq; +extern ia64_mv_readb_t __ia64_readb_relaxed; +extern ia64_mv_readw_t __ia64_readw_relaxed; +extern ia64_mv_readl_t __ia64_readl_relaxed; +extern ia64_mv_readq_t __ia64_readq_relaxed; + +#define MACHVEC_HELPER(name) \ + struct ia64_machine_vector machvec_##name __attribute__ ((unused, __section__ (".machvec"))) \ + = MACHVEC_INIT(name); + +#define MACHVEC_DEFINE(name) MACHVEC_HELPER(name) + +MACHVEC_DEFINE(MACHVEC_PLATFORM_NAME) diff --git a/xen/include/asm-ia64/linux/asm/sn/README.origin b/xen/include/asm-ia64/linux/asm/sn/README.origin new file mode 100644 index 0000000000..da44c15c0a --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/README.origin @@ -0,0 +1,23 @@ +# Source files in this directory are identical copies of linux-2.6.19 files: +# +# NOTE: DO NOT commit changes to these files! If a file +# needs to be changed, move it to ../linux-xen and follow +# the instructions in the README there. + +geo.h -> linux/include/asm-ia64/sn/geo.h +klconfig.h -> linux/include/asm-ia64/sn/klconfig.h +l1.h -> linux/include/asm-ia64/sn/l1.h +leds.h -> linux/include/asm-ia64/sn/leds.h +module.h -> linux/include/asm-ia64/sn/module.h +pcibus_provider_defs.h -> linux/include/asm-ia64/sn/pcibus_provider_defs.h +pcidev.h -> linux/include/asm-ia64/sn/pcidev.h +pda.h -> linux/include/asm-ia64/sn/pda.h +pic.h -> linux/include/asm-ia64/sn/pic.h +shub_mmr.h -> linux/include/asm-ia64/sn/shub_mmr.h +shubio.h -> linux/include/asm-ia64/sn/shubio.h +simulator.h -> linux/include/asm-ia64/sn/simulator.h +sn_cpuid.h -> linux/include/asm-ia64/sn/sn_cpuid.h +sn_feature_sets.h -> linux/include/asm-ia64/sn/sn_feature_sets.h +tiocp.h -> linux/include/asm-ia64/sn/tiocp.h +xbow.h -> linux/arch/ia64/sn/include/xtalk/xbow.h +xwidgetdev.h -> linux/arch/ia64/sn/include/xtalk/xwidgetdev.h diff --git a/xen/include/asm-ia64/linux/asm/sn/geo.h b/xen/include/asm-ia64/linux/asm/sn/geo.h new file mode 100644 index 0000000000..f083c94340 --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/geo.h @@ -0,0 +1,132 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef _ASM_IA64_SN_GEO_H +#define _ASM_IA64_SN_GEO_H + +/* The geoid_t implementation below is based loosely on the pcfg_t + implementation in sys/SN/promcfg.h. */ + +/* Type declaractions */ + +/* Size of a geoid_t structure (must be before decl. of geoid_u) */ +#define GEOID_SIZE 8 /* Would 16 be better? The size can + be different on different platforms. */ + +#define MAX_SLOTS 0xf /* slots per module */ +#define MAX_SLABS 0xf /* slabs per slot */ + +typedef unsigned char geo_type_t; + +/* Fields common to all substructures */ +typedef struct geo_common_s { + moduleid_t module; /* The module (box) this h/w lives in */ + geo_type_t type; /* What type of h/w is named by this geoid_t */ + slabid_t slab:4; /* slab (ASIC), 0 .. 15 within slot */ + slotid_t slot:4; /* slot (Blade), 0 .. 15 within module */ +} geo_common_t; + +/* Additional fields for particular types of hardware */ +typedef struct geo_node_s { + geo_common_t common; /* No additional fields needed */ +} geo_node_t; + +typedef struct geo_rtr_s { + geo_common_t common; /* No additional fields needed */ +} geo_rtr_t; + +typedef struct geo_iocntl_s { + geo_common_t common; /* No additional fields needed */ +} geo_iocntl_t; + +typedef struct geo_pcicard_s { + geo_iocntl_t common; + char bus; /* Bus/widget number */ + char slot; /* PCI slot number */ +} geo_pcicard_t; + +/* Subcomponents of a node */ +typedef struct geo_cpu_s { + geo_node_t node; + char slice; /* Which CPU on the node */ +} geo_cpu_t; + +typedef struct geo_mem_s { + geo_node_t node; + char membus; /* The memory bus on the node */ + char memslot; /* The memory slot on the bus */ +} geo_mem_t; + + +typedef union geoid_u { + geo_common_t common; + geo_node_t node; + geo_iocntl_t iocntl; + geo_pcicard_t pcicard; + geo_rtr_t rtr; + geo_cpu_t cpu; + geo_mem_t mem; + char padsize[GEOID_SIZE]; +} geoid_t; + + +/* Preprocessor macros */ + +#define GEO_MAX_LEN 48 /* max. formatted length, plus some pad: + module/001c07/slab/5/node/memory/2/slot/4 */ + +/* Values for geo_type_t */ +#define GEO_TYPE_INVALID 0 +#define GEO_TYPE_MODULE 1 +#define GEO_TYPE_NODE 2 +#define GEO_TYPE_RTR 3 +#define GEO_TYPE_IOCNTL 4 +#define GEO_TYPE_IOCARD 5 +#define GEO_TYPE_CPU 6 +#define GEO_TYPE_MEM 7 +#define GEO_TYPE_MAX (GEO_TYPE_MEM+1) + +/* Parameter for hwcfg_format_geoid_compt() */ +#define GEO_COMPT_MODULE 1 +#define GEO_COMPT_SLAB 2 +#define GEO_COMPT_IOBUS 3 +#define GEO_COMPT_IOSLOT 4 +#define GEO_COMPT_CPU 5 +#define GEO_COMPT_MEMBUS 6 +#define GEO_COMPT_MEMSLOT 7 + +#define GEO_INVALID_STR "" + +#define INVALID_NASID ((nasid_t)-1) +#define INVALID_CNODEID ((cnodeid_t)-1) +#define INVALID_PNODEID ((pnodeid_t)-1) +#define INVALID_SLAB (slabid_t)-1 +#define INVALID_SLOT (slotid_t)-1 +#define INVALID_MODULE ((moduleid_t)-1) + +static inline slabid_t geo_slab(geoid_t g) +{ + return (g.common.type == GEO_TYPE_INVALID) ? + INVALID_SLAB : g.common.slab; +} + +static inline slotid_t geo_slot(geoid_t g) +{ + return (g.common.type == GEO_TYPE_INVALID) ? + INVALID_SLOT : g.common.slot; +} + +static inline moduleid_t geo_module(geoid_t g) +{ + return (g.common.type == GEO_TYPE_INVALID) ? + INVALID_MODULE : g.common.module; +} + +extern geoid_t cnodeid_get_geoid(cnodeid_t cnode); + +#endif /* _ASM_IA64_SN_GEO_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/klconfig.h b/xen/include/asm-ia64/linux/asm/sn/klconfig.h new file mode 100644 index 0000000000..bcbf209d63 --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/klconfig.h @@ -0,0 +1,246 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Derived from IRIX . + * + * Copyright (C) 1992-1997,1999,2001-2004 Silicon Graphics, Inc. All Rights Reserved. + * Copyright (C) 1999 by Ralf Baechle + */ +#ifndef _ASM_IA64_SN_KLCONFIG_H +#define _ASM_IA64_SN_KLCONFIG_H + +/* + * The KLCONFIG structures store info about the various BOARDs found + * during Hardware Discovery. In addition, it stores info about the + * components found on the BOARDs. + */ + +typedef s32 klconf_off_t; + + +/* Functions/macros needed to use this structure */ + +typedef struct kl_config_hdr { + char pad[20]; + klconf_off_t ch_board_info; /* the link list of boards */ + char pad0[88]; +} kl_config_hdr_t; + + +#define NODE_OFFSET_TO_LBOARD(nasid,off) (lboard_t*)(GLOBAL_CAC_ADDR((nasid), (off))) + +/* + * The KLCONFIG area is organized as a LINKED LIST of BOARDs. A BOARD + * can be either 'LOCAL' or 'REMOTE'. LOCAL means it is attached to + * the LOCAL/current NODE. REMOTE means it is attached to a different + * node.(TBD - Need a way to treat ROUTER boards.) + * + * There are 2 different structures to represent these boards - + * lboard - Local board, rboard - remote board. These 2 structures + * can be arbitrarily mixed in the LINKED LIST of BOARDs. (Refer + * Figure below). The first byte of the rboard or lboard structure + * is used to find out its type - no unions are used. + * If it is a lboard, then the config info of this board will be found + * on the local node. (LOCAL NODE BASE + offset value gives pointer to + * the structure. + * If it is a rboard, the local structure contains the node number + * and the offset of the beginning of the LINKED LIST on the remote node. + * The details of the hardware on a remote node can be built locally, + * if required, by reading the LINKED LIST on the remote node and + * ignoring all the rboards on that node. + * + * The local node uses the REMOTE NODE NUMBER + OFFSET to point to the + * First board info on the remote node. The remote node list is + * traversed as the local list, using the REMOTE BASE ADDRESS and not + * the local base address and ignoring all rboard values. + * + * + KLCONFIG + + +------------+ +------------+ +------------+ +------------+ + | lboard | +-->| lboard | +-->| rboard | +-->| lboard | + +------------+ | +------------+ | +------------+ | +------------+ + | board info | | | board info | | |errinfo,bptr| | | board info | + +------------+ | +------------+ | +------------+ | +------------+ + | offset |--+ | offset |--+ | offset |--+ |offset=NULL | + +------------+ +------------+ +------------+ +------------+ + + + +------------+ + | board info | + +------------+ +--------------------------------+ + | compt 1 |------>| type, rev, diaginfo, size ... | (CPU) + +------------+ +--------------------------------+ + | compt 2 |--+ + +------------+ | +--------------------------------+ + | ... | +--->| type, rev, diaginfo, size ... | (MEM_BANK) + +------------+ +--------------------------------+ + | errinfo |--+ + +------------+ | +--------------------------------+ + +--->|r/l brd errinfo,compt err flags | + +--------------------------------+ + + * + * Each BOARD consists of COMPONENTs and the BOARD structure has + * pointers (offsets) to its COMPONENT structure. + * The COMPONENT structure has version info, size and speed info, revision, + * error info and the NIC info. This structure can accommodate any + * BOARD with arbitrary COMPONENT composition. + * + * The ERRORINFO part of each BOARD has error information + * that describes errors about the BOARD itself. It also has flags to + * indicate the COMPONENT(s) on the board that have errors. The error + * information specific to the COMPONENT is present in the respective + * COMPONENT structure. + * + * The ERRORINFO structure is also treated like a COMPONENT, ie. the + * BOARD has pointers(offset) to the ERRORINFO structure. The rboard + * structure also has a pointer to the ERRORINFO structure. This is + * the place to store ERRORINFO about a REMOTE NODE, if the HUB on + * that NODE is not working or if the REMOTE MEMORY is BAD. In cases where + * only the CPU of the REMOTE NODE is disabled, the ERRORINFO pointer can + * be a NODE NUMBER, REMOTE OFFSET combination, pointing to error info + * which is present on the REMOTE NODE.(TBD) + * REMOTE ERRINFO can be stored on any of the nearest nodes + * or on all the nearest nodes.(TBD) + * Like BOARD structures, REMOTE ERRINFO structures can be built locally + * using the rboard errinfo pointer. + * + * In order to get useful information from this Data organization, a set of + * interface routines are provided (TBD). The important thing to remember while + * manipulating the structures, is that, the NODE number information should + * be used. If the NODE is non-zero (remote) then each offset should + * be added to the REMOTE BASE ADDR else it should be added to the LOCAL BASE ADDR. + * This includes offsets for BOARDS, COMPONENTS and ERRORINFO. + * + * Note that these structures do not provide much info about connectivity. + * That info will be part of HWGRAPH, which is an extension of the cfg_t + * data structure. (ref IP27prom/cfg.h) It has to be extended to include + * the IO part of the Network(TBD). + * + * The data structures below define the above concepts. + */ + + +/* + * BOARD classes + */ + +#define KLCLASS_MASK 0xf0 +#define KLCLASS_NONE 0x00 +#define KLCLASS_NODE 0x10 /* CPU, Memory and HUB board */ +#define KLCLASS_CPU KLCLASS_NODE +#define KLCLASS_IO 0x20 /* BaseIO, 4 ch SCSI, ethernet, FDDI + and the non-graphics widget boards */ +#define KLCLASS_ROUTER 0x30 /* Router board */ +#define KLCLASS_MIDPLANE 0x40 /* We need to treat this as a board + so that we can record error info */ +#define KLCLASS_IOBRICK 0x70 /* IP35 iobrick */ +#define KLCLASS_MAX 8 /* Bump this if a new CLASS is added */ + +#define KLCLASS(_x) ((_x) & KLCLASS_MASK) + + +/* + * board types + */ + +#define KLTYPE_MASK 0x0f +#define KLTYPE(_x) ((_x) & KLTYPE_MASK) + +#define KLTYPE_SNIA (KLCLASS_CPU | 0x1) +#define KLTYPE_TIO (KLCLASS_CPU | 0x2) + +#define KLTYPE_ROUTER (KLCLASS_ROUTER | 0x1) +#define KLTYPE_META_ROUTER (KLCLASS_ROUTER | 0x3) +#define KLTYPE_REPEATER_ROUTER (KLCLASS_ROUTER | 0x4) + +#define KLTYPE_IOBRICK_XBOW (KLCLASS_MIDPLANE | 0x2) + +#define KLTYPE_IOBRICK (KLCLASS_IOBRICK | 0x0) +#define KLTYPE_NBRICK (KLCLASS_IOBRICK | 0x4) +#define KLTYPE_PXBRICK (KLCLASS_IOBRICK | 0x6) +#define KLTYPE_IXBRICK (KLCLASS_IOBRICK | 0x7) +#define KLTYPE_CGBRICK (KLCLASS_IOBRICK | 0x8) +#define KLTYPE_OPUSBRICK (KLCLASS_IOBRICK | 0x9) +#define KLTYPE_SABRICK (KLCLASS_IOBRICK | 0xa) +#define KLTYPE_IABRICK (KLCLASS_IOBRICK | 0xb) +#define KLTYPE_PABRICK (KLCLASS_IOBRICK | 0xc) +#define KLTYPE_GABRICK (KLCLASS_IOBRICK | 0xd) + + +/* + * board structures + */ + +#define MAX_COMPTS_PER_BRD 24 + +typedef struct lboard_s { + klconf_off_t brd_next_any; /* Next BOARD */ + unsigned char struct_type; /* type of structure, local or remote */ + unsigned char brd_type; /* type+class */ + unsigned char brd_sversion; /* version of this structure */ + unsigned char brd_brevision; /* board revision */ + unsigned char brd_promver; /* board prom version, if any */ + unsigned char brd_flags; /* Enabled, Disabled etc */ + unsigned char brd_slot; /* slot number */ + unsigned short brd_debugsw; /* Debug switches */ + geoid_t brd_geoid; /* geo id */ + partid_t brd_partition; /* Partition number */ + unsigned short brd_diagval; /* diagnostic value */ + unsigned short brd_diagparm; /* diagnostic parameter */ + unsigned char brd_inventory; /* inventory history */ + unsigned char brd_numcompts; /* Number of components */ + nic_t brd_nic; /* Number in CAN */ + nasid_t brd_nasid; /* passed parameter */ + klconf_off_t brd_compts[MAX_COMPTS_PER_BRD]; /* pointers to COMPONENTS */ + klconf_off_t brd_errinfo; /* Board's error information */ + struct lboard_s *brd_parent; /* Logical parent for this brd */ + char pad0[4]; + unsigned char brd_confidence; /* confidence that the board is bad */ + nasid_t brd_owner; /* who owns this board */ + unsigned char brd_nic_flags; /* To handle 8 more NICs */ + char pad1[24]; /* future expansion */ + char brd_name[32]; + nasid_t brd_next_same_host; /* host of next brd w/same nasid */ + klconf_off_t brd_next_same; /* Next BOARD with same nasid */ +} lboard_t; + +/* + * Generic info structure. This stores common info about a + * component. + */ + +typedef struct klinfo_s { /* Generic info */ + unsigned char struct_type; /* type of this structure */ + unsigned char struct_version; /* version of this structure */ + unsigned char flags; /* Enabled, disabled etc */ + unsigned char revision; /* component revision */ + unsigned short diagval; /* result of diagnostics */ + unsigned short diagparm; /* diagnostic parameter */ + unsigned char inventory; /* previous inventory status */ + unsigned short partid; /* widget part number */ + nic_t nic; /* MUst be aligned properly */ + unsigned char physid; /* physical id of component */ + unsigned int virtid; /* virtual id as seen by system */ + unsigned char widid; /* Widget id - if applicable */ + nasid_t nasid; /* node number - from parent */ + char pad1; /* pad out structure. */ + char pad2; /* pad out structure. */ + void *data; + klconf_off_t errinfo; /* component specific errors */ + unsigned short pad3; /* pci fields have moved over to */ + unsigned short pad4; /* klbri_t */ +} klinfo_t ; + + +static inline lboard_t *find_lboard_next(lboard_t * brd) +{ + if (brd && brd->brd_next_any) + return NODE_OFFSET_TO_LBOARD(NASID_GET(brd), brd->brd_next_any); + return NULL; +} + +#endif /* _ASM_IA64_SN_KLCONFIG_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/l1.h b/xen/include/asm-ia64/linux/asm/sn/l1.h new file mode 100644 index 0000000000..344bf44bb3 --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/l1.h @@ -0,0 +1,51 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992-1997,2000-2004 Silicon Graphics, Inc. All Rights Reserved. + */ + +#ifndef _ASM_IA64_SN_L1_H +#define _ASM_IA64_SN_L1_H + +/* brick type response codes */ +#define L1_BRICKTYPE_PX 0x23 /* # */ +#define L1_BRICKTYPE_PE 0x25 /* % */ +#define L1_BRICKTYPE_N_p0 0x26 /* & */ +#define L1_BRICKTYPE_IP45 0x34 /* 4 */ +#define L1_BRICKTYPE_IP41 0x35 /* 5 */ +#define L1_BRICKTYPE_TWISTER 0x36 /* 6 */ /* IP53 & ROUTER */ +#define L1_BRICKTYPE_IX 0x3d /* = */ +#define L1_BRICKTYPE_IP34 0x61 /* a */ +#define L1_BRICKTYPE_GA 0x62 /* b */ +#define L1_BRICKTYPE_C 0x63 /* c */ +#define L1_BRICKTYPE_OPUS_TIO 0x66 /* f */ +#define L1_BRICKTYPE_I 0x69 /* i */ +#define L1_BRICKTYPE_N 0x6e /* n */ +#define L1_BRICKTYPE_OPUS 0x6f /* o */ +#define L1_BRICKTYPE_P 0x70 /* p */ +#define L1_BRICKTYPE_R 0x72 /* r */ +#define L1_BRICKTYPE_CHI_CG 0x76 /* v */ +#define L1_BRICKTYPE_X 0x78 /* x */ +#define L1_BRICKTYPE_X2 0x79 /* y */ +#define L1_BRICKTYPE_SA 0x5e /* ^ */ +#define L1_BRICKTYPE_PA 0x6a /* j */ +#define L1_BRICKTYPE_IA 0x6b /* k */ +#define L1_BRICKTYPE_ATHENA 0x2b /* + */ +#define L1_BRICKTYPE_DAYTONA 0x7a /* z */ +#define L1_BRICKTYPE_1932 0x2c /* . */ +#define L1_BRICKTYPE_191010 0x2e /* , */ + +/* board type response codes */ +#define L1_BOARDTYPE_IP69 0x0100 /* CA */ +#define L1_BOARDTYPE_IP63 0x0200 /* CB */ +#define L1_BOARDTYPE_BASEIO 0x0300 /* IB */ +#define L1_BOARDTYPE_PCIE2SLOT 0x0400 /* IC */ +#define L1_BOARDTYPE_PCIX3SLOT 0x0500 /* ID */ +#define L1_BOARDTYPE_PCIXPCIE4SLOT 0x0600 /* IE */ +#define L1_BOARDTYPE_ABACUS 0x0700 /* AB */ +#define L1_BOARDTYPE_DAYTONA 0x0800 /* AD */ +#define L1_BOARDTYPE_INVAL (-1) /* invalid brick type */ + +#endif /* _ASM_IA64_SN_L1_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/leds.h b/xen/include/asm-ia64/linux/asm/sn/leds.h new file mode 100644 index 0000000000..66cf8c4d92 --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/leds.h @@ -0,0 +1,33 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved. + */ +#ifndef _ASM_IA64_SN_LEDS_H +#define _ASM_IA64_SN_LEDS_H + +#include +#include +#include + +#define LED0 (LOCAL_MMR_ADDR(SH_REAL_JUNK_BUS_LED0)) +#define LED_CPU_SHIFT 16 + +#define LED_CPU_HEARTBEAT 0x01 +#define LED_CPU_ACTIVITY 0x02 +#define LED_ALWAYS_SET 0x00 + +/* + * Basic macros for flashing the LEDS on an SGI SN. + */ + +static __inline__ void +set_led_bits(u8 value, u8 mask) +{ + pda->led_state = (pda->led_state & ~mask) | (value & mask); + *pda->led_address = (short) pda->led_state; +} + +#endif /* _ASM_IA64_SN_LEDS_H */ + diff --git a/xen/include/asm-ia64/linux/asm/sn/module.h b/xen/include/asm-ia64/linux/asm/sn/module.h new file mode 100644 index 0000000000..734e980ece --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/module.h @@ -0,0 +1,127 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2004 Silicon Graphics, Inc. All rights reserved. + */ +#ifndef _ASM_IA64_SN_MODULE_H +#define _ASM_IA64_SN_MODULE_H + +/* parameter for format_module_id() */ +#define MODULE_FORMAT_BRIEF 1 +#define MODULE_FORMAT_LONG 2 +#define MODULE_FORMAT_LCD 3 + +/* + * Module id format + * + * 31-16 Rack ID (encoded class, group, number - 16-bit unsigned int) + * 15-8 Brick type (8-bit ascii character) + * 7-0 Bay (brick position in rack (0-63) - 8-bit unsigned int) + * + */ + +/* + * Macros for getting the brick type + */ +#define MODULE_BTYPE_MASK 0xff00 +#define MODULE_BTYPE_SHFT 8 +#define MODULE_GET_BTYPE(_m) (((_m) & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT) +#define MODULE_BT_TO_CHAR(_b) ((char)(_b)) +#define MODULE_GET_BTCHAR(_m) (MODULE_BT_TO_CHAR(MODULE_GET_BTYPE(_m))) + +/* + * Macros for getting the rack ID. + */ +#define MODULE_RACK_MASK 0xffff0000 +#define MODULE_RACK_SHFT 16 +#define MODULE_GET_RACK(_m) (((_m) & MODULE_RACK_MASK) >> MODULE_RACK_SHFT) + +/* + * Macros for getting the brick position + */ +#define MODULE_BPOS_MASK 0x00ff +#define MODULE_BPOS_SHFT 0 +#define MODULE_GET_BPOS(_m) (((_m) & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT) + +/* + * Macros for encoding and decoding rack IDs + * A rack number consists of three parts: + * class (0==CPU/mixed, 1==I/O), group, number + * + * Rack number is stored just as it is displayed on the screen: + * a 3-decimal-digit number. + */ +#define RACK_CLASS_DVDR 100 +#define RACK_GROUP_DVDR 10 +#define RACK_NUM_DVDR 1 + +#define RACK_CREATE_RACKID(_c, _g, _n) ((_c) * RACK_CLASS_DVDR + \ + (_g) * RACK_GROUP_DVDR + (_n) * RACK_NUM_DVDR) + +#define RACK_GET_CLASS(_r) ((_r) / RACK_CLASS_DVDR) +#define RACK_GET_GROUP(_r) (((_r) - RACK_GET_CLASS(_r) * \ + RACK_CLASS_DVDR) / RACK_GROUP_DVDR) +#define RACK_GET_NUM(_r) (((_r) - RACK_GET_CLASS(_r) * \ + RACK_CLASS_DVDR - RACK_GET_GROUP(_r) * \ + RACK_GROUP_DVDR) / RACK_NUM_DVDR) + +/* + * Macros for encoding and decoding rack IDs + * A rack number consists of three parts: + * class 1 bit, 0==CPU/mixed, 1==I/O + * group 2 bits for CPU/mixed, 3 bits for I/O + * number 3 bits for CPU/mixed, 2 bits for I/O (1 based) + */ +#define RACK_GROUP_BITS(_r) (RACK_GET_CLASS(_r) ? 3 : 2) +#define RACK_NUM_BITS(_r) (RACK_GET_CLASS(_r) ? 2 : 3) + +#define RACK_CLASS_MASK(_r) 0x20 +#define RACK_CLASS_SHFT(_r) 5 +#define RACK_ADD_CLASS(_r, _c) \ + ((_r) |= (_c) << RACK_CLASS_SHFT(_r) & RACK_CLASS_MASK(_r)) + +#define RACK_GROUP_SHFT(_r) RACK_NUM_BITS(_r) +#define RACK_GROUP_MASK(_r) \ + ( (((unsigned)1< + +/* + * In ia64, pci_dev->sysdata must be a *pci_controller. To provide access to + * the pcidev_info structs for all devices under a controller, we extend the + * definition of pci_controller, via sn_pci_controller, to include a list + * of pcidev_info. + */ +struct sn_pci_controller { + struct pci_controller pci_controller; + struct list_head pcidev_info; +}; + +#define SN_PCI_CONTROLLER(dev) ((struct sn_pci_controller *) dev->sysdata) + +#define SN_PCIDEV_INFO(dev) sn_pcidev_info_get(dev) + +#define SN_PCIBUS_BUSSOFT_INFO(pci_bus) \ + (struct pcibus_info *)((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data)) +/* + * Given a pci_bus, return the sn pcibus_bussoft struct. Note that + * this only works for root busses, not for busses represented by PPB's. + */ + +#define SN_PCIBUS_BUSSOFT(pci_bus) \ + ((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data)) + +#define SN_PCIBUS_BUSSOFT_INFO(pci_bus) \ + (struct pcibus_info *)((struct pcibus_bussoft *)(PCI_CONTROLLER((pci_bus))->platform_data)) +/* + * Given a struct pci_dev, return the sn pcibus_bussoft struct. Note + * that this is not equivalent to SN_PCIBUS_BUSSOFT(pci_dev->bus) due + * due to possible PPB's in the path. + */ + +#define SN_PCIDEV_BUSSOFT(pci_dev) \ + (SN_PCIDEV_INFO(pci_dev)->pdi_host_pcidev_info->pdi_pcibus_info) + +#define SN_PCIDEV_BUSPROVIDER(pci_dev) \ + (SN_PCIDEV_INFO(pci_dev)->pdi_provider) + +#define PCIIO_BUS_NONE 255 /* bus 255 reserved */ +#define PCIIO_SLOT_NONE 255 +#define PCIIO_FUNC_NONE 255 +#define PCIIO_VENDOR_ID_NONE (-1) + +struct pcidev_info { + u64 pdi_pio_mapped_addr[7]; /* 6 BARs PLUS 1 ROM */ + u64 pdi_slot_host_handle; /* Bus and devfn Host pci_dev */ + + struct pcibus_bussoft *pdi_pcibus_info; /* Kernel common bus soft */ + struct pcidev_info *pdi_host_pcidev_info; /* Kernel Host pci_dev */ + struct pci_dev *pdi_linux_pcidev; /* Kernel pci_dev */ + + struct sn_irq_info *pdi_sn_irq_info; + struct sn_pcibus_provider *pdi_provider; /* sn pci ops */ + struct pci_dev *host_pci_dev; /* host bus link */ + struct list_head pdi_list; /* List of pcidev_info */ +}; + +extern void sn_irq_fixup(struct pci_dev *pci_dev, + struct sn_irq_info *sn_irq_info); +extern void sn_irq_unfixup(struct pci_dev *pci_dev); +extern struct pcidev_info * sn_pcidev_info_get(struct pci_dev *); +extern void sn_pci_controller_fixup(int segment, int busnum, + struct pci_bus *bus); +extern void sn_bus_store_sysdata(struct pci_dev *dev); +extern void sn_bus_free_sysdata(void); +extern void sn_generate_path(struct pci_bus *pci_bus, char *address); +extern void sn_pci_fixup_slot(struct pci_dev *dev); +extern void sn_pci_unfixup_slot(struct pci_dev *dev); +extern void sn_irq_lh_init(void); +#endif /* _ASM_IA64_SN_PCI_PCIDEV_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/pda.h b/xen/include/asm-ia64/linux/asm/sn/pda.h new file mode 100644 index 0000000000..1c5108d44d --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/pda.h @@ -0,0 +1,69 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved. + */ +#ifndef _ASM_IA64_SN_PDA_H +#define _ASM_IA64_SN_PDA_H + +#include +#include +#include + + +/* + * CPU-specific data structure. + * + * One of these structures is allocated for each cpu of a NUMA system. + * + * This structure provides a convenient way of keeping together + * all SN per-cpu data structures. + */ + +typedef struct pda_s { + + /* + * Support for SN LEDs + */ + volatile short *led_address; + u8 led_state; + u8 hb_state; /* supports blinking heartbeat leds */ + unsigned int hb_count; + + unsigned int idle_flag; + + volatile unsigned long *bedrock_rev_id; + volatile unsigned long *pio_write_status_addr; + unsigned long pio_write_status_val; + volatile unsigned long *pio_shub_war_cam_addr; + + unsigned long sn_in_service_ivecs[4]; + int sn_lb_int_war_ticks; + int sn_last_irq; + int sn_first_irq; +} pda_t; + + +#define CACHE_ALIGN(x) (((x) + SMP_CACHE_BYTES-1) & ~(SMP_CACHE_BYTES-1)) + +/* + * PDA + * Per-cpu private data area for each cpu. The PDA is located immediately after + * the IA64 cpu_data area. A full page is allocated for the cp_data area for each + * cpu but only a small amout of the page is actually used. We put the SNIA PDA + * in the same page as the cpu_data area. Note that there is a check in the setup + * code to verify that we don't overflow the page. + * + * Seems like we should should cache-line align the pda so that any changes in the + * size of the cpu_data area don't change cache layout. Should we align to 32, 64, 128 + * or 512 boundary. Each has merits. For now, pick 128 but should be revisited later. + */ +DECLARE_PER_CPU(struct pda_s, pda_percpu); + +#define pda (&__ia64_per_cpu_var(pda_percpu)) + +#define pdacpu(cpu) (&per_cpu(pda_percpu, cpu)) + +#endif /* _ASM_IA64_SN_PDA_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/pic.h b/xen/include/asm-ia64/linux/asm/sn/pic.h new file mode 100644 index 0000000000..5f9da5fd6e --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/pic.h @@ -0,0 +1,261 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved. + */ +#ifndef _ASM_IA64_SN_PCI_PIC_H +#define _ASM_IA64_SN_PCI_PIC_H + +/* + * PIC AS DEVICE ZERO + * ------------------ + * + * PIC handles PCI/X busses. PCI/X requires that the 'bridge' (i.e. PIC) + * be designated as 'device 0'. That is a departure from earlier SGI + * PCI bridges. Because of that we use config space 1 to access the + * config space of the first actual PCI device on the bus. + * Here's what the PIC manual says: + * + * The current PCI-X bus specification now defines that the parent + * hosts bus bridge (PIC for example) must be device 0 on bus 0. PIC + * reduced the total number of devices from 8 to 4 and removed the + * device registers and windows, now only supporting devices 0,1,2, and + * 3. PIC did leave all 8 configuration space windows. The reason was + * there was nothing to gain by removing them. Here in lies the problem. + * The device numbering we do using 0 through 3 is unrelated to the device + * numbering which PCI-X requires in configuration space. In the past we + * correlated Configs pace and our device space 0 <-> 0, 1 <-> 1, etc. + * PCI-X requires we start a 1, not 0 and currently the PX brick + * does associate our: + * + * device 0 with configuration space window 1, + * device 1 with configuration space window 2, + * device 2 with configuration space window 3, + * device 3 with configuration space window 4. + * + * The net effect is that all config space access are off-by-one with + * relation to other per-slot accesses on the PIC. + * Here is a table that shows some of that: + * + * Internal Slot# + * | + * | 0 1 2 3 + * ----------|--------------------------------------- + * config | 0x21000 0x22000 0x23000 0x24000 + * | + * even rrb | 0[0] n/a 1[0] n/a [] == implied even/odd + * | + * odd rrb | n/a 0[1] n/a 1[1] + * | + * int dev | 00 01 10 11 + * | + * ext slot# | 1 2 3 4 + * ----------|--------------------------------------- + */ + +#define PIC_ATE_TARGETID_SHFT 8 +#define PIC_HOST_INTR_ADDR 0x0000FFFFFFFFFFFFUL +#define PIC_PCI64_ATTR_TARG_SHFT 60 + + +/***************************************************************************** + *********************** PIC MMR structure mapping *************************** + *****************************************************************************/ + +/* NOTE: PIC WAR. PV#854697. PIC does not allow writes just to [31:0] + * of a 64-bit register. When writing PIC registers, always write the + * entire 64 bits. + */ + +struct pic { + + /* 0x000000-0x00FFFF -- Local Registers */ + + /* 0x000000-0x000057 -- Standard Widget Configuration */ + u64 p_wid_id; /* 0x000000 */ + u64 p_wid_stat; /* 0x000008 */ + u64 p_wid_err_upper; /* 0x000010 */ + u64 p_wid_err_lower; /* 0x000018 */ + #define p_wid_err p_wid_err_lower + u64 p_wid_control; /* 0x000020 */ + u64 p_wid_req_timeout; /* 0x000028 */ + u64 p_wid_int_upper; /* 0x000030 */ + u64 p_wid_int_lower; /* 0x000038 */ + #define p_wid_int p_wid_int_lower + u64 p_wid_err_cmdword; /* 0x000040 */ + u64 p_wid_llp; /* 0x000048 */ + u64 p_wid_tflush; /* 0x000050 */ + + /* 0x000058-0x00007F -- Bridge-specific Widget Configuration */ + u64 p_wid_aux_err; /* 0x000058 */ + u64 p_wid_resp_upper; /* 0x000060 */ + u64 p_wid_resp_lower; /* 0x000068 */ + #define p_wid_resp p_wid_resp_lower + u64 p_wid_tst_pin_ctrl; /* 0x000070 */ + u64 p_wid_addr_lkerr; /* 0x000078 */ + + /* 0x000080-0x00008F -- PMU & MAP */ + u64 p_dir_map; /* 0x000080 */ + u64 _pad_000088; /* 0x000088 */ + + /* 0x000090-0x00009F -- SSRAM */ + u64 p_map_fault; /* 0x000090 */ + u64 _pad_000098; /* 0x000098 */ + + /* 0x0000A0-0x0000AF -- Arbitration */ + u64 p_arb; /* 0x0000A0 */ + u64 _pad_0000A8; /* 0x0000A8 */ + + /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */ + u64 p_ate_parity_err; /* 0x0000B0 */ + u64 _pad_0000B8; /* 0x0000B8 */ + + /* 0x0000C0-0x0000FF -- PCI/GIO */ + u64 p_bus_timeout; /* 0x0000C0 */ + u64 p_pci_cfg; /* 0x0000C8 */ + u64 p_pci_err_upper; /* 0x0000D0 */ + u64 p_pci_err_lower; /* 0x0000D8 */ + #define p_pci_err p_pci_err_lower + u64 _pad_0000E0[4]; /* 0x0000{E0..F8} */ + + /* 0x000100-0x0001FF -- Interrupt */ + u64 p_int_status; /* 0x000100 */ + u64 p_int_enable; /* 0x000108 */ + u64 p_int_rst_stat; /* 0x000110 */ + u64 p_int_mode; /* 0x000118 */ + u64 p_int_device; /* 0x000120 */ + u64 p_int_host_err; /* 0x000128 */ + u64 p_int_addr[8]; /* 0x0001{30,,,68} */ + u64 p_err_int_view; /* 0x000170 */ + u64 p_mult_int; /* 0x000178 */ + u64 p_force_always[8]; /* 0x0001{80,,,B8} */ + u64 p_force_pin[8]; /* 0x0001{C0,,,F8} */ + + /* 0x000200-0x000298 -- Device */ + u64 p_device[4]; /* 0x0002{00,,,18} */ + u64 _pad_000220[4]; /* 0x0002{20,,,38} */ + u64 p_wr_req_buf[4]; /* 0x0002{40,,,58} */ + u64 _pad_000260[4]; /* 0x0002{60,,,78} */ + u64 p_rrb_map[2]; /* 0x0002{80,,,88} */ + #define p_even_resp p_rrb_map[0] /* 0x000280 */ + #define p_odd_resp p_rrb_map[1] /* 0x000288 */ + u64 p_resp_status; /* 0x000290 */ + u64 p_resp_clear; /* 0x000298 */ + + u64 _pad_0002A0[12]; /* 0x0002{A0..F8} */ + + /* 0x000300-0x0003F8 -- Buffer Address Match Registers */ + struct { + u64 upper; /* 0x0003{00,,,F0} */ + u64 lower; /* 0x0003{08,,,F8} */ + } p_buf_addr_match[16]; + + /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */ + struct { + u64 flush_w_touch; /* 0x000{400,,,5C0} */ + u64 flush_wo_touch; /* 0x000{408,,,5C8} */ + u64 inflight; /* 0x000{410,,,5D0} */ + u64 prefetch; /* 0x000{418,,,5D8} */ + u64 total_pci_retry; /* 0x000{420,,,5E0} */ + u64 max_pci_retry; /* 0x000{428,,,5E8} */ + u64 max_latency; /* 0x000{430,,,5F0} */ + u64 clear_all; /* 0x000{438,,,5F8} */ + } p_buf_count[8]; + + + /* 0x000600-0x0009FF -- PCI/X registers */ + u64 p_pcix_bus_err_addr; /* 0x000600 */ + u64 p_pcix_bus_err_attr; /* 0x000608 */ + u64 p_pcix_bus_err_data; /* 0x000610 */ + u64 p_pcix_pio_split_addr; /* 0x000618 */ + u64 p_pcix_pio_split_attr; /* 0x000620 */ + u64 p_pcix_dma_req_err_attr; /* 0x000628 */ + u64 p_pcix_dma_req_err_addr; /* 0x000630 */ + u64 p_pcix_timeout; /* 0x000638 */ + + u64 _pad_000640[120]; /* 0x000{640,,,9F8} */ + + /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */ + struct { + u64 p_buf_addr; /* 0x000{A00,,,AF0} */ + u64 p_buf_attr; /* 0X000{A08,,,AF8} */ + } p_pcix_read_buf_64[16]; + + struct { + u64 p_buf_addr; /* 0x000{B00,,,BE0} */ + u64 p_buf_attr; /* 0x000{B08,,,BE8} */ + u64 p_buf_valid; /* 0x000{B10,,,BF0} */ + u64 __pad1; /* 0x000{B18,,,BF8} */ + } p_pcix_write_buf_64[8]; + + /* End of Local Registers -- Start of Address Map space */ + + char _pad_000c00[0x010000 - 0x000c00]; + + /* 0x010000-0x011fff -- Internal ATE RAM (Auto Parity Generation) */ + u64 p_int_ate_ram[1024]; /* 0x010000-0x011fff */ + + /* 0x012000-0x013fff -- Internal ATE RAM (Manual Parity Generation) */ + u64 p_int_ate_ram_mp[1024]; /* 0x012000-0x013fff */ + + char _pad_014000[0x18000 - 0x014000]; + + /* 0x18000-0x197F8 -- PIC Write Request Ram */ + u64 p_wr_req_lower[256]; /* 0x18000 - 0x187F8 */ + u64 p_wr_req_upper[256]; /* 0x18800 - 0x18FF8 */ + u64 p_wr_req_parity[256]; /* 0x19000 - 0x197F8 */ + + char _pad_019800[0x20000 - 0x019800]; + + /* 0x020000-0x027FFF -- PCI Device Configuration Spaces */ + union { + u8 c[0x1000 / 1]; /* 0x02{0000,,,7FFF} */ + u16 s[0x1000 / 2]; /* 0x02{0000,,,7FFF} */ + u32 l[0x1000 / 4]; /* 0x02{0000,,,7FFF} */ + u64 d[0x1000 / 8]; /* 0x02{0000,,,7FFF} */ + union { + u8 c[0x100 / 1]; + u16 s[0x100 / 2]; + u32 l[0x100 / 4]; + u64 d[0x100 / 8]; + } f[8]; + } p_type0_cfg_dev[8]; /* 0x02{0000,,,7FFF} */ + + /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */ + union { + u8 c[0x1000 / 1]; /* 0x028000-0x029000 */ + u16 s[0x1000 / 2]; /* 0x028000-0x029000 */ + u32 l[0x1000 / 4]; /* 0x028000-0x029000 */ + u64 d[0x1000 / 8]; /* 0x028000-0x029000 */ + union { + u8 c[0x100 / 1]; + u16 s[0x100 / 2]; + u32 l[0x100 / 4]; + u64 d[0x100 / 8]; + } f[8]; + } p_type1_cfg; /* 0x028000-0x029000 */ + + char _pad_029000[0x030000-0x029000]; + + /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */ + union { + u8 c[8 / 1]; + u16 s[8 / 2]; + u32 l[8 / 4]; + u64 d[8 / 8]; + } p_pci_iack; /* 0x030000-0x030007 */ + + char _pad_030007[0x040000-0x030008]; + + /* 0x040000-0x030007 -- PCIX Special Cycle */ + union { + u8 c[8 / 1]; + u16 s[8 / 2]; + u32 l[8 / 4]; + u64 d[8 / 8]; + } p_pcix_cycle; /* 0x040000-0x040007 */ +}; + +#endif /* _ASM_IA64_SN_PCI_PIC_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/shub_mmr.h b/xen/include/asm-ia64/linux/asm/sn/shub_mmr.h new file mode 100644 index 0000000000..7de1d1d4b7 --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/shub_mmr.h @@ -0,0 +1,502 @@ +/* + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2001-2005 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef _ASM_IA64_SN_SHUB_MMR_H +#define _ASM_IA64_SN_SHUB_MMR_H + +/* ==================================================================== */ +/* Register "SH_IPI_INT" */ +/* SHub Inter-Processor Interrupt Registers */ +/* ==================================================================== */ +#define SH1_IPI_INT __IA64_UL_CONST(0x0000000110000380) +#define SH2_IPI_INT __IA64_UL_CONST(0x0000000010000380) + +/* SH_IPI_INT_TYPE */ +/* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ +#define SH_IPI_INT_TYPE_SHFT 0 +#define SH_IPI_INT_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) + +/* SH_IPI_INT_AGT */ +/* Description: Agent, must be 0 for SHub */ +#define SH_IPI_INT_AGT_SHFT 3 +#define SH_IPI_INT_AGT_MASK __IA64_UL_CONST(0x0000000000000008) + +/* SH_IPI_INT_PID */ +/* Description: Processor ID, same setting as on targeted McKinley */ +#define SH_IPI_INT_PID_SHFT 4 +#define SH_IPI_INT_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) + +/* SH_IPI_INT_BASE */ +/* Description: Optional interrupt vector area, 2MB aligned */ +#define SH_IPI_INT_BASE_SHFT 21 +#define SH_IPI_INT_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) + +/* SH_IPI_INT_IDX */ +/* Description: Targeted McKinley interrupt vector */ +#define SH_IPI_INT_IDX_SHFT 52 +#define SH_IPI_INT_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) + +/* SH_IPI_INT_SEND */ +/* Description: Send Interrupt Message to PI, This generates a puls */ +#define SH_IPI_INT_SEND_SHFT 63 +#define SH_IPI_INT_SEND_MASK __IA64_UL_CONST(0x8000000000000000) + +/* ==================================================================== */ +/* Register "SH_EVENT_OCCURRED" */ +/* SHub Interrupt Event Occurred */ +/* ==================================================================== */ +#define SH1_EVENT_OCCURRED __IA64_UL_CONST(0x0000000110010000) +#define SH1_EVENT_OCCURRED_ALIAS __IA64_UL_CONST(0x0000000110010008) +#define SH2_EVENT_OCCURRED __IA64_UL_CONST(0x0000000010010000) +#define SH2_EVENT_OCCURRED_ALIAS __IA64_UL_CONST(0x0000000010010008) + +/* ==================================================================== */ +/* Register "SH_PI_CAM_CONTROL" */ +/* CRB CAM MMR Access Control */ +/* ==================================================================== */ +#define SH1_PI_CAM_CONTROL __IA64_UL_CONST(0x0000000120050300) + +/* ==================================================================== */ +/* Register "SH_SHUB_ID" */ +/* SHub ID Number */ +/* ==================================================================== */ +#define SH1_SHUB_ID __IA64_UL_CONST(0x0000000110060580) +#define SH1_SHUB_ID_REVISION_SHFT 28 +#define SH1_SHUB_ID_REVISION_MASK __IA64_UL_CONST(0x00000000f0000000) + +/* ==================================================================== */ +/* Register "SH_RTC" */ +/* Real-time Clock */ +/* ==================================================================== */ +#define SH1_RTC __IA64_UL_CONST(0x00000001101c0000) +#define SH2_RTC __IA64_UL_CONST(0x00000002101c0000) +#define SH_RTC_MASK __IA64_UL_CONST(0x007fffffffffffff) + +/* ==================================================================== */ +/* Register "SH_PIO_WRITE_STATUS_0|1" */ +/* PIO Write Status for CPU 0 & 1 */ +/* ==================================================================== */ +#define SH1_PIO_WRITE_STATUS_0 __IA64_UL_CONST(0x0000000120070200) +#define SH1_PIO_WRITE_STATUS_1 __IA64_UL_CONST(0x0000000120070280) +#define SH2_PIO_WRITE_STATUS_0 __IA64_UL_CONST(0x0000000020070200) +#define SH2_PIO_WRITE_STATUS_1 __IA64_UL_CONST(0x0000000020070280) +#define SH2_PIO_WRITE_STATUS_2 __IA64_UL_CONST(0x0000000020070300) +#define SH2_PIO_WRITE_STATUS_3 __IA64_UL_CONST(0x0000000020070380) + +/* SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK */ +/* Description: Deadlock response detected */ +#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_SHFT 1 +#define SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK \ + __IA64_UL_CONST(0x0000000000000002) + +/* SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT */ +/* Description: Count of currently pending PIO writes */ +#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_SHFT 56 +#define SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK \ + __IA64_UL_CONST(0x3f00000000000000) + +/* ==================================================================== */ +/* Register "SH_PIO_WRITE_STATUS_0_ALIAS" */ +/* ==================================================================== */ +#define SH1_PIO_WRITE_STATUS_0_ALIAS __IA64_UL_CONST(0x0000000120070208) +#define SH2_PIO_WRITE_STATUS_0_ALIAS __IA64_UL_CONST(0x0000000020070208) + +/* ==================================================================== */ +/* Register "SH_EVENT_OCCURRED" */ +/* SHub Interrupt Event Occurred */ +/* ==================================================================== */ +/* SH_EVENT_OCCURRED_UART_INT */ +/* Description: Pending Junk Bus UART Interrupt */ +#define SH_EVENT_OCCURRED_UART_INT_SHFT 20 +#define SH_EVENT_OCCURRED_UART_INT_MASK __IA64_UL_CONST(0x0000000000100000) + +/* SH_EVENT_OCCURRED_IPI_INT */ +/* Description: Pending IPI Interrupt */ +#define SH_EVENT_OCCURRED_IPI_INT_SHFT 28 +#define SH_EVENT_OCCURRED_IPI_INT_MASK __IA64_UL_CONST(0x0000000010000000) + +/* SH_EVENT_OCCURRED_II_INT0 */ +/* Description: Pending II 0 Interrupt */ +#define SH_EVENT_OCCURRED_II_INT0_SHFT 29 +#define SH_EVENT_OCCURRED_II_INT0_MASK __IA64_UL_CONST(0x0000000020000000) + +/* SH_EVENT_OCCURRED_II_INT1 */ +/* Description: Pending II 1 Interrupt */ +#define SH_EVENT_OCCURRED_II_INT1_SHFT 30 +#define SH_EVENT_OCCURRED_II_INT1_MASK __IA64_UL_CONST(0x0000000040000000) + +/* SH2_EVENT_OCCURRED_EXTIO_INT2 */ +/* Description: Pending SHUB 2 EXT IO INT2 */ +#define SH2_EVENT_OCCURRED_EXTIO_INT2_SHFT 33 +#define SH2_EVENT_OCCURRED_EXTIO_INT2_MASK __IA64_UL_CONST(0x0000000200000000) + +/* SH2_EVENT_OCCURRED_EXTIO_INT3 */ +/* Description: Pending SHUB 2 EXT IO INT3 */ +#define SH2_EVENT_OCCURRED_EXTIO_INT3_SHFT 34 +#define SH2_EVENT_OCCURRED_EXTIO_INT3_MASK __IA64_UL_CONST(0x0000000400000000) + +#define SH_ALL_INT_MASK \ + (SH_EVENT_OCCURRED_UART_INT_MASK | SH_EVENT_OCCURRED_IPI_INT_MASK | \ + SH_EVENT_OCCURRED_II_INT0_MASK | SH_EVENT_OCCURRED_II_INT1_MASK | \ + SH_EVENT_OCCURRED_II_INT1_MASK | SH2_EVENT_OCCURRED_EXTIO_INT2_MASK | \ + SH2_EVENT_OCCURRED_EXTIO_INT3_MASK) + + +/* ==================================================================== */ +/* LEDS */ +/* ==================================================================== */ +#define SH1_REAL_JUNK_BUS_LED0 0x7fed00000UL +#define SH1_REAL_JUNK_BUS_LED1 0x7fed10000UL +#define SH1_REAL_JUNK_BUS_LED2 0x7fed20000UL +#define SH1_REAL_JUNK_BUS_LED3 0x7fed30000UL + +#define SH2_REAL_JUNK_BUS_LED0 0xf0000000UL +#define SH2_REAL_JUNK_BUS_LED1 0xf0010000UL +#define SH2_REAL_JUNK_BUS_LED2 0xf0020000UL +#define SH2_REAL_JUNK_BUS_LED3 0xf0030000UL + +/* ==================================================================== */ +/* Register "SH1_PTC_0" */ +/* Puge Translation Cache Message Configuration Information */ +/* ==================================================================== */ +#define SH1_PTC_0 __IA64_UL_CONST(0x00000001101a0000) + +/* SH1_PTC_0_A */ +/* Description: Type */ +#define SH1_PTC_0_A_SHFT 0 + +/* SH1_PTC_0_PS */ +/* Description: Page Size */ +#define SH1_PTC_0_PS_SHFT 2 + +/* SH1_PTC_0_RID */ +/* Description: Region ID */ +#define SH1_PTC_0_RID_SHFT 8 + +/* SH1_PTC_0_START */ +/* Description: Start */ +#define SH1_PTC_0_START_SHFT 63 + +/* ==================================================================== */ +/* Register "SH1_PTC_1" */ +/* Puge Translation Cache Message Configuration Information */ +/* ==================================================================== */ +#define SH1_PTC_1 __IA64_UL_CONST(0x00000001101a0080) + +/* SH1_PTC_1_START */ +/* Description: PTC_1 Start */ +#define SH1_PTC_1_START_SHFT 63 + +/* ==================================================================== */ +/* Register "SH2_PTC" */ +/* Puge Translation Cache Message Configuration Information */ +/* ==================================================================== */ +#define SH2_PTC __IA64_UL_CONST(0x0000000170000000) + +/* SH2_PTC_A */ +/* Description: Type */ +#define SH2_PTC_A_SHFT 0 + +/* SH2_PTC_PS */ +/* Description: Page Size */ +#define SH2_PTC_PS_SHFT 2 + +/* SH2_PTC_RID */ +/* Description: Region ID */ +#define SH2_PTC_RID_SHFT 4 + +/* SH2_PTC_START */ +/* Description: Start */ +#define SH2_PTC_START_SHFT 63 + +/* SH2_PTC_ADDR_RID */ +/* Description: Region ID */ +#define SH2_PTC_ADDR_SHFT 4 +#define SH2_PTC_ADDR_MASK __IA64_UL_CONST(0x1ffffffffffff000) + +/* ==================================================================== */ +/* Register "SH_RTC1_INT_CONFIG" */ +/* SHub RTC 1 Interrupt Config Registers */ +/* ==================================================================== */ + +#define SH1_RTC1_INT_CONFIG __IA64_UL_CONST(0x0000000110001480) +#define SH2_RTC1_INT_CONFIG __IA64_UL_CONST(0x0000000010001480) +#define SH_RTC1_INT_CONFIG_MASK __IA64_UL_CONST(0x0ff3ffffffefffff) +#define SH_RTC1_INT_CONFIG_INIT __IA64_UL_CONST(0x0000000000000000) + +/* SH_RTC1_INT_CONFIG_TYPE */ +/* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ +#define SH_RTC1_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC1_INT_CONFIG_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) + +/* SH_RTC1_INT_CONFIG_AGT */ +/* Description: Agent, must be 0 for SHub */ +#define SH_RTC1_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC1_INT_CONFIG_AGT_MASK __IA64_UL_CONST(0x0000000000000008) + +/* SH_RTC1_INT_CONFIG_PID */ +/* Description: Processor ID, same setting as on targeted McKinley */ +#define SH_RTC1_INT_CONFIG_PID_SHFT 4 +#define SH_RTC1_INT_CONFIG_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) + +/* SH_RTC1_INT_CONFIG_BASE */ +/* Description: Optional interrupt vector area, 2MB aligned */ +#define SH_RTC1_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC1_INT_CONFIG_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) + +/* SH_RTC1_INT_CONFIG_IDX */ +/* Description: Targeted McKinley interrupt vector */ +#define SH_RTC1_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC1_INT_CONFIG_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) + +/* ==================================================================== */ +/* Register "SH_RTC1_INT_ENABLE" */ +/* SHub RTC 1 Interrupt Enable Registers */ +/* ==================================================================== */ + +#define SH1_RTC1_INT_ENABLE __IA64_UL_CONST(0x0000000110001500) +#define SH2_RTC1_INT_ENABLE __IA64_UL_CONST(0x0000000010001500) +#define SH_RTC1_INT_ENABLE_MASK __IA64_UL_CONST(0x0000000000000001) +#define SH_RTC1_INT_ENABLE_INIT __IA64_UL_CONST(0x0000000000000000) + +/* SH_RTC1_INT_ENABLE_RTC1_ENABLE */ +/* Description: Enable RTC 1 Interrupt */ +#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_SHFT 0 +#define SH_RTC1_INT_ENABLE_RTC1_ENABLE_MASK \ + __IA64_UL_CONST(0x0000000000000001) + +/* ==================================================================== */ +/* Register "SH_RTC2_INT_CONFIG" */ +/* SHub RTC 2 Interrupt Config Registers */ +/* ==================================================================== */ + +#define SH1_RTC2_INT_CONFIG __IA64_UL_CONST(0x0000000110001580) +#define SH2_RTC2_INT_CONFIG __IA64_UL_CONST(0x0000000010001580) +#define SH_RTC2_INT_CONFIG_MASK __IA64_UL_CONST(0x0ff3ffffffefffff) +#define SH_RTC2_INT_CONFIG_INIT __IA64_UL_CONST(0x0000000000000000) + +/* SH_RTC2_INT_CONFIG_TYPE */ +/* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ +#define SH_RTC2_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC2_INT_CONFIG_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) + +/* SH_RTC2_INT_CONFIG_AGT */ +/* Description: Agent, must be 0 for SHub */ +#define SH_RTC2_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC2_INT_CONFIG_AGT_MASK __IA64_UL_CONST(0x0000000000000008) + +/* SH_RTC2_INT_CONFIG_PID */ +/* Description: Processor ID, same setting as on targeted McKinley */ +#define SH_RTC2_INT_CONFIG_PID_SHFT 4 +#define SH_RTC2_INT_CONFIG_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) + +/* SH_RTC2_INT_CONFIG_BASE */ +/* Description: Optional interrupt vector area, 2MB aligned */ +#define SH_RTC2_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC2_INT_CONFIG_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) + +/* SH_RTC2_INT_CONFIG_IDX */ +/* Description: Targeted McKinley interrupt vector */ +#define SH_RTC2_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC2_INT_CONFIG_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) + +/* ==================================================================== */ +/* Register "SH_RTC2_INT_ENABLE" */ +/* SHub RTC 2 Interrupt Enable Registers */ +/* ==================================================================== */ + +#define SH1_RTC2_INT_ENABLE __IA64_UL_CONST(0x0000000110001600) +#define SH2_RTC2_INT_ENABLE __IA64_UL_CONST(0x0000000010001600) +#define SH_RTC2_INT_ENABLE_MASK __IA64_UL_CONST(0x0000000000000001) +#define SH_RTC2_INT_ENABLE_INIT __IA64_UL_CONST(0x0000000000000000) + +/* SH_RTC2_INT_ENABLE_RTC2_ENABLE */ +/* Description: Enable RTC 2 Interrupt */ +#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_SHFT 0 +#define SH_RTC2_INT_ENABLE_RTC2_ENABLE_MASK \ + __IA64_UL_CONST(0x0000000000000001) + +/* ==================================================================== */ +/* Register "SH_RTC3_INT_CONFIG" */ +/* SHub RTC 3 Interrupt Config Registers */ +/* ==================================================================== */ + +#define SH1_RTC3_INT_CONFIG __IA64_UL_CONST(0x0000000110001680) +#define SH2_RTC3_INT_CONFIG __IA64_UL_CONST(0x0000000010001680) +#define SH_RTC3_INT_CONFIG_MASK __IA64_UL_CONST(0x0ff3ffffffefffff) +#define SH_RTC3_INT_CONFIG_INIT __IA64_UL_CONST(0x0000000000000000) + +/* SH_RTC3_INT_CONFIG_TYPE */ +/* Description: Type of Interrupt: 0=INT, 2=PMI, 4=NMI, 5=INIT */ +#define SH_RTC3_INT_CONFIG_TYPE_SHFT 0 +#define SH_RTC3_INT_CONFIG_TYPE_MASK __IA64_UL_CONST(0x0000000000000007) + +/* SH_RTC3_INT_CONFIG_AGT */ +/* Description: Agent, must be 0 for SHub */ +#define SH_RTC3_INT_CONFIG_AGT_SHFT 3 +#define SH_RTC3_INT_CONFIG_AGT_MASK __IA64_UL_CONST(0x0000000000000008) + +/* SH_RTC3_INT_CONFIG_PID */ +/* Description: Processor ID, same setting as on targeted McKinley */ +#define SH_RTC3_INT_CONFIG_PID_SHFT 4 +#define SH_RTC3_INT_CONFIG_PID_MASK __IA64_UL_CONST(0x00000000000ffff0) + +/* SH_RTC3_INT_CONFIG_BASE */ +/* Description: Optional interrupt vector area, 2MB aligned */ +#define SH_RTC3_INT_CONFIG_BASE_SHFT 21 +#define SH_RTC3_INT_CONFIG_BASE_MASK __IA64_UL_CONST(0x0003ffffffe00000) + +/* SH_RTC3_INT_CONFIG_IDX */ +/* Description: Targeted McKinley interrupt vector */ +#define SH_RTC3_INT_CONFIG_IDX_SHFT 52 +#define SH_RTC3_INT_CONFIG_IDX_MASK __IA64_UL_CONST(0x0ff0000000000000) + +/* ==================================================================== */ +/* Register "SH_RTC3_INT_ENABLE" */ +/* SHub RTC 3 Interrupt Enable Registers */ +/* ==================================================================== */ + +#define SH1_RTC3_INT_ENABLE __IA64_UL_CONST(0x0000000110001700) +#define SH2_RTC3_INT_ENABLE __IA64_UL_CONST(0x0000000010001700) +#define SH_RTC3_INT_ENABLE_MASK __IA64_UL_CONST(0x0000000000000001) +#define SH_RTC3_INT_ENABLE_INIT __IA64_UL_CONST(0x0000000000000000) + +/* SH_RTC3_INT_ENABLE_RTC3_ENABLE */ +/* Description: Enable RTC 3 Interrupt */ +#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_SHFT 0 +#define SH_RTC3_INT_ENABLE_RTC3_ENABLE_MASK \ + __IA64_UL_CONST(0x0000000000000001) + +/* SH_EVENT_OCCURRED_RTC1_INT */ +/* Description: Pending RTC 1 Interrupt */ +#define SH_EVENT_OCCURRED_RTC1_INT_SHFT 24 +#define SH_EVENT_OCCURRED_RTC1_INT_MASK __IA64_UL_CONST(0x0000000001000000) + +/* SH_EVENT_OCCURRED_RTC2_INT */ +/* Description: Pending RTC 2 Interrupt */ +#define SH_EVENT_OCCURRED_RTC2_INT_SHFT 25 +#define SH_EVENT_OCCURRED_RTC2_INT_MASK __IA64_UL_CONST(0x0000000002000000) + +/* SH_EVENT_OCCURRED_RTC3_INT */ +/* Description: Pending RTC 3 Interrupt */ +#define SH_EVENT_OCCURRED_RTC3_INT_SHFT 26 +#define SH_EVENT_OCCURRED_RTC3_INT_MASK __IA64_UL_CONST(0x0000000004000000) + +/* ==================================================================== */ +/* Register "SH_IPI_ACCESS" */ +/* CPU interrupt Access Permission Bits */ +/* ==================================================================== */ + +#define SH1_IPI_ACCESS __IA64_UL_CONST(0x0000000110060480) +#define SH2_IPI_ACCESS0 __IA64_UL_CONST(0x0000000010060c00) +#define SH2_IPI_ACCESS1 __IA64_UL_CONST(0x0000000010060c80) +#define SH2_IPI_ACCESS2 __IA64_UL_CONST(0x0000000010060d00) +#define SH2_IPI_ACCESS3 __IA64_UL_CONST(0x0000000010060d80) + +/* ==================================================================== */ +/* Register "SH_INT_CMPB" */ +/* RTC Compare Value for Processor B */ +/* ==================================================================== */ + +#define SH1_INT_CMPB __IA64_UL_CONST(0x00000001101b0080) +#define SH2_INT_CMPB __IA64_UL_CONST(0x00000000101b0080) +#define SH_INT_CMPB_MASK __IA64_UL_CONST(0x007fffffffffffff) +#define SH_INT_CMPB_INIT __IA64_UL_CONST(0x0000000000000000) + +/* SH_INT_CMPB_REAL_TIME_CMPB */ +/* Description: Real Time Clock Compare */ +#define SH_INT_CMPB_REAL_TIME_CMPB_SHFT 0 +#define SH_INT_CMPB_REAL_TIME_CMPB_MASK __IA64_UL_CONST(0x007fffffffffffff) + +/* ==================================================================== */ +/* Register "SH_INT_CMPC" */ +/* RTC Compare Value for Processor C */ +/* ==================================================================== */ + +#define SH1_INT_CMPC __IA64_UL_CONST(0x00000001101b0100) +#define SH2_INT_CMPC __IA64_UL_CONST(0x00000000101b0100) +#define SH_INT_CMPC_MASK __IA64_UL_CONST(0x007fffffffffffff) +#define SH_INT_CMPC_INIT __IA64_UL_CONST(0x0000000000000000) + +/* SH_INT_CMPC_REAL_TIME_CMPC */ +/* Description: Real Time Clock Compare */ +#define SH_INT_CMPC_REAL_TIME_CMPC_SHFT 0 +#define SH_INT_CMPC_REAL_TIME_CMPC_MASK __IA64_UL_CONST(0x007fffffffffffff) + +/* ==================================================================== */ +/* Register "SH_INT_CMPD" */ +/* RTC Compare Value for Processor D */ +/* ==================================================================== */ + +#define SH1_INT_CMPD __IA64_UL_CONST(0x00000001101b0180) +#define SH2_INT_CMPD __IA64_UL_CONST(0x00000000101b0180) +#define SH_INT_CMPD_MASK __IA64_UL_CONST(0x007fffffffffffff) +#define SH_INT_CMPD_INIT __IA64_UL_CONST(0x0000000000000000) + +/* SH_INT_CMPD_REAL_TIME_CMPD */ +/* Description: Real Time Clock Compare */ +#define SH_INT_CMPD_REAL_TIME_CMPD_SHFT 0 +#define SH_INT_CMPD_REAL_TIME_CMPD_MASK __IA64_UL_CONST(0x007fffffffffffff) + +/* ==================================================================== */ +/* Register "SH_MD_DQLP_MMR_DIR_PRIVEC0" */ +/* privilege vector for acc=0 */ +/* ==================================================================== */ +#define SH1_MD_DQLP_MMR_DIR_PRIVEC0 __IA64_UL_CONST(0x0000000100030300) + +/* ==================================================================== */ +/* Register "SH_MD_DQRP_MMR_DIR_PRIVEC0" */ +/* privilege vector for acc=0 */ +/* ==================================================================== */ +#define SH1_MD_DQRP_MMR_DIR_PRIVEC0 __IA64_UL_CONST(0x0000000100050300) + +/* ==================================================================== */ +/* Some MMRs are functionally identical (or close enough) on both SHUB1 */ +/* and SHUB2 that it makes sense to define a geberic name for the MMR. */ +/* It is acceptible to use (for example) SH_IPI_INT to reference the */ +/* the IPI MMR. The value of SH_IPI_INT is determined at runtime based */ +/* on the type of the SHUB. Do not use these #defines in performance */ +/* critical code or loops - there is a small performance penalty. */ +/* ==================================================================== */ +#define shubmmr(a,b) (is_shub2() ? a##2_##b : a##1_##b) + +#define SH_REAL_JUNK_BUS_LED0 shubmmr(SH, REAL_JUNK_BUS_LED0) +#define SH_IPI_INT shubmmr(SH, IPI_INT) +#define SH_EVENT_OCCURRED shubmmr(SH, EVENT_OCCURRED) +#define SH_EVENT_OCCURRED_ALIAS shubmmr(SH, EVENT_OCCURRED_ALIAS) +#define SH_RTC shubmmr(SH, RTC) +#define SH_RTC1_INT_CONFIG shubmmr(SH, RTC1_INT_CONFIG) +#define SH_RTC1_INT_ENABLE shubmmr(SH, RTC1_INT_ENABLE) +#define SH_RTC2_INT_CONFIG shubmmr(SH, RTC2_INT_CONFIG) +#define SH_RTC2_INT_ENABLE shubmmr(SH, RTC2_INT_ENABLE) +#define SH_RTC3_INT_CONFIG shubmmr(SH, RTC3_INT_CONFIG) +#define SH_RTC3_INT_ENABLE shubmmr(SH, RTC3_INT_ENABLE) +#define SH_INT_CMPB shubmmr(SH, INT_CMPB) +#define SH_INT_CMPC shubmmr(SH, INT_CMPC) +#define SH_INT_CMPD shubmmr(SH, INT_CMPD) + +/* ========================================================================== */ +/* Register "SH2_BT_ENG_CSR_0" */ +/* Engine 0 Control and Status Register */ +/* ========================================================================== */ + +#define SH2_BT_ENG_CSR_0 __IA64_UL_CONST(0x0000000030040000) +#define SH2_BT_ENG_SRC_ADDR_0 __IA64_UL_CONST(0x0000000030040080) +#define SH2_BT_ENG_DEST_ADDR_0 __IA64_UL_CONST(0x0000000030040100) +#define SH2_BT_ENG_NOTIF_ADDR_0 __IA64_UL_CONST(0x0000000030040180) + +/* ========================================================================== */ +/* BTE interfaces 1-3 */ +/* ========================================================================== */ + +#define SH2_BT_ENG_CSR_1 __IA64_UL_CONST(0x0000000030050000) +#define SH2_BT_ENG_CSR_2 __IA64_UL_CONST(0x0000000030060000) +#define SH2_BT_ENG_CSR_3 __IA64_UL_CONST(0x0000000030070000) + +#endif /* _ASM_IA64_SN_SHUB_MMR_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/shubio.h b/xen/include/asm-ia64/linux/asm/sn/shubio.h new file mode 100644 index 0000000000..22a6f18a53 --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/shubio.h @@ -0,0 +1,3358 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992 - 1997, 2000-2005 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef _ASM_IA64_SN_SHUBIO_H +#define _ASM_IA64_SN_SHUBIO_H + +#define HUB_WIDGET_ID_MAX 0xf +#define IIO_NUM_ITTES 7 +#define HUB_NUM_BIG_WINDOW (IIO_NUM_ITTES - 1) + +#define IIO_WID 0x00400000 /* Crosstalk Widget Identification */ + /* This register is also accessible from + * Crosstalk at address 0x0. */ +#define IIO_WSTAT 0x00400008 /* Crosstalk Widget Status */ +#define IIO_WCR 0x00400020 /* Crosstalk Widget Control Register */ +#define IIO_ILAPR 0x00400100 /* IO Local Access Protection Register */ +#define IIO_ILAPO 0x00400108 /* IO Local Access Protection Override */ +#define IIO_IOWA 0x00400110 /* IO Outbound Widget Access */ +#define IIO_IIWA 0x00400118 /* IO Inbound Widget Access */ +#define IIO_IIDEM 0x00400120 /* IO Inbound Device Error Mask */ +#define IIO_ILCSR 0x00400128 /* IO LLP Control and Status Register */ +#define IIO_ILLR 0x00400130 /* IO LLP Log Register */ +#define IIO_IIDSR 0x00400138 /* IO Interrupt Destination */ + +#define IIO_IGFX0 0x00400140 /* IO Graphics Node-Widget Map 0 */ +#define IIO_IGFX1 0x00400148 /* IO Graphics Node-Widget Map 1 */ + +#define IIO_ISCR0 0x00400150 /* IO Scratch Register 0 */ +#define IIO_ISCR1 0x00400158 /* IO Scratch Register 1 */ + +#define IIO_ITTE1 0x00400160 /* IO Translation Table Entry 1 */ +#define IIO_ITTE2 0x00400168 /* IO Translation Table Entry 2 */ +#define IIO_ITTE3 0x00400170 /* IO Translation Table Entry 3 */ +#define IIO_ITTE4 0x00400178 /* IO Translation Table Entry 4 */ +#define IIO_ITTE5 0x00400180 /* IO Translation Table Entry 5 */ +#define IIO_ITTE6 0x00400188 /* IO Translation Table Entry 6 */ +#define IIO_ITTE7 0x00400190 /* IO Translation Table Entry 7 */ + +#define IIO_IPRB0 0x00400198 /* IO PRB Entry 0 */ +#define IIO_IPRB8 0x004001A0 /* IO PRB Entry 8 */ +#define IIO_IPRB9 0x004001A8 /* IO PRB Entry 9 */ +#define IIO_IPRBA 0x004001B0 /* IO PRB Entry A */ +#define IIO_IPRBB 0x004001B8 /* IO PRB Entry B */ +#define IIO_IPRBC 0x004001C0 /* IO PRB Entry C */ +#define IIO_IPRBD 0x004001C8 /* IO PRB Entry D */ +#define IIO_IPRBE 0x004001D0 /* IO PRB Entry E */ +#define IIO_IPRBF 0x004001D8 /* IO PRB Entry F */ + +#define IIO_IXCC 0x004001E0 /* IO Crosstalk Credit Count Timeout */ +#define IIO_IMEM 0x004001E8 /* IO Miscellaneous Error Mask */ +#define IIO_IXTT 0x004001F0 /* IO Crosstalk Timeout Threshold */ +#define IIO_IECLR 0x004001F8 /* IO Error Clear Register */ +#define IIO_IBCR 0x00400200 /* IO BTE Control Register */ + +#define IIO_IXSM 0x00400208 /* IO Crosstalk Spurious Message */ +#define IIO_IXSS 0x00400210 /* IO Crosstalk Spurious Sideband */ + +#define IIO_ILCT 0x00400218 /* IO LLP Channel Test */ + +#define IIO_IIEPH1 0x00400220 /* IO Incoming Error Packet Header, Part 1 */ +#define IIO_IIEPH2 0x00400228 /* IO Incoming Error Packet Header, Part 2 */ + +#define IIO_ISLAPR 0x00400230 /* IO SXB Local Access Protection Regster */ +#define IIO_ISLAPO 0x00400238 /* IO SXB Local Access Protection Override */ + +#define IIO_IWI 0x00400240 /* IO Wrapper Interrupt Register */ +#define IIO_IWEL 0x00400248 /* IO Wrapper Error Log Register */ +#define IIO_IWC 0x00400250 /* IO Wrapper Control Register */ +#define IIO_IWS 0x00400258 /* IO Wrapper Status Register */ +#define IIO_IWEIM 0x00400260 /* IO Wrapper Error Interrupt Masking Register */ + +#define IIO_IPCA 0x00400300 /* IO PRB Counter Adjust */ + +#define IIO_IPRTE0_A 0x00400308 /* IO PIO Read Address Table Entry 0, Part A */ +#define IIO_IPRTE1_A 0x00400310 /* IO PIO Read Address Table Entry 1, Part A */ +#define IIO_IPRTE2_A 0x00400318 /* IO PIO Read Address Table Entry 2, Part A */ +#define IIO_IPRTE3_A 0x00400320 /* IO PIO Read Address Table Entry 3, Part A */ +#define IIO_IPRTE4_A 0x00400328 /* IO PIO Read Address Table Entry 4, Part A */ +#define IIO_IPRTE5_A 0x00400330 /* IO PIO Read Address Table Entry 5, Part A */ +#define IIO_IPRTE6_A 0x00400338 /* IO PIO Read Address Table Entry 6, Part A */ +#define IIO_IPRTE7_A 0x00400340 /* IO PIO Read Address Table Entry 7, Part A */ + +#define IIO_IPRTE0_B 0x00400348 /* IO PIO Read Address Table Entry 0, Part B */ +#define IIO_IPRTE1_B 0x00400350 /* IO PIO Read Address Table Entry 1, Part B */ +#define IIO_IPRTE2_B 0x00400358 /* IO PIO Read Address Table Entry 2, Part B */ +#define IIO_IPRTE3_B 0x00400360 /* IO PIO Read Address Table Entry 3, Part B */ +#define IIO_IPRTE4_B 0x00400368 /* IO PIO Read Address Table Entry 4, Part B */ +#define IIO_IPRTE5_B 0x00400370 /* IO PIO Read Address Table Entry 5, Part B */ +#define IIO_IPRTE6_B 0x00400378 /* IO PIO Read Address Table Entry 6, Part B */ +#define IIO_IPRTE7_B 0x00400380 /* IO PIO Read Address Table Entry 7, Part B */ + +#define IIO_IPDR 0x00400388 /* IO PIO Deallocation Register */ +#define IIO_ICDR 0x00400390 /* IO CRB Entry Deallocation Register */ +#define IIO_IFDR 0x00400398 /* IO IOQ FIFO Depth Register */ +#define IIO_IIAP 0x004003A0 /* IO IIQ Arbitration Parameters */ +#define IIO_ICMR 0x004003A8 /* IO CRB Management Register */ +#define IIO_ICCR 0x004003B0 /* IO CRB Control Register */ +#define IIO_ICTO 0x004003B8 /* IO CRB Timeout */ +#define IIO_ICTP 0x004003C0 /* IO CRB Timeout Prescalar */ + +#define IIO_ICRB0_A 0x00400400 /* IO CRB Entry 0_A */ +#define IIO_ICRB0_B 0x00400408 /* IO CRB Entry 0_B */ +#define IIO_ICRB0_C 0x00400410 /* IO CRB Entry 0_C */ +#define IIO_ICRB0_D 0x00400418 /* IO CRB Entry 0_D */ +#define IIO_ICRB0_E 0x00400420 /* IO CRB Entry 0_E */ + +#define IIO_ICRB1_A 0x00400430 /* IO CRB Entry 1_A */ +#define IIO_ICRB1_B 0x00400438 /* IO CRB Entry 1_B */ +#define IIO_ICRB1_C 0x00400440 /* IO CRB Entry 1_C */ +#define IIO_ICRB1_D 0x00400448 /* IO CRB Entry 1_D */ +#define IIO_ICRB1_E 0x00400450 /* IO CRB Entry 1_E */ + +#define IIO_ICRB2_A 0x00400460 /* IO CRB Entry 2_A */ +#define IIO_ICRB2_B 0x00400468 /* IO CRB Entry 2_B */ +#define IIO_ICRB2_C 0x00400470 /* IO CRB Entry 2_C */ +#define IIO_ICRB2_D 0x00400478 /* IO CRB Entry 2_D */ +#define IIO_ICRB2_E 0x00400480 /* IO CRB Entry 2_E */ + +#define IIO_ICRB3_A 0x00400490 /* IO CRB Entry 3_A */ +#define IIO_ICRB3_B 0x00400498 /* IO CRB Entry 3_B */ +#define IIO_ICRB3_C 0x004004a0 /* IO CRB Entry 3_C */ +#define IIO_ICRB3_D 0x004004a8 /* IO CRB Entry 3_D */ +#define IIO_ICRB3_E 0x004004b0 /* IO CRB Entry 3_E */ + +#define IIO_ICRB4_A 0x004004c0 /* IO CRB Entry 4_A */ +#define IIO_ICRB4_B 0x004004c8 /* IO CRB Entry 4_B */ +#define IIO_ICRB4_C 0x004004d0 /* IO CRB Entry 4_C */ +#define IIO_ICRB4_D 0x004004d8 /* IO CRB Entry 4_D */ +#define IIO_ICRB4_E 0x004004e0 /* IO CRB Entry 4_E */ + +#define IIO_ICRB5_A 0x004004f0 /* IO CRB Entry 5_A */ +#define IIO_ICRB5_B 0x004004f8 /* IO CRB Entry 5_B */ +#define IIO_ICRB5_C 0x00400500 /* IO CRB Entry 5_C */ +#define IIO_ICRB5_D 0x00400508 /* IO CRB Entry 5_D */ +#define IIO_ICRB5_E 0x00400510 /* IO CRB Entry 5_E */ + +#define IIO_ICRB6_A 0x00400520 /* IO CRB Entry 6_A */ +#define IIO_ICRB6_B 0x00400528 /* IO CRB Entry 6_B */ +#define IIO_ICRB6_C 0x00400530 /* IO CRB Entry 6_C */ +#define IIO_ICRB6_D 0x00400538 /* IO CRB Entry 6_D */ +#define IIO_ICRB6_E 0x00400540 /* IO CRB Entry 6_E */ + +#define IIO_ICRB7_A 0x00400550 /* IO CRB Entry 7_A */ +#define IIO_ICRB7_B 0x00400558 /* IO CRB Entry 7_B */ +#define IIO_ICRB7_C 0x00400560 /* IO CRB Entry 7_C */ +#define IIO_ICRB7_D 0x00400568 /* IO CRB Entry 7_D */ +#define IIO_ICRB7_E 0x00400570 /* IO CRB Entry 7_E */ + +#define IIO_ICRB8_A 0x00400580 /* IO CRB Entry 8_A */ +#define IIO_ICRB8_B 0x00400588 /* IO CRB Entry 8_B */ +#define IIO_ICRB8_C 0x00400590 /* IO CRB Entry 8_C */ +#define IIO_ICRB8_D 0x00400598 /* IO CRB Entry 8_D */ +#define IIO_ICRB8_E 0x004005a0 /* IO CRB Entry 8_E */ + +#define IIO_ICRB9_A 0x004005b0 /* IO CRB Entry 9_A */ +#define IIO_ICRB9_B 0x004005b8 /* IO CRB Entry 9_B */ +#define IIO_ICRB9_C 0x004005c0 /* IO CRB Entry 9_C */ +#define IIO_ICRB9_D 0x004005c8 /* IO CRB Entry 9_D */ +#define IIO_ICRB9_E 0x004005d0 /* IO CRB Entry 9_E */ + +#define IIO_ICRBA_A 0x004005e0 /* IO CRB Entry A_A */ +#define IIO_ICRBA_B 0x004005e8 /* IO CRB Entry A_B */ +#define IIO_ICRBA_C 0x004005f0 /* IO CRB Entry A_C */ +#define IIO_ICRBA_D 0x004005f8 /* IO CRB Entry A_D */ +#define IIO_ICRBA_E 0x00400600 /* IO CRB Entry A_E */ + +#define IIO_ICRBB_A 0x00400610 /* IO CRB Entry B_A */ +#define IIO_ICRBB_B 0x00400618 /* IO CRB Entry B_B */ +#define IIO_ICRBB_C 0x00400620 /* IO CRB Entry B_C */ +#define IIO_ICRBB_D 0x00400628 /* IO CRB Entry B_D */ +#define IIO_ICRBB_E 0x00400630 /* IO CRB Entry B_E */ + +#define IIO_ICRBC_A 0x00400640 /* IO CRB Entry C_A */ +#define IIO_ICRBC_B 0x00400648 /* IO CRB Entry C_B */ +#define IIO_ICRBC_C 0x00400650 /* IO CRB Entry C_C */ +#define IIO_ICRBC_D 0x00400658 /* IO CRB Entry C_D */ +#define IIO_ICRBC_E 0x00400660 /* IO CRB Entry C_E */ + +#define IIO_ICRBD_A 0x00400670 /* IO CRB Entry D_A */ +#define IIO_ICRBD_B 0x00400678 /* IO CRB Entry D_B */ +#define IIO_ICRBD_C 0x00400680 /* IO CRB Entry D_C */ +#define IIO_ICRBD_D 0x00400688 /* IO CRB Entry D_D */ +#define IIO_ICRBD_E 0x00400690 /* IO CRB Entry D_E */ + +#define IIO_ICRBE_A 0x004006a0 /* IO CRB Entry E_A */ +#define IIO_ICRBE_B 0x004006a8 /* IO CRB Entry E_B */ +#define IIO_ICRBE_C 0x004006b0 /* IO CRB Entry E_C */ +#define IIO_ICRBE_D 0x004006b8 /* IO CRB Entry E_D */ +#define IIO_ICRBE_E 0x004006c0 /* IO CRB Entry E_E */ + +#define IIO_ICSML 0x00400700 /* IO CRB Spurious Message Low */ +#define IIO_ICSMM 0x00400708 /* IO CRB Spurious Message Middle */ +#define IIO_ICSMH 0x00400710 /* IO CRB Spurious Message High */ + +#define IIO_IDBSS 0x00400718 /* IO Debug Submenu Select */ + +#define IIO_IBLS0 0x00410000 /* IO BTE Length Status 0 */ +#define IIO_IBSA0 0x00410008 /* IO BTE Source Address 0 */ +#define IIO_IBDA0 0x00410010 /* IO BTE Destination Address 0 */ +#define IIO_IBCT0 0x00410018 /* IO BTE Control Terminate 0 */ +#define IIO_IBNA0 0x00410020 /* IO BTE Notification Address 0 */ +#define IIO_IBIA0 0x00410028 /* IO BTE Interrupt Address 0 */ +#define IIO_IBLS1 0x00420000 /* IO BTE Length Status 1 */ +#define IIO_IBSA1 0x00420008 /* IO BTE Source Address 1 */ +#define IIO_IBDA1 0x00420010 /* IO BTE Destination Address 1 */ +#define IIO_IBCT1 0x00420018 /* IO BTE Control Terminate 1 */ +#define IIO_IBNA1 0x00420020 /* IO BTE Notification Address 1 */ +#define IIO_IBIA1 0x00420028 /* IO BTE Interrupt Address 1 */ + +#define IIO_IPCR 0x00430000 /* IO Performance Control */ +#define IIO_IPPR 0x00430008 /* IO Performance Profiling */ + +/************************************************************************ + * * + * Description: This register echoes some information from the * + * LB_REV_ID register. It is available through Crosstalk as described * + * above. The REV_NUM and MFG_NUM fields receive their values from * + * the REVISION and MANUFACTURER fields in the LB_REV_ID register. * + * The PART_NUM field's value is the Crosstalk device ID number that * + * Steve Miller assigned to the SHub chip. * + * * + ************************************************************************/ + +typedef union ii_wid_u { + u64 ii_wid_regval; + struct { + u64 w_rsvd_1:1; + u64 w_mfg_num:11; + u64 w_part_num:16; + u64 w_rev_num:4; + u64 w_rsvd:32; + } ii_wid_fld_s; +} ii_wid_u_t; + +/************************************************************************ + * * + * The fields in this register are set upon detection of an error * + * and cleared by various mechanisms, as explained in the * + * description. * + * * + ************************************************************************/ + +typedef union ii_wstat_u { + u64 ii_wstat_regval; + struct { + u64 w_pending:4; + u64 w_xt_crd_to:1; + u64 w_xt_tail_to:1; + u64 w_rsvd_3:3; + u64 w_tx_mx_rty:1; + u64 w_rsvd_2:6; + u64 w_llp_tx_cnt:8; + u64 w_rsvd_1:8; + u64 w_crazy:1; + u64 w_rsvd:31; + } ii_wstat_fld_s; +} ii_wstat_u_t; + +/************************************************************************ + * * + * Description: This is a read-write enabled register. It controls * + * various aspects of the Crosstalk flow control. * + * * + ************************************************************************/ + +typedef union ii_wcr_u { + u64 ii_wcr_regval; + struct { + u64 w_wid:4; + u64 w_tag:1; + u64 w_rsvd_1:8; + u64 w_dst_crd:3; + u64 w_f_bad_pkt:1; + u64 w_dir_con:1; + u64 w_e_thresh:5; + u64 w_rsvd:41; + } ii_wcr_fld_s; +} ii_wcr_u_t; + +/************************************************************************ + * * + * Description: This register's value is a bit vector that guards * + * access to local registers within the II as well as to external * + * Crosstalk widgets. Each bit in the register corresponds to a * + * particular region in the system; a region consists of one, two or * + * four nodes (depending on the value of the REGION_SIZE field in the * + * LB_REV_ID register, which is documented in Section 8.3.1.1). The * + * protection provided by this register applies to PIO read * + * operations as well as PIO write operations. The II will perform a * + * PIO read or write request only if the bit for the requestor's * + * region is set; otherwise, the II will not perform the requested * + * operation and will return an error response. When a PIO read or * + * write request targets an external Crosstalk widget, then not only * + * must the bit for the requestor's region be set in the ILAPR, but * + * also the target widget's bit in the IOWA register must be set in * + * order for the II to perform the requested operation; otherwise, * + * the II will return an error response. Hence, the protection * + * provided by the IOWA register supplements the protection provided * + * by the ILAPR for requests that target external Crosstalk widgets. * + * This register itself can be accessed only by the nodes whose * + * region ID bits are enabled in this same register. It can also be * + * accessed through the IAlias space by the local processors. * + * The reset value of this register allows access by all nodes. * + * * + ************************************************************************/ + +typedef union ii_ilapr_u { + u64 ii_ilapr_regval; + struct { + u64 i_region:64; + } ii_ilapr_fld_s; +} ii_ilapr_u_t; + +/************************************************************************ + * * + * Description: A write to this register of the 64-bit value * + * "SGIrules" in ASCII, will cause the bit in the ILAPR register * + * corresponding to the region of the requestor to be set (allow * + * access). A write of any other value will be ignored. Access * + * protection for this register is "SGIrules". * + * This register can also be accessed through the IAlias space. * + * However, this access will not change the access permissions in the * + * ILAPR. * + * * + ************************************************************************/ + +typedef union ii_ilapo_u { + u64 ii_ilapo_regval; + struct { + u64 i_io_ovrride:64; + } ii_ilapo_fld_s; +} ii_ilapo_u_t; + +/************************************************************************ + * * + * This register qualifies all the PIO and Graphics writes launched * + * from the SHUB towards a widget. * + * * + ************************************************************************/ + +typedef union ii_iowa_u { + u64 ii_iowa_regval; + struct { + u64 i_w0_oac:1; + u64 i_rsvd_1:7; + u64 i_wx_oac:8; + u64 i_rsvd:48; + } ii_iowa_fld_s; +} ii_iowa_u_t; + +/************************************************************************ + * * + * Description: This register qualifies all the requests launched * + * from a widget towards the Shub. This register is intended to be * + * used by software in case of misbehaving widgets. * + * * + * * + ************************************************************************/ + +typedef union ii_iiwa_u { + u64 ii_iiwa_regval; + struct { + u64 i_w0_iac:1; + u64 i_rsvd_1:7; + u64 i_wx_iac:8; + u64 i_rsvd:48; + } ii_iiwa_fld_s; +} ii_iiwa_u_t; + +/************************************************************************ + * * + * Description: This register qualifies all the operations launched * + * from a widget towards the SHub. It allows individual access * + * control for up to 8 devices per widget. A device refers to * + * individual DMA master hosted by a widget. * + * The bits in each field of this register are cleared by the Shub * + * upon detection of an error which requires the device to be * + * disabled. These fields assume that 0=TNUM=7 (i.e., Bridge-centric * + * Crosstalk). Whether or not a device has access rights to this * + * Shub is determined by an AND of the device enable bit in the * + * appropriate field of this register and the corresponding bit in * + * the Wx_IAC field (for the widget which this device belongs to). * + * The bits in this field are set by writing a 1 to them. Incoming * + * replies from Crosstalk are not subject to this access control * + * mechanism. * + * * + ************************************************************************/ + +typedef union ii_iidem_u { + u64 ii_iidem_regval; + struct { + u64 i_w8_dxs:8; + u64 i_w9_dxs:8; + u64 i_wa_dxs:8; + u64 i_wb_dxs:8; + u64 i_wc_dxs:8; + u64 i_wd_dxs:8; + u64 i_we_dxs:8; + u64 i_wf_dxs:8; + } ii_iidem_fld_s; +} ii_iidem_u_t; + +/************************************************************************ + * * + * This register contains the various programmable fields necessary * + * for controlling and observing the LLP signals. * + * * + ************************************************************************/ + +typedef union ii_ilcsr_u { + u64 ii_ilcsr_regval; + struct { + u64 i_nullto:6; + u64 i_rsvd_4:2; + u64 i_wrmrst:1; + u64 i_rsvd_3:1; + u64 i_llp_en:1; + u64 i_bm8:1; + u64 i_llp_stat:2; + u64 i_remote_power:1; + u64 i_rsvd_2:1; + u64 i_maxrtry:10; + u64 i_d_avail_sel:2; + u64 i_rsvd_1:4; + u64 i_maxbrst:10; + u64 i_rsvd:22; + + } ii_ilcsr_fld_s; +} ii_ilcsr_u_t; + +/************************************************************************ + * * + * This is simply a status registers that monitors the LLP error * + * rate. * + * * + ************************************************************************/ + +typedef union ii_illr_u { + u64 ii_illr_regval; + struct { + u64 i_sn_cnt:16; + u64 i_cb_cnt:16; + u64 i_rsvd:32; + } ii_illr_fld_s; +} ii_illr_u_t; + +/************************************************************************ + * * + * Description: All II-detected non-BTE error interrupts are * + * specified via this register. * + * NOTE: The PI interrupt register address is hardcoded in the II. If * + * PI_ID==0, then the II sends an interrupt request (Duplonet PWRI * + * packet) to address offset 0x0180_0090 within the local register * + * address space of PI0 on the node specified by the NODE field. If * + * PI_ID==1, then the II sends the interrupt request to address * + * offset 0x01A0_0090 within the local register address space of PI1 * + * on the node specified by the NODE field. * + * * + ************************************************************************/ + +typedef union ii_iidsr_u { + u64 ii_iidsr_regval; + struct { + u64 i_level:8; + u64 i_pi_id:1; + u64 i_node:11; + u64 i_rsvd_3:4; + u64 i_enable:1; + u64 i_rsvd_2:3; + u64 i_int_sent:2; + u64 i_rsvd_1:2; + u64 i_pi0_forward_int:1; + u64 i_pi1_forward_int:1; + u64 i_rsvd:30; + } ii_iidsr_fld_s; +} ii_iidsr_u_t; + +/************************************************************************ + * * + * There are two instances of this register. This register is used * + * for matching up the incoming responses from the graphics widget to * + * the processor that initiated the graphics operation. The * + * write-responses are converted to graphics credits and returned to * + * the processor so that the processor interface can manage the flow * + * control. * + * * + ************************************************************************/ + +typedef union ii_igfx0_u { + u64 ii_igfx0_regval; + struct { + u64 i_w_num:4; + u64 i_pi_id:1; + u64 i_n_num:12; + u64 i_p_num:1; + u64 i_rsvd:46; + } ii_igfx0_fld_s; +} ii_igfx0_u_t; + +/************************************************************************ + * * + * There are two instances of this register. This register is used * + * for matching up the incoming responses from the graphics widget to * + * the processor that initiated the graphics operation. The * + * write-responses are converted to graphics credits and returned to * + * the processor so that the processor interface can manage the flow * + * control. * + * * + ************************************************************************/ + +typedef union ii_igfx1_u { + u64 ii_igfx1_regval; + struct { + u64 i_w_num:4; + u64 i_pi_id:1; + u64 i_n_num:12; + u64 i_p_num:1; + u64 i_rsvd:46; + } ii_igfx1_fld_s; +} ii_igfx1_u_t; + +/************************************************************************ + * * + * There are two instances of this registers. These registers are * + * used as scratch registers for software use. * + * * + ************************************************************************/ + +typedef union ii_iscr0_u { + u64 ii_iscr0_regval; + struct { + u64 i_scratch:64; + } ii_iscr0_fld_s; +} ii_iscr0_u_t; + +/************************************************************************ + * * + * There are two instances of this registers. These registers are * + * used as scratch registers for software use. * + * * + ************************************************************************/ + +typedef union ii_iscr1_u { + u64 ii_iscr1_regval; + struct { + u64 i_scratch:64; + } ii_iscr1_fld_s; +} ii_iscr1_u_t; + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Shub Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the SHub is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Shub is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + +typedef union ii_itte1_u { + u64 ii_itte1_regval; + struct { + u64 i_offset:5; + u64 i_rsvd_1:3; + u64 i_w_num:4; + u64 i_iosp:1; + u64 i_rsvd:51; + } ii_itte1_fld_s; +} ii_itte1_u_t; + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Shub Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Shub is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Shub is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + +typedef union ii_itte2_u { + u64 ii_itte2_regval; + struct { + u64 i_offset:5; + u64 i_rsvd_1:3; + u64 i_w_num:4; + u64 i_iosp:1; + u64 i_rsvd:51; + } ii_itte2_fld_s; +} ii_itte2_u_t; + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Shub Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Shub is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the SHub is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + +typedef union ii_itte3_u { + u64 ii_itte3_regval; + struct { + u64 i_offset:5; + u64 i_rsvd_1:3; + u64 i_w_num:4; + u64 i_iosp:1; + u64 i_rsvd:51; + } ii_itte3_fld_s; +} ii_itte3_u_t; + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a SHub Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the SHub is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the SHub is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + +typedef union ii_itte4_u { + u64 ii_itte4_regval; + struct { + u64 i_offset:5; + u64 i_rsvd_1:3; + u64 i_w_num:4; + u64 i_iosp:1; + u64 i_rsvd:51; + } ii_itte4_fld_s; +} ii_itte4_u_t; + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a SHub Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Shub is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Shub is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + +typedef union ii_itte5_u { + u64 ii_itte5_regval; + struct { + u64 i_offset:5; + u64 i_rsvd_1:3; + u64 i_w_num:4; + u64 i_iosp:1; + u64 i_rsvd:51; + } ii_itte5_fld_s; +} ii_itte5_u_t; + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Shub Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Shub is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the Shub is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + +typedef union ii_itte6_u { + u64 ii_itte6_regval; + struct { + u64 i_offset:5; + u64 i_rsvd_1:3; + u64 i_w_num:4; + u64 i_iosp:1; + u64 i_rsvd:51; + } ii_itte6_fld_s; +} ii_itte6_u_t; + +/************************************************************************ + * * + * Description: There are seven instances of translation table entry * + * registers. Each register maps a Shub Big Window to a 48-bit * + * address on Crosstalk. * + * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window * + * number) are used to select one of these 7 registers. The Widget * + * number field is then derived from the W_NUM field for synthesizing * + * a Crosstalk packet. The 5 bits of OFFSET are concatenated with * + * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34] * + * are padded with zeros. Although the maximum Crosstalk space * + * addressable by the Shub is thus the lower 16 GBytes per widget * + * (M-mode), however only 7/32nds of this * + * space can be accessed. * + * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big * + * Window number) are used to select one of these 7 registers. The * + * Widget number field is then derived from the W_NUM field for * + * synthesizing a Crosstalk packet. The 5 bits of OFFSET are * + * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP * + * field is used as Crosstalk[47], and remainder of the Crosstalk * + * address bits (Crosstalk[46:34]) are always zero. While the maximum * + * Crosstalk space addressable by the SHub is thus the lower * + * 8-GBytes per widget (N-mode), only 7/32nds * + * of this space can be accessed. * + * * + ************************************************************************/ + +typedef union ii_itte7_u { + u64 ii_itte7_regval; + struct { + u64 i_offset:5; + u64 i_rsvd_1:3; + u64 i_w_num:4; + u64 i_iosp:1; + u64 i_rsvd:51; + } ii_itte7_fld_s; +} ii_itte7_u_t; + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of SHub and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + +typedef union ii_iprb0_u { + u64 ii_iprb0_regval; + struct { + u64 i_c:8; + u64 i_na:14; + u64 i_rsvd_2:2; + u64 i_nb:14; + u64 i_rsvd_1:2; + u64 i_m:2; + u64 i_f:1; + u64 i_of_cnt:5; + u64 i_error:1; + u64 i_rd_to:1; + u64 i_spur_wr:1; + u64 i_spur_rd:1; + u64 i_rsvd:11; + u64 i_mult_err:1; + } ii_iprb0_fld_s; +} ii_iprb0_u_t; + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of SHub and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + +typedef union ii_iprb8_u { + u64 ii_iprb8_regval; + struct { + u64 i_c:8; + u64 i_na:14; + u64 i_rsvd_2:2; + u64 i_nb:14; + u64 i_rsvd_1:2; + u64 i_m:2; + u64 i_f:1; + u64 i_of_cnt:5; + u64 i_error:1; + u64 i_rd_to:1; + u64 i_spur_wr:1; + u64 i_spur_rd:1; + u64 i_rsvd:11; + u64 i_mult_err:1; + } ii_iprb8_fld_s; +} ii_iprb8_u_t; + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of SHub and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + +typedef union ii_iprb9_u { + u64 ii_iprb9_regval; + struct { + u64 i_c:8; + u64 i_na:14; + u64 i_rsvd_2:2; + u64 i_nb:14; + u64 i_rsvd_1:2; + u64 i_m:2; + u64 i_f:1; + u64 i_of_cnt:5; + u64 i_error:1; + u64 i_rd_to:1; + u64 i_spur_wr:1; + u64 i_spur_rd:1; + u64 i_rsvd:11; + u64 i_mult_err:1; + } ii_iprb9_fld_s; +} ii_iprb9_u_t; + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of SHub and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * * + * * + ************************************************************************/ + +typedef union ii_iprba_u { + u64 ii_iprba_regval; + struct { + u64 i_c:8; + u64 i_na:14; + u64 i_rsvd_2:2; + u64 i_nb:14; + u64 i_rsvd_1:2; + u64 i_m:2; + u64 i_f:1; + u64 i_of_cnt:5; + u64 i_error:1; + u64 i_rd_to:1; + u64 i_spur_wr:1; + u64 i_spur_rd:1; + u64 i_rsvd:11; + u64 i_mult_err:1; + } ii_iprba_fld_s; +} ii_iprba_u_t; + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of SHub and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + +typedef union ii_iprbb_u { + u64 ii_iprbb_regval; + struct { + u64 i_c:8; + u64 i_na:14; + u64 i_rsvd_2:2; + u64 i_nb:14; + u64 i_rsvd_1:2; + u64 i_m:2; + u64 i_f:1; + u64 i_of_cnt:5; + u64 i_error:1; + u64 i_rd_to:1; + u64 i_spur_wr:1; + u64 i_spur_rd:1; + u64 i_rsvd:11; + u64 i_mult_err:1; + } ii_iprbb_fld_s; +} ii_iprbb_u_t; + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of SHub and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + +typedef union ii_iprbc_u { + u64 ii_iprbc_regval; + struct { + u64 i_c:8; + u64 i_na:14; + u64 i_rsvd_2:2; + u64 i_nb:14; + u64 i_rsvd_1:2; + u64 i_m:2; + u64 i_f:1; + u64 i_of_cnt:5; + u64 i_error:1; + u64 i_rd_to:1; + u64 i_spur_wr:1; + u64 i_spur_rd:1; + u64 i_rsvd:11; + u64 i_mult_err:1; + } ii_iprbc_fld_s; +} ii_iprbc_u_t; + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of SHub and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + +typedef union ii_iprbd_u { + u64 ii_iprbd_regval; + struct { + u64 i_c:8; + u64 i_na:14; + u64 i_rsvd_2:2; + u64 i_nb:14; + u64 i_rsvd_1:2; + u64 i_m:2; + u64 i_f:1; + u64 i_of_cnt:5; + u64 i_error:1; + u64 i_rd_to:1; + u64 i_spur_wr:1; + u64 i_spur_rd:1; + u64 i_rsvd:11; + u64 i_mult_err:1; + } ii_iprbd_fld_s; +} ii_iprbd_u_t; + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of SHub and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + +typedef union ii_iprbe_u { + u64 ii_iprbe_regval; + struct { + u64 i_c:8; + u64 i_na:14; + u64 i_rsvd_2:2; + u64 i_nb:14; + u64 i_rsvd_1:2; + u64 i_m:2; + u64 i_f:1; + u64 i_of_cnt:5; + u64 i_error:1; + u64 i_rd_to:1; + u64 i_spur_wr:1; + u64 i_spur_rd:1; + u64 i_rsvd:11; + u64 i_mult_err:1; + } ii_iprbe_fld_s; +} ii_iprbe_u_t; + +/************************************************************************ + * * + * Description: There are 9 instances of this register, one per * + * actual widget in this implementation of Shub and Crossbow. * + * Note: Crossbow only has ports for Widgets 8 through F, widget 0 * + * refers to Crossbow's internal space. * + * This register contains the state elements per widget that are * + * necessary to manage the PIO flow control on Crosstalk and on the * + * Router Network. See the PIO Flow Control chapter for a complete * + * description of this register * + * The SPUR_WR bit requires some explanation. When this register is * + * written, the new value of the C field is captured in an internal * + * register so the hardware can remember what the programmer wrote * + * into the credit counter. The SPUR_WR bit sets whenever the C field * + * increments above this stored value, which indicates that there * + * have been more responses received than requests sent. The SPUR_WR * + * bit cannot be cleared until a value is written to the IPRBx * + * register; the write will correct the C field and capture its new * + * value in the internal register. Even if IECLR[E_PRB_x] is set, the * + * SPUR_WR bit will persist if IPRBx hasn't yet been written. * + * . * + * * + ************************************************************************/ + +typedef union ii_iprbf_u { + u64 ii_iprbf_regval; + struct { + u64 i_c:8; + u64 i_na:14; + u64 i_rsvd_2:2; + u64 i_nb:14; + u64 i_rsvd_1:2; + u64 i_m:2; + u64 i_f:1; + u64 i_of_cnt:5; + u64 i_error:1; + u64 i_rd_to:1; + u64 i_spur_wr:1; + u64 i_spur_rd:1; + u64 i_rsvd:11; + u64 i_mult_err:1; + } ii_iprbe_fld_s; +} ii_iprbf_u_t; + +/************************************************************************ + * * + * This register specifies the timeout value to use for monitoring * + * Crosstalk credits which are used outbound to Crosstalk. An * + * internal counter called the Crosstalk Credit Timeout Counter * + * increments every 128 II clocks. The counter starts counting * + * anytime the credit count drops below a threshold, and resets to * + * zero (stops counting) anytime the credit count is at or above the * + * threshold. The threshold is 1 credit in direct connect mode and 2 * + * in Crossbow connect mode. When the internal Crosstalk Credit * + * Timeout Counter reaches the value programmed in this register, a * + * Crosstalk Credit Timeout has occurred. The internal counter is not * + * readable from software, and stops counting at its maximum value, * + * so it cannot cause more than one interrupt. * + * * + ************************************************************************/ + +typedef union ii_ixcc_u { + u64 ii_ixcc_regval; + struct { + u64 i_time_out:26; + u64 i_rsvd:38; + } ii_ixcc_fld_s; +} ii_ixcc_u_t; + +/************************************************************************ + * * + * Description: This register qualifies all the PIO and DMA * + * operations launched from widget 0 towards the SHub. In * + * addition, it also qualifies accesses by the BTE streams. * + * The bits in each field of this register are cleared by the SHub * + * upon detection of an error which requires widget 0 or the BTE * + * streams to be terminated. Whether or not widget x has access * + * rights to this SHub is determined by an AND of the device * + * enable bit in the appropriate field of this register and bit 0 in * + * the Wx_IAC field. The bits in this field are set by writing a 1 to * + * them. Incoming replies from Crosstalk are not subject to this * + * access control mechanism. * + * * + ************************************************************************/ + +typedef union ii_imem_u { + u64 ii_imem_regval; + struct { + u64 i_w0_esd:1; + u64 i_rsvd_3:3; + u64 i_b0_esd:1; + u64 i_rsvd_2:3; + u64 i_b1_esd:1; + u64 i_rsvd_1:3; + u64 i_clr_precise:1; + u64 i_rsvd:51; + } ii_imem_fld_s; +} ii_imem_u_t; + +/************************************************************************ + * * + * Description: This register specifies the timeout value to use for * + * monitoring Crosstalk tail flits coming into the Shub in the * + * TAIL_TO field. An internal counter associated with this register * + * is incremented every 128 II internal clocks (7 bits). The counter * + * starts counting anytime a header micropacket is received and stops * + * counting (and resets to zero) any time a micropacket with a Tail * + * bit is received. Once the counter reaches the threshold value * + * programmed in this register, it generates an interrupt to the * + * processor that is programmed into the IIDSR. The counter saturates * + * (does not roll over) at its maximum value, so it cannot cause * + * another interrupt until after it is cleared. * + * The register also contains the Read Response Timeout values. The * + * Prescalar is 23 bits, and counts II clocks. An internal counter * + * increments on every II clock and when it reaches the value in the * + * Prescalar field, all IPRTE registers with their valid bits set * + * have their Read Response timers bumped. Whenever any of them match * + * the value in the RRSP_TO field, a Read Response Timeout has * + * occurred, and error handling occurs as described in the Error * + * Handling section of this document. * + * * + ************************************************************************/ + +typedef union ii_ixtt_u { + u64 ii_ixtt_regval; + struct { + u64 i_tail_to:26; + u64 i_rsvd_1:6; + u64 i_rrsp_ps:23; + u64 i_rrsp_to:5; + u64 i_rsvd:4; + } ii_ixtt_fld_s; +} ii_ixtt_u_t; + +/************************************************************************ + * * + * Writing a 1 to the fields of this register clears the appropriate * + * error bits in other areas of SHub. Note that when the * + * E_PRB_x bits are used to clear error bits in PRB registers, * + * SPUR_RD and SPUR_WR may persist, because they require additional * + * action to clear them. See the IPRBx and IXSS Register * + * specifications. * + * * + ************************************************************************/ + +typedef union ii_ieclr_u { + u64 ii_ieclr_regval; + struct { + u64 i_e_prb_0:1; + u64 i_rsvd:7; + u64 i_e_prb_8:1; + u64 i_e_prb_9:1; + u64 i_e_prb_a:1; + u64 i_e_prb_b:1; + u64 i_e_prb_c:1; + u64 i_e_prb_d:1; + u64 i_e_prb_e:1; + u64 i_e_prb_f:1; + u64 i_e_crazy:1; + u64 i_e_bte_0:1; + u64 i_e_bte_1:1; + u64 i_reserved_1:10; + u64 i_spur_rd_hdr:1; + u64 i_cam_intr_to:1; + u64 i_cam_overflow:1; + u64 i_cam_read_miss:1; + u64 i_ioq_rep_underflow:1; + u64 i_ioq_req_underflow:1; + u64 i_ioq_rep_overflow:1; + u64 i_ioq_req_overflow:1; + u64 i_iiq_rep_overflow:1; + u64 i_iiq_req_overflow:1; + u64 i_ii_xn_rep_cred_overflow:1; + u64 i_ii_xn_req_cred_overflow:1; + u64 i_ii_xn_invalid_cmd:1; + u64 i_xn_ii_invalid_cmd:1; + u64 i_reserved_2:21; + } ii_ieclr_fld_s; +} ii_ieclr_u_t; + +/************************************************************************ + * * + * This register controls both BTEs. SOFT_RESET is intended for * + * recovery after an error. COUNT controls the total number of CRBs * + * that both BTEs (combined) can use, which affects total BTE * + * bandwidth. * + * * + ************************************************************************/ + +typedef union ii_ibcr_u { + u64 ii_ibcr_regval; + struct { + u64 i_count:4; + u64 i_rsvd_1:4; + u64 i_soft_reset:1; + u64 i_rsvd:55; + } ii_ibcr_fld_s; +} ii_ibcr_u_t; + +/************************************************************************ + * * + * This register contains the header of a spurious read response * + * received from Crosstalk. A spurious read response is defined as a * + * read response received by II from a widget for which (1) the SIDN * + * has a value between 1 and 7, inclusive (II never sends requests to * + * these widgets (2) there is no valid IPRTE register which * + * corresponds to the TNUM, or (3) the widget indicated in SIDN is * + * not the same as the widget recorded in the IPRTE register * + * referenced by the TNUM. If this condition is true, and if the * + * IXSS[VALID] bit is clear, then the header of the spurious read * + * response is capture in IXSM and IXSS, and IXSS[VALID] is set. The * + * errant header is thereby captured, and no further spurious read * + * respones are captured until IXSS[VALID] is cleared by setting the * + * appropriate bit in IECLR.Everytime a spurious read response is * + * detected, the SPUR_RD bit of the PRB corresponding to the incoming * + * message's SIDN field is set. This always happens, regarless of * + * whether a header is captured. The programmer should check * + * IXSM[SIDN] to determine which widget sent the spurious response, * + * because there may be more than one SPUR_RD bit set in the PRB * + * registers. The widget indicated by IXSM[SIDN] was the first * + * spurious read response to be received since the last time * + * IXSS[VALID] was clear. The SPUR_RD bit of the corresponding PRB * + * will be set. Any SPUR_RD bits in any other PRB registers indicate * + * spurious messages from other widets which were detected after the * + * header was captured.. * + * * + ************************************************************************/ + +typedef union ii_ixsm_u { + u64 ii_ixsm_regval; + struct { + u64 i_byte_en:32; + u64 i_reserved:1; + u64 i_tag:3; + u64 i_alt_pactyp:4; + u64 i_bo:1; + u64 i_error:1; + u64 i_vbpm:1; + u64 i_gbr:1; + u64 i_ds:2; + u64 i_ct:1; + u64 i_tnum:5; + u64 i_pactyp:4; + u64 i_sidn:4; + u64 i_didn:4; + } ii_ixsm_fld_s; +} ii_ixsm_u_t; + +/************************************************************************ + * * + * This register contains the sideband bits of a spurious read * + * response received from Crosstalk. * + * * + ************************************************************************/ + +typedef union ii_ixss_u { + u64 ii_ixss_regval; + struct { + u64 i_sideband:8; + u64 i_rsvd:55; + u64 i_valid:1; + } ii_ixss_fld_s; +} ii_ixss_u_t; + +/************************************************************************ + * * + * This register enables software to access the II LLP's test port. * + * Refer to the LLP 2.5 documentation for an explanation of the test * + * port. Software can write to this register to program the values * + * for the control fields (TestErrCapture, TestClear, TestFlit, * + * TestMask and TestSeed). Similarly, software can read from this * + * register to obtain the values of the test port's status outputs * + * (TestCBerr, TestValid and TestData). * + * * + ************************************************************************/ + +typedef union ii_ilct_u { + u64 ii_ilct_regval; + struct { + u64 i_test_seed:20; + u64 i_test_mask:8; + u64 i_test_data:20; + u64 i_test_valid:1; + u64 i_test_cberr:1; + u64 i_test_flit:3; + u64 i_test_clear:1; + u64 i_test_err_capture:1; + u64 i_rsvd:9; + } ii_ilct_fld_s; +} ii_ilct_u_t; + +/************************************************************************ + * * + * If the II detects an illegal incoming Duplonet packet (request or * + * reply) when VALID==0 in the IIEPH1 register, then it saves the * + * contents of the packet's header flit in the IIEPH1 and IIEPH2 * + * registers, sets the VALID bit in IIEPH1, clears the OVERRUN bit, * + * and assigns a value to the ERR_TYPE field which indicates the * + * specific nature of the error. The II recognizes four different * + * types of errors: short request packets (ERR_TYPE==2), short reply * + * packets (ERR_TYPE==3), long request packets (ERR_TYPE==4) and long * + * reply packets (ERR_TYPE==5). The encodings for these types of * + * errors were chosen to be consistent with the same types of errors * + * indicated by the ERR_TYPE field in the LB_ERROR_HDR1 register (in * + * the LB unit). If the II detects an illegal incoming Duplonet * + * packet when VALID==1 in the IIEPH1 register, then it merely sets * + * the OVERRUN bit to indicate that a subsequent error has happened, * + * and does nothing further. * + * * + ************************************************************************/ + +typedef union ii_iieph1_u { + u64 ii_iieph1_regval; + struct { + u64 i_command:7; + u64 i_rsvd_5:1; + u64 i_suppl:14; + u64 i_rsvd_4:1; + u64 i_source:14; + u64 i_rsvd_3:1; + u64 i_err_type:4; + u64 i_rsvd_2:4; + u64 i_overrun:1; + u64 i_rsvd_1:3; + u64 i_valid:1; + u64 i_rsvd:13; + } ii_iieph1_fld_s; +} ii_iieph1_u_t; + +/************************************************************************ + * * + * This register holds the Address field from the header flit of an * + * incoming erroneous Duplonet packet, along with the tail bit which * + * accompanied this header flit. This register is essentially an * + * extension of IIEPH1. Two registers were necessary because the 64 * + * bits available in only a single register were insufficient to * + * capture the entire header flit of an erroneous packet. * + * * + ************************************************************************/ + +typedef union ii_iieph2_u { + u64 ii_iieph2_regval; + struct { + u64 i_rsvd_0:3; + u64 i_address:47; + u64 i_rsvd_1:10; + u64 i_tail:1; + u64 i_rsvd:3; + } ii_iieph2_fld_s; +} ii_iieph2_u_t; + +/******************************/ + +/************************************************************************ + * * + * This register's value is a bit vector that guards access from SXBs * + * to local registers within the II as well as to external Crosstalk * + * widgets * + * * + ************************************************************************/ + +typedef union ii_islapr_u { + u64 ii_islapr_regval; + struct { + u64 i_region:64; + } ii_islapr_fld_s; +} ii_islapr_u_t; + +/************************************************************************ + * * + * A write to this register of the 56-bit value "Pup+Bun" will cause * + * the bit in the ISLAPR register corresponding to the region of the * + * requestor to be set (access allowed). ( + * * + ************************************************************************/ + +typedef union ii_islapo_u { + u64 ii_islapo_regval; + struct { + u64 i_io_sbx_ovrride:56; + u64 i_rsvd:8; + } ii_islapo_fld_s; +} ii_islapo_u_t; + +/************************************************************************ + * * + * Determines how long the wrapper will wait aftr an interrupt is * + * initially issued from the II before it times out the outstanding * + * interrupt and drops it from the interrupt queue. * + * * + ************************************************************************/ + +typedef union ii_iwi_u { + u64 ii_iwi_regval; + struct { + u64 i_prescale:24; + u64 i_rsvd:8; + u64 i_timeout:8; + u64 i_rsvd1:8; + u64 i_intrpt_retry_period:8; + u64 i_rsvd2:8; + } ii_iwi_fld_s; +} ii_iwi_u_t; + +/************************************************************************ + * * + * Log errors which have occurred in the II wrapper. The errors are * + * cleared by writing to the IECLR register. * + * * + ************************************************************************/ + +typedef union ii_iwel_u { + u64 ii_iwel_regval; + struct { + u64 i_intr_timed_out:1; + u64 i_rsvd:7; + u64 i_cam_overflow:1; + u64 i_cam_read_miss:1; + u64 i_rsvd1:2; + u64 i_ioq_rep_underflow:1; + u64 i_ioq_req_underflow:1; + u64 i_ioq_rep_overflow:1; + u64 i_ioq_req_overflow:1; + u64 i_iiq_rep_overflow:1; + u64 i_iiq_req_overflow:1; + u64 i_rsvd2:6; + u64 i_ii_xn_rep_cred_over_under:1; + u64 i_ii_xn_req_cred_over_under:1; + u64 i_rsvd3:6; + u64 i_ii_xn_invalid_cmd:1; + u64 i_xn_ii_invalid_cmd:1; + u64 i_rsvd4:30; + } ii_iwel_fld_s; +} ii_iwel_u_t; + +/************************************************************************ + * * + * Controls the II wrapper. * + * * + ************************************************************************/ + +typedef union ii_iwc_u { + u64 ii_iwc_regval; + struct { + u64 i_dma_byte_swap:1; + u64 i_rsvd:3; + u64 i_cam_read_lines_reset:1; + u64 i_rsvd1:3; + u64 i_ii_xn_cred_over_under_log:1; + u64 i_rsvd2:19; + u64 i_xn_rep_iq_depth:5; + u64 i_rsvd3:3; + u64 i_xn_req_iq_depth:5; + u64 i_rsvd4:3; + u64 i_iiq_depth:6; + u64 i_rsvd5:12; + u64 i_force_rep_cred:1; + u64 i_force_req_cred:1; + } ii_iwc_fld_s; +} ii_iwc_u_t; + +/************************************************************************ + * * + * Status in the II wrapper. * + * * + ************************************************************************/ + +typedef union ii_iws_u { + u64 ii_iws_regval; + struct { + u64 i_xn_rep_iq_credits:5; + u64 i_rsvd:3; + u64 i_xn_req_iq_credits:5; + u64 i_rsvd1:51; + } ii_iws_fld_s; +} ii_iws_u_t; + +/************************************************************************ + * * + * Masks errors in the IWEL register. * + * * + ************************************************************************/ + +typedef union ii_iweim_u { + u64 ii_iweim_regval; + struct { + u64 i_intr_timed_out:1; + u64 i_rsvd:7; + u64 i_cam_overflow:1; + u64 i_cam_read_miss:1; + u64 i_rsvd1:2; + u64 i_ioq_rep_underflow:1; + u64 i_ioq_req_underflow:1; + u64 i_ioq_rep_overflow:1; + u64 i_ioq_req_overflow:1; + u64 i_iiq_rep_overflow:1; + u64 i_iiq_req_overflow:1; + u64 i_rsvd2:6; + u64 i_ii_xn_rep_cred_overflow:1; + u64 i_ii_xn_req_cred_overflow:1; + u64 i_rsvd3:6; + u64 i_ii_xn_invalid_cmd:1; + u64 i_xn_ii_invalid_cmd:1; + u64 i_rsvd4:30; + } ii_iweim_fld_s; +} ii_iweim_u_t; + +/************************************************************************ + * * + * A write to this register causes a particular field in the * + * corresponding widget's PRB entry to be adjusted up or down by 1. * + * This counter should be used when recovering from error and reset * + * conditions. Note that software would be capable of causing * + * inadvertent overflow or underflow of these counters. * + * * + ************************************************************************/ + +typedef union ii_ipca_u { + u64 ii_ipca_regval; + struct { + u64 i_wid:4; + u64 i_adjust:1; + u64 i_rsvd_1:3; + u64 i_field:2; + u64 i_rsvd:54; + } ii_ipca_fld_s; +} ii_ipca_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte0a_u { + u64 ii_iprte0a_regval; + struct { + u64 i_rsvd_1:54; + u64 i_widget:4; + u64 i_to_cnt:5; + u64 i_vld:1; + } ii_iprte0a_fld_s; +} ii_iprte0a_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte1a_u { + u64 ii_iprte1a_regval; + struct { + u64 i_rsvd_1:54; + u64 i_widget:4; + u64 i_to_cnt:5; + u64 i_vld:1; + } ii_iprte1a_fld_s; +} ii_iprte1a_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte2a_u { + u64 ii_iprte2a_regval; + struct { + u64 i_rsvd_1:54; + u64 i_widget:4; + u64 i_to_cnt:5; + u64 i_vld:1; + } ii_iprte2a_fld_s; +} ii_iprte2a_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte3a_u { + u64 ii_iprte3a_regval; + struct { + u64 i_rsvd_1:54; + u64 i_widget:4; + u64 i_to_cnt:5; + u64 i_vld:1; + } ii_iprte3a_fld_s; +} ii_iprte3a_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte4a_u { + u64 ii_iprte4a_regval; + struct { + u64 i_rsvd_1:54; + u64 i_widget:4; + u64 i_to_cnt:5; + u64 i_vld:1; + } ii_iprte4a_fld_s; +} ii_iprte4a_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte5a_u { + u64 ii_iprte5a_regval; + struct { + u64 i_rsvd_1:54; + u64 i_widget:4; + u64 i_to_cnt:5; + u64 i_vld:1; + } ii_iprte5a_fld_s; +} ii_iprte5a_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte6a_u { + u64 ii_iprte6a_regval; + struct { + u64 i_rsvd_1:54; + u64 i_widget:4; + u64 i_to_cnt:5; + u64 i_vld:1; + } ii_iprte6a_fld_s; +} ii_iprte6a_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte7a_u { + u64 ii_iprte7a_regval; + struct { + u64 i_rsvd_1:54; + u64 i_widget:4; + u64 i_to_cnt:5; + u64 i_vld:1; + } ii_iprtea7_fld_s; +} ii_iprte7a_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte0b_u { + u64 ii_iprte0b_regval; + struct { + u64 i_rsvd_1:3; + u64 i_address:47; + u64 i_init:3; + u64 i_source:11; + } ii_iprte0b_fld_s; +} ii_iprte0b_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte1b_u { + u64 ii_iprte1b_regval; + struct { + u64 i_rsvd_1:3; + u64 i_address:47; + u64 i_init:3; + u64 i_source:11; + } ii_iprte1b_fld_s; +} ii_iprte1b_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte2b_u { + u64 ii_iprte2b_regval; + struct { + u64 i_rsvd_1:3; + u64 i_address:47; + u64 i_init:3; + u64 i_source:11; + } ii_iprte2b_fld_s; +} ii_iprte2b_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte3b_u { + u64 ii_iprte3b_regval; + struct { + u64 i_rsvd_1:3; + u64 i_address:47; + u64 i_init:3; + u64 i_source:11; + } ii_iprte3b_fld_s; +} ii_iprte3b_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte4b_u { + u64 ii_iprte4b_regval; + struct { + u64 i_rsvd_1:3; + u64 i_address:47; + u64 i_init:3; + u64 i_source:11; + } ii_iprte4b_fld_s; +} ii_iprte4b_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte5b_u { + u64 ii_iprte5b_regval; + struct { + u64 i_rsvd_1:3; + u64 i_address:47; + u64 i_init:3; + u64 i_source:11; + } ii_iprte5b_fld_s; +} ii_iprte5b_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte6b_u { + u64 ii_iprte6b_regval; + struct { + u64 i_rsvd_1:3; + u64 i_address:47; + u64 i_init:3; + u64 i_source:11; + + } ii_iprte6b_fld_s; +} ii_iprte6b_u_t; + +/************************************************************************ + * * + * There are 8 instances of this register. This register contains * + * the information that the II has to remember once it has launched a * + * PIO Read operation. The contents are used to form the correct * + * Router Network packet and direct the Crosstalk reply to the * + * appropriate processor. * + * * + ************************************************************************/ + +typedef union ii_iprte7b_u { + u64 ii_iprte7b_regval; + struct { + u64 i_rsvd_1:3; + u64 i_address:47; + u64 i_init:3; + u64 i_source:11; + } ii_iprte7b_fld_s; +} ii_iprte7b_u_t; + +/************************************************************************ + * * + * Description: SHub II contains a feature which did not exist in * + * the Hub which automatically cleans up after a Read Response * + * timeout, including deallocation of the IPRTE and recovery of IBuf * + * space. The inclusion of this register in SHub is for backward * + * compatibility * + * A write to this register causes an entry from the table of * + * outstanding PIO Read Requests to be freed and returned to the * + * stack of free entries. This register is used in handling the * + * timeout errors that result in a PIO Reply never returning from * + * Crosstalk. * + * Note that this register does not affect the contents of the IPRTE * + * registers. The Valid bits in those registers have to be * + * specifically turned off by software. * + * * + ************************************************************************/ + +typedef union ii_ipdr_u { + u64 ii_ipdr_regval; + struct { + u64 i_te:3; + u64 i_rsvd_1:1; + u64 i_pnd:1; + u64 i_init_rpcnt:1; + u64 i_rsvd:58; + } ii_ipdr_fld_s; +} ii_ipdr_u_t; + +/************************************************************************ + * * + * A write to this register causes a CRB entry to be returned to the * + * queue of free CRBs. The entry should have previously been cleared * + * (mark bit) via backdoor access to the pertinent CRB entry. This * + * register is used in the last step of handling the errors that are * + * captured and marked in CRB entries. Briefly: 1) first error for * + * DMA write from a particular device, and first error for a * + * particular BTE stream, lead to a marked CRB entry, and processor * + * interrupt, 2) software reads the error information captured in the * + * CRB entry, and presumably takes some corrective action, 3) * + * software clears the mark bit, and finally 4) software writes to * + * the ICDR register to return the CRB entry to the list of free CRB * + * entries. * + * * + ************************************************************************/ + +typedef union ii_icdr_u { + u64 ii_icdr_regval; + struct { + u64 i_crb_num:4; + u64 i_pnd:1; + u64 i_rsvd:59; + } ii_icdr_fld_s; +} ii_icdr_u_t; + +/************************************************************************ + * * + * This register provides debug access to two FIFOs inside of II. * + * Both IOQ_MAX* fields of this register contain the instantaneous * + * depth (in units of the number of available entries) of the * + * associated IOQ FIFO. A read of this register will return the * + * number of free entries on each FIFO at the time of the read. So * + * when a FIFO is idle, the associated field contains the maximum * + * depth of the FIFO. This register is writable for debug reasons * + * and is intended to be written with the maximum desired FIFO depth * + * while the FIFO is idle. Software must assure that II is idle when * + * this register is written. If there are any active entries in any * + * of these FIFOs when this register is written, the results are * + * undefined. * + * * + ************************************************************************/ + +typedef union ii_ifdr_u { + u64 ii_ifdr_regval; + struct { + u64 i_ioq_max_rq:7; + u64 i_set_ioq_rq:1; + u64 i_ioq_max_rp:7; + u64 i_set_ioq_rp:1; + u64 i_rsvd:48; + } ii_ifdr_fld_s; +} ii_ifdr_u_t; + +/************************************************************************ + * * + * This register allows the II to become sluggish in removing * + * messages from its inbound queue (IIQ). This will cause messages to * + * back up in either virtual channel. Disabling the "molasses" mode * + * subsequently allows the II to be tested under stress. In the * + * sluggish ("Molasses") mode, the localized effects of congestion * + * can be observed. * + * * + ************************************************************************/ + +typedef union ii_iiap_u { + u64 ii_iiap_regval; + struct { + u64 i_rq_mls:6; + u64 i_rsvd_1:2; + u64 i_rp_mls:6; + u64 i_rsvd:50; + } ii_iiap_fld_s; +} ii_iiap_u_t; + +/************************************************************************ + * * + * This register allows several parameters of CRB operation to be * + * set. Note that writing to this register can have catastrophic side * + * effects, if the CRB is not quiescent, i.e. if the CRB is * + * processing protocol messages when the write occurs. * + * * + ************************************************************************/ + +typedef union ii_icmr_u { + u64 ii_icmr_regval; + struct { + u64 i_sp_msg:1; + u64 i_rd_hdr:1; + u64 i_rsvd_4:2; + u64 i_c_cnt:4; + u64 i_rsvd_3:4; + u64 i_clr_rqpd:1; + u64 i_clr_rppd:1; + u64 i_rsvd_2:2; + u64 i_fc_cnt:4; + u64 i_crb_vld:15; + u64 i_crb_mark:15; + u64 i_rsvd_1:2; + u64 i_precise:1; + u64 i_rsvd:11; + } ii_icmr_fld_s; +} ii_icmr_u_t; + +/************************************************************************ + * * + * This register allows control of the table portion of the CRB * + * logic via software. Control operations from this register have * + * priority over all incoming Crosstalk or BTE requests. * + * * + ************************************************************************/ + +typedef union ii_iccr_u { + u64 ii_iccr_regval; + struct { + u64 i_crb_num:4; + u64 i_rsvd_1:4; + u64 i_cmd:8; + u64 i_pending:1; + u64 i_rsvd:47; + } ii_iccr_fld_s; +} ii_iccr_u_t; + +/************************************************************************ + * * + * This register allows the maximum timeout value to be programmed. * + * * + ************************************************************************/ + +typedef union ii_icto_u { + u64 ii_icto_regval; + struct { + u64 i_timeout:8; + u64 i_rsvd:56; + } ii_icto_fld_s; +} ii_icto_u_t; + +/************************************************************************ + * * + * This register allows the timeout prescalar to be programmed. An * + * internal counter is associated with this register. When the * + * internal counter reaches the value of the PRESCALE field, the * + * timer registers in all valid CRBs are incremented (CRBx_D[TIMEOUT] * + * field). The internal counter resets to zero, and then continues * + * counting. * + * * + ************************************************************************/ + +typedef union ii_ictp_u { + u64 ii_ictp_regval; + struct { + u64 i_prescale:24; + u64 i_rsvd:40; + } ii_ictp_fld_s; +} ii_ictp_u_t; + +/************************************************************************ + * * + * Description: There are 15 CRB Entries (ICRB0 to ICRBE) that are * + * used for Crosstalk operations (both cacheline and partial * + * operations) or BTE/IO. Because the CRB entries are very wide, five * + * registers (_A to _E) are required to read and write each entry. * + * The CRB Entry registers can be conceptualized as rows and columns * + * (illustrated in the table above). Each row contains the 4 * + * registers required for a single CRB Entry. The first doubleword * + * (column) for each entry is labeled A, and the second doubleword * + * (higher address) is labeled B, the third doubleword is labeled C, * + * the fourth doubleword is labeled D and the fifth doubleword is * + * labeled E. All CRB entries have their addresses on a quarter * + * cacheline aligned boundary. * + * Upon reset, only the following fields are initialized: valid * + * (VLD), priority count, timeout, timeout valid, and context valid. * + * All other bits should be cleared by software before use (after * + * recovering any potential error state from before the reset). * + * The following four tables summarize the format for the four * + * registers that are used for each ICRB# Entry. * + * * + ************************************************************************/ + +typedef union ii_icrb0_a_u { + u64 ii_icrb0_a_regval; + struct { + u64 ia_iow:1; + u64 ia_vld:1; + u64 ia_addr:47; + u64 ia_tnum:5; + u64 ia_sidn:4; + u64 ia_rsvd:6; + } ii_icrb0_a_fld_s; +} ii_icrb0_a_u_t; + +/************************************************************************ + * * + * Description: There are 15 CRB Entries (ICRB0 to ICRBE) that are * + * used for Crosstalk operations (both cacheline and partial * + * operations) or BTE/IO. Because the CRB entries are very wide, five * + * registers (_A to _E) are required to read and write each entry. * + * * + ************************************************************************/ + +typedef union ii_icrb0_b_u { + u64 ii_icrb0_b_regval; + struct { + u64 ib_xt_err:1; + u64 ib_mark:1; + u64 ib_ln_uce:1; + u64 ib_errcode:3; + u64 ib_error:1; + u64 ib_stall__bte_1:1; + u64 ib_stall__bte_0:1; + u64 ib_stall__intr:1; + u64 ib_stall_ib:1; + u64 ib_intvn:1; + u64 ib_wb:1; + u64 ib_hold:1; + u64 ib_ack:1; + u64 ib_resp:1; + u64 ib_ack_cnt:11; + u64 ib_rsvd:7; + u64 ib_exc:5; + u64 ib_init:3; + u64 ib_imsg:8; + u64 ib_imsgtype:2; + u64 ib_use_old:1; + u64 ib_rsvd_1:11; + } ii_icrb0_b_fld_s; +} ii_icrb0_b_u_t; + +/************************************************************************ + * * + * Description: There are 15 CRB Entries (ICRB0 to ICRBE) that are * + * used for Crosstalk operations (both cacheline and partial * + * operations) or BTE/IO. Because the CRB entries are very wide, five * + * registers (_A to _E) are required to read and write each entry. * + * * + ************************************************************************/ + +typedef union ii_icrb0_c_u { + u64 ii_icrb0_c_regval; + struct { + u64 ic_source:15; + u64 ic_size:2; + u64 ic_ct:1; + u64 ic_bte_num:1; + u64 ic_gbr:1; + u64 ic_resprqd:1; + u64 ic_bo:1; + u64 ic_suppl:15; + u64 ic_rsvd:27; + } ii_icrb0_c_fld_s; +} ii_icrb0_c_u_t; + +/************************************************************************ + * * + * Description: There are 15 CRB Entries (ICRB0 to ICRBE) that are * + * used for Crosstalk operations (both cacheline and partial * + * operations) or BTE/IO. Because the CRB entries are very wide, five * + * registers (_A to _E) are required to read and write each entry. * + * * + ************************************************************************/ + +typedef union ii_icrb0_d_u { + u64 ii_icrb0_d_regval; + struct { + u64 id_pa_be:43; + u64 id_bte_op:1; + u64 id_pr_psc:4; + u64 id_pr_cnt:4; + u64 id_sleep:1; + u64 id_rsvd:11; + } ii_icrb0_d_fld_s; +} ii_icrb0_d_u_t; + +/************************************************************************ + * * + * Description: There are 15 CRB Entries (ICRB0 to ICRBE) that are * + * used for Crosstalk operations (both cacheline and partial * + * operations) or BTE/IO. Because the CRB entries are very wide, five * + * registers (_A to _E) are required to read and write each entry. * + * * + ************************************************************************/ + +typedef union ii_icrb0_e_u { + u64 ii_icrb0_e_regval; + struct { + u64 ie_timeout:8; + u64 ie_context:15; + u64 ie_rsvd:1; + u64 ie_tvld:1; + u64 ie_cvld:1; + u64 ie_rsvd_0:38; + } ii_icrb0_e_fld_s; +} ii_icrb0_e_u_t; + +/************************************************************************ + * * + * This register contains the lower 64 bits of the header of the * + * spurious message captured by II. Valid when the SP_MSG bit in ICMR * + * register is set. * + * * + ************************************************************************/ + +typedef union ii_icsml_u { + u64 ii_icsml_regval; + struct { + u64 i_tt_addr:47; + u64 i_newsuppl_ex:14; + u64 i_reserved:2; + u64 i_overflow:1; + } ii_icsml_fld_s; +} ii_icsml_u_t; + +/************************************************************************ + * * + * This register contains the middle 64 bits of the header of the * + * spurious message captured by II. Valid when the SP_MSG bit in ICMR * + * register is set. * + * * + ************************************************************************/ + +typedef union ii_icsmm_u { + u64 ii_icsmm_regval; + struct { + u64 i_tt_ack_cnt:11; + u64 i_reserved:53; + } ii_icsmm_fld_s; +} ii_icsmm_u_t; + +/************************************************************************ + * * + * This register contains the microscopic state, all the inputs to * + * the protocol table, captured with the spurious message. Valid when * + * the SP_MSG bit in the ICMR register is set. * + * * + ************************************************************************/ + +typedef union ii_icsmh_u { + u64 ii_icsmh_regval; + struct { + u64 i_tt_vld:1; + u64 i_xerr:1; + u64 i_ft_cwact_o:1; + u64 i_ft_wact_o:1; + u64 i_ft_active_o:1; + u64 i_sync:1; + u64 i_mnusg:1; + u64 i_mnusz:1; + u64 i_plusz:1; + u64 i_plusg:1; + u64 i_tt_exc:5; + u64 i_tt_wb:1; + u64 i_tt_hold:1; + u64 i_tt_ack:1; + u64 i_tt_resp:1; + u64 i_tt_intvn:1; + u64 i_g_stall_bte1:1; + u64 i_g_stall_bte0:1; + u64 i_g_stall_il:1; + u64 i_g_stall_ib:1; + u64 i_tt_imsg:8; + u64 i_tt_imsgtype:2; + u64 i_tt_use_old:1; + u64 i_tt_respreqd:1; + u64 i_tt_bte_num:1; + u64 i_cbn:1; + u64 i_match:1; + u64 i_rpcnt_lt_34:1; + u64 i_rpcnt_ge_34:1; + u64 i_rpcnt_lt_18:1; + u64 i_rpcnt_ge_18:1; + u64 i_rpcnt_lt_2:1; + u64 i_rpcnt_ge_2:1; + u64 i_rqcnt_lt_18:1; + u64 i_rqcnt_ge_18:1; + u64 i_rqcnt_lt_2:1; + u64 i_rqcnt_ge_2:1; + u64 i_tt_device:7; + u64 i_tt_init:3; + u64 i_reserved:5; + } ii_icsmh_fld_s; +} ii_icsmh_u_t; + +/************************************************************************ + * * + * The Shub DEBUG unit provides a 3-bit selection signal to the * + * II core and a 3-bit selection signal to the fsbclk domain in the II * + * wrapper. * + * * + ************************************************************************/ + +typedef union ii_idbss_u { + u64 ii_idbss_regval; + struct { + u64 i_iioclk_core_submenu:3; + u64 i_rsvd:5; + u64 i_fsbclk_wrapper_submenu:3; + u64 i_rsvd_1:5; + u64 i_iioclk_menu:5; + u64 i_rsvd_2:43; + } ii_idbss_fld_s; +} ii_idbss_u_t; + +/************************************************************************ + * * + * Description: This register is used to set up the length for a * + * transfer and then to monitor the progress of that transfer. This * + * register needs to be initialized before a transfer is started. A * + * legitimate write to this register will set the Busy bit, clear the * + * Error bit, and initialize the length to the value desired. * + * While the transfer is in progress, hardware will decrement the * + * length field with each successful block that is copied. Once the * + * transfer completes, hardware will clear the Busy bit. The length * + * field will also contain the number of cache lines left to be * + * transferred. * + * * + ************************************************************************/ + +typedef union ii_ibls0_u { + u64 ii_ibls0_regval; + struct { + u64 i_length:16; + u64 i_error:1; + u64 i_rsvd_1:3; + u64 i_busy:1; + u64 i_rsvd:43; + } ii_ibls0_fld_s; +} ii_ibls0_u_t; + +/************************************************************************ + * * + * This register should be loaded before a transfer is started. The * + * address to be loaded in bits 39:0 is the 40-bit TRex+ physical * + * address as described in Section 1.3, Figure2 and Figure3. Since * + * the bottom 7 bits of the address are always taken to be zero, BTE * + * transfers are always cacheline-aligned. * + * * + ************************************************************************/ + +typedef union ii_ibsa0_u { + u64 ii_ibsa0_regval; + struct { + u64 i_rsvd_1:7; + u64 i_addr:42; + u64 i_rsvd:15; + } ii_ibsa0_fld_s; +} ii_ibsa0_u_t; + +/************************************************************************ + * * + * This register should be loaded before a transfer is started. The * + * address to be loaded in bits 39:0 is the 40-bit TRex+ physical * + * address as described in Section 1.3, Figure2 and Figure3. Since * + * the bottom 7 bits of the address are always taken to be zero, BTE * + * transfers are always cacheline-aligned. * + * * + ************************************************************************/ + +typedef union ii_ibda0_u { + u64 ii_ibda0_regval; + struct { + u64 i_rsvd_1:7; + u64 i_addr:42; + u64 i_rsvd:15; + } ii_ibda0_fld_s; +} ii_ibda0_u_t; + +/************************************************************************ + * * + * Writing to this register sets up the attributes of the transfer * + * and initiates the transfer operation. Reading this register has * + * the side effect of terminating any transfer in progress. Note: * + * stopping a transfer midstream could have an adverse impact on the * + * other BTE. If a BTE stream has to be stopped (due to error * + * handling for example), both BTE streams should be stopped and * + * their transfers discarded. * + * * + ************************************************************************/ + +typedef union ii_ibct0_u { + u64 ii_ibct0_regval; + struct { + u64 i_zerofill:1; + u64 i_rsvd_2:3; + u64 i_notify:1; + u64 i_rsvd_1:3; + u64 i_poison:1; + u64 i_rsvd:55; + } ii_ibct0_fld_s; +} ii_ibct0_u_t; + +/************************************************************************ + * * + * This register contains the address to which the WINV is sent. * + * This address has to be cache line aligned. * + * * + ************************************************************************/ + +typedef union ii_ibna0_u { + u64 ii_ibna0_regval; + struct { + u64 i_rsvd_1:7; + u64 i_addr:42; + u64 i_rsvd:15; + } ii_ibna0_fld_s; +} ii_ibna0_u_t; + +/************************************************************************ + * * + * This register contains the programmable level as well as the node * + * ID and PI unit of the processor to which the interrupt will be * + * sent. * + * * + ************************************************************************/ + +typedef union ii_ibia0_u { + u64 ii_ibia0_regval; + struct { + u64 i_rsvd_2:1; + u64 i_node_id:11; + u64 i_rsvd_1:4; + u64 i_level:7; + u64 i_rsvd:41; + } ii_ibia0_fld_s; +} ii_ibia0_u_t; + +/************************************************************************ + * * + * Description: This register is used to set up the length for a * + * transfer and then to monitor the progress of that transfer. This * + * register needs to be initialized before a transfer is started. A * + * legitimate write to this register will set the Busy bit, clear the * + * Error bit, and initialize the length to the value desired. * + * While the transfer is in progress, hardware will decrement the * + * length field with each successful block that is copied. Once the * + * transfer completes, hardware will clear the Busy bit. The length * + * field will also contain the number of cache lines left to be * + * transferred. * + * * + ************************************************************************/ + +typedef union ii_ibls1_u { + u64 ii_ibls1_regval; + struct { + u64 i_length:16; + u64 i_error:1; + u64 i_rsvd_1:3; + u64 i_busy:1; + u64 i_rsvd:43; + } ii_ibls1_fld_s; +} ii_ibls1_u_t; + +/************************************************************************ + * * + * This register should be loaded before a transfer is started. The * + * address to be loaded in bits 39:0 is the 40-bit TRex+ physical * + * address as described in Section 1.3, Figure2 and Figure3. Since * + * the bottom 7 bits of the address are always taken to be zero, BTE * + * transfers are always cacheline-aligned. * + * * + ************************************************************************/ + +typedef union ii_ibsa1_u { + u64 ii_ibsa1_regval; + struct { + u64 i_rsvd_1:7; + u64 i_addr:33; + u64 i_rsvd:24; + } ii_ibsa1_fld_s; +} ii_ibsa1_u_t; + +/************************************************************************ + * * + * This register should be loaded before a transfer is started. The * + * address to be loaded in bits 39:0 is the 40-bit TRex+ physical * + * address as described in Section 1.3, Figure2 and Figure3. Since * + * the bottom 7 bits of the address are always taken to be zero, BTE * + * transfers are always cacheline-aligned. * + * * + ************************************************************************/ + +typedef union ii_ibda1_u { + u64 ii_ibda1_regval; + struct { + u64 i_rsvd_1:7; + u64 i_addr:33; + u64 i_rsvd:24; + } ii_ibda1_fld_s; +} ii_ibda1_u_t; + +/************************************************************************ + * * + * Writing to this register sets up the attributes of the transfer * + * and initiates the transfer operation. Reading this register has * + * the side effect of terminating any transfer in progress. Note: * + * stopping a transfer midstream could have an adverse impact on the * + * other BTE. If a BTE stream has to be stopped (due to error * + * handling for example), both BTE streams should be stopped and * + * their transfers discarded. * + * * + ************************************************************************/ + +typedef union ii_ibct1_u { + u64 ii_ibct1_regval; + struct { + u64 i_zerofill:1; + u64 i_rsvd_2:3; + u64 i_notify:1; + u64 i_rsvd_1:3; + u64 i_poison:1; + u64 i_rsvd:55; + } ii_ibct1_fld_s; +} ii_ibct1_u_t; + +/************************************************************************ + * * + * This register contains the address to which the WINV is sent. * + * This address has to be cache line aligned. * + * * + ************************************************************************/ + +typedef union ii_ibna1_u { + u64 ii_ibna1_regval; + struct { + u64 i_rsvd_1:7; + u64 i_addr:33; + u64 i_rsvd:24; + } ii_ibna1_fld_s; +} ii_ibna1_u_t; + +/************************************************************************ + * * + * This register contains the programmable level as well as the node * + * ID and PI unit of the processor to which the interrupt will be * + * sent. * + * * + ************************************************************************/ + +typedef union ii_ibia1_u { + u64 ii_ibia1_regval; + struct { + u64 i_pi_id:1; + u64 i_node_id:8; + u64 i_rsvd_1:7; + u64 i_level:7; + u64 i_rsvd:41; + } ii_ibia1_fld_s; +} ii_ibia1_u_t; + +/************************************************************************ + * * + * This register defines the resources that feed information into * + * the two performance counters located in the IO Performance * + * Profiling Register. There are 17 different quantities that can be * + * measured. Given these 17 different options, the two performance * + * counters have 15 of them in common; menu selections 0 through 0xE * + * are identical for each performance counter. As for the other two * + * options, one is available from one performance counter and the * + * other is available from the other performance counter. Hence, the * + * II supports all 17*16=272 possible combinations of quantities to * + * measure. * + * * + ************************************************************************/ + +typedef union ii_ipcr_u { + u64 ii_ipcr_regval; + struct { + u64 i_ippr0_c:4; + u64 i_ippr1_c:4; + u64 i_icct:8; + u64 i_rsvd:48; + } ii_ipcr_fld_s; +} ii_ipcr_u_t; + +/************************************************************************ + * * + * * + * * + ************************************************************************/ + +typedef union ii_ippr_u { + u64 ii_ippr_regval; + struct { + u64 i_ippr0:32; + u64 i_ippr1:32; + } ii_ippr_fld_s; +} ii_ippr_u_t; + +/************************************************************************ + * * + * The following defines which were not formed into structures are * + * probably indentical to another register, and the name of the * + * register is provided against each of these registers. This * + * information needs to be checked carefully * + * * + * IIO_ICRB1_A IIO_ICRB0_A * + * IIO_ICRB1_B IIO_ICRB0_B * + * IIO_ICRB1_C IIO_ICRB0_C * + * IIO_ICRB1_D IIO_ICRB0_D * + * IIO_ICRB1_E IIO_ICRB0_E * + * IIO_ICRB2_A IIO_ICRB0_A * + * IIO_ICRB2_B IIO_ICRB0_B * + * IIO_ICRB2_C IIO_ICRB0_C * + * IIO_ICRB2_D IIO_ICRB0_D * + * IIO_ICRB2_E IIO_ICRB0_E * + * IIO_ICRB3_A IIO_ICRB0_A * + * IIO_ICRB3_B IIO_ICRB0_B * + * IIO_ICRB3_C IIO_ICRB0_C * + * IIO_ICRB3_D IIO_ICRB0_D * + * IIO_ICRB3_E IIO_ICRB0_E * + * IIO_ICRB4_A IIO_ICRB0_A * + * IIO_ICRB4_B IIO_ICRB0_B * + * IIO_ICRB4_C IIO_ICRB0_C * + * IIO_ICRB4_D IIO_ICRB0_D * + * IIO_ICRB4_E IIO_ICRB0_E * + * IIO_ICRB5_A IIO_ICRB0_A * + * IIO_ICRB5_B IIO_ICRB0_B * + * IIO_ICRB5_C IIO_ICRB0_C * + * IIO_ICRB5_D IIO_ICRB0_D * + * IIO_ICRB5_E IIO_ICRB0_E * + * IIO_ICRB6_A IIO_ICRB0_A * + * IIO_ICRB6_B IIO_ICRB0_B * + * IIO_ICRB6_C IIO_ICRB0_C * + * IIO_ICRB6_D IIO_ICRB0_D * + * IIO_ICRB6_E IIO_ICRB0_E * + * IIO_ICRB7_A IIO_ICRB0_A * + * IIO_ICRB7_B IIO_ICRB0_B * + * IIO_ICRB7_C IIO_ICRB0_C * + * IIO_ICRB7_D IIO_ICRB0_D * + * IIO_ICRB7_E IIO_ICRB0_E * + * IIO_ICRB8_A IIO_ICRB0_A * + * IIO_ICRB8_B IIO_ICRB0_B * + * IIO_ICRB8_C IIO_ICRB0_C * + * IIO_ICRB8_D IIO_ICRB0_D * + * IIO_ICRB8_E IIO_ICRB0_E * + * IIO_ICRB9_A IIO_ICRB0_A * + * IIO_ICRB9_B IIO_ICRB0_B * + * IIO_ICRB9_C IIO_ICRB0_C * + * IIO_ICRB9_D IIO_ICRB0_D * + * IIO_ICRB9_E IIO_ICRB0_E * + * IIO_ICRBA_A IIO_ICRB0_A * + * IIO_ICRBA_B IIO_ICRB0_B * + * IIO_ICRBA_C IIO_ICRB0_C * + * IIO_ICRBA_D IIO_ICRB0_D * + * IIO_ICRBA_E IIO_ICRB0_E * + * IIO_ICRBB_A IIO_ICRB0_A * + * IIO_ICRBB_B IIO_ICRB0_B * + * IIO_ICRBB_C IIO_ICRB0_C * + * IIO_ICRBB_D IIO_ICRB0_D * + * IIO_ICRBB_E IIO_ICRB0_E * + * IIO_ICRBC_A IIO_ICRB0_A * + * IIO_ICRBC_B IIO_ICRB0_B * + * IIO_ICRBC_C IIO_ICRB0_C * + * IIO_ICRBC_D IIO_ICRB0_D * + * IIO_ICRBC_E IIO_ICRB0_E * + * IIO_ICRBD_A IIO_ICRB0_A * + * IIO_ICRBD_B IIO_ICRB0_B * + * IIO_ICRBD_C IIO_ICRB0_C * + * IIO_ICRBD_D IIO_ICRB0_D * + * IIO_ICRBD_E IIO_ICRB0_E * + * IIO_ICRBE_A IIO_ICRB0_A * + * IIO_ICRBE_B IIO_ICRB0_B * + * IIO_ICRBE_C IIO_ICRB0_C * + * IIO_ICRBE_D IIO_ICRB0_D * + * IIO_ICRBE_E IIO_ICRB0_E * + * * + ************************************************************************/ + +/* + * Slightly friendlier names for some common registers. + */ +#define IIO_WIDGET IIO_WID /* Widget identification */ +#define IIO_WIDGET_STAT IIO_WSTAT /* Widget status register */ +#define IIO_WIDGET_CTRL IIO_WCR /* Widget control register */ +#define IIO_PROTECT IIO_ILAPR /* IO interface protection */ +#define IIO_PROTECT_OVRRD IIO_ILAPO /* IO protect override */ +#define IIO_OUTWIDGET_ACCESS IIO_IOWA /* Outbound widget access */ +#define IIO_INWIDGET_ACCESS IIO_IIWA /* Inbound widget access */ +#define IIO_INDEV_ERR_MASK IIO_IIDEM /* Inbound device error mask */ +#define IIO_LLP_CSR IIO_ILCSR /* LLP control and status */ +#define IIO_LLP_LOG IIO_ILLR /* LLP log */ +#define IIO_XTALKCC_TOUT IIO_IXCC /* Xtalk credit count timeout */ +#define IIO_XTALKTT_TOUT IIO_IXTT /* Xtalk tail timeout */ +#define IIO_IO_ERR_CLR IIO_IECLR /* IO error clear */ +#define IIO_IGFX_0 IIO_IGFX0 +#define IIO_IGFX_1 IIO_IGFX1 +#define IIO_IBCT_0 IIO_IBCT0 +#define IIO_IBCT_1 IIO_IBCT1 +#define IIO_IBLS_0 IIO_IBLS0 +#define IIO_IBLS_1 IIO_IBLS1 +#define IIO_IBSA_0 IIO_IBSA0 +#define IIO_IBSA_1 IIO_IBSA1 +#define IIO_IBDA_0 IIO_IBDA0 +#define IIO_IBDA_1 IIO_IBDA1 +#define IIO_IBNA_0 IIO_IBNA0 +#define IIO_IBNA_1 IIO_IBNA1 +#define IIO_IBIA_0 IIO_IBIA0 +#define IIO_IBIA_1 IIO_IBIA1 +#define IIO_IOPRB_0 IIO_IPRB0 + +#define IIO_PRTE_A(_x) (IIO_IPRTE0_A + (8 * (_x))) +#define IIO_PRTE_B(_x) (IIO_IPRTE0_B + (8 * (_x))) +#define IIO_NUM_PRTES 8 /* Total number of PRB table entries */ +#define IIO_WIDPRTE_A(x) IIO_PRTE_A(((x) - 8)) /* widget ID to its PRTE num */ +#define IIO_WIDPRTE_B(x) IIO_PRTE_B(((x) - 8)) /* widget ID to its PRTE num */ + +#define IIO_NUM_IPRBS 9 + +#define IIO_LLP_CSR_IS_UP 0x00002000 +#define IIO_LLP_CSR_LLP_STAT_MASK 0x00003000 +#define IIO_LLP_CSR_LLP_STAT_SHFT 12 + +#define IIO_LLP_CB_MAX 0xffff /* in ILLR CB_CNT, Max Check Bit errors */ +#define IIO_LLP_SN_MAX 0xffff /* in ILLR SN_CNT, Max Sequence Number errors */ + +/* key to IIO_PROTECT_OVRRD */ +#define IIO_PROTECT_OVRRD_KEY 0x53474972756c6573ull /* "SGIrules" */ + +/* BTE register names */ +#define IIO_BTE_STAT_0 IIO_IBLS_0 /* Also BTE length/status 0 */ +#define IIO_BTE_SRC_0 IIO_IBSA_0 /* Also BTE source address 0 */ +#define IIO_BTE_DEST_0 IIO_IBDA_0 /* Also BTE dest. address 0 */ +#define IIO_BTE_CTRL_0 IIO_IBCT_0 /* Also BTE control/terminate 0 */ +#define IIO_BTE_NOTIFY_0 IIO_IBNA_0 /* Also BTE notification 0 */ +#define IIO_BTE_INT_0 IIO_IBIA_0 /* Also BTE interrupt 0 */ +#define IIO_BTE_OFF_0 0 /* Base offset from BTE 0 regs. */ +#define IIO_BTE_OFF_1 (IIO_IBLS_1 - IIO_IBLS_0) /* Offset from base to BTE 1 */ + +/* BTE register offsets from base */ +#define BTEOFF_STAT 0 +#define BTEOFF_SRC (IIO_BTE_SRC_0 - IIO_BTE_STAT_0) +#define BTEOFF_DEST (IIO_BTE_DEST_0 - IIO_BTE_STAT_0) +#define BTEOFF_CTRL (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0) +#define BTEOFF_NOTIFY (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0) +#define BTEOFF_INT (IIO_BTE_INT_0 - IIO_BTE_STAT_0) + +/* names used in shub diags */ +#define IIO_BASE_BTE0 IIO_IBLS_0 +#define IIO_BASE_BTE1 IIO_IBLS_1 + +/* + * Macro which takes the widget number, and returns the + * IO PRB address of that widget. + * value _x is expected to be a widget number in the range + * 0, 8 - 0xF + */ +#define IIO_IOPRB(_x) (IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \ + (_x) : \ + (_x) - (HUB_WIDGET_ID_MIN-1)) << 3) ) + +/* GFX Flow Control Node/Widget Register */ +#define IIO_IGFX_W_NUM_BITS 4 /* size of widget num field */ +#define IIO_IGFX_W_NUM_MASK ((1<> IIO_WSTAT_TXRETRY_SHFT) & \ + IIO_WSTAT_TXRETRY_MASK) + +/* Number of II perf. counters we can multiplex at once */ + +#define IO_PERF_SETS 32 + +/* Bit for the widget in inbound access register */ +#define IIO_IIWA_WIDGET(_w) ((u64)(1ULL << _w)) +/* Bit for the widget in outbound access register */ +#define IIO_IOWA_WIDGET(_w) ((u64)(1ULL << _w)) + +/* NOTE: The following define assumes that we are going to get + * widget numbers from 8 thru F and the device numbers within + * widget from 0 thru 7. + */ +#define IIO_IIDEM_WIDGETDEV_MASK(w, d) ((u64)(1ULL << (8 * ((w) - 8) + (d)))) + +/* IO Interrupt Destination Register */ +#define IIO_IIDSR_SENT_SHIFT 28 +#define IIO_IIDSR_SENT_MASK 0x30000000 +#define IIO_IIDSR_ENB_SHIFT 24 +#define IIO_IIDSR_ENB_MASK 0x01000000 +#define IIO_IIDSR_NODE_SHIFT 9 +#define IIO_IIDSR_NODE_MASK 0x000ff700 +#define IIO_IIDSR_PI_ID_SHIFT 8 +#define IIO_IIDSR_PI_ID_MASK 0x00000100 +#define IIO_IIDSR_LVL_SHIFT 0 +#define IIO_IIDSR_LVL_MASK 0x000000ff + +/* Xtalk timeout threshhold register (IIO_IXTT) */ +#define IXTT_RRSP_TO_SHFT 55 /* read response timeout */ +#define IXTT_RRSP_TO_MASK (0x1FULL << IXTT_RRSP_TO_SHFT) +#define IXTT_RRSP_PS_SHFT 32 /* read responsed TO prescalar */ +#define IXTT_RRSP_PS_MASK (0x7FFFFFULL << IXTT_RRSP_PS_SHFT) +#define IXTT_TAIL_TO_SHFT 0 /* tail timeout counter threshold */ +#define IXTT_TAIL_TO_MASK (0x3FFFFFFULL << IXTT_TAIL_TO_SHFT) + +/* + * The IO LLP control status register and widget control register + */ + +typedef union hubii_wcr_u { + u64 wcr_reg_value; + struct { + u64 wcr_widget_id:4, /* LLP crossbar credit */ + wcr_tag_mode:1, /* Tag mode */ + wcr_rsvd1:8, /* Reserved */ + wcr_xbar_crd:3, /* LLP crossbar credit */ + wcr_f_bad_pkt:1, /* Force bad llp pkt enable */ + wcr_dir_con:1, /* widget direct connect */ + wcr_e_thresh:5, /* elasticity threshold */ + wcr_rsvd:41; /* unused */ + } wcr_fields_s; +} hubii_wcr_t; + +#define iwcr_dir_con wcr_fields_s.wcr_dir_con + +/* The structures below are defined to extract and modify the ii +performance registers */ + +/* io_perf_sel allows the caller to specify what tests will be + performed */ + +typedef union io_perf_sel { + u64 perf_sel_reg; + struct { + u64 perf_ippr0:4, perf_ippr1:4, perf_icct:8, perf_rsvd:48; + } perf_sel_bits; +} io_perf_sel_t; + +/* io_perf_cnt is to extract the count from the shub registers. Due to + hardware problems there is only one counter, not two. */ + +typedef union io_perf_cnt { + u64 perf_cnt; + struct { + u64 perf_cnt:20, perf_rsvd2:12, perf_rsvd1:32; + } perf_cnt_bits; + +} io_perf_cnt_t; + +typedef union iprte_a { + u64 entry; + struct { + u64 i_rsvd_1:3; + u64 i_addr:38; + u64 i_init:3; + u64 i_source:8; + u64 i_rsvd:2; + u64 i_widget:4; + u64 i_to_cnt:5; + u64 i_vld:1; + } iprte_fields; +} iprte_a_t; + +#endif /* _ASM_IA64_SN_SHUBIO_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/simulator.h b/xen/include/asm-ia64/linux/asm/sn/simulator.h new file mode 100644 index 0000000000..c3fd3eb257 --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/simulator.h @@ -0,0 +1,20 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * Copyright (C) 2000-2004 Silicon Graphics, Inc. All rights reserved. + */ + +#ifndef _ASM_IA64_SN_SIMULATOR_H +#define _ASM_IA64_SN_SIMULATOR_H + + +#define SNMAGIC 0xaeeeeeee8badbeefL +#define IS_MEDUSA() ({long sn; asm("mov %0=cpuid[%1]" : "=r"(sn) : "r"(2)); sn == SNMAGIC;}) + +#define SIMULATOR_SLEEP() asm("nop.i 0x8beef") +#define IS_RUNNING_ON_SIMULATOR() (sn_prom_type) +#define IS_RUNNING_ON_FAKE_PROM() (sn_prom_type == 2) +extern int sn_prom_type; /* 0=hardware, 1=medusa/realprom, 2=medusa/fakeprom */ + +#endif /* _ASM_IA64_SN_SIMULATOR_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/sn_cpuid.h b/xen/include/asm-ia64/linux/asm/sn/sn_cpuid.h new file mode 100644 index 0000000000..a676dd9ace --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/sn_cpuid.h @@ -0,0 +1,132 @@ +/* + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000-2005 Silicon Graphics, Inc. All rights reserved. + */ + + +#ifndef _ASM_IA64_SN_SN_CPUID_H +#define _ASM_IA64_SN_SN_CPUID_H + +#include +#include +#include +#include + + +/* + * Functions for converting between cpuids, nodeids and NASIDs. + * + * These are for SGI platforms only. + * + */ + + + + +/* + * Definitions of terms (these definitions are for IA64 ONLY. Other architectures + * use cpuid/cpunum quite defferently): + * + * CPUID - a number in range of 0..NR_CPUS-1 that uniquely identifies + * the cpu. The value cpuid has no significance on IA64 other than + * the boot cpu is 0. + * smp_processor_id() returns the cpuid of the current cpu. + * + * CPU_PHYSICAL_ID (also known as HARD_PROCESSOR_ID) + * This is the same as 31:24 of the processor LID register + * hard_smp_processor_id()- cpu_physical_id of current processor + * cpu_physical_id(cpuid) - convert a to a + * cpu_logical_id(phy_id) - convert a to a + * * not real efficient - don't use in perf critical code + * + * SLICE - a number in the range of 0 - 3 (typically) that represents the + * cpu number on a brick. + * + * SUBNODE - (almost obsolete) the number of the FSB that a cpu is + * connected to. This is also the same as the PI number. Usually 0 or 1. + * + * NOTE!!!: the value of the bits in the cpu physical id (SAPICid or LID) of a cpu has no + * significance. The SAPIC id (LID) is a 16-bit cookie that has meaning only to the PROM. + * + * + * The macros convert between cpu physical ids & slice/nasid/cnodeid. + * These terms are described below: + * + * + * Brick + * ----- ----- ----- ----- CPU + * | 0 | | 1 | | 0 | | 1 | SLICE + * ----- ----- ----- ----- + * | | | | + * | | | | + * 0 | | 2 0 | | 2 FSB SLOT + * ------- ------- + * | | + * | | + * | | + * ------------ ------------- + * | | | | + * | SHUB | | SHUB | NASID (0..MAX_NASIDS) + * | |----- | | CNODEID (0..num_compact_nodes-1) + * | | | | + * | | | | + * ------------ ------------- + * | | + * + * + */ + +#define get_node_number(addr) NASID_GET(addr) + +/* + * NOTE: on non-MP systems, only cpuid 0 exists + */ + +extern short physical_node_map[]; /* indexed by nasid to get cnode */ + +/* + * Macros for retrieving info about current cpu + */ +#define get_nasid() (sn_nodepda->phys_cpuid[smp_processor_id()].nasid) +#define get_subnode() (sn_nodepda->phys_cpuid[smp_processor_id()].subnode) +#define get_slice() (sn_nodepda->phys_cpuid[smp_processor_id()].slice) +#define get_cnode() (sn_nodepda->phys_cpuid[smp_processor_id()].cnode) +#define get_sapicid() ((ia64_getreg(_IA64_REG_CR_LID) >> 16) & 0xffff) + +/* + * Macros for retrieving info about an arbitrary cpu + * cpuid - logical cpu id + */ +#define cpuid_to_nasid(cpuid) (sn_nodepda->phys_cpuid[cpuid].nasid) +#define cpuid_to_subnode(cpuid) (sn_nodepda->phys_cpuid[cpuid].subnode) +#define cpuid_to_slice(cpuid) (sn_nodepda->phys_cpuid[cpuid].slice) + + +/* + * Dont use the following in performance critical code. They require scans + * of potentially large tables. + */ +extern int nasid_slice_to_cpuid(int, int); + +/* + * cnodeid_to_nasid - convert a cnodeid to a NASID + */ +#define cnodeid_to_nasid(cnodeid) (sn_cnodeid_to_nasid[cnodeid]) + +/* + * nasid_to_cnodeid - convert a NASID to a cnodeid + */ +#define nasid_to_cnodeid(nasid) (physical_node_map[nasid]) + +/* + * partition_coherence_id - get the coherence ID of the current partition + */ +extern u8 sn_coherency_id; +#define partition_coherence_id() (sn_coherency_id) + +#endif /* _ASM_IA64_SN_SN_CPUID_H */ + diff --git a/xen/include/asm-ia64/linux/asm/sn/sn_feature_sets.h b/xen/include/asm-ia64/linux/asm/sn/sn_feature_sets.h new file mode 100644 index 0000000000..30dcfa442e --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/sn_feature_sets.h @@ -0,0 +1,51 @@ +#ifndef _ASM_IA64_SN_FEATURE_SETS_H +#define _ASM_IA64_SN_FEATURE_SETS_H + +/* + * SN PROM Features + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (c) 2005-2006 Silicon Graphics, Inc. All rights reserved. + */ + + +/* --------------------- PROM Features -----------------------------*/ +extern int sn_prom_feature_available(int id); + +#define MAX_PROM_FEATURE_SETS 2 + +/* + * The following defines features that may or may not be supported by the + * current PROM. The OS uses sn_prom_feature_available(feature) to test for + * the presence of a PROM feature. Down rev (old) PROMs will always test + * "false" for new features. + * + * Use: + * if (sn_prom_feature_available(PRF_XXX)) + * ... + */ + +#define PRF_PAL_CACHE_FLUSH_SAFE 0 +#define PRF_DEVICE_FLUSH_LIST 1 +#define PRF_HOTPLUG_SUPPORT 2 + +/* --------------------- OS Features -------------------------------*/ + +/* + * The following defines OS features that are optionally present in + * the operating system. + * During boot, PROM is notified of these features via a series of calls: + * + * ia64_sn_set_os_feature(feature1); + * + * Once enabled, a feature cannot be disabled. + * + * By default, features are disabled unless explicitly enabled. + */ +#define OSF_MCA_SLV_TO_OS_INIT_SLV 0 +#define OSF_FEAT_LOG_SBES 1 + +#endif /* _ASM_IA64_SN_FEATURE_SETS_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/tiocp.h b/xen/include/asm-ia64/linux/asm/sn/tiocp.h new file mode 100644 index 0000000000..e8ad0bb5b6 --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/tiocp.h @@ -0,0 +1,257 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003-2005 Silicon Graphics, Inc. All rights reserved. + */ +#ifndef _ASM_IA64_SN_PCI_TIOCP_H +#define _ASM_IA64_SN_PCI_TIOCP_H + +#define TIOCP_HOST_INTR_ADDR 0x003FFFFFFFFFFFFFUL +#define TIOCP_PCI64_CMDTYPE_MEM (0x1ull << 60) +#define TIOCP_PCI64_CMDTYPE_MSI (0x3ull << 60) + + +/***************************************************************************** + *********************** TIOCP MMR structure mapping *************************** + *****************************************************************************/ + +struct tiocp{ + + /* 0x000000-0x00FFFF -- Local Registers */ + + /* 0x000000-0x000057 -- (Legacy Widget Space) Configuration */ + u64 cp_id; /* 0x000000 */ + u64 cp_stat; /* 0x000008 */ + u64 cp_err_upper; /* 0x000010 */ + u64 cp_err_lower; /* 0x000018 */ + #define cp_err cp_err_lower + u64 cp_control; /* 0x000020 */ + u64 cp_req_timeout; /* 0x000028 */ + u64 cp_intr_upper; /* 0x000030 */ + u64 cp_intr_lower; /* 0x000038 */ + #define cp_intr cp_intr_lower + u64 cp_err_cmdword; /* 0x000040 */ + u64 _pad_000048; /* 0x000048 */ + u64 cp_tflush; /* 0x000050 */ + + /* 0x000058-0x00007F -- Bridge-specific Configuration */ + u64 cp_aux_err; /* 0x000058 */ + u64 cp_resp_upper; /* 0x000060 */ + u64 cp_resp_lower; /* 0x000068 */ + #define cp_resp cp_resp_lower + u64 cp_tst_pin_ctrl; /* 0x000070 */ + u64 cp_addr_lkerr; /* 0x000078 */ + + /* 0x000080-0x00008F -- PMU & MAP */ + u64 cp_dir_map; /* 0x000080 */ + u64 _pad_000088; /* 0x000088 */ + + /* 0x000090-0x00009F -- SSRAM */ + u64 cp_map_fault; /* 0x000090 */ + u64 _pad_000098; /* 0x000098 */ + + /* 0x0000A0-0x0000AF -- Arbitration */ + u64 cp_arb; /* 0x0000A0 */ + u64 _pad_0000A8; /* 0x0000A8 */ + + /* 0x0000B0-0x0000BF -- Number In A Can or ATE Parity Error */ + u64 cp_ate_parity_err; /* 0x0000B0 */ + u64 _pad_0000B8; /* 0x0000B8 */ + + /* 0x0000C0-0x0000FF -- PCI/GIO */ + u64 cp_bus_timeout; /* 0x0000C0 */ + u64 cp_pci_cfg; /* 0x0000C8 */ + u64 cp_pci_err_upper; /* 0x0000D0 */ + u64 cp_pci_err_lower; /* 0x0000D8 */ + #define cp_pci_err cp_pci_err_lower + u64 _pad_0000E0[4]; /* 0x0000{E0..F8} */ + + /* 0x000100-0x0001FF -- Interrupt */ + u64 cp_int_status; /* 0x000100 */ + u64 cp_int_enable; /* 0x000108 */ + u64 cp_int_rst_stat; /* 0x000110 */ + u64 cp_int_mode; /* 0x000118 */ + u64 cp_int_device; /* 0x000120 */ + u64 cp_int_host_err; /* 0x000128 */ + u64 cp_int_addr[8]; /* 0x0001{30,,,68} */ + u64 cp_err_int_view; /* 0x000170 */ + u64 cp_mult_int; /* 0x000178 */ + u64 cp_force_always[8]; /* 0x0001{80,,,B8} */ + u64 cp_force_pin[8]; /* 0x0001{C0,,,F8} */ + + /* 0x000200-0x000298 -- Device */ + u64 cp_device[4]; /* 0x0002{00,,,18} */ + u64 _pad_000220[4]; /* 0x0002{20,,,38} */ + u64 cp_wr_req_buf[4]; /* 0x0002{40,,,58} */ + u64 _pad_000260[4]; /* 0x0002{60,,,78} */ + u64 cp_rrb_map[2]; /* 0x0002{80,,,88} */ + #define cp_even_resp cp_rrb_map[0] /* 0x000280 */ + #define cp_odd_resp cp_rrb_map[1] /* 0x000288 */ + u64 cp_resp_status; /* 0x000290 */ + u64 cp_resp_clear; /* 0x000298 */ + + u64 _pad_0002A0[12]; /* 0x0002{A0..F8} */ + + /* 0x000300-0x0003F8 -- Buffer Address Match Registers */ + struct { + u64 upper; /* 0x0003{00,,,F0} */ + u64 lower; /* 0x0003{08,,,F8} */ + } cp_buf_addr_match[16]; + + /* 0x000400-0x0005FF -- Performance Monitor Registers (even only) */ + struct { + u64 flush_w_touch; /* 0x000{400,,,5C0} */ + u64 flush_wo_touch; /* 0x000{408,,,5C8} */ + u64 inflight; /* 0x000{410,,,5D0} */ + u64 prefetch; /* 0x000{418,,,5D8} */ + u64 total_pci_retry; /* 0x000{420,,,5E0} */ + u64 max_pci_retry; /* 0x000{428,,,5E8} */ + u64 max_latency; /* 0x000{430,,,5F0} */ + u64 clear_all; /* 0x000{438,,,5F8} */ + } cp_buf_count[8]; + + + /* 0x000600-0x0009FF -- PCI/X registers */ + u64 cp_pcix_bus_err_addr; /* 0x000600 */ + u64 cp_pcix_bus_err_attr; /* 0x000608 */ + u64 cp_pcix_bus_err_data; /* 0x000610 */ + u64 cp_pcix_pio_split_addr; /* 0x000618 */ + u64 cp_pcix_pio_split_attr; /* 0x000620 */ + u64 cp_pcix_dma_req_err_attr; /* 0x000628 */ + u64 cp_pcix_dma_req_err_addr; /* 0x000630 */ + u64 cp_pcix_timeout; /* 0x000638 */ + + u64 _pad_000640[24]; /* 0x000{640,,,6F8} */ + + /* 0x000700-0x000737 -- Debug Registers */ + u64 cp_ct_debug_ctl; /* 0x000700 */ + u64 cp_br_debug_ctl; /* 0x000708 */ + u64 cp_mux3_debug_ctl; /* 0x000710 */ + u64 cp_mux4_debug_ctl; /* 0x000718 */ + u64 cp_mux5_debug_ctl; /* 0x000720 */ + u64 cp_mux6_debug_ctl; /* 0x000728 */ + u64 cp_mux7_debug_ctl; /* 0x000730 */ + + u64 _pad_000738[89]; /* 0x000{738,,,9F8} */ + + /* 0x000A00-0x000BFF -- PCI/X Read&Write Buffer */ + struct { + u64 cp_buf_addr; /* 0x000{A00,,,AF0} */ + u64 cp_buf_attr; /* 0X000{A08,,,AF8} */ + } cp_pcix_read_buf_64[16]; + + struct { + u64 cp_buf_addr; /* 0x000{B00,,,BE0} */ + u64 cp_buf_attr; /* 0x000{B08,,,BE8} */ + u64 cp_buf_valid; /* 0x000{B10,,,BF0} */ + u64 __pad1; /* 0x000{B18,,,BF8} */ + } cp_pcix_write_buf_64[8]; + + /* End of Local Registers -- Start of Address Map space */ + + char _pad_000c00[0x010000 - 0x000c00]; + + /* 0x010000-0x011FF8 -- Internal ATE RAM (Auto Parity Generation) */ + u64 cp_int_ate_ram[1024]; /* 0x010000-0x011FF8 */ + + char _pad_012000[0x14000 - 0x012000]; + + /* 0x014000-0x015FF8 -- Internal ATE RAM (Manual Parity Generation) */ + u64 cp_int_ate_ram_mp[1024]; /* 0x014000-0x015FF8 */ + + char _pad_016000[0x18000 - 0x016000]; + + /* 0x18000-0x197F8 -- TIOCP Write Request Ram */ + u64 cp_wr_req_lower[256]; /* 0x18000 - 0x187F8 */ + u64 cp_wr_req_upper[256]; /* 0x18800 - 0x18FF8 */ + u64 cp_wr_req_parity[256]; /* 0x19000 - 0x197F8 */ + + char _pad_019800[0x1C000 - 0x019800]; + + /* 0x1C000-0x1EFF8 -- TIOCP Read Response Ram */ + u64 cp_rd_resp_lower[512]; /* 0x1C000 - 0x1CFF8 */ + u64 cp_rd_resp_upper[512]; /* 0x1D000 - 0x1DFF8 */ + u64 cp_rd_resp_parity[512]; /* 0x1E000 - 0x1EFF8 */ + + char _pad_01F000[0x20000 - 0x01F000]; + + /* 0x020000-0x021FFF -- Host Device (CP) Configuration Space (not used) */ + char _pad_020000[0x021000 - 0x20000]; + + /* 0x021000-0x027FFF -- PCI Device Configuration Spaces */ + union { + u8 c[0x1000 / 1]; /* 0x02{0000,,,7FFF} */ + u16 s[0x1000 / 2]; /* 0x02{0000,,,7FFF} */ + u32 l[0x1000 / 4]; /* 0x02{0000,,,7FFF} */ + u64 d[0x1000 / 8]; /* 0x02{0000,,,7FFF} */ + union { + u8 c[0x100 / 1]; + u16 s[0x100 / 2]; + u32 l[0x100 / 4]; + u64 d[0x100 / 8]; + } f[8]; + } cp_type0_cfg_dev[7]; /* 0x02{1000,,,7FFF} */ + + /* 0x028000-0x028FFF -- PCI Type 1 Configuration Space */ + union { + u8 c[0x1000 / 1]; /* 0x028000-0x029000 */ + u16 s[0x1000 / 2]; /* 0x028000-0x029000 */ + u32 l[0x1000 / 4]; /* 0x028000-0x029000 */ + u64 d[0x1000 / 8]; /* 0x028000-0x029000 */ + union { + u8 c[0x100 / 1]; + u16 s[0x100 / 2]; + u32 l[0x100 / 4]; + u64 d[0x100 / 8]; + } f[8]; + } cp_type1_cfg; /* 0x028000-0x029000 */ + + char _pad_029000[0x030000-0x029000]; + + /* 0x030000-0x030007 -- PCI Interrupt Acknowledge Cycle */ + union { + u8 c[8 / 1]; + u16 s[8 / 2]; + u32 l[8 / 4]; + u64 d[8 / 8]; + } cp_pci_iack; /* 0x030000-0x030007 */ + + char _pad_030007[0x040000-0x030008]; + + /* 0x040000-0x040007 -- PCIX Special Cycle */ + union { + u8 c[8 / 1]; + u16 s[8 / 2]; + u32 l[8 / 4]; + u64 d[8 / 8]; + } cp_pcix_cycle; /* 0x040000-0x040007 */ + + char _pad_040007[0x200000-0x040008]; + + /* 0x200000-0x7FFFFF -- PCI/GIO Device Spaces */ + union { + u8 c[0x100000 / 1]; + u16 s[0x100000 / 2]; + u32 l[0x100000 / 4]; + u64 d[0x100000 / 8]; + } cp_devio_raw[6]; /* 0x200000-0x7FFFFF */ + + #define cp_devio(n) cp_devio_raw[((n)<2)?(n*2):(n+2)] + + char _pad_800000[0xA00000-0x800000]; + + /* 0xA00000-0xBFFFFF -- PCI/GIO Device Spaces w/flush */ + union { + u8 c[0x100000 / 1]; + u16 s[0x100000 / 2]; + u32 l[0x100000 / 4]; + u64 d[0x100000 / 8]; + } cp_devio_raw_flush[6]; /* 0xA00000-0xBFFFFF */ + + #define cp_devio_flush(n) cp_devio_raw_flush[((n)<2)?(n*2):(n+2)] + +}; + +#endif /* _ASM_IA64_SN_PCI_TIOCP_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/xbow.h b/xen/include/asm-ia64/linux/asm/sn/xbow.h new file mode 100644 index 0000000000..90f37a4133 --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/xbow.h @@ -0,0 +1,301 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992-1997,2000-2006 Silicon Graphics, Inc. All Rights + * Reserved. + */ +#ifndef _ASM_IA64_SN_XTALK_XBOW_H +#define _ASM_IA64_SN_XTALK_XBOW_H + +#define XBOW_PORT_8 0x8 +#define XBOW_PORT_C 0xc +#define XBOW_PORT_F 0xf + +#define MAX_XBOW_PORTS 8 /* number of ports on xbow chip */ +#define BASE_XBOW_PORT XBOW_PORT_8 /* Lowest external port */ + +#define XBOW_CREDIT 4 + +#define MAX_XBOW_NAME 16 + +/* Register set for each xbow link */ +typedef volatile struct xb_linkregs_s { +/* + * we access these through synergy unswizzled space, so the address + * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) + * That's why we put the register first and filler second. + */ + u32 link_ibf; + u32 filler0; /* filler for proper alignment */ + u32 link_control; + u32 filler1; + u32 link_status; + u32 filler2; + u32 link_arb_upper; + u32 filler3; + u32 link_arb_lower; + u32 filler4; + u32 link_status_clr; + u32 filler5; + u32 link_reset; + u32 filler6; + u32 link_aux_status; + u32 filler7; +} xb_linkregs_t; + +typedef volatile struct xbow_s { + /* standard widget configuration 0x000000-0x000057 */ + struct widget_cfg xb_widget; /* 0x000000 */ + + /* helper fieldnames for accessing bridge widget */ + +#define xb_wid_id xb_widget.w_id +#define xb_wid_stat xb_widget.w_status +#define xb_wid_err_upper xb_widget.w_err_upper_addr +#define xb_wid_err_lower xb_widget.w_err_lower_addr +#define xb_wid_control xb_widget.w_control +#define xb_wid_req_timeout xb_widget.w_req_timeout +#define xb_wid_int_upper xb_widget.w_intdest_upper_addr +#define xb_wid_int_lower xb_widget.w_intdest_lower_addr +#define xb_wid_err_cmdword xb_widget.w_err_cmd_word +#define xb_wid_llp xb_widget.w_llp_cfg +#define xb_wid_stat_clr xb_widget.w_tflush + +/* + * we access these through synergy unswizzled space, so the address + * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.) + * That's why we put the register first and filler second. + */ + /* xbow-specific widget configuration 0x000058-0x0000FF */ + u32 xb_wid_arb_reload; /* 0x00005C */ + u32 _pad_000058; + u32 xb_perf_ctr_a; /* 0x000064 */ + u32 _pad_000060; + u32 xb_perf_ctr_b; /* 0x00006c */ + u32 _pad_000068; + u32 xb_nic; /* 0x000074 */ + u32 _pad_000070; + + /* Xbridge only */ + u32 xb_w0_rst_fnc; /* 0x00007C */ + u32 _pad_000078; + u32 xb_l8_rst_fnc; /* 0x000084 */ + u32 _pad_000080; + u32 xb_l9_rst_fnc; /* 0x00008c */ + u32 _pad_000088; + u32 xb_la_rst_fnc; /* 0x000094 */ + u32 _pad_000090; + u32 xb_lb_rst_fnc; /* 0x00009c */ + u32 _pad_000098; + u32 xb_lc_rst_fnc; /* 0x0000a4 */ + u32 _pad_0000a0; + u32 xb_ld_rst_fnc; /* 0x0000ac */ + u32 _pad_0000a8; + u32 xb_le_rst_fnc; /* 0x0000b4 */ + u32 _pad_0000b0; + u32 xb_lf_rst_fnc; /* 0x0000bc */ + u32 _pad_0000b8; + u32 xb_lock; /* 0x0000c4 */ + u32 _pad_0000c0; + u32 xb_lock_clr; /* 0x0000cc */ + u32 _pad_0000c8; + /* end of Xbridge only */ + u32 _pad_0000d0[12]; + + /* Link Specific Registers, port 8..15 0x000100-0x000300 */ + xb_linkregs_t xb_link_raw[MAX_XBOW_PORTS]; +} xbow_t; + +#define xb_link(p) xb_link_raw[(p) & (MAX_XBOW_PORTS - 1)] + +#define XB_FLAGS_EXISTS 0x1 /* device exists */ +#define XB_FLAGS_MASTER 0x2 +#define XB_FLAGS_SLAVE 0x0 +#define XB_FLAGS_GBR 0x4 +#define XB_FLAGS_16BIT 0x8 +#define XB_FLAGS_8BIT 0x0 + +/* is widget port number valid? (based on version 7.0 of xbow spec) */ +#define XBOW_WIDGET_IS_VALID(wid) ((wid) >= XBOW_PORT_8 && (wid) <= XBOW_PORT_F) + +/* whether to use upper or lower arbitration register, given source widget id */ +#define XBOW_ARB_IS_UPPER(wid) ((wid) >= XBOW_PORT_8 && (wid) <= XBOW_PORT_B) +#define XBOW_ARB_IS_LOWER(wid) ((wid) >= XBOW_PORT_C && (wid) <= XBOW_PORT_F) + +/* offset of arbitration register, given source widget id */ +#define XBOW_ARB_OFF(wid) (XBOW_ARB_IS_UPPER(wid) ? 0x1c : 0x24) + +#define XBOW_WID_ID WIDGET_ID +#define XBOW_WID_STAT WIDGET_STATUS +#define XBOW_WID_ERR_UPPER WIDGET_ERR_UPPER_ADDR +#define XBOW_WID_ERR_LOWER WIDGET_ERR_LOWER_ADDR +#define XBOW_WID_CONTROL WIDGET_CONTROL +#define XBOW_WID_REQ_TO WIDGET_REQ_TIMEOUT +#define XBOW_WID_INT_UPPER WIDGET_INTDEST_UPPER_ADDR +#define XBOW_WID_INT_LOWER WIDGET_INTDEST_LOWER_ADDR +#define XBOW_WID_ERR_CMDWORD WIDGET_ERR_CMD_WORD +#define XBOW_WID_LLP WIDGET_LLP_CFG +#define XBOW_WID_STAT_CLR WIDGET_TFLUSH +#define XBOW_WID_ARB_RELOAD 0x5c +#define XBOW_WID_PERF_CTR_A 0x64 +#define XBOW_WID_PERF_CTR_B 0x6c +#define XBOW_WID_NIC 0x74 + +/* Xbridge only */ +#define XBOW_W0_RST_FNC 0x00007C +#define XBOW_L8_RST_FNC 0x000084 +#define XBOW_L9_RST_FNC 0x00008c +#define XBOW_LA_RST_FNC 0x000094 +#define XBOW_LB_RST_FNC 0x00009c +#define XBOW_LC_RST_FNC 0x0000a4 +#define XBOW_LD_RST_FNC 0x0000ac +#define XBOW_LE_RST_FNC 0x0000b4 +#define XBOW_LF_RST_FNC 0x0000bc +#define XBOW_RESET_FENCE(x) ((x) > 7 && (x) < 16) ? \ + (XBOW_W0_RST_FNC + ((x) - 7) * 8) : \ + ((x) == 0) ? XBOW_W0_RST_FNC : 0 +#define XBOW_LOCK 0x0000c4 +#define XBOW_LOCK_CLR 0x0000cc +/* End of Xbridge only */ + +/* used only in ide, but defined here within the reserved portion */ +/* of the widget0 address space (before 0xf4) */ +#define XBOW_WID_UNDEF 0xe4 + +/* xbow link register set base, legal value for x is 0x8..0xf */ +#define XB_LINK_BASE 0x100 +#define XB_LINK_OFFSET 0x40 +#define XB_LINK_REG_BASE(x) (XB_LINK_BASE + ((x) & (MAX_XBOW_PORTS - 1)) * XB_LINK_OFFSET) + +#define XB_LINK_IBUF_FLUSH(x) (XB_LINK_REG_BASE(x) + 0x4) +#define XB_LINK_CTRL(x) (XB_LINK_REG_BASE(x) + 0xc) +#define XB_LINK_STATUS(x) (XB_LINK_REG_BASE(x) + 0x14) +#define XB_LINK_ARB_UPPER(x) (XB_LINK_REG_BASE(x) + 0x1c) +#define XB_LINK_ARB_LOWER(x) (XB_LINK_REG_BASE(x) + 0x24) +#define XB_LINK_STATUS_CLR(x) (XB_LINK_REG_BASE(x) + 0x2c) +#define XB_LINK_RESET(x) (XB_LINK_REG_BASE(x) + 0x34) +#define XB_LINK_AUX_STATUS(x) (XB_LINK_REG_BASE(x) + 0x3c) + +/* link_control(x) */ +#define XB_CTRL_LINKALIVE_IE 0x80000000 /* link comes alive */ +/* reserved: 0x40000000 */ +#define XB_CTRL_PERF_CTR_MODE_MSK 0x30000000 /* perf counter mode */ +#define XB_CTRL_IBUF_LEVEL_MSK 0x0e000000 /* input packet buffer + level */ +#define XB_CTRL_8BIT_MODE 0x01000000 /* force link into 8 + bit mode */ +#define XB_CTRL_BAD_LLP_PKT 0x00800000 /* force bad LLP + packet */ +#define XB_CTRL_WIDGET_CR_MSK 0x007c0000 /* LLP widget credit + mask */ +#define XB_CTRL_WIDGET_CR_SHFT 18 /* LLP widget credit + shift */ +#define XB_CTRL_ILLEGAL_DST_IE 0x00020000 /* illegal destination + */ +#define XB_CTRL_OALLOC_IBUF_IE 0x00010000 /* overallocated input + buffer */ +/* reserved: 0x0000fe00 */ +#define XB_CTRL_BNDWDTH_ALLOC_IE 0x00000100 /* bandwidth alloc */ +#define XB_CTRL_RCV_CNT_OFLOW_IE 0x00000080 /* rcv retry overflow */ +#define XB_CTRL_XMT_CNT_OFLOW_IE 0x00000040 /* xmt retry overflow */ +#define XB_CTRL_XMT_MAX_RTRY_IE 0x00000020 /* max transmit retry */ +#define XB_CTRL_RCV_IE 0x00000010 /* receive */ +#define XB_CTRL_XMT_RTRY_IE 0x00000008 /* transmit retry */ +/* reserved: 0x00000004 */ +#define XB_CTRL_MAXREQ_TOUT_IE 0x00000002 /* maximum request + timeout */ +#define XB_CTRL_SRC_TOUT_IE 0x00000001 /* source timeout */ + +/* link_status(x) */ +#define XB_STAT_LINKALIVE XB_CTRL_LINKALIVE_IE +/* reserved: 0x7ff80000 */ +#define XB_STAT_MULTI_ERR 0x00040000 /* multi error */ +#define XB_STAT_ILLEGAL_DST_ERR XB_CTRL_ILLEGAL_DST_IE +#define XB_STAT_OALLOC_IBUF_ERR XB_CTRL_OALLOC_IBUF_IE +#define XB_STAT_BNDWDTH_ALLOC_ID_MSK 0x0000ff00 /* port bitmask */ +#define XB_STAT_RCV_CNT_OFLOW_ERR XB_CTRL_RCV_CNT_OFLOW_IE +#define XB_STAT_XMT_CNT_OFLOW_ERR XB_CTRL_XMT_CNT_OFLOW_IE +#define XB_STAT_XMT_MAX_RTRY_ERR XB_CTRL_XMT_MAX_RTRY_IE +#define XB_STAT_RCV_ERR XB_CTRL_RCV_IE +#define XB_STAT_XMT_RTRY_ERR XB_CTRL_XMT_RTRY_IE +/* reserved: 0x00000004 */ +#define XB_STAT_MAXREQ_TOUT_ERR XB_CTRL_MAXREQ_TOUT_IE +#define XB_STAT_SRC_TOUT_ERR XB_CTRL_SRC_TOUT_IE + +/* link_aux_status(x) */ +#define XB_AUX_STAT_RCV_CNT 0xff000000 +#define XB_AUX_STAT_XMT_CNT 0x00ff0000 +#define XB_AUX_STAT_TOUT_DST 0x0000ff00 +#define XB_AUX_LINKFAIL_RST_BAD 0x00000040 +#define XB_AUX_STAT_PRESENT 0x00000020 +#define XB_AUX_STAT_PORT_WIDTH 0x00000010 +/* reserved: 0x0000000f */ + +/* + * link_arb_upper/link_arb_lower(x), (reg) should be the link_arb_upper + * register if (x) is 0x8..0xb, link_arb_lower if (x) is 0xc..0xf + */ +#define XB_ARB_GBR_MSK 0x1f +#define XB_ARB_RR_MSK 0x7 +#define XB_ARB_GBR_SHFT(x) (((x) & 0x3) * 8) +#define XB_ARB_RR_SHFT(x) (((x) & 0x3) * 8 + 5) +#define XB_ARB_GBR_CNT(reg,x) ((reg) >> XB_ARB_GBR_SHFT(x) & XB_ARB_GBR_MSK) +#define XB_ARB_RR_CNT(reg,x) ((reg) >> XB_ARB_RR_SHFT(x) & XB_ARB_RR_MSK) + +/* XBOW_WID_STAT */ +#define XB_WID_STAT_LINK_INTR_SHFT (24) +#define XB_WID_STAT_LINK_INTR_MASK (0xFF << XB_WID_STAT_LINK_INTR_SHFT) +#define XB_WID_STAT_LINK_INTR(x) \ + (0x1 << (((x)&7) + XB_WID_STAT_LINK_INTR_SHFT)) +#define XB_WID_STAT_WIDGET0_INTR 0x00800000 +#define XB_WID_STAT_SRCID_MASK 0x000003c0 /* Xbridge only */ +#define XB_WID_STAT_REG_ACC_ERR 0x00000020 +#define XB_WID_STAT_RECV_TOUT 0x00000010 /* Xbridge only */ +#define XB_WID_STAT_ARB_TOUT 0x00000008 /* Xbridge only */ +#define XB_WID_STAT_XTALK_ERR 0x00000004 +#define XB_WID_STAT_DST_TOUT 0x00000002 /* Xbridge only */ +#define XB_WID_STAT_MULTI_ERR 0x00000001 + +#define XB_WID_STAT_SRCID_SHFT 6 + +/* XBOW_WID_CONTROL */ +#define XB_WID_CTRL_REG_ACC_IE XB_WID_STAT_REG_ACC_ERR +#define XB_WID_CTRL_RECV_TOUT XB_WID_STAT_RECV_TOUT +#define XB_WID_CTRL_ARB_TOUT XB_WID_STAT_ARB_TOUT +#define XB_WID_CTRL_XTALK_IE XB_WID_STAT_XTALK_ERR + +/* XBOW_WID_INT_UPPER */ +/* defined in xwidget.h for WIDGET_INTDEST_UPPER_ADDR */ + +/* XBOW WIDGET part number, in the ID register */ +#define XBOW_WIDGET_PART_NUM 0x0 /* crossbow */ +#define XXBOW_WIDGET_PART_NUM 0xd000 /* Xbridge */ +#define XBOW_WIDGET_MFGR_NUM 0x0 +#define XXBOW_WIDGET_MFGR_NUM 0x0 +#define PXBOW_WIDGET_PART_NUM 0xd100 /* PIC */ + +#define XBOW_REV_1_0 0x1 /* xbow rev 1.0 is "1" */ +#define XBOW_REV_1_1 0x2 /* xbow rev 1.1 is "2" */ +#define XBOW_REV_1_2 0x3 /* xbow rev 1.2 is "3" */ +#define XBOW_REV_1_3 0x4 /* xbow rev 1.3 is "4" */ +#define XBOW_REV_2_0 0x5 /* xbow rev 2.0 is "5" */ + +#define XXBOW_PART_REV_1_0 (XXBOW_WIDGET_PART_NUM << 4 | 0x1 ) +#define XXBOW_PART_REV_2_0 (XXBOW_WIDGET_PART_NUM << 4 | 0x2 ) + +/* XBOW_WID_ARB_RELOAD */ +#define XBOW_WID_ARB_RELOAD_INT 0x3f /* GBR reload interval */ + +#define IS_XBRIDGE_XBOW(wid) \ + (XWIDGET_PART_NUM(wid) == XXBOW_WIDGET_PART_NUM && \ + XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) + +#define IS_PIC_XBOW(wid) \ + (XWIDGET_PART_NUM(wid) == PXBOW_WIDGET_PART_NUM && \ + XWIDGET_MFG_NUM(wid) == XXBOW_WIDGET_MFGR_NUM) + +#define XBOW_WAR_ENABLED(pv, widid) ((1 << XWIDGET_REV_NUM(widid)) & pv) + +#endif /* _ASM_IA64_SN_XTALK_XBOW_H */ diff --git a/xen/include/asm-ia64/linux/asm/sn/xwidgetdev.h b/xen/include/asm-ia64/linux/asm/sn/xwidgetdev.h new file mode 100644 index 0000000000..2800eda0fd --- /dev/null +++ b/xen/include/asm-ia64/linux/asm/sn/xwidgetdev.h @@ -0,0 +1,70 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All Rights Reserved. + */ +#ifndef _ASM_IA64_SN_XTALK_XWIDGET_H +#define _ASM_IA64_SN_XTALK_XWIDGET_H + +/* WIDGET_ID */ +#define WIDGET_REV_NUM 0xf0000000 +#define WIDGET_PART_NUM 0x0ffff000 +#define WIDGET_MFG_NUM 0x00000ffe +#define WIDGET_REV_NUM_SHFT 28 +#define WIDGET_PART_NUM_SHFT 12 +#define WIDGET_MFG_NUM_SHFT 1 + +#define XWIDGET_PART_NUM(widgetid) (((widgetid) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT) +#define XWIDGET_REV_NUM(widgetid) (((widgetid) & WIDGET_REV_NUM) >> WIDGET_REV_NUM_SHFT) +#define XWIDGET_MFG_NUM(widgetid) (((widgetid) & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT) +#define XWIDGET_PART_REV_NUM(widgetid) ((XWIDGET_PART_NUM(widgetid) << 4) | \ + XWIDGET_REV_NUM(widgetid)) +#define XWIDGET_PART_REV_NUM_REV(partrev) (partrev & 0xf) + +/* widget configuration registers */ +struct widget_cfg{ + u32 w_id; /* 0x04 */ + u32 w_pad_0; /* 0x00 */ + u32 w_status; /* 0x0c */ + u32 w_pad_1; /* 0x08 */ + u32 w_err_upper_addr; /* 0x14 */ + u32 w_pad_2; /* 0x10 */ + u32 w_err_lower_addr; /* 0x1c */ + u32 w_pad_3; /* 0x18 */ + u32 w_control; /* 0x24 */ + u32 w_pad_4; /* 0x20 */ + u32 w_req_timeout; /* 0x2c */ + u32 w_pad_5; /* 0x28 */ + u32 w_intdest_upper_addr; /* 0x34 */ + u32 w_pad_6; /* 0x30 */ + u32 w_intdest_lower_addr; /* 0x3c */ + u32 w_pad_7; /* 0x38 */ + u32 w_err_cmd_word; /* 0x44 */ + u32 w_pad_8; /* 0x40 */ + u32 w_llp_cfg; /* 0x4c */ + u32 w_pad_9; /* 0x48 */ + u32 w_tflush; /* 0x54 */ + u32 w_pad_10; /* 0x50 */ +}; + +/* + * Crosstalk Widget Hardware Identification, as defined in the Crosstalk spec. + */ +struct xwidget_hwid{ + int mfg_num; + int rev_num; + int part_num; +}; + +struct xwidget_info{ + + struct xwidget_hwid xwi_hwid; /* Widget Identification */ + char xwi_masterxid; /* Hub's Widget Port Number */ + void *xwi_hubinfo; /* Hub's provider private info */ + u64 *xwi_hub_provider; /* prom provider functions */ + void *xwi_vertex; +}; + +#endif /* _ASM_IA64_SN_XTALK_XWIDGET_H */ diff --git a/xen/include/asm-ia64/linux/completion.h b/xen/include/asm-ia64/linux/completion.h new file mode 100644 index 0000000000..268c5a4a2b --- /dev/null +++ b/xen/include/asm-ia64/linux/completion.h @@ -0,0 +1,57 @@ +#ifndef __LINUX_COMPLETION_H +#define __LINUX_COMPLETION_H + +/* + * (C) Copyright 2001 Linus Torvalds + * + * Atomic wait-for-completion handler data structures. + * See kernel/sched.c for details. + */ + +#include + +struct completion { + unsigned int done; + wait_queue_head_t wait; +}; + +#define COMPLETION_INITIALIZER(work) \ + { 0, __WAIT_QUEUE_HEAD_INITIALIZER((work).wait) } + +#define COMPLETION_INITIALIZER_ONSTACK(work) \ + ({ init_completion(&work); work; }) + +#define DECLARE_COMPLETION(work) \ + struct completion work = COMPLETION_INITIALIZER(work) + +/* + * Lockdep needs to run a non-constant initializer for on-stack + * completions - so we use the _ONSTACK() variant for those that + * are on the kernel stack: + */ +#ifdef CONFIG_LOCKDEP +# define DECLARE_COMPLETION_ONSTACK(work) \ + struct completion work = COMPLETION_INITIALIZER_ONSTACK(work) +#else +# define DECLARE_COMPLETION_ONSTACK(work) DECLARE_COMPLETION(work) +#endif + +static inline void init_completion(struct completion *x) +{ + x->done = 0; + init_waitqueue_head(&x->wait); +} + +extern void FASTCALL(wait_for_completion(struct completion *)); +extern int FASTCALL(wait_for_completion_interruptible(struct completion *x)); +extern unsigned long FASTCALL(wait_for_completion_timeout(struct completion *x, + unsigned long timeout)); +extern unsigned long FASTCALL(wait_for_completion_interruptible_timeout( + struct completion *x, unsigned long timeout)); + +extern void FASTCALL(complete(struct completion *)); +extern void FASTCALL(complete_all(struct completion *)); + +#define INIT_COMPLETION(x) ((x).done = 0) + +#endif diff --git a/xen/include/asm-ia64/linux/ioport.h b/xen/include/asm-ia64/linux/ioport.h new file mode 100644 index 0000000000..d42c833990 --- /dev/null +++ b/xen/include/asm-ia64/linux/ioport.h @@ -0,0 +1,136 @@ +/* + * ioport.h Definitions of routines for detecting, reserving and + * allocating system resources. + * + * Authors: Linus Torvalds + */ + +#ifndef _LINUX_IOPORT_H +#define _LINUX_IOPORT_H + +#include +#include +/* + * Resources are tree-like, allowing + * nesting etc.. + */ +struct resource { + resource_size_t start; + resource_size_t end; + const char *name; + unsigned long flags; + struct resource *parent, *sibling, *child; +}; + +struct resource_list { + struct resource_list *next; + struct resource *res; + struct pci_dev *dev; +}; + +/* + * IO resources have these defined flags. + */ +#define IORESOURCE_BITS 0x000000ff /* Bus-specific bits */ + +#define IORESOURCE_IO 0x00000100 /* Resource type */ +#define IORESOURCE_MEM 0x00000200 +#define IORESOURCE_IRQ 0x00000400 +#define IORESOURCE_DMA 0x00000800 + +#define IORESOURCE_PREFETCH 0x00001000 /* No side effects */ +#define IORESOURCE_READONLY 0x00002000 +#define IORESOURCE_CACHEABLE 0x00004000 +#define IORESOURCE_RANGELENGTH 0x00008000 +#define IORESOURCE_SHADOWABLE 0x00010000 +#define IORESOURCE_BUS_HAS_VGA 0x00080000 + +#define IORESOURCE_DISABLED 0x10000000 +#define IORESOURCE_UNSET 0x20000000 +#define IORESOURCE_AUTO 0x40000000 +#define IORESOURCE_BUSY 0x80000000 /* Driver has marked this resource busy */ + +/* ISA PnP IRQ specific bits (IORESOURCE_BITS) */ +#define IORESOURCE_IRQ_HIGHEDGE (1<<0) +#define IORESOURCE_IRQ_LOWEDGE (1<<1) +#define IORESOURCE_IRQ_HIGHLEVEL (1<<2) +#define IORESOURCE_IRQ_LOWLEVEL (1<<3) +#define IORESOURCE_IRQ_SHAREABLE (1<<4) + +/* ISA PnP DMA specific bits (IORESOURCE_BITS) */ +#define IORESOURCE_DMA_TYPE_MASK (3<<0) +#define IORESOURCE_DMA_8BIT (0<<0) +#define IORESOURCE_DMA_8AND16BIT (1<<0) +#define IORESOURCE_DMA_16BIT (2<<0) + +#define IORESOURCE_DMA_MASTER (1<<2) +#define IORESOURCE_DMA_BYTE (1<<3) +#define IORESOURCE_DMA_WORD (1<<4) + +#define IORESOURCE_DMA_SPEED_MASK (3<<6) +#define IORESOURCE_DMA_COMPATIBLE (0<<6) +#define IORESOURCE_DMA_TYPEA (1<<6) +#define IORESOURCE_DMA_TYPEB (2<<6) +#define IORESOURCE_DMA_TYPEF (3<<6) + +/* ISA PnP memory I/O specific bits (IORESOURCE_BITS) */ +#define IORESOURCE_MEM_WRITEABLE (1<<0) /* dup: IORESOURCE_READONLY */ +#define IORESOURCE_MEM_CACHEABLE (1<<1) /* dup: IORESOURCE_CACHEABLE */ +#define IORESOURCE_MEM_RANGELENGTH (1<<2) /* dup: IORESOURCE_RANGELENGTH */ +#define IORESOURCE_MEM_TYPE_MASK (3<<3) +#define IORESOURCE_MEM_8BIT (0<<3) +#define IORESOURCE_MEM_16BIT (1<<3) +#define IORESOURCE_MEM_8AND16BIT (2<<3) +#define IORESOURCE_MEM_32BIT (3<<3) +#define IORESOURCE_MEM_SHADOWABLE (1<<5) /* dup: IORESOURCE_SHADOWABLE */ +#define IORESOURCE_MEM_EXPANSIONROM (1<<6) + +/* PCI ROM control bits (IORESOURCE_BITS) */ +#define IORESOURCE_ROM_ENABLE (1<<0) /* ROM is enabled, same as PCI_ROM_ADDRESS_ENABLE */ +#define IORESOURCE_ROM_SHADOW (1<<1) /* ROM is copy at C000:0 */ +#define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */ + +/* PC/ISA/whatever - the normal PC address spaces: IO and memory */ +extern struct resource ioport_resource; +extern struct resource iomem_resource; + +extern int request_resource(struct resource *root, struct resource *new); +extern struct resource * ____request_resource(struct resource *root, struct resource *new); +extern int release_resource(struct resource *new); +extern int insert_resource(struct resource *parent, struct resource *new); +extern int allocate_resource(struct resource *root, struct resource *new, + resource_size_t size, resource_size_t min, + resource_size_t max, resource_size_t align, + void (*alignf)(void *, struct resource *, + resource_size_t, resource_size_t), + void *alignf_data); +int adjust_resource(struct resource *res, resource_size_t start, + resource_size_t size); + +/* get registered SYSTEM_RAM resources in specified area */ +extern int find_next_system_ram(struct resource *res); + +/* Convenience shorthand with allocation */ +#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name)) +#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name)) +#define rename_region(region, newname) do { (region)->name = (newname); } while (0) + +extern struct resource * __request_region(struct resource *, + resource_size_t start, + resource_size_t n, const char *name); + +/* Compatibility cruft */ +#define release_region(start,n) __release_region(&ioport_resource, (start), (n)) +#define check_mem_region(start,n) __check_region(&iomem_resource, (start), (n)) +#define release_mem_region(start,n) __release_region(&iomem_resource, (start), (n)) + +extern int __check_region(struct resource *, resource_size_t, resource_size_t); +extern void __release_region(struct resource *, resource_size_t, + resource_size_t); + +static inline int __deprecated check_region(resource_size_t s, + resource_size_t n) +{ + return __check_region(&ioport_resource, s, n); +} +#endif /* _LINUX_IOPORT_H */ diff --git a/xen/include/asm-ia64/linux/klist.h b/xen/include/asm-ia64/linux/klist.h new file mode 100644 index 0000000000..74071254c9 --- /dev/null +++ b/xen/include/asm-ia64/linux/klist.h @@ -0,0 +1,61 @@ +/* + * klist.h - Some generic list helpers, extending struct list_head a bit. + * + * Implementations are found in lib/klist.c + * + * + * Copyright (C) 2005 Patrick Mochel + * + * This file is rleased under the GPL v2. + */ + +#ifndef _LINUX_KLIST_H +#define _LINUX_KLIST_H + +#include +#include +#include +#include + +struct klist_node; +struct klist { + spinlock_t k_lock; + struct list_head k_list; + void (*get)(struct klist_node *); + void (*put)(struct klist_node *); +}; + + +extern void klist_init(struct klist * k, void (*get)(struct klist_node *), + void (*put)(struct klist_node *)); + +struct klist_node { + struct klist * n_klist; + struct list_head n_node; + struct kref n_ref; + struct completion n_removed; +}; + +extern void klist_add_tail(struct klist_node * n, struct klist * k); +extern void klist_add_head(struct klist_node * n, struct klist * k); + +extern void klist_del(struct klist_node * n); +extern void klist_remove(struct klist_node * n); + +extern int klist_node_attached(struct klist_node * n); + + +struct klist_iter { + struct klist * i_klist; + struct list_head * i_head; + struct klist_node * i_cur; +}; + + +extern void klist_iter_init(struct klist * k, struct klist_iter * i); +extern void klist_iter_init_node(struct klist * k, struct klist_iter * i, + struct klist_node * n); +extern void klist_iter_exit(struct klist_iter * i); +extern struct klist_node * klist_next(struct klist_iter * i); + +#endif diff --git a/xen/include/asm-ia64/linux/kref.h b/xen/include/asm-ia64/linux/kref.h new file mode 100644 index 0000000000..6fee353989 --- /dev/null +++ b/xen/include/asm-ia64/linux/kref.h @@ -0,0 +1,32 @@ +/* + * kref.c - library routines for handling generic reference counted objects + * + * Copyright (C) 2004 Greg Kroah-Hartman + * Copyright (C) 2004 IBM Corp. + * + * based on kobject.h which was: + * Copyright (C) 2002-2003 Patrick Mochel + * Copyright (C) 2002-2003 Open Source Development Labs + * + * This file is released under the GPLv2. + * + */ + +#ifndef _KREF_H_ +#define _KREF_H_ + +#ifdef __KERNEL__ + +#include +#include + +struct kref { + atomic_t refcount; +}; + +void kref_init(struct kref *kref); +void kref_get(struct kref *kref); +int kref_put(struct kref *kref, void (*release) (struct kref *kref)); + +#endif /* __KERNEL__ */ +#endif /* _KREF_H_ */ diff --git a/xen/include/asm-ia64/linux/mod_devicetable.h b/xen/include/asm-ia64/linux/mod_devicetable.h new file mode 100644 index 0000000000..e0c393cc72 --- /dev/null +++ b/xen/include/asm-ia64/linux/mod_devicetable.h @@ -0,0 +1,323 @@ +/* + * Device tables which are exported to userspace via + * scripts/mod/file2alias.c. You must keep that file in sync with this + * header. + */ + +#ifndef LINUX_MOD_DEVICETABLE_H +#define LINUX_MOD_DEVICETABLE_H + +#ifdef __KERNEL__ +#include +typedef unsigned long kernel_ulong_t; +#endif + +#define PCI_ANY_ID (~0) + +struct pci_device_id { + __u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/ + __u32 subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */ + __u32 class, class_mask; /* (class,subclass,prog-if) triplet */ + kernel_ulong_t driver_data; /* Data private to the driver */ +}; + + +#define IEEE1394_MATCH_VENDOR_ID 0x0001 +#define IEEE1394_MATCH_MODEL_ID 0x0002 +#define IEEE1394_MATCH_SPECIFIER_ID 0x0004 +#define IEEE1394_MATCH_VERSION 0x0008 + +struct ieee1394_device_id { + __u32 match_flags; + __u32 vendor_id; + __u32 model_id; + __u32 specifier_id; + __u32 version; + kernel_ulong_t driver_data + __attribute__((aligned(sizeof(kernel_ulong_t)))); +}; + + +/* + * Device table entry for "new style" table-driven USB drivers. + * User mode code can read these tables to choose which modules to load. + * Declare the table as a MODULE_DEVICE_TABLE. + * + * A probe() parameter will point to a matching entry from this table. + * Use the driver_info field for each match to hold information tied + * to that match: device quirks, etc. + * + * Terminate the driver's table with an all-zeroes entry. + * Use the flag values to control which fields are compared. + */ + +/** + * struct usb_device_id - identifies USB devices for probing and hotplugging + * @match_flags: Bit mask controlling of the other fields are used to match + * against new devices. Any field except for driver_info may be used, + * although some only make sense in conjunction with other fields. + * This is usually set by a USB_DEVICE_*() macro, which sets all + * other fields in this structure except for driver_info. + * @idVendor: USB vendor ID for a device; numbers are assigned + * by the USB forum to its members. + * @idProduct: Vendor-assigned product ID. + * @bcdDevice_lo: Low end of range of vendor-assigned product version numbers. + * This is also used to identify individual product versions, for + * a range consisting of a single device. + * @bcdDevice_hi: High end of version number range. The range of product + * versions is inclusive. + * @bDeviceClass: Class of device; numbers are assigned + * by the USB forum. Products may choose to implement classes, + * or be vendor-specific. Device classes specify behavior of all + * the interfaces on a devices. + * @bDeviceSubClass: Subclass of device; associated with bDeviceClass. + * @bDeviceProtocol: Protocol of device; associated with bDeviceClass. + * @bInterfaceClass: Class of interface; numbers are assigned + * by the USB forum. Products may choose to implement classes, + * or be vendor-specific. Interface classes specify behavior only + * of a given interface; other interfaces may support other classes. + * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass. + * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass. + * @driver_info: Holds information used by the driver. Usually it holds + * a pointer to a descriptor understood by the driver, or perhaps + * device flags. + * + * In most cases, drivers will create a table of device IDs by using + * USB_DEVICE(), or similar macros designed for that purpose. + * They will then export it to userspace using MODULE_DEVICE_TABLE(), + * and provide it to the USB core through their usb_driver structure. + * + * See the usb_match_id() function for information about how matches are + * performed. Briefly, you will normally use one of several macros to help + * construct these entries. Each entry you provide will either identify + * one or more specific products, or will identify a class of products + * which have agreed to behave the same. You should put the more specific + * matches towards the beginning of your table, so that driver_info can + * record quirks of specific products. + */ +struct usb_device_id { + /* which fields to match against? */ + __u16 match_flags; + + /* Used for product specific matches; range is inclusive */ + __u16 idVendor; + __u16 idProduct; + __u16 bcdDevice_lo; + __u16 bcdDevice_hi; + + /* Used for device class matches */ + __u8 bDeviceClass; + __u8 bDeviceSubClass; + __u8 bDeviceProtocol; + + /* Used for interface class matches */ + __u8 bInterfaceClass; + __u8 bInterfaceSubClass; + __u8 bInterfaceProtocol; + + /* not matched against */ + kernel_ulong_t driver_info; +}; + +/* Some useful macros to use to create struct usb_device_id */ +#define USB_DEVICE_ID_MATCH_VENDOR 0x0001 +#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002 +#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004 +#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008 +#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010 +#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020 +#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040 +#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080 +#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100 +#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200 + +/* s390 CCW devices */ +struct ccw_device_id { + __u16 match_flags; /* which fields to match against */ + + __u16 cu_type; /* control unit type */ + __u16 dev_type; /* device type */ + __u8 cu_model; /* control unit model */ + __u8 dev_model; /* device model */ + + kernel_ulong_t driver_info; +}; + +#define CCW_DEVICE_ID_MATCH_CU_TYPE 0x01 +#define CCW_DEVICE_ID_MATCH_CU_MODEL 0x02 +#define CCW_DEVICE_ID_MATCH_DEVICE_TYPE 0x04 +#define CCW_DEVICE_ID_MATCH_DEVICE_MODEL 0x08 + +/* s390 AP bus devices */ +struct ap_device_id { + __u16 match_flags; /* which fields to match against */ + __u8 dev_type; /* device type */ + __u8 pad1; + __u32 pad2; + kernel_ulong_t driver_info; +}; + +#define AP_DEVICE_ID_MATCH_DEVICE_TYPE 0x01 + + +#define PNP_ID_LEN 8 +#define PNP_MAX_DEVICES 8 + +struct pnp_device_id { + __u8 id[PNP_ID_LEN]; + kernel_ulong_t driver_data; +}; + +struct pnp_card_device_id { + __u8 id[PNP_ID_LEN]; + kernel_ulong_t driver_data; + struct { + __u8 id[PNP_ID_LEN]; + } devs[PNP_MAX_DEVICES]; +}; + + +#define SERIO_ANY 0xff + +struct serio_device_id { + __u8 type; + __u8 extra; + __u8 id; + __u8 proto; +}; + +/* + * Struct used for matching a device + */ +struct of_device_id +{ + char name[32]; + char type[32]; + char compatible[128]; +#ifdef __KERNEL__ + void *data; +#else + kernel_ulong_t data; +#endif +}; + +/* VIO */ +struct vio_device_id { + char type[32]; + char compat[32]; +}; + +/* PCMCIA */ + +struct pcmcia_device_id { + __u16 match_flags; + + __u16 manf_id; + __u16 card_id; + + __u8 func_id; + + /* for real multi-function devices */ + __u8 function; + + /* for pseudo multi-function devices */ + __u8 device_no; + + __u32 prod_id_hash[4] + __attribute__((aligned(sizeof(__u32)))); + + /* not matched against in kernelspace*/ +#ifdef __KERNEL__ + const char * prod_id[4]; +#else + kernel_ulong_t prod_id[4] + __attribute__((aligned(sizeof(kernel_ulong_t)))); +#endif + + /* not matched against */ + kernel_ulong_t driver_info; +#ifdef __KERNEL__ + char * cisfile; +#else + kernel_ulong_t cisfile; +#endif +}; + +#define PCMCIA_DEV_ID_MATCH_MANF_ID 0x0001 +#define PCMCIA_DEV_ID_MATCH_CARD_ID 0x0002 +#define PCMCIA_DEV_ID_MATCH_FUNC_ID 0x0004 +#define PCMCIA_DEV_ID_MATCH_FUNCTION 0x0008 +#define PCMCIA_DEV_ID_MATCH_PROD_ID1 0x0010 +#define PCMCIA_DEV_ID_MATCH_PROD_ID2 0x0020 +#define PCMCIA_DEV_ID_MATCH_PROD_ID3 0x0040 +#define PCMCIA_DEV_ID_MATCH_PROD_ID4 0x0080 +#define PCMCIA_DEV_ID_MATCH_DEVICE_NO 0x0100 +#define PCMCIA_DEV_ID_MATCH_FAKE_CIS 0x0200 +#define PCMCIA_DEV_ID_MATCH_ANONYMOUS 0x0400 + +/* I2C */ +struct i2c_device_id { + __u16 id; +}; + +/* Input */ +#define INPUT_DEVICE_ID_EV_MAX 0x1f +#define INPUT_DEVICE_ID_KEY_MAX 0x1ff +#define INPUT_DEVICE_ID_REL_MAX 0x0f +#define INPUT_DEVICE_ID_ABS_MAX 0x3f +#define INPUT_DEVICE_ID_MSC_MAX 0x07 +#define INPUT_DEVICE_ID_LED_MAX 0x0f +#define INPUT_DEVICE_ID_SND_MAX 0x07 +#define INPUT_DEVICE_ID_FF_MAX 0x7f +#define INPUT_DEVICE_ID_SW_MAX 0x0f + +#define INPUT_DEVICE_ID_MATCH_BUS 1 +#define INPUT_DEVICE_ID_MATCH_VENDOR 2 +#define INPUT_DEVICE_ID_MATCH_PRODUCT 4 +#define INPUT_DEVICE_ID_MATCH_VERSION 8 + +#define INPUT_DEVICE_ID_MATCH_EVBIT 0x0010 +#define INPUT_DEVICE_ID_MATCH_KEYBIT 0x0020 +#define INPUT_DEVICE_ID_MATCH_RELBIT 0x0040 +#define INPUT_DEVICE_ID_MATCH_ABSBIT 0x0080 +#define INPUT_DEVICE_ID_MATCH_MSCIT 0x0100 +#define INPUT_DEVICE_ID_MATCH_LEDBIT 0x0200 +#define INPUT_DEVICE_ID_MATCH_SNDBIT 0x0400 +#define INPUT_DEVICE_ID_MATCH_FFBIT 0x0800 +#define INPUT_DEVICE_ID_MATCH_SWBIT 0x1000 + +struct input_device_id { + + kernel_ulong_t flags; + + __u16 bustype; + __u16 vendor; + __u16 product; + __u16 version; + + kernel_ulong_t evbit[INPUT_DEVICE_ID_EV_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t keybit[INPUT_DEVICE_ID_KEY_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t relbit[INPUT_DEVICE_ID_REL_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t absbit[INPUT_DEVICE_ID_ABS_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t mscbit[INPUT_DEVICE_ID_MSC_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t ledbit[INPUT_DEVICE_ID_LED_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t sndbit[INPUT_DEVICE_ID_SND_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t ffbit[INPUT_DEVICE_ID_FF_MAX / BITS_PER_LONG + 1]; + kernel_ulong_t swbit[INPUT_DEVICE_ID_SW_MAX / BITS_PER_LONG + 1]; + + kernel_ulong_t driver_info; +}; + +/* EISA */ + +#define EISA_SIG_LEN 8 + +/* The EISA signature, in ASCII form, null terminated */ +struct eisa_device_id { + char sig[EISA_SIG_LEN]; + kernel_ulong_t driver_data; +}; + +#define EISA_DEVICE_MODALIAS_FMT "eisa:s%s" + +#endif /* LINUX_MOD_DEVICETABLE_H */ diff --git a/xen/include/asm-ia64/linux/pci_ids.h b/xen/include/asm-ia64/linux/pci_ids.h new file mode 100644 index 0000000000..fa4e1d7997 --- /dev/null +++ b/xen/include/asm-ia64/linux/pci_ids.h @@ -0,0 +1,2356 @@ +/* + * PCI Class, Vendor and Device IDs + * + * Please keep sorted. + */ + +/* Device classes and subclasses */ + +#define PCI_CLASS_NOT_DEFINED 0x0000 +#define PCI_CLASS_NOT_DEFINED_VGA 0x0001 + +#define PCI_BASE_CLASS_STORAGE 0x01 +#define PCI_CLASS_STORAGE_SCSI 0x0100 +#define PCI_CLASS_STORAGE_IDE 0x0101 +#define PCI_CLASS_STORAGE_FLOPPY 0x0102 +#define PCI_CLASS_STORAGE_IPI 0x0103 +#define PCI_CLASS_STORAGE_RAID 0x0104 +#define PCI_CLASS_STORAGE_SAS 0x0107 +#define PCI_CLASS_STORAGE_OTHER 0x0180 + +#define PCI_BASE_CLASS_NETWORK 0x02 +#define PCI_CLASS_NETWORK_ETHERNET 0x0200 +#define PCI_CLASS_NETWORK_TOKEN_RING 0x0201 +#define PCI_CLASS_NETWORK_FDDI 0x0202 +#define PCI_CLASS_NETWORK_ATM 0x0203 +#define PCI_CLASS_NETWORK_OTHER 0x0280 + +#define PCI_BASE_CLASS_DISPLAY 0x03 +#define PCI_CLASS_DISPLAY_VGA 0x0300 +#define PCI_CLASS_DISPLAY_XGA 0x0301 +#define PCI_CLASS_DISPLAY_3D 0x0302 +#define PCI_CLASS_DISPLAY_OTHER 0x0380 + +#define PCI_BASE_CLASS_MULTIMEDIA 0x04 +#define PCI_CLASS_MULTIMEDIA_VIDEO 0x0400 +#define PCI_CLASS_MULTIMEDIA_AUDIO 0x0401 +#define PCI_CLASS_MULTIMEDIA_PHONE 0x0402 +#define PCI_CLASS_MULTIMEDIA_OTHER 0x0480 + +#define PCI_BASE_CLASS_MEMORY 0x05 +#define PCI_CLASS_MEMORY_RAM 0x0500 +#define PCI_CLASS_MEMORY_FLASH 0x0501 +#define PCI_CLASS_MEMORY_OTHER 0x0580 + +#define PCI_BASE_CLASS_BRIDGE 0x06 +#define PCI_CLASS_BRIDGE_HOST 0x0600 +#define PCI_CLASS_BRIDGE_ISA 0x0601 +#define PCI_CLASS_BRIDGE_EISA 0x0602 +#define PCI_CLASS_BRIDGE_MC 0x0603 +#define PCI_CLASS_BRIDGE_PCI 0x0604 +#define PCI_CLASS_BRIDGE_PCMCIA 0x0605 +#define PCI_CLASS_BRIDGE_NUBUS 0x0606 +#define PCI_CLASS_BRIDGE_CARDBUS 0x0607 +#define PCI_CLASS_BRIDGE_RACEWAY 0x0608 +#define PCI_CLASS_BRIDGE_OTHER 0x0680 + +#define PCI_BASE_CLASS_COMMUNICATION 0x07 +#define PCI_CLASS_COMMUNICATION_SERIAL 0x0700 +#define PCI_CLASS_COMMUNICATION_PARALLEL 0x0701 +#define PCI_CLASS_COMMUNICATION_MULTISERIAL 0x0702 +#define PCI_CLASS_COMMUNICATION_MODEM 0x0703 +#define PCI_CLASS_COMMUNICATION_OTHER 0x0780 + +#define PCI_BASE_CLASS_SYSTEM 0x08 +#define PCI_CLASS_SYSTEM_PIC 0x0800 +#define PCI_CLASS_SYSTEM_PIC_IOAPIC 0x080010 +#define PCI_CLASS_SYSTEM_PIC_IOXAPIC 0x080020 +#define PCI_CLASS_SYSTEM_DMA 0x0801 +#define PCI_CLASS_SYSTEM_TIMER 0x0802 +#define PCI_CLASS_SYSTEM_RTC 0x0803 +#define PCI_CLASS_SYSTEM_PCI_HOTPLUG 0x0804 +#define PCI_CLASS_SYSTEM_SDHCI 0x0805 +#define PCI_CLASS_SYSTEM_OTHER 0x0880 + +#define PCI_BASE_CLASS_INPUT 0x09 +#define PCI_CLASS_INPUT_KEYBOARD 0x0900 +#define PCI_CLASS_INPUT_PEN 0x0901 +#define PCI_CLASS_INPUT_MOUSE 0x0902 +#define PCI_CLASS_INPUT_SCANNER 0x0903 +#define PCI_CLASS_INPUT_GAMEPORT 0x0904 +#define PCI_CLASS_INPUT_OTHER 0x0980 + +#define PCI_BASE_CLASS_DOCKING 0x0a +#define PCI_CLASS_DOCKING_GENERIC 0x0a00 +#define PCI_CLASS_DOCKING_OTHER 0x0a80 + +#define PCI_BASE_CLASS_PROCESSOR 0x0b +#define PCI_CLASS_PROCESSOR_386 0x0b00 +#define PCI_CLASS_PROCESSOR_486 0x0b01 +#define PCI_CLASS_PROCESSOR_PENTIUM 0x0b02 +#define PCI_CLASS_PROCESSOR_ALPHA 0x0b10 +#define PCI_CLASS_PROCESSOR_POWERPC 0x0b20 +#define PCI_CLASS_PROCESSOR_MIPS 0x0b30 +#define PCI_CLASS_PROCESSOR_CO 0x0b40 + +#define PCI_BASE_CLASS_SERIAL 0x0c +#define PCI_CLASS_SERIAL_FIREWIRE 0x0c00 +#define PCI_CLASS_SERIAL_ACCESS 0x0c01 +#define PCI_CLASS_SERIAL_SSA 0x0c02 +#define PCI_CLASS_SERIAL_USB 0x0c03 +#define PCI_CLASS_SERIAL_USB_UHCI 0x0c0300 +#define PCI_CLASS_SERIAL_USB_OHCI 0x0c0310 +#define PCI_CLASS_SERIAL_USB_EHCI 0x0c0320 +#define PCI_CLASS_SERIAL_FIBER 0x0c04 +#define PCI_CLASS_SERIAL_SMBUS 0x0c05 + +#define PCI_BASE_CLASS_INTELLIGENT 0x0e +#define PCI_CLASS_INTELLIGENT_I2O 0x0e00 + +#define PCI_BASE_CLASS_SATELLITE 0x0f +#define PCI_CLASS_SATELLITE_TV 0x0f00 +#define PCI_CLASS_SATELLITE_AUDIO 0x0f01 +#define PCI_CLASS_SATELLITE_VOICE 0x0f03 +#define PCI_CLASS_SATELLITE_DATA 0x0f04 + +#define PCI_BASE_CLASS_CRYPT 0x10 +#define PCI_CLASS_CRYPT_NETWORK 0x1000 +#define PCI_CLASS_CRYPT_ENTERTAINMENT 0x1001 +#define PCI_CLASS_CRYPT_OTHER 0x1080 + +#define PCI_BASE_CLASS_SIGNAL_PROCESSING 0x11 +#define PCI_CLASS_SP_DPIO 0x1100 +#define PCI_CLASS_SP_OTHER 0x1180 + +#define PCI_CLASS_OTHERS 0xff + +/* Vendors and devices. Sort key: vendor first, device next. */ + +#define PCI_VENDOR_ID_DYNALINK 0x0675 +#define PCI_DEVICE_ID_DYNALINK_IS64PH 0x1702 + +#define PCI_VENDOR_ID_BERKOM 0x0871 +#define PCI_DEVICE_ID_BERKOM_A1T 0xffa1 +#define PCI_DEVICE_ID_BERKOM_T_CONCEPT 0xffa2 +#define PCI_DEVICE_ID_BERKOM_A4T 0xffa4 +#define PCI_DEVICE_ID_BERKOM_SCITEL_QUADRO 0xffa8 + +#define PCI_VENDOR_ID_COMPAQ 0x0e11 +#define PCI_DEVICE_ID_COMPAQ_TOKENRING 0x0508 +#define PCI_DEVICE_ID_COMPAQ_TACHYON 0xa0fc +#define PCI_DEVICE_ID_COMPAQ_SMART2P 0xae10 +#define PCI_DEVICE_ID_COMPAQ_NETEL100 0xae32 +#define PCI_DEVICE_ID_COMPAQ_NETEL10 0xae34 +#define PCI_DEVICE_ID_COMPAQ_TRIFLEX_IDE 0xae33 +#define PCI_DEVICE_ID_COMPAQ_NETFLEX3I 0xae35 +#define PCI_DEVICE_ID_COMPAQ_NETEL100D 0xae40 +#define PCI_DEVICE_ID_COMPAQ_NETEL100PI 0xae43 +#define PCI_DEVICE_ID_COMPAQ_NETEL100I 0xb011 +#define PCI_DEVICE_ID_COMPAQ_CISS 0xb060 +#define PCI_DEVICE_ID_COMPAQ_CISSB 0xb178 +#define PCI_DEVICE_ID_COMPAQ_CISSC 0x46 +#define PCI_DEVICE_ID_COMPAQ_THUNDER 0xf130 +#define PCI_DEVICE_ID_COMPAQ_NETFLEX3B 0xf150 + +#define PCI_VENDOR_ID_NCR 0x1000 +#define PCI_VENDOR_ID_LSI_LOGIC 0x1000 +#define PCI_DEVICE_ID_NCR_53C810 0x0001 +#define PCI_DEVICE_ID_NCR_53C820 0x0002 +#define PCI_DEVICE_ID_NCR_53C825 0x0003 +#define PCI_DEVICE_ID_NCR_53C815 0x0004 +#define PCI_DEVICE_ID_LSI_53C810AP 0x0005 +#define PCI_DEVICE_ID_NCR_53C860 0x0006 +#define PCI_DEVICE_ID_LSI_53C1510 0x000a +#define PCI_DEVICE_ID_NCR_53C896 0x000b +#define PCI_DEVICE_ID_NCR_53C895 0x000c +#define PCI_DEVICE_ID_NCR_53C885 0x000d +#define PCI_DEVICE_ID_NCR_53C875 0x000f +#define PCI_DEVICE_ID_NCR_53C1510 0x0010 +#define PCI_DEVICE_ID_LSI_53C895A 0x0012 +#define PCI_DEVICE_ID_LSI_53C875A 0x0013 +#define PCI_DEVICE_ID_LSI_53C1010_33 0x0020 +#define PCI_DEVICE_ID_LSI_53C1010_66 0x0021 +#define PCI_DEVICE_ID_LSI_53C1030 0x0030 +#define PCI_DEVICE_ID_LSI_1030_53C1035 0x0032 +#define PCI_DEVICE_ID_LSI_53C1035 0x0040 +#define PCI_DEVICE_ID_NCR_53C875J 0x008f +#define PCI_DEVICE_ID_LSI_FC909 0x0621 +#define PCI_DEVICE_ID_LSI_FC929 0x0622 +#define PCI_DEVICE_ID_LSI_FC929_LAN 0x0623 +#define PCI_DEVICE_ID_LSI_FC919 0x0624 +#define PCI_DEVICE_ID_LSI_FC919_LAN 0x0625 +#define PCI_DEVICE_ID_LSI_FC929X 0x0626 +#define PCI_DEVICE_ID_LSI_FC939X 0x0642 +#define PCI_DEVICE_ID_LSI_FC949X 0x0640 +#define PCI_DEVICE_ID_LSI_FC949ES 0x0646 +#define PCI_DEVICE_ID_LSI_FC919X 0x0628 +#define PCI_DEVICE_ID_NCR_YELLOWFIN 0x0701 +#define PCI_DEVICE_ID_LSI_61C102 0x0901 +#define PCI_DEVICE_ID_LSI_63C815 0x1000 +#define PCI_DEVICE_ID_LSI_SAS1064 0x0050 +#define PCI_DEVICE_ID_LSI_SAS1064R 0x0411 +#define PCI_DEVICE_ID_LSI_SAS1066 0x005E +#define PCI_DEVICE_ID_LSI_SAS1068 0x0054 +#define PCI_DEVICE_ID_LSI_SAS1064A 0x005C +#define PCI_DEVICE_ID_LSI_SAS1064E 0x0056 +#define PCI_DEVICE_ID_LSI_SAS1066E 0x005A +#define PCI_DEVICE_ID_LSI_SAS1068E 0x0058 +#define PCI_DEVICE_ID_LSI_SAS1078 0x0060 + +#define PCI_VENDOR_ID_ATI 0x1002 +/* Mach64 */ +#define PCI_DEVICE_ID_ATI_68800 0x4158 +#define PCI_DEVICE_ID_ATI_215CT222 0x4354 +#define PCI_DEVICE_ID_ATI_210888CX 0x4358 +#define PCI_DEVICE_ID_ATI_215ET222 0x4554 +/* Mach64 / Rage */ +#define PCI_DEVICE_ID_ATI_215GB 0x4742 +#define PCI_DEVICE_ID_ATI_215GD 0x4744 +#define PCI_DEVICE_ID_ATI_215GI 0x4749 +#define PCI_DEVICE_ID_ATI_215GP 0x4750 +#define PCI_DEVICE_ID_ATI_215GQ 0x4751 +#define PCI_DEVICE_ID_ATI_215XL 0x4752 +#define PCI_DEVICE_ID_ATI_215GT 0x4754 +#define PCI_DEVICE_ID_ATI_215GTB 0x4755 +#define PCI_DEVICE_ID_ATI_215_IV 0x4756 +#define PCI_DEVICE_ID_ATI_215_IW 0x4757 +#define PCI_DEVICE_ID_ATI_215_IZ 0x475A +#define PCI_DEVICE_ID_ATI_210888GX 0x4758 +#define PCI_DEVICE_ID_ATI_215_LB 0x4c42 +#define PCI_DEVICE_ID_ATI_215_LD 0x4c44 +#define PCI_DEVICE_ID_ATI_215_LG 0x4c47 +#define PCI_DEVICE_ID_ATI_215_LI 0x4c49 +#define PCI_DEVICE_ID_ATI_215_LM 0x4c4D +#define PCI_DEVICE_ID_ATI_215_LN 0x4c4E +#define PCI_DEVICE_ID_ATI_215_LR 0x4c52 +#define PCI_DEVICE_ID_ATI_215_LS 0x4c53 +#define PCI_DEVICE_ID_ATI_264_LT 0x4c54 +/* Mach64 VT */ +#define PCI_DEVICE_ID_ATI_264VT 0x5654 +#define PCI_DEVICE_ID_ATI_264VU 0x5655 +#define PCI_DEVICE_ID_ATI_264VV 0x5656 +/* Rage128 GL */ +#define PCI_DEVICE_ID_ATI_RAGE128_RE 0x5245 +#define PCI_DEVICE_ID_ATI_RAGE128_RF 0x5246 +#define PCI_DEVICE_ID_ATI_RAGE128_RG 0x5247 +/* Rage128 VR */ +#define PCI_DEVICE_ID_ATI_RAGE128_RK 0x524b +#define PCI_DEVICE_ID_ATI_RAGE128_RL 0x524c +#define PCI_DEVICE_ID_ATI_RAGE128_SE 0x5345 +#define PCI_DEVICE_ID_ATI_RAGE128_SF 0x5346 +#define PCI_DEVICE_ID_ATI_RAGE128_SG 0x5347 +#define PCI_DEVICE_ID_ATI_RAGE128_SH 0x5348 +#define PCI_DEVICE_ID_ATI_RAGE128_SK 0x534b +#define PCI_DEVICE_ID_ATI_RAGE128_SL 0x534c +#define PCI_DEVICE_ID_ATI_RAGE128_SM 0x534d +#define PCI_DEVICE_ID_ATI_RAGE128_SN 0x534e +/* Rage128 Ultra */ +#define PCI_DEVICE_ID_ATI_RAGE128_TF 0x5446 +#define PCI_DEVICE_ID_ATI_RAGE128_TL 0x544c +#define PCI_DEVICE_ID_ATI_RAGE128_TR 0x5452 +#define PCI_DEVICE_ID_ATI_RAGE128_TS 0x5453 +#define PCI_DEVICE_ID_ATI_RAGE128_TT 0x5454 +#define PCI_DEVICE_ID_ATI_RAGE128_TU 0x5455 +/* Rage128 M3 */ +#define PCI_DEVICE_ID_ATI_RAGE128_LE 0x4c45 +#define PCI_DEVICE_ID_ATI_RAGE128_LF 0x4c46 +/* Rage128 M4 */ +#define PCI_DEVICE_ID_ATI_RAGE128_MF 0x4d46 +#define PCI_DEVICE_ID_ATI_RAGE128_ML 0x4d4c +/* Rage128 Pro GL */ +#define PCI_DEVICE_ID_ATI_RAGE128_PA 0x5041 +#define PCI_DEVICE_ID_ATI_RAGE128_PB 0x5042 +#define PCI_DEVICE_ID_ATI_RAGE128_PC 0x5043 +#define PCI_DEVICE_ID_ATI_RAGE128_PD 0x5044 +#define PCI_DEVICE_ID_ATI_RAGE128_PE 0x5045 +#define PCI_DEVICE_ID_ATI_RAGE128_PF 0x5046 +/* Rage128 Pro VR */ +#define PCI_DEVICE_ID_ATI_RAGE128_PG 0x5047 +#define PCI_DEVICE_ID_ATI_RAGE128_PH 0x5048 +#define PCI_DEVICE_ID_ATI_RAGE128_PI 0x5049 +#define PCI_DEVICE_ID_ATI_RAGE128_PJ 0x504A +#define PCI_DEVICE_ID_ATI_RAGE128_PK 0x504B +#define PCI_DEVICE_ID_ATI_RAGE128_PL 0x504C +#define PCI_DEVICE_ID_ATI_RAGE128_PM 0x504D +#define PCI_DEVICE_ID_ATI_RAGE128_PN 0x504E +#define PCI_DEVICE_ID_ATI_RAGE128_PO 0x504F +#define PCI_DEVICE_ID_ATI_RAGE128_PP 0x5050 +#define PCI_DEVICE_ID_ATI_RAGE128_PQ 0x5051 +#define PCI_DEVICE_ID_ATI_RAGE128_PR 0x5052 +#define PCI_DEVICE_ID_ATI_RAGE128_PS 0x5053 +#define PCI_DEVICE_ID_ATI_RAGE128_PT 0x5054 +#define PCI_DEVICE_ID_ATI_RAGE128_PU 0x5055 +#define PCI_DEVICE_ID_ATI_RAGE128_PV 0x5056 +#define PCI_DEVICE_ID_ATI_RAGE128_PW 0x5057 +#define PCI_DEVICE_ID_ATI_RAGE128_PX 0x5058 +/* Rage128 M4 */ +/* Radeon R100 */ +#define PCI_DEVICE_ID_ATI_RADEON_QD 0x5144 +#define PCI_DEVICE_ID_ATI_RADEON_QE 0x5145 +#define PCI_DEVICE_ID_ATI_RADEON_QF 0x5146 +#define PCI_DEVICE_ID_ATI_RADEON_QG 0x5147 +/* Radeon RV100 (VE) */ +#define PCI_DEVICE_ID_ATI_RADEON_QY 0x5159 +#define PCI_DEVICE_ID_ATI_RADEON_QZ 0x515a +/* Radeon R200 (8500) */ +#define PCI_DEVICE_ID_ATI_RADEON_QL 0x514c +#define PCI_DEVICE_ID_ATI_RADEON_QN 0x514e +#define PCI_DEVICE_ID_ATI_RADEON_QO 0x514f +#define PCI_DEVICE_ID_ATI_RADEON_Ql 0x516c +#define PCI_DEVICE_ID_ATI_RADEON_BB 0x4242 +/* Radeon R200 (9100) */ +#define PCI_DEVICE_ID_ATI_RADEON_QM 0x514d +/* Radeon RV200 (7500) */ +#define PCI_DEVICE_ID_ATI_RADEON_QW 0x5157 +#define PCI_DEVICE_ID_ATI_RADEON_QX 0x5158 +/* Radeon NV-100 */ +/* Radeon RV250 (9000) */ +#define PCI_DEVICE_ID_ATI_RADEON_Id 0x4964 +#define PCI_DEVICE_ID_ATI_RADEON_Ie 0x4965 +#define PCI_DEVICE_ID_ATI_RADEON_If 0x4966 +#define PCI_DEVICE_ID_ATI_RADEON_Ig 0x4967 +/* Radeon RV280 (9200) */ +#define PCI_DEVICE_ID_ATI_RADEON_Ya 0x5961 +#define PCI_DEVICE_ID_ATI_RADEON_Yd 0x5964 +/* Radeon R300 (9500) */ +/* Radeon R300 (9700) */ +#define PCI_DEVICE_ID_ATI_RADEON_ND 0x4e44 +#define PCI_DEVICE_ID_ATI_RADEON_NE 0x4e45 +#define PCI_DEVICE_ID_ATI_RADEON_NF 0x4e46 +#define PCI_DEVICE_ID_ATI_RADEON_NG 0x4e47 +/* Radeon R350 (9800) */ +/* Radeon RV350 (9600) */ +/* Radeon M6 */ +#define PCI_DEVICE_ID_ATI_RADEON_LY 0x4c59 +#define PCI_DEVICE_ID_ATI_RADEON_LZ 0x4c5a +/* Radeon M7 */ +#define PCI_DEVICE_ID_ATI_RADEON_LW 0x4c57 +#define PCI_DEVICE_ID_ATI_RADEON_LX 0x4c58 +/* Radeon M9 */ +#define PCI_DEVICE_ID_ATI_RADEON_Ld 0x4c64 +#define PCI_DEVICE_ID_ATI_RADEON_Le 0x4c65 +#define PCI_DEVICE_ID_ATI_RADEON_Lf 0x4c66 +#define PCI_DEVICE_ID_ATI_RADEON_Lg 0x4c67 +/* Radeon */ +/* RadeonIGP */ +#define PCI_DEVICE_ID_ATI_RS100 0xcab0 +#define PCI_DEVICE_ID_ATI_RS200 0xcab2 +#define PCI_DEVICE_ID_ATI_RS200_B 0xcbb2 +#define PCI_DEVICE_ID_ATI_RS250 0xcab3 +#define PCI_DEVICE_ID_ATI_RS300_100 0x5830 +#define PCI_DEVICE_ID_ATI_RS300_133 0x5831 +#define PCI_DEVICE_ID_ATI_RS300_166 0x5832 +#define PCI_DEVICE_ID_ATI_RS300_200 0x5833 +#define PCI_DEVICE_ID_ATI_RS350_100 0x7830 +#define PCI_DEVICE_ID_ATI_RS350_133 0x7831 +#define PCI_DEVICE_ID_ATI_RS350_166 0x7832 +#define PCI_DEVICE_ID_ATI_RS350_200 0x7833 +#define PCI_DEVICE_ID_ATI_RS400_100 0x5a30 +#define PCI_DEVICE_ID_ATI_RS400_133 0x5a31 +#define PCI_DEVICE_ID_ATI_RS400_166 0x5a32 +#define PCI_DEVICE_ID_ATI_RS400_200 0x5a33 +#define PCI_DEVICE_ID_ATI_RS480 0x5950 +/* ATI IXP Chipset */ +#define PCI_DEVICE_ID_ATI_IXP200_IDE 0x4349 +#define PCI_DEVICE_ID_ATI_IXP200_SMBUS 0x4353 +#define PCI_DEVICE_ID_ATI_IXP300_SMBUS 0x4363 +#define PCI_DEVICE_ID_ATI_IXP300_IDE 0x4369 +#define PCI_DEVICE_ID_ATI_IXP300_SATA 0x436e +#define PCI_DEVICE_ID_ATI_IXP400_SMBUS 0x4372 +#define PCI_DEVICE_ID_ATI_IXP400_IDE 0x4376 +#define PCI_DEVICE_ID_ATI_IXP400_SATA 0x4379 +#define PCI_DEVICE_ID_ATI_IXP400_SATA2 0x437a +#define PCI_DEVICE_ID_ATI_IXP600_SATA 0x4380 +#define PCI_DEVICE_ID_ATI_IXP600_SRAID 0x4381 +#define PCI_DEVICE_ID_ATI_IXP600_IDE 0x438c + +#define PCI_VENDOR_ID_VLSI 0x1004 +#define PCI_DEVICE_ID_VLSI_82C592 0x0005 +#define PCI_DEVICE_ID_VLSI_82C593 0x0006 +#define PCI_DEVICE_ID_VLSI_82C594 0x0007 +#define PCI_DEVICE_ID_VLSI_82C597 0x0009 +#define PCI_DEVICE_ID_VLSI_82C541 0x000c +#define PCI_DEVICE_ID_VLSI_82C543 0x000d +#define PCI_DEVICE_ID_VLSI_82C532 0x0101 +#define PCI_DEVICE_ID_VLSI_82C534 0x0102 +#define PCI_DEVICE_ID_VLSI_82C535 0x0104 +#define PCI_DEVICE_ID_VLSI_82C147 0x0105 +#define PCI_DEVICE_ID_VLSI_VAS96011 0x0702 + +#define PCI_VENDOR_ID_ADL 0x1005 +#define PCI_DEVICE_ID_ADL_2301 0x2301 + +#define PCI_VENDOR_ID_NS 0x100b +#define PCI_DEVICE_ID_NS_87415 0x0002 +#define PCI_DEVICE_ID_NS_87560_LIO 0x000e +#define PCI_DEVICE_ID_NS_87560_USB 0x0012 +#define PCI_DEVICE_ID_NS_83815 0x0020 +#define PCI_DEVICE_ID_NS_83820 0x0022 +#define PCI_DEVICE_ID_NS_CS5535_ISA 0x002b +#define PCI_DEVICE_ID_NS_CS5535_IDE 0x002d +#define PCI_DEVICE_ID_NS_CS5535_AUDIO 0x002e +#define PCI_DEVICE_ID_NS_CS5535_USB 0x002f +#define PCI_DEVICE_ID_NS_CS5535_VIDEO 0x0030 +#define PCI_DEVICE_ID_NS_SATURN 0x0035 +#define PCI_DEVICE_ID_NS_SCx200_BRIDGE 0x0500 +#define PCI_DEVICE_ID_NS_SCx200_SMI 0x0501 +#define PCI_DEVICE_ID_NS_SCx200_IDE 0x0502 +#define PCI_DEVICE_ID_NS_SCx200_AUDIO 0x0503 +#define PCI_DEVICE_ID_NS_SCx200_VIDEO 0x0504 +#define PCI_DEVICE_ID_NS_SCx200_XBUS 0x0505 +#define PCI_DEVICE_ID_NS_SC1100_BRIDGE 0x0510 +#define PCI_DEVICE_ID_NS_SC1100_SMI 0x0511 +#define PCI_DEVICE_ID_NS_SC1100_XBUS 0x0515 +#define PCI_DEVICE_ID_NS_87410 0xd001 + +#define PCI_DEVICE_ID_NS_CS5535_HOST_BRIDGE 0x0028 +#define PCI_DEVICE_ID_NS_CS5535_ISA_BRIDGE 0x002b + +#define PCI_VENDOR_ID_TSENG 0x100c +#define PCI_DEVICE_ID_TSENG_W32P_2 0x3202 +#define PCI_DEVICE_ID_TSENG_W32P_b 0x3205 +#define PCI_DEVICE_ID_TSENG_W32P_c 0x3206 +#define PCI_DEVICE_ID_TSENG_W32P_d 0x3207 +#define PCI_DEVICE_ID_TSENG_ET6000 0x3208 + +#define PCI_VENDOR_ID_WEITEK 0x100e +#define PCI_DEVICE_ID_WEITEK_P9000 0x9001 +#define PCI_DEVICE_ID_WEITEK_P9100 0x9100 + +#define PCI_VENDOR_ID_DEC 0x1011 +#define PCI_DEVICE_ID_DEC_BRD 0x0001 +#define PCI_DEVICE_ID_DEC_TULIP 0x0002 +#define PCI_DEVICE_ID_DEC_TGA 0x0004 +#define PCI_DEVICE_ID_DEC_TULIP_FAST 0x0009 +#define PCI_DEVICE_ID_DEC_TGA2 0x000D +#define PCI_DEVICE_ID_DEC_FDDI 0x000F +#define PCI_DEVICE_ID_DEC_TULIP_PLUS 0x0014 +#define PCI_DEVICE_ID_DEC_21142 0x0019 +#define PCI_DEVICE_ID_DEC_21052 0x0021 +#define PCI_DEVICE_ID_DEC_21150 0x0022 +#define PCI_DEVICE_ID_DEC_21152 0x0024 +#define PCI_DEVICE_ID_DEC_21153 0x0025 +#define PCI_DEVICE_ID_DEC_21154 0x0026 +#define PCI_DEVICE_ID_DEC_21285 0x1065 +#define PCI_DEVICE_ID_COMPAQ_42XX 0x0046 + +#define PCI_VENDOR_ID_CIRRUS 0x1013 +#define PCI_DEVICE_ID_CIRRUS_7548 0x0038 +#define PCI_DEVICE_ID_CIRRUS_5430 0x00a0 +#define PCI_DEVICE_ID_CIRRUS_5434_4 0x00a4 +#define PCI_DEVICE_ID_CIRRUS_5434_8 0x00a8 +#define PCI_DEVICE_ID_CIRRUS_5436 0x00ac +#define PCI_DEVICE_ID_CIRRUS_5446 0x00b8 +#define PCI_DEVICE_ID_CIRRUS_5480 0x00bc +#define PCI_DEVICE_ID_CIRRUS_5462 0x00d0 +#define PCI_DEVICE_ID_CIRRUS_5464 0x00d4 +#define PCI_DEVICE_ID_CIRRUS_5465 0x00d6 +#define PCI_DEVICE_ID_CIRRUS_6729 0x1100 +#define PCI_DEVICE_ID_CIRRUS_6832 0x1110 +#define PCI_DEVICE_ID_CIRRUS_7543 0x1202 +#define PCI_DEVICE_ID_CIRRUS_4610 0x6001 +#define PCI_DEVICE_ID_CIRRUS_4612 0x6003 +#define PCI_DEVICE_ID_CIRRUS_4615 0x6004 + +#define PCI_VENDOR_ID_IBM 0x1014 +#define PCI_DEVICE_ID_IBM_TR 0x0018 +#define PCI_DEVICE_ID_IBM_TR_WAKE 0x003e +#define PCI_DEVICE_ID_IBM_CPC710_PCI64 0x00fc +#define PCI_DEVICE_ID_IBM_SNIPE 0x0180 +#define PCI_DEVICE_ID_IBM_CITRINE 0x028C +#define PCI_DEVICE_ID_IBM_GEMSTONE 0xB166 +#define PCI_DEVICE_ID_IBM_OBSIDIAN 0x02BD +#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_1 0x0031 +#define PCI_DEVICE_ID_IBM_ICOM_DEV_ID_2 0x0219 +#define PCI_DEVICE_ID_IBM_ICOM_V2_TWO_PORTS_RVX 0x021A +#define PCI_DEVICE_ID_IBM_ICOM_V2_ONE_PORT_RVX_ONE_PORT_MDM 0x0251 +#define PCI_DEVICE_ID_IBM_ICOM_FOUR_PORT_MODEL 0x252 + +#define PCI_VENDOR_ID_COMPEX2 0x101a /* pci.ids says "AT&T GIS (NCR)" */ +#define PCI_DEVICE_ID_COMPEX2_100VG 0x0005 + +#define PCI_VENDOR_ID_WD 0x101c +#define PCI_DEVICE_ID_WD_90C 0xc24a + +#define PCI_VENDOR_ID_AMI 0x101e +#define PCI_DEVICE_ID_AMI_MEGARAID3 0x1960 +#define PCI_DEVICE_ID_AMI_MEGARAID 0x9010 +#define PCI_DEVICE_ID_AMI_MEGARAID2 0x9060 + +#define PCI_VENDOR_ID_AMD 0x1022 +#define PCI_DEVICE_ID_AMD_K8_NB 0x1100 +#define PCI_DEVICE_ID_AMD_K8_NB_MISC 0x1103 +#define PCI_DEVICE_ID_AMD_LANCE 0x2000 +#define PCI_DEVICE_ID_AMD_LANCE_HOME 0x2001 +#define PCI_DEVICE_ID_AMD_SCSI 0x2020 +#define PCI_DEVICE_ID_AMD_SERENADE 0x36c0 +#define PCI_DEVICE_ID_AMD_FE_GATE_7006 0x7006 +#define PCI_DEVICE_ID_AMD_FE_GATE_7007 0x7007 +#define PCI_DEVICE_ID_AMD_FE_GATE_700C 0x700C +#define PCI_DEVICE_ID_AMD_FE_GATE_700E 0x700E +#define PCI_DEVICE_ID_AMD_COBRA_7401 0x7401 +#define PCI_DEVICE_ID_AMD_VIPER_7409 0x7409 +#define PCI_DEVICE_ID_AMD_VIPER_740B 0x740B +#define PCI_DEVICE_ID_AMD_VIPER_7410 0x7410 +#define PCI_DEVICE_ID_AMD_VIPER_7411 0x7411 +#define PCI_DEVICE_ID_AMD_VIPER_7413 0x7413 +#define PCI_DEVICE_ID_AMD_VIPER_7440 0x7440 +#define PCI_DEVICE_ID_AMD_OPUS_7441 0x7441 +#define PCI_DEVICE_ID_AMD_OPUS_7443 0x7443 +#define PCI_DEVICE_ID_AMD_VIPER_7443 0x7443 +#define PCI_DEVICE_ID_AMD_OPUS_7445 0x7445 +#define PCI_DEVICE_ID_AMD_8111_LPC 0x7468 +#define PCI_DEVICE_ID_AMD_8111_IDE 0x7469 +#define PCI_DEVICE_ID_AMD_8111_SMBUS2 0x746a +#define PCI_DEVICE_ID_AMD_8111_SMBUS 0x746b +#define PCI_DEVICE_ID_AMD_8111_AUDIO 0x746d +#define PCI_DEVICE_ID_AMD_8151_0 0x7454 +#define PCI_DEVICE_ID_AMD_8131_BRIDGE 0x7450 +#define PCI_DEVICE_ID_AMD_8131_APIC 0x7451 +#define PCI_DEVICE_ID_AMD_8132_BRIDGE 0x7458 +#define PCI_DEVICE_ID_AMD_CS5536_ISA 0x2090 +#define PCI_DEVICE_ID_AMD_CS5536_FLASH 0x2091 +#define PCI_DEVICE_ID_AMD_CS5536_AUDIO 0x2093 +#define PCI_DEVICE_ID_AMD_CS5536_OHC 0x2094 +#define PCI_DEVICE_ID_AMD_CS5536_EHC 0x2095 +#define PCI_DEVICE_ID_AMD_CS5536_UDC 0x2096 +#define PCI_DEVICE_ID_AMD_CS5536_UOC 0x2097 +#define PCI_DEVICE_ID_AMD_CS5536_IDE 0x209A + +#define PCI_DEVICE_ID_AMD_LX_VIDEO 0x2081 +#define PCI_DEVICE_ID_AMD_LX_AES 0x2082 + +#define PCI_VENDOR_ID_TRIDENT 0x1023 +#define PCI_DEVICE_ID_TRIDENT_4DWAVE_DX 0x2000 +#define PCI_DEVICE_ID_TRIDENT_4DWAVE_NX 0x2001 +#define PCI_DEVICE_ID_TRIDENT_9320 0x9320 +#define PCI_DEVICE_ID_TRIDENT_9388 0x9388 +#define PCI_DEVICE_ID_TRIDENT_9397 0x9397 +#define PCI_DEVICE_ID_TRIDENT_939A 0x939A +#define PCI_DEVICE_ID_TRIDENT_9520 0x9520 +#define PCI_DEVICE_ID_TRIDENT_9525 0x9525 +#define PCI_DEVICE_ID_TRIDENT_9420 0x9420 +#define PCI_DEVICE_ID_TRIDENT_9440 0x9440 +#define PCI_DEVICE_ID_TRIDENT_9660 0x9660 +#define PCI_DEVICE_ID_TRIDENT_9750 0x9750 +#define PCI_DEVICE_ID_TRIDENT_9850 0x9850 +#define PCI_DEVICE_ID_TRIDENT_9880 0x9880 +#define PCI_DEVICE_ID_TRIDENT_8400 0x8400 +#define PCI_DEVICE_ID_TRIDENT_8420 0x8420 +#define PCI_DEVICE_ID_TRIDENT_8500 0x8500 + +#define PCI_VENDOR_ID_AI 0x1025 +#define PCI_DEVICE_ID_AI_M1435 0x1435 + +#define PCI_VENDOR_ID_DELL 0x1028 +#define PCI_DEVICE_ID_DELL_RACIII 0x0008 +#define PCI_DEVICE_ID_DELL_RAC4 0x0012 +#define PCI_DEVICE_ID_DELL_PERC5 0x0015 + +#define PCI_VENDOR_ID_MATROX 0x102B +#define PCI_DEVICE_ID_MATROX_MGA_2 0x0518 +#define PCI_DEVICE_ID_MATROX_MIL 0x0519 +#define PCI_DEVICE_ID_MATROX_MYS 0x051A +#define PCI_DEVICE_ID_MATROX_MIL_2 0x051b +#define PCI_DEVICE_ID_MATROX_MYS_AGP 0x051e +#define PCI_DEVICE_ID_MATROX_MIL_2_AGP 0x051f +#define PCI_DEVICE_ID_MATROX_MGA_IMP 0x0d10 +#define PCI_DEVICE_ID_MATROX_G100_MM 0x1000 +#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001 +#define PCI_DEVICE_ID_MATROX_G200_PCI 0x0520 +#define PCI_DEVICE_ID_MATROX_G200_AGP 0x0521 +#define PCI_DEVICE_ID_MATROX_G400 0x0525 +#define PCI_DEVICE_ID_MATROX_G550 0x2527 +#define PCI_DEVICE_ID_MATROX_VIA 0x4536 + +#define PCI_VENDOR_ID_CT 0x102c +#define PCI_DEVICE_ID_CT_69000 0x00c0 +#define PCI_DEVICE_ID_CT_65545 0x00d8 +#define PCI_DEVICE_ID_CT_65548 0x00dc +#define PCI_DEVICE_ID_CT_65550 0x00e0 +#define PCI_DEVICE_ID_CT_65554 0x00e4 +#define PCI_DEVICE_ID_CT_65555 0x00e5 + +#define PCI_VENDOR_ID_MIRO 0x1031 +#define PCI_DEVICE_ID_MIRO_36050 0x5601 +#define PCI_DEVICE_ID_MIRO_DC10PLUS 0x7efe +#define PCI_DEVICE_ID_MIRO_DC30PLUS 0xd801 + +#define PCI_VENDOR_ID_NEC 0x1033 +#define PCI_DEVICE_ID_NEC_CBUS_1 0x0001 /* PCI-Cbus Bridge */ +#define PCI_DEVICE_ID_NEC_LOCAL 0x0002 /* Local Bridge */ +#define PCI_DEVICE_ID_NEC_ATM 0x0003 /* ATM LAN Controller */ +#define PCI_DEVICE_ID_NEC_R4000 0x0004 /* R4000 Bridge */ +#define PCI_DEVICE_ID_NEC_486 0x0005 /* 486 Like Peripheral Bus Bridge */ +#define PCI_DEVICE_ID_NEC_ACCEL_1 0x0006 /* Graphic Accelerator */ +#define PCI_DEVICE_ID_NEC_UXBUS 0x0007 /* UX-Bus Bridge */ +#define PCI_DEVICE_ID_NEC_ACCEL_2 0x0008 /* Graphic Accelerator */ +#define PCI_DEVICE_ID_NEC_GRAPH 0x0009 /* PCI-CoreGraph Bridge */ +#define PCI_DEVICE_ID_NEC_VL 0x0016 /* PCI-VL Bridge */ +#define PCI_DEVICE_ID_NEC_STARALPHA2 0x002c /* STAR ALPHA2 */ +#define PCI_DEVICE_ID_NEC_CBUS_2 0x002d /* PCI-Cbus Bridge */ +#define PCI_DEVICE_ID_NEC_USB 0x0035 /* PCI-USB Host */ +#define PCI_DEVICE_ID_NEC_CBUS_3 0x003b +#define PCI_DEVICE_ID_NEC_NAPCCARD 0x003e +#define PCI_DEVICE_ID_NEC_PCX2 0x0046 /* PowerVR */ +#define PCI_DEVICE_ID_NEC_NILE4 0x005a +#define PCI_DEVICE_ID_NEC_VRC5476 0x009b +#define PCI_DEVICE_ID_NEC_VRC4173 0x00a5 +#define PCI_DEVICE_ID_NEC_VRC5477_AC97 0x00a6 +#define PCI_DEVICE_ID_NEC_PC9821CS01 0x800c /* PC-9821-CS01 */ +#define PCI_DEVICE_ID_NEC_PC9821NRB06 0x800d /* PC-9821NR-B06 */ + +#define PCI_VENDOR_ID_FD 0x1036 +#define PCI_DEVICE_ID_FD_36C70 0x0000 + +#define PCI_VENDOR_ID_SI 0x1039 +#define PCI_DEVICE_ID_SI_5591_AGP 0x0001 +#define PCI_DEVICE_ID_SI_6202 0x0002 +#define PCI_DEVICE_ID_SI_503 0x0008 +#define PCI_DEVICE_ID_SI_ACPI 0x0009 +#define PCI_DEVICE_ID_SI_SMBUS 0x0016 +#define PCI_DEVICE_ID_SI_LPC 0x0018 +#define PCI_DEVICE_ID_SI_5597_VGA 0x0200 +#define PCI_DEVICE_ID_SI_6205 0x0205 +#define PCI_DEVICE_ID_SI_501 0x0406 +#define PCI_DEVICE_ID_SI_496 0x0496 +#define PCI_DEVICE_ID_SI_300 0x0300 +#define PCI_DEVICE_ID_SI_315H 0x0310 +#define PCI_DEVICE_ID_SI_315 0x0315 +#define PCI_DEVICE_ID_SI_315PRO 0x0325 +#define PCI_DEVICE_ID_SI_530 0x0530 +#define PCI_DEVICE_ID_SI_540 0x0540 +#define PCI_DEVICE_ID_SI_550 0x0550 +#define PCI_DEVICE_ID_SI_540_VGA 0x5300 +#define PCI_DEVICE_ID_SI_550_VGA 0x5315 +#define PCI_DEVICE_ID_SI_620 0x0620 +#define PCI_DEVICE_ID_SI_630 0x0630 +#define PCI_DEVICE_ID_SI_633 0x0633 +#define PCI_DEVICE_ID_SI_635 0x0635 +#define PCI_DEVICE_ID_SI_640 0x0640 +#define PCI_DEVICE_ID_SI_645 0x0645 +#define PCI_DEVICE_ID_SI_646 0x0646 +#define PCI_DEVICE_ID_SI_648 0x0648 +#define PCI_DEVICE_ID_SI_650 0x0650 +#define PCI_DEVICE_ID_SI_651 0x0651 +#define PCI_DEVICE_ID_SI_655 0x0655 +#define PCI_DEVICE_ID_SI_661 0x0661 +#define PCI_DEVICE_ID_SI_730 0x0730 +#define PCI_DEVICE_ID_SI_733 0x0733 +#define PCI_DEVICE_ID_SI_630_VGA 0x6300 +#define PCI_DEVICE_ID_SI_735 0x0735 +#define PCI_DEVICE_ID_SI_740 0x0740 +#define PCI_DEVICE_ID_SI_741 0x0741 +#define PCI_DEVICE_ID_SI_745 0x0745 +#define PCI_DEVICE_ID_SI_746 0x0746 +#define PCI_DEVICE_ID_SI_755 0x0755 +#define PCI_DEVICE_ID_SI_760 0x0760 +#define PCI_DEVICE_ID_SI_900 0x0900 +#define PCI_DEVICE_ID_SI_961 0x0961 +#define PCI_DEVICE_ID_SI_962 0x0962 +#define PCI_DEVICE_ID_SI_963 0x0963 +#define PCI_DEVICE_ID_SI_965 0x0965 +#define PCI_DEVICE_ID_SI_966 0x0966 +#define PCI_DEVICE_ID_SI_968 0x0968 +#define PCI_DEVICE_ID_SI_5511 0x5511 +#define PCI_DEVICE_ID_SI_5513 0x5513 +#define PCI_DEVICE_ID_SI_5517 0x5517 +#define PCI_DEVICE_ID_SI_5518 0x5518 +#define PCI_DEVICE_ID_SI_5571 0x5571 +#define PCI_DEVICE_ID_SI_5581 0x5581 +#define PCI_DEVICE_ID_SI_5582 0x5582 +#define PCI_DEVICE_ID_SI_5591 0x5591 +#define PCI_DEVICE_ID_SI_5596 0x5596 +#define PCI_DEVICE_ID_SI_5597 0x5597 +#define PCI_DEVICE_ID_SI_5598 0x5598 +#define PCI_DEVICE_ID_SI_5600 0x5600 +#define PCI_DEVICE_ID_SI_7012 0x7012 +#define PCI_DEVICE_ID_SI_7013 0x7013 +#define PCI_DEVICE_ID_SI_7016 0x7016 +#define PCI_DEVICE_ID_SI_7018 0x7018 + +#define PCI_VENDOR_ID_HP 0x103c +#define PCI_DEVICE_ID_HP_VISUALIZE_EG 0x1005 +#define PCI_DEVICE_ID_HP_VISUALIZE_FX6 0x1006 +#define PCI_DEVICE_ID_HP_VISUALIZE_FX4 0x1008 +#define PCI_DEVICE_ID_HP_VISUALIZE_FX2 0x100a +#define PCI_DEVICE_ID_HP_TACHYON 0x1028 +#define PCI_DEVICE_ID_HP_TACHLITE 0x1029 +#define PCI_DEVICE_ID_HP_J2585A 0x1030 +#define PCI_DEVICE_ID_HP_J2585B 0x1031 +#define PCI_DEVICE_ID_HP_J2973A 0x1040 +#define PCI_DEVICE_ID_HP_J2970A 0x1042 +#define PCI_DEVICE_ID_HP_DIVA 0x1048 +#define PCI_DEVICE_ID_HP_DIVA_TOSCA1 0x1049 +#define PCI_DEVICE_ID_HP_DIVA_TOSCA2 0x104A +#define PCI_DEVICE_ID_HP_DIVA_MAESTRO 0x104B +#define PCI_DEVICE_ID_HP_REO_IOC 0x10f1 +#define PCI_DEVICE_ID_HP_VISUALIZE_FXE 0x108b +#define PCI_DEVICE_ID_HP_DIVA_HALFDOME 0x1223 +#define PCI_DEVICE_ID_HP_DIVA_KEYSTONE 0x1226 +#define PCI_DEVICE_ID_HP_DIVA_POWERBAR 0x1227 +#define PCI_DEVICE_ID_HP_ZX1_IOC 0x122a +#define PCI_DEVICE_ID_HP_PCIX_LBA 0x122e +#define PCI_DEVICE_ID_HP_SX1000_IOC 0x127c +#define PCI_DEVICE_ID_HP_DIVA_EVEREST 0x1282 +#define PCI_DEVICE_ID_HP_DIVA_AUX 0x1290 +#define PCI_DEVICE_ID_HP_DIVA_RMP3 0x1301 +#define PCI_DEVICE_ID_HP_DIVA_HURRICANE 0x132a +#define PCI_DEVICE_ID_HP_CISSA 0x3220 +#define PCI_DEVICE_ID_HP_CISSC 0x3230 +#define PCI_DEVICE_ID_HP_CISSD 0x3238 +#define PCI_DEVICE_ID_HP_ZX2_IOC 0x4031 + +#define PCI_VENDOR_ID_PCTECH 0x1042 +#define PCI_DEVICE_ID_PCTECH_RZ1000 0x1000 +#define PCI_DEVICE_ID_PCTECH_RZ1001 0x1001 +#define PCI_DEVICE_ID_PCTECH_SAMURAI_IDE 0x3020 + +#define PCI_VENDOR_ID_ASUSTEK 0x1043 +#define PCI_DEVICE_ID_ASUSTEK_0675 0x0675 + +#define PCI_VENDOR_ID_DPT 0x1044 +#define PCI_DEVICE_ID_DPT 0xa400 + +#define PCI_VENDOR_ID_OPTI 0x1045 +#define PCI_DEVICE_ID_OPTI_82C558 0xc558 +#define PCI_DEVICE_ID_OPTI_82C621 0xc621 +#define PCI_DEVICE_ID_OPTI_82C700 0xc700 +#define PCI_DEVICE_ID_OPTI_82C825 0xd568 + +#define PCI_VENDOR_ID_ELSA 0x1048 +#define PCI_DEVICE_ID_ELSA_MICROLINK 0x1000 +#define PCI_DEVICE_ID_ELSA_QS3000 0x3000 + + +#define PCI_VENDOR_ID_BUSLOGIC 0x104B +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140 +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040 +#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130 + +#define PCI_VENDOR_ID_TI 0x104c +#define PCI_DEVICE_ID_TI_TVP4020 0x3d07 +#define PCI_DEVICE_ID_TI_4450 0x8011 +#define PCI_DEVICE_ID_TI_XX21_XX11 0x8031 +#define PCI_DEVICE_ID_TI_XX21_XX11_SD 0x8034 +#define PCI_DEVICE_ID_TI_X515 0x8036 +#define PCI_DEVICE_ID_TI_XX12 0x8039 +#define PCI_DEVICE_ID_TI_1130 0xac12 +#define PCI_DEVICE_ID_TI_1031 0xac13 +#define PCI_DEVICE_ID_TI_1131 0xac15 +#define PCI_DEVICE_ID_TI_1250 0xac16 +#define PCI_DEVICE_ID_TI_1220 0xac17 +#define PCI_DEVICE_ID_TI_1221 0xac19 +#define PCI_DEVICE_ID_TI_1210 0xac1a +#define PCI_DEVICE_ID_TI_1450 0xac1b +#define PCI_DEVICE_ID_TI_1225 0xac1c +#define PCI_DEVICE_ID_TI_1251A 0xac1d +#define PCI_DEVICE_ID_TI_1211 0xac1e +#define PCI_DEVICE_ID_TI_1251B 0xac1f +#define PCI_DEVICE_ID_TI_4410 0xac41 +#define PCI_DEVICE_ID_TI_4451 0xac42 +#define PCI_DEVICE_ID_TI_4510 0xac44 +#define PCI_DEVICE_ID_TI_4520 0xac46 +#define PCI_DEVICE_ID_TI_7510 0xac47 +#define PCI_DEVICE_ID_TI_7610 0xac48 +#define PCI_DEVICE_ID_TI_7410 0xac49 +#define PCI_DEVICE_ID_TI_1410 0xac50 +#define PCI_DEVICE_ID_TI_1420 0xac51 +#define PCI_DEVICE_ID_TI_1451A 0xac52 +#define PCI_DEVICE_ID_TI_1620 0xac54 +#define PCI_DEVICE_ID_TI_1520 0xac55 +#define PCI_DEVICE_ID_TI_1510 0xac56 +#define PCI_DEVICE_ID_TI_X620 0xac8d +#define PCI_DEVICE_ID_TI_X420 0xac8e + +#define PCI_VENDOR_ID_SONY 0x104d + + +/* Winbond have two vendor IDs! See 0x10ad as well */ +#define PCI_VENDOR_ID_WINBOND2 0x1050 +#define PCI_DEVICE_ID_WINBOND2_89C940F 0x5a5a +#define PCI_DEVICE_ID_WINBOND2_6692 0x6692 + +#define PCI_VENDOR_ID_ANIGMA 0x1051 +#define PCI_DEVICE_ID_ANIGMA_MC145575 0x0100 + +#define PCI_VENDOR_ID_EFAR 0x1055 +#define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130 +#define PCI_DEVICE_ID_EFAR_SLC90E66_3 0x9463 + +#define PCI_VENDOR_ID_MOTOROLA 0x1057 +#define PCI_DEVICE_ID_MOTOROLA_MPC105 0x0001 +#define PCI_DEVICE_ID_MOTOROLA_MPC106 0x0002 +#define PCI_DEVICE_ID_MOTOROLA_MPC107 0x0004 +#define PCI_DEVICE_ID_MOTOROLA_RAVEN 0x4801 +#define PCI_DEVICE_ID_MOTOROLA_FALCON 0x4802 +#define PCI_DEVICE_ID_MOTOROLA_HAWK 0x4803 +#define PCI_DEVICE_ID_MOTOROLA_HARRIER 0x480b +#define PCI_DEVICE_ID_MOTOROLA_MPC5200 0x5803 +#define PCI_DEVICE_ID_MOTOROLA_MPC5200B 0x5809 + +#define PCI_VENDOR_ID_PROMISE 0x105a +#define PCI_DEVICE_ID_PROMISE_20265 0x0d30 +#define PCI_DEVICE_ID_PROMISE_20267 0x4d30 +#define PCI_DEVICE_ID_PROMISE_20246 0x4d33 +#define PCI_DEVICE_ID_PROMISE_20262 0x4d38 +#define PCI_DEVICE_ID_PROMISE_20263 0x0D38 +#define PCI_DEVICE_ID_PROMISE_20268 0x4d68 +#define PCI_DEVICE_ID_PROMISE_20269 0x4d69 +#define PCI_DEVICE_ID_PROMISE_20270 0x6268 +#define PCI_DEVICE_ID_PROMISE_20271 0x6269 +#define PCI_DEVICE_ID_PROMISE_20275 0x1275 +#define PCI_DEVICE_ID_PROMISE_20276 0x5275 +#define PCI_DEVICE_ID_PROMISE_20277 0x7275 + + +#define PCI_VENDOR_ID_UMC 0x1060 +#define PCI_DEVICE_ID_UMC_UM8673F 0x0101 +#define PCI_DEVICE_ID_UMC_UM8886BF 0x673a +#define PCI_DEVICE_ID_UMC_UM8886A 0x886a + + +#define PCI_VENDOR_ID_MYLEX 0x1069 +#define PCI_DEVICE_ID_MYLEX_DAC960_P 0x0001 +#define PCI_DEVICE_ID_MYLEX_DAC960_PD 0x0002 +#define PCI_DEVICE_ID_MYLEX_DAC960_PG 0x0010 +#define PCI_DEVICE_ID_MYLEX_DAC960_LA 0x0020 +#define PCI_DEVICE_ID_MYLEX_DAC960_LP 0x0050 +#define PCI_DEVICE_ID_MYLEX_DAC960_BA 0xBA56 +#define PCI_DEVICE_ID_MYLEX_DAC960_GEM 0xB166 + + +#define PCI_VENDOR_ID_APPLE 0x106b +#define PCI_DEVICE_ID_APPLE_BANDIT 0x0001 +#define PCI_DEVICE_ID_APPLE_HYDRA 0x000e +#define PCI_DEVICE_ID_APPLE_UNI_N_FW 0x0018 +#define PCI_DEVICE_ID_APPLE_UNI_N_AGP 0x0020 +#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC 0x0021 +#define PCI_DEVICE_ID_APPLE_UNI_N_GMACP 0x0024 +#define PCI_DEVICE_ID_APPLE_UNI_N_AGP_P 0x0027 +#define PCI_DEVICE_ID_APPLE_UNI_N_AGP15 0x002d +#define PCI_DEVICE_ID_APPLE_UNI_N_PCI15 0x002e +#define PCI_DEVICE_ID_APPLE_UNI_N_GMAC2 0x0032 +#define PCI_DEVICE_ID_APPLE_UNI_N_ATA 0x0033 +#define PCI_DEVICE_ID_APPLE_UNI_N_AGP2 0x0034 +#define PCI_DEVICE_ID_APPLE_IPID_ATA100 0x003b +#define PCI_DEVICE_ID_APPLE_K2_ATA100 0x0043 +#define PCI_DEVICE_ID_APPLE_U3_AGP 0x004b +#define PCI_DEVICE_ID_APPLE_K2_GMAC 0x004c +#define PCI_DEVICE_ID_APPLE_SH_ATA 0x0050 +#define PCI_DEVICE_ID_APPLE_SH_SUNGEM 0x0051 +#define PCI_DEVICE_ID_APPLE_U3L_AGP 0x0058 +#define PCI_DEVICE_ID_APPLE_U3H_AGP 0x0059 +#define PCI_DEVICE_ID_APPLE_IPID2_AGP 0x0066 +#define PCI_DEVICE_ID_APPLE_IPID2_ATA 0x0069 +#define PCI_DEVICE_ID_APPLE_IPID2_FW 0x006a +#define PCI_DEVICE_ID_APPLE_IPID2_GMAC 0x006b +#define PCI_DEVICE_ID_APPLE_TIGON3 0x1645 + +#define PCI_VENDOR_ID_YAMAHA 0x1073 +#define PCI_DEVICE_ID_YAMAHA_724 0x0004 +#define PCI_DEVICE_ID_YAMAHA_724F 0x000d +#define PCI_DEVICE_ID_YAMAHA_740 0x000a +#define PCI_DEVICE_ID_YAMAHA_740C 0x000c +#define PCI_DEVICE_ID_YAMAHA_744 0x0010 +#define PCI_DEVICE_ID_YAMAHA_754 0x0012 + + +#define PCI_VENDOR_ID_QLOGIC 0x1077 +#define PCI_DEVICE_ID_QLOGIC_ISP10160 0x1016 +#define PCI_DEVICE_ID_QLOGIC_ISP1020 0x1020 +#define PCI_DEVICE_ID_QLOGIC_ISP1080 0x1080 +#define PCI_DEVICE_ID_QLOGIC_ISP12160 0x1216 +#define PCI_DEVICE_ID_QLOGIC_ISP1240 0x1240 +#define PCI_DEVICE_ID_QLOGIC_ISP1280 0x1280 +#define PCI_DEVICE_ID_QLOGIC_ISP2100 0x2100 +#define PCI_DEVICE_ID_QLOGIC_ISP2200 0x2200 +#define PCI_DEVICE_ID_QLOGIC_ISP2300 0x2300 +#define PCI_DEVICE_ID_QLOGIC_ISP2312 0x2312 +#define PCI_DEVICE_ID_QLOGIC_ISP2322 0x2322 +#define PCI_DEVICE_ID_QLOGIC_ISP6312 0x6312 +#define PCI_DEVICE_ID_QLOGIC_ISP6322 0x6322 +#define PCI_DEVICE_ID_QLOGIC_ISP2422 0x2422 +#define PCI_DEVICE_ID_QLOGIC_ISP2432 0x2432 +#define PCI_DEVICE_ID_QLOGIC_ISP2512 0x2512 +#define PCI_DEVICE_ID_QLOGIC_ISP2522 0x2522 +#define PCI_DEVICE_ID_QLOGIC_ISP5422 0x5422 +#define PCI_DEVICE_ID_QLOGIC_ISP5432 0x5432 + +#define PCI_VENDOR_ID_CYRIX 0x1078 +#define PCI_DEVICE_ID_CYRIX_5510 0x0000 +#define PCI_DEVICE_ID_CYRIX_PCI_MASTER 0x0001 +#define PCI_DEVICE_ID_CYRIX_5520 0x0002 +#define PCI_DEVICE_ID_CYRIX_5530_LEGACY 0x0100 +#define PCI_DEVICE_ID_CYRIX_5530_IDE 0x0102 +#define PCI_DEVICE_ID_CYRIX_5530_AUDIO 0x0103 +#define PCI_DEVICE_ID_CYRIX_5530_VIDEO 0x0104 + + + +#define PCI_VENDOR_ID_CONTAQ 0x1080 +#define PCI_DEVICE_ID_CONTAQ_82C693 0xc693 + + +#define PCI_VENDOR_ID_OLICOM 0x108d +#define PCI_DEVICE_ID_OLICOM_OC2325 0x0012 +#define PCI_DEVICE_ID_OLICOM_OC2183 0x0013 +#define PCI_DEVICE_ID_OLICOM_OC2326 0x0014 + +#define PCI_VENDOR_ID_SUN 0x108e +#define PCI_DEVICE_ID_SUN_EBUS 0x1000 +#define PCI_DEVICE_ID_SUN_HAPPYMEAL 0x1001 +#define PCI_DEVICE_ID_SUN_RIO_EBUS 0x1100 +#define PCI_DEVICE_ID_SUN_RIO_GEM 0x1101 +#define PCI_DEVICE_ID_SUN_RIO_1394 0x1102 +#define PCI_DEVICE_ID_SUN_RIO_USB 0x1103 +#define PCI_DEVICE_ID_SUN_GEM 0x2bad +#define PCI_DEVICE_ID_SUN_SIMBA 0x5000 +#define PCI_DEVICE_ID_SUN_PBM 0x8000 +#define PCI_DEVICE_ID_SUN_SCHIZO 0x8001 +#define PCI_DEVICE_ID_SUN_SABRE 0xa000 +#define PCI_DEVICE_ID_SUN_HUMMINGBIRD 0xa001 +#define PCI_DEVICE_ID_SUN_TOMATILLO 0xa801 +#define PCI_DEVICE_ID_SUN_CASSINI 0xabba + +#define PCI_VENDOR_ID_CMD 0x1095 +#define PCI_DEVICE_ID_CMD_643 0x0643 +#define PCI_DEVICE_ID_CMD_646 0x0646 +#define PCI_DEVICE_ID_CMD_648 0x0648 +#define PCI_DEVICE_ID_CMD_649 0x0649 + +#define PCI_DEVICE_ID_SII_680 0x0680 +#define PCI_DEVICE_ID_SII_3112 0x3112 +#define PCI_DEVICE_ID_SII_1210SA 0x0240 + + +#define PCI_VENDOR_ID_BROOKTREE 0x109e +#define PCI_DEVICE_ID_BROOKTREE_878 0x0878 +#define PCI_DEVICE_ID_BROOKTREE_879 0x0879 + + +#define PCI_VENDOR_ID_SGI 0x10a9 +#define PCI_DEVICE_ID_SGI_IOC3 0x0003 +#define PCI_DEVICE_ID_SGI_IOC4 0x100a +#define PCI_VENDOR_ID_SGI_LITHIUM 0x1002 + + +#define PCI_VENDOR_ID_WINBOND 0x10ad +#define PCI_DEVICE_ID_WINBOND_82C105 0x0105 +#define PCI_DEVICE_ID_WINBOND_83C553 0x0565 + + +#define PCI_VENDOR_ID_PLX 0x10b5 +#define PCI_DEVICE_ID_PLX_R685 0x1030 +#define PCI_DEVICE_ID_PLX_ROMULUS 0x106a +#define PCI_DEVICE_ID_PLX_SPCOM800 0x1076 +#define PCI_DEVICE_ID_PLX_1077 0x1077 +#define PCI_DEVICE_ID_PLX_SPCOM200 0x1103 +#define PCI_DEVICE_ID_PLX_DJINN_ITOO 0x1151 +#define PCI_DEVICE_ID_PLX_R753 0x1152 +#define PCI_DEVICE_ID_PLX_OLITEC 0x1187 +#define PCI_DEVICE_ID_PLX_PCI200SYN 0x3196 +#define PCI_DEVICE_ID_PLX_9050 0x9050 +#define PCI_DEVICE_ID_PLX_9080 0x9080 +#define PCI_DEVICE_ID_PLX_GTEK_SERIAL2 0xa001 + +#define PCI_VENDOR_ID_MADGE 0x10b6 +#define PCI_DEVICE_ID_MADGE_MK2 0x0002 + +#define PCI_VENDOR_ID_3COM 0x10b7 +#define PCI_DEVICE_ID_3COM_3C985 0x0001 +#define PCI_DEVICE_ID_3COM_3C940 0x1700 +#define PCI_DEVICE_ID_3COM_3C339 0x3390 +#define PCI_DEVICE_ID_3COM_3C359 0x3590 +#define PCI_DEVICE_ID_3COM_3C940B 0x80eb +#define PCI_DEVICE_ID_3COM_3CR990 0x9900 +#define PCI_DEVICE_ID_3COM_3CR990_TX_95 0x9902 +#define PCI_DEVICE_ID_3COM_3CR990_TX_97 0x9903 +#define PCI_DEVICE_ID_3COM_3CR990B 0x9904 +#define PCI_DEVICE_ID_3COM_3CR990_FX 0x9905 +#define PCI_DEVICE_ID_3COM_3CR990SVR95 0x9908 +#define PCI_DEVICE_ID_3COM_3CR990SVR97 0x9909 +#define PCI_DEVICE_ID_3COM_3CR990SVR 0x990a + + +#define PCI_VENDOR_ID_AL 0x10b9 +#define PCI_DEVICE_ID_AL_M1533 0x1533 +#define PCI_DEVICE_ID_AL_M1535 0x1535 +#define PCI_DEVICE_ID_AL_M1541 0x1541 +#define PCI_DEVICE_ID_AL_M1563 0x1563 +#define PCI_DEVICE_ID_AL_M1621 0x1621 +#define PCI_DEVICE_ID_AL_M1631 0x1631 +#define PCI_DEVICE_ID_AL_M1632 0x1632 +#define PCI_DEVICE_ID_AL_M1641 0x1641 +#define PCI_DEVICE_ID_AL_M1644 0x1644 +#define PCI_DEVICE_ID_AL_M1647 0x1647 +#define PCI_DEVICE_ID_AL_M1651 0x1651 +#define PCI_DEVICE_ID_AL_M1671 0x1671 +#define PCI_DEVICE_ID_AL_M1681 0x1681 +#define PCI_DEVICE_ID_AL_M1683 0x1683 +#define PCI_DEVICE_ID_AL_M1689 0x1689 +#define PCI_DEVICE_ID_AL_M5219 0x5219 +#define PCI_DEVICE_ID_AL_M5228 0x5228 +#define PCI_DEVICE_ID_AL_M5229 0x5229 +#define PCI_DEVICE_ID_AL_M5451 0x5451 +#define PCI_DEVICE_ID_AL_M7101 0x7101 + + + +#define PCI_VENDOR_ID_NEOMAGIC 0x10c8 +#define PCI_DEVICE_ID_NEOMAGIC_NM256AV_AUDIO 0x8005 +#define PCI_DEVICE_ID_NEOMAGIC_NM256ZX_AUDIO 0x8006 +#define PCI_DEVICE_ID_NEOMAGIC_NM256XL_PLUS_AUDIO 0x8016 + + +#define PCI_VENDOR_ID_TCONRAD 0x10da +#define PCI_DEVICE_ID_TCONRAD_TOKENRING 0x0508 + + +#define PCI_VENDOR_ID_NVIDIA 0x10de +#define PCI_DEVICE_ID_NVIDIA_TNT 0x0020 +#define PCI_DEVICE_ID_NVIDIA_TNT2 0x0028 +#define PCI_DEVICE_ID_NVIDIA_UTNT2 0x0029 +#define PCI_DEVICE_ID_NVIDIA_TNT_UNKNOWN 0x002a +#define PCI_DEVICE_ID_NVIDIA_VTNT2 0x002C +#define PCI_DEVICE_ID_NVIDIA_UVTNT2 0x002D +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SMBUS 0x0034 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_IDE 0x0035 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA 0x0036 +#define PCI_DEVICE_ID_NVIDIA_NVENET_10 0x0037 +#define PCI_DEVICE_ID_NVIDIA_NVENET_11 0x0038 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP04_SATA2 0x003e +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_ULTRA 0x0040 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800 0x0041 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_LE 0x0042 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800_GT 0x0045 +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_4000 0x004E +#define PCI_DEVICE_ID_NVIDIA_NFORCE4_SMBUS 0x0052 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_IDE 0x0053 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA 0x0054 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_CK804_SATA2 0x0055 +#define PCI_DEVICE_ID_NVIDIA_NVENET_8 0x0056 +#define PCI_DEVICE_ID_NVIDIA_NVENET_9 0x0057 +#define PCI_DEVICE_ID_NVIDIA_CK804_AUDIO 0x0059 +#define PCI_DEVICE_ID_NVIDIA_CK804_PCIE 0x005d +#define PCI_DEVICE_ID_NVIDIA_NFORCE2_SMBUS 0x0064 +#define PCI_DEVICE_ID_NVIDIA_NFORCE2_IDE 0x0065 +#define PCI_DEVICE_ID_NVIDIA_NVENET_2 0x0066 +#define PCI_DEVICE_ID_NVIDIA_MCP2_MODEM 0x0069 +#define PCI_DEVICE_ID_NVIDIA_MCP2_AUDIO 0x006a +#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SMBUS 0x0084 +#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_IDE 0x0085 +#define PCI_DEVICE_ID_NVIDIA_NVENET_4 0x0086 +#define PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM 0x0089 +#define PCI_DEVICE_ID_NVIDIA_CK8_AUDIO 0x008a +#define PCI_DEVICE_ID_NVIDIA_NVENET_5 0x008c +#define PCI_DEVICE_ID_NVIDIA_NFORCE2S_SATA 0x008e +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GT 0x0090 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_7800_GTX 0x0091 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800 0x0098 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_7800_GTX 0x0099 +#define PCI_DEVICE_ID_NVIDIA_ITNT2 0x00A0 +#define PCI_DEVICE_ID_GEFORCE_6800A 0x00c1 +#define PCI_DEVICE_ID_GEFORCE_6800A_LE 0x00c2 +#define PCI_DEVICE_ID_GEFORCE_GO_6800 0x00c8 +#define PCI_DEVICE_ID_GEFORCE_GO_6800_ULTRA 0x00c9 +#define PCI_DEVICE_ID_QUADRO_FX_GO1400 0x00cc +#define PCI_DEVICE_ID_QUADRO_FX_1400 0x00ce +#define PCI_DEVICE_ID_NVIDIA_NFORCE3 0x00d1 +#define PCI_DEVICE_ID_NVIDIA_NFORCE3_SMBUS 0x00d4 +#define PCI_DEVICE_ID_NVIDIA_NFORCE3_IDE 0x00d5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_3 0x00d6 +#define PCI_DEVICE_ID_NVIDIA_MCP3_MODEM 0x00d9 +#define PCI_DEVICE_ID_NVIDIA_MCP3_AUDIO 0x00da +#define PCI_DEVICE_ID_NVIDIA_NVENET_7 0x00df +#define PCI_DEVICE_ID_NVIDIA_NFORCE3S 0x00e1 +#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA 0x00e3 +#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SMBUS 0x00e4 +#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_IDE 0x00e5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_6 0x00e6 +#define PCI_DEVICE_ID_NVIDIA_CK8S_AUDIO 0x00ea +#define PCI_DEVICE_ID_NVIDIA_NFORCE3S_SATA2 0x00ee +#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_ALT1 0x00f0 +#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT1 0x00f1 +#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6600_ALT2 0x00f2 +#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6200_ALT1 0x00f3 +#define PCIE_DEVICE_ID_NVIDIA_GEFORCE_6800_GT 0x00f9 +#define PCIE_DEVICE_ID_NVIDIA_QUADRO_NVS280 0x00fd +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_SDR 0x0100 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_DDR 0x0101 +#define PCI_DEVICE_ID_NVIDIA_QUADRO 0x0103 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX 0x0110 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_MX2 0x0111 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GO 0x0112 +#define PCI_DEVICE_ID_NVIDIA_QUADRO2_MXR 0x0113 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600_GT 0x0140 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6600 0x0141 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6610_XL 0x0145 +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_540 0x014E +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6200 0x014F +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS 0x0150 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_GTS2 0x0151 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE2_ULTRA 0x0152 +#define PCI_DEVICE_ID_NVIDIA_QUADRO2_PRO 0x0153 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6200_TURBOCACHE 0x0161 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200 0x0164 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250 0x0166 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6200_1 0x0167 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_GO_6250_1 0x0168 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_460 0x0170 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440 0x0171 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420 0x0172 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_SE 0x0173 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO 0x0174 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO 0x0175 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_420_GO_M32 0x0176 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_460_GO 0x0177 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500XGL 0x0178 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_440_GO_M64 0x0179 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_200 0x017A +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_550XGL 0x017B +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_500_GOGL 0x017C +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_410_GO_M16 0x017D +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440_8X 0x0181 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_440SE_8X 0x0182 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_420_8X 0x0183 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_4000 0x0185 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_448_GO 0x0186 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_488_GO 0x0187 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_580_XGL 0x0188 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_MX_MAC 0x0189 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_280_NVS 0x018A +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_380_XGL 0x018B +#define PCI_DEVICE_ID_NVIDIA_IGEFORCE2 0x01a0 +#define PCI_DEVICE_ID_NVIDIA_NFORCE 0x01a4 +#define PCI_DEVICE_ID_NVIDIA_MCP1_AUDIO 0x01b1 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_SMBUS 0x01b4 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_IDE 0x01bc +#define PCI_DEVICE_ID_NVIDIA_MCP1_MODEM 0x01c1 +#define PCI_DEVICE_ID_NVIDIA_NVENET_1 0x01c3 +#define PCI_DEVICE_ID_NVIDIA_NFORCE2 0x01e0 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE3 0x0200 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_1 0x0201 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE3_2 0x0202 +#define PCI_DEVICE_ID_NVIDIA_QUADRO_DDC 0x0203 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B 0x0211 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_LE 0x0212 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_6800B_GT 0x0215 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4600 0x0250 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4400 0x0251 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4200 0x0253 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_900XGL 0x0258 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_750XGL 0x0259 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700XGL 0x025B +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SMBUS 0x0264 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_IDE 0x0265 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA 0x0266 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP51_SATA2 0x0267 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SMBUS 0x0368 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_IDE 0x036E +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA 0x037E +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP55_SATA2 0x037F +#define PCI_DEVICE_ID_NVIDIA_NVENET_12 0x0268 +#define PCI_DEVICE_ID_NVIDIA_NVENET_13 0x0269 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800 0x0280 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800_8X 0x0281 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_TI_4800SE 0x0282 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE4_4200_GO 0x0286 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_980_XGL 0x0288 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_780_XGL 0x0289 +#define PCI_DEVICE_ID_NVIDIA_QUADRO4_700_GOGL 0x028C +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800_ULTRA 0x0301 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5800 0x0302 +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_2000 0x0308 +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1000 0x0309 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600_ULTRA 0x0311 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600 0x0312 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5600SE 0x0314 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5600 0x031A +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5650 0x031B +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO700 0x031C +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200 0x0320 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_ULTRA 0x0321 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200_1 0x0322 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5200SE 0x0323 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5200 0x0324 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250 0x0325 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5500 0x0326 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5100 0x0327 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5250_32 0x0328 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO_5200 0x0329 +#define PCI_DEVICE_ID_NVIDIA_QUADRO_NVS_280_PCI 0x032A +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_500 0x032B +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5300 0x032C +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5100 0x032D +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900_ULTRA 0x0330 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900 0x0331 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900XT 0x0332 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5950_ULTRA 0x0333 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5900ZT 0x0334 +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_3000 0x0338 +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_700 0x033F +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700_ULTRA 0x0341 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700 0x0342 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700LE 0x0343 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_5700VE 0x0344 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_1 0x0347 +#define PCI_DEVICE_ID_NVIDIA_GEFORCE_FX_GO5700_2 0x0348 +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_GO1000 0x034C +#define PCI_DEVICE_ID_NVIDIA_QUADRO_FX_1100 0x034E +#define PCI_DEVICE_ID_NVIDIA_NVENET_14 0x0372 +#define PCI_DEVICE_ID_NVIDIA_NVENET_15 0x0373 +#define PCI_DEVICE_ID_NVIDIA_NVENET_16 0x03E5 +#define PCI_DEVICE_ID_NVIDIA_NVENET_17 0x03E6 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA 0x03E7 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_IDE 0x03EC +#define PCI_DEVICE_ID_NVIDIA_NVENET_18 0x03EE +#define PCI_DEVICE_ID_NVIDIA_NVENET_19 0x03EF +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA2 0x03F6 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP61_SATA3 0x03F7 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP65_IDE 0x0448 +#define PCI_DEVICE_ID_NVIDIA_NVENET_20 0x0450 +#define PCI_DEVICE_ID_NVIDIA_NVENET_21 0x0451 +#define PCI_DEVICE_ID_NVIDIA_NVENET_22 0x0452 +#define PCI_DEVICE_ID_NVIDIA_NVENET_23 0x0453 +#define PCI_DEVICE_ID_NVIDIA_NFORCE_MCP67_IDE 0x0560 + +#define PCI_VENDOR_ID_IMS 0x10e0 +#define PCI_DEVICE_ID_IMS_TT128 0x9128 +#define PCI_DEVICE_ID_IMS_TT3D 0x9135 + + + + +#define PCI_VENDOR_ID_INTERG 0x10ea +#define PCI_DEVICE_ID_INTERG_1682 0x1682 +#define PCI_DEVICE_ID_INTERG_2000 0x2000 +#define PCI_DEVICE_ID_INTERG_2010 0x2010 +#define PCI_DEVICE_ID_INTERG_5000 0x5000 +#define PCI_DEVICE_ID_INTERG_5050 0x5050 + +#define PCI_VENDOR_ID_REALTEK 0x10ec +#define PCI_DEVICE_ID_REALTEK_8139 0x8139 + +#define PCI_VENDOR_ID_XILINX 0x10ee +#define PCI_DEVICE_ID_RME_DIGI96 0x3fc0 +#define PCI_DEVICE_ID_RME_DIGI96_8 0x3fc1 +#define PCI_DEVICE_ID_RME_DIGI96_8_PRO 0x3fc2 +#define PCI_DEVICE_ID_RME_DIGI96_8_PAD_OR_PST 0x3fc3 +#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP 0x3fc5 +#define PCI_DEVICE_ID_XILINX_HAMMERFALL_DSP_MADI 0x3fc6 + + +#define PCI_VENDOR_ID_INIT 0x1101 + +#define PCI_VENDOR_ID_CREATIVE 0x1102 /* duplicate: ECTIVA */ +#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002 + +#define PCI_VENDOR_ID_ECTIVA 0x1102 /* duplicate: CREATIVE */ +#define PCI_DEVICE_ID_ECTIVA_EV1938 0x8938 + +#define PCI_VENDOR_ID_TTI 0x1103 +#define PCI_DEVICE_ID_TTI_HPT343 0x0003 +#define PCI_DEVICE_ID_TTI_HPT366 0x0004 +#define PCI_DEVICE_ID_TTI_HPT372 0x0005 +#define PCI_DEVICE_ID_TTI_HPT302 0x0006 +#define PCI_DEVICE_ID_TTI_HPT371 0x0007 +#define PCI_DEVICE_ID_TTI_HPT374 0x0008 +#define PCI_DEVICE_ID_TTI_HPT372N 0x0009 /* apparently a 372N variant? */ + +#define PCI_VENDOR_ID_VIA 0x1106 +#define PCI_DEVICE_ID_VIA_8763_0 0x0198 +#define PCI_DEVICE_ID_VIA_8380_0 0x0204 +#define PCI_DEVICE_ID_VIA_3238_0 0x0238 +#define PCI_DEVICE_ID_VIA_PT880 0x0258 +#define PCI_DEVICE_ID_VIA_PT880ULTRA 0x0308 +#define PCI_DEVICE_ID_VIA_PX8X0_0 0x0259 +#define PCI_DEVICE_ID_VIA_3269_0 0x0269 +#define PCI_DEVICE_ID_VIA_K8T800PRO_0 0x0282 +#define PCI_DEVICE_ID_VIA_3296_0 0x0296 +#define PCI_DEVICE_ID_VIA_8363_0 0x0305 +#define PCI_DEVICE_ID_VIA_P4M800CE 0x0314 +#define PCI_DEVICE_ID_VIA_8371_0 0x0391 +#define PCI_DEVICE_ID_VIA_8501_0 0x0501 +#define PCI_DEVICE_ID_VIA_82C561 0x0561 +#define PCI_DEVICE_ID_VIA_82C586_1 0x0571 +#define PCI_DEVICE_ID_VIA_82C576 0x0576 +#define PCI_DEVICE_ID_VIA_SATA_EIDE 0x0581 +#define PCI_DEVICE_ID_VIA_82C586_0 0x0586 +#define PCI_DEVICE_ID_VIA_82C596 0x0596 +#define PCI_DEVICE_ID_VIA_82C597_0 0x0597 +#define PCI_DEVICE_ID_VIA_82C598_0 0x0598 +#define PCI_DEVICE_ID_VIA_8601_0 0x0601 +#define PCI_DEVICE_ID_VIA_8605_0 0x0605 +#define PCI_DEVICE_ID_VIA_82C686 0x0686 +#define PCI_DEVICE_ID_VIA_82C691_0 0x0691 +#define PCI_DEVICE_ID_VIA_82C576_1 0x1571 +#define PCI_DEVICE_ID_VIA_82C586_2 0x3038 +#define PCI_DEVICE_ID_VIA_82C586_3 0x3040 +#define PCI_DEVICE_ID_VIA_82C596_3 0x3050 +#define PCI_DEVICE_ID_VIA_82C596B_3 0x3051 +#define PCI_DEVICE_ID_VIA_82C686_4 0x3057 +#define PCI_DEVICE_ID_VIA_82C686_5 0x3058 +#define PCI_DEVICE_ID_VIA_8233_5 0x3059 +#define PCI_DEVICE_ID_VIA_8233_0 0x3074 +#define PCI_DEVICE_ID_VIA_8633_0 0x3091 +#define PCI_DEVICE_ID_VIA_8367_0 0x3099 +#define PCI_DEVICE_ID_VIA_8653_0 0x3101 +#define PCI_DEVICE_ID_VIA_8622 0x3102 +#define PCI_DEVICE_ID_VIA_8235_USB_2 0x3104 +#define PCI_DEVICE_ID_VIA_8233C_0 0x3109 +#define PCI_DEVICE_ID_VIA_8361 0x3112 +#define PCI_DEVICE_ID_VIA_XM266 0x3116 +#define PCI_DEVICE_ID_VIA_612X 0x3119 +#define PCI_DEVICE_ID_VIA_862X_0 0x3123 +#define PCI_DEVICE_ID_VIA_8753_0 0x3128 +#define PCI_DEVICE_ID_VIA_8233A 0x3147 +#define PCI_DEVICE_ID_VIA_8703_51_0 0x3148 +#define PCI_DEVICE_ID_VIA_8237_SATA 0x3149 +#define PCI_DEVICE_ID_VIA_XN266 0x3156 +#define PCI_DEVICE_ID_VIA_6410 0x3164 +#define PCI_DEVICE_ID_VIA_8754C_0 0x3168 +#define PCI_DEVICE_ID_VIA_8235 0x3177 +#define PCI_DEVICE_ID_VIA_8385_0 0x3188 +#define PCI_DEVICE_ID_VIA_8377_0 0x3189 +#define PCI_DEVICE_ID_VIA_8378_0 0x3205 +#define PCI_DEVICE_ID_VIA_8783_0 0x3208 +#define PCI_DEVICE_ID_VIA_8237 0x3227 +#define PCI_DEVICE_ID_VIA_8251 0x3287 +#define PCI_DEVICE_ID_VIA_8237A 0x3337 +#define PCI_DEVICE_ID_VIA_8231 0x8231 +#define PCI_DEVICE_ID_VIA_8231_4 0x8235 +#define PCI_DEVICE_ID_VIA_8365_1 0x8305 +#define PCI_DEVICE_ID_VIA_CX700 0x8324 +#define PCI_DEVICE_ID_VIA_8371_1 0x8391 +#define PCI_DEVICE_ID_VIA_82C598_1 0x8598 +#define PCI_DEVICE_ID_VIA_838X_1 0xB188 +#define PCI_DEVICE_ID_VIA_83_87XX_1 0xB198 + +#define PCI_VENDOR_ID_SIEMENS 0x110A +#define PCI_DEVICE_ID_SIEMENS_DSCC4 0x2102 + + +#define PCI_VENDOR_ID_VORTEX 0x1119 +#define PCI_DEVICE_ID_VORTEX_GDT60x0 0x0000 +#define PCI_DEVICE_ID_VORTEX_GDT6000B 0x0001 +#define PCI_DEVICE_ID_VORTEX_GDT6x10 0x0002 +#define PCI_DEVICE_ID_VORTEX_GDT6x20 0x0003 +#define PCI_DEVICE_ID_VORTEX_GDT6530 0x0004 +#define PCI_DEVICE_ID_VORTEX_GDT6550 0x0005 +#define PCI_DEVICE_ID_VORTEX_GDT6x17 0x0006 +#define PCI_DEVICE_ID_VORTEX_GDT6x27 0x0007 +#define PCI_DEVICE_ID_VORTEX_GDT6537 0x0008 +#define PCI_DEVICE_ID_VORTEX_GDT6557 0x0009 +#define PCI_DEVICE_ID_VORTEX_GDT6x15 0x000a +#define PCI_DEVICE_ID_VORTEX_GDT6x25 0x000b +#define PCI_DEVICE_ID_VORTEX_GDT6535 0x000c +#define PCI_DEVICE_ID_VORTEX_GDT6555 0x000d +#define PCI_DEVICE_ID_VORTEX_GDT6x17RP 0x0100 +#define PCI_DEVICE_ID_VORTEX_GDT6x27RP 0x0101 +#define PCI_DEVICE_ID_VORTEX_GDT6537RP 0x0102 +#define PCI_DEVICE_ID_VORTEX_GDT6557RP 0x0103 +#define PCI_DEVICE_ID_VORTEX_GDT6x11RP 0x0104 +#define PCI_DEVICE_ID_VORTEX_GDT6x21RP 0x0105 + +#define PCI_VENDOR_ID_EF 0x111a +#define PCI_DEVICE_ID_EF_ATM_FPGA 0x0000 +#define PCI_DEVICE_ID_EF_ATM_ASIC 0x0002 +#define PCI_VENDOR_ID_EF_ATM_LANAI2 0x0003 +#define PCI_VENDOR_ID_EF_ATM_LANAIHB 0x0005 + +#define PCI_VENDOR_ID_IDT 0x111d +#define PCI_DEVICE_ID_IDT_IDT77201 0x0001 + +#define PCI_VENDOR_ID_FORE 0x1127 +#define PCI_DEVICE_ID_FORE_PCA200E 0x0300 + + +#define PCI_VENDOR_ID_PHILIPS 0x1131 +#define PCI_DEVICE_ID_PHILIPS_SAA7146 0x7146 +#define PCI_DEVICE_ID_PHILIPS_SAA9730 0x9730 + +#define PCI_VENDOR_ID_EICON 0x1133 +#define PCI_DEVICE_ID_EICON_DIVA20 0xe002 +#define PCI_DEVICE_ID_EICON_DIVA20_U 0xe004 +#define PCI_DEVICE_ID_EICON_DIVA201 0xe005 +#define PCI_DEVICE_ID_EICON_DIVA202 0xe00b +#define PCI_DEVICE_ID_EICON_MAESTRA 0xe010 +#define PCI_DEVICE_ID_EICON_MAESTRAQ 0xe012 +#define PCI_DEVICE_ID_EICON_MAESTRAQ_U 0xe013 +#define PCI_DEVICE_ID_EICON_MAESTRAP 0xe014 + +#define PCI_VENDOR_ID_ZIATECH 0x1138 +#define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550 + + + +#define PCI_VENDOR_ID_SYSKONNECT 0x1148 +#define PCI_DEVICE_ID_SYSKONNECT_TR 0x4200 +#define PCI_DEVICE_ID_SYSKONNECT_GE 0x4300 +#define PCI_DEVICE_ID_SYSKONNECT_YU 0x4320 +#define PCI_DEVICE_ID_SYSKONNECT_9DXX 0x4400 +#define PCI_DEVICE_ID_SYSKONNECT_9MXX 0x4500 + + +#define PCI_VENDOR_ID_DIGI 0x114f +#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_E 0x0070 +#define PCI_DEVICE_ID_DIGI_DF_M_E 0x0071 +#define PCI_DEVICE_ID_DIGI_DF_M_IOM2_A 0x0072 +#define PCI_DEVICE_ID_DIGI_DF_M_A 0x0073 +#define PCI_DEVICE_ID_NEO_2DB9 0x00C8 +#define PCI_DEVICE_ID_NEO_2DB9PRI 0x00C9 +#define PCI_DEVICE_ID_NEO_2RJ45 0x00CA +#define PCI_DEVICE_ID_NEO_2RJ45PRI 0x00CB + + +#define PCI_VENDOR_ID_XIRCOM 0x115d +#define PCI_DEVICE_ID_XIRCOM_RBM56G 0x0101 +#define PCI_DEVICE_ID_XIRCOM_X3201_MDM 0x0103 + + +#define PCI_VENDOR_ID_SERVERWORKS 0x1166 +#define PCI_DEVICE_ID_SERVERWORKS_HE 0x0008 +#define PCI_DEVICE_ID_SERVERWORKS_LE 0x0009 +#define PCI_DEVICE_ID_SERVERWORKS_GCNB_LE 0x0017 +#define PCI_DEVICE_ID_SERVERWORKS_EPB 0x0103 +#define PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE 0x0132 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200 +#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201 +#define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203 +#define PCI_DEVICE_ID_SERVERWORKS_HT1000SB 0x0205 +#define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211 +#define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212 +#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213 +#define PCI_DEVICE_ID_SERVERWORKS_HT1000IDE 0x0214 +#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2 0x0217 +#define PCI_DEVICE_ID_SERVERWORKS_CSB6LPC 0x0227 + +#define PCI_VENDOR_ID_SBE 0x1176 +#define PCI_DEVICE_ID_SBE_WANXL100 0x0301 +#define PCI_DEVICE_ID_SBE_WANXL200 0x0302 +#define PCI_DEVICE_ID_SBE_WANXL400 0x0104 + +#define PCI_VENDOR_ID_TOSHIBA 0x1179 +#define PCI_DEVICE_ID_TOSHIBA_PICCOLO 0x0102 +#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_1 0x0103 +#define PCI_DEVICE_ID_TOSHIBA_PICCOLO_2 0x0105 +#define PCI_DEVICE_ID_TOSHIBA_TOPIC95 0x060a +#define PCI_DEVICE_ID_TOSHIBA_TOPIC97 0x060f +#define PCI_DEVICE_ID_TOSHIBA_TOPIC100 0x0617 + +#define PCI_VENDOR_ID_TOSHIBA_2 0x102f +#define PCI_DEVICE_ID_TOSHIBA_TC35815CF 0x0030 +#define PCI_DEVICE_ID_TOSHIBA_TC86C001_MISC 0x0108 +#define PCI_DEVICE_ID_TOSHIBA_SPIDER_NET 0x01b3 + +#define PCI_VENDOR_ID_RICOH 0x1180 +#define PCI_DEVICE_ID_RICOH_RL5C465 0x0465 +#define PCI_DEVICE_ID_RICOH_RL5C466 0x0466 +#define PCI_DEVICE_ID_RICOH_RL5C475 0x0475 +#define PCI_DEVICE_ID_RICOH_RL5C476 0x0476 +#define PCI_DEVICE_ID_RICOH_RL5C478 0x0478 +#define PCI_DEVICE_ID_RICOH_R5C822 0x0822 + +#define PCI_VENDOR_ID_DLINK 0x1186 +#define PCI_DEVICE_ID_DLINK_DGE510T 0x4c00 + +#define PCI_VENDOR_ID_ARTOP 0x1191 +#define PCI_DEVICE_ID_ARTOP_ATP850UF 0x0005 +#define PCI_DEVICE_ID_ARTOP_ATP860 0x0006 +#define PCI_DEVICE_ID_ARTOP_ATP860R 0x0007 +#define PCI_DEVICE_ID_ARTOP_ATP865 0x0008 +#define PCI_DEVICE_ID_ARTOP_ATP865R 0x0009 +#define PCI_DEVICE_ID_ARTOP_AEC7610 0x8002 +#define PCI_DEVICE_ID_ARTOP_AEC7612UW 0x8010 +#define PCI_DEVICE_ID_ARTOP_AEC7612U 0x8020 +#define PCI_DEVICE_ID_ARTOP_AEC7612S 0x8030 +#define PCI_DEVICE_ID_ARTOP_AEC7612D 0x8040 +#define PCI_DEVICE_ID_ARTOP_AEC7612SUW 0x8050 +#define PCI_DEVICE_ID_ARTOP_8060 0x8060 + +#define PCI_VENDOR_ID_ZEITNET 0x1193 +#define PCI_DEVICE_ID_ZEITNET_1221 0x0001 +#define PCI_DEVICE_ID_ZEITNET_1225 0x0002 + + +#define PCI_VENDOR_ID_FUJITSU_ME 0x119e +#define PCI_DEVICE_ID_FUJITSU_FS155 0x0001 +#define PCI_DEVICE_ID_FUJITSU_FS50 0x0003 + +#define PCI_SUBVENDOR_ID_KEYSPAN 0x11a9 +#define PCI_SUBDEVICE_ID_KEYSPAN_SX2 0x5334 + +#define PCI_VENDOR_ID_MARVELL 0x11ab +#define PCI_DEVICE_ID_MARVELL_GT64111 0x4146 +#define PCI_DEVICE_ID_MARVELL_GT64260 0x6430 +#define PCI_DEVICE_ID_MARVELL_MV64360 0x6460 +#define PCI_DEVICE_ID_MARVELL_MV64460 0x6480 + +#define PCI_VENDOR_ID_V3 0x11b0 +#define PCI_DEVICE_ID_V3_V960 0x0001 +#define PCI_DEVICE_ID_V3_V351 0x0002 + + +#define PCI_VENDOR_ID_ATT 0x11c1 +#define PCI_DEVICE_ID_ATT_VENUS_MODEM 0x480 + + +#define PCI_VENDOR_ID_SPECIALIX 0x11cb +#define PCI_DEVICE_ID_SPECIALIX_IO8 0x2000 +#define PCI_DEVICE_ID_SPECIALIX_RIO 0x8000 +#define PCI_SUBDEVICE_ID_SPECIALIX_SPEED4 0xa004 + + +#define PCI_VENDOR_ID_ANALOG_DEVICES 0x11d4 +#define PCI_DEVICE_ID_AD1889JS 0x1889 + + +#define PCI_DEVICE_ID_SEGA_BBA 0x1234 + +#define PCI_VENDOR_ID_ZORAN 0x11de +#define PCI_DEVICE_ID_ZORAN_36057 0x6057 +#define PCI_DEVICE_ID_ZORAN_36120 0x6120 + + +#define PCI_VENDOR_ID_COMPEX 0x11f6 +#define PCI_DEVICE_ID_COMPEX_ENET100VG4 0x0112 + +#define PCI_VENDOR_ID_RP 0x11fe +#define PCI_DEVICE_ID_RP32INTF 0x0001 +#define PCI_DEVICE_ID_RP8INTF 0x0002 +#define PCI_DEVICE_ID_RP16INTF 0x0003 +#define PCI_DEVICE_ID_RP4QUAD 0x0004 +#define PCI_DEVICE_ID_RP8OCTA 0x0005 +#define PCI_DEVICE_ID_RP8J 0x0006 +#define PCI_DEVICE_ID_RP4J 0x0007 +#define PCI_DEVICE_ID_RP8SNI 0x0008 +#define PCI_DEVICE_ID_RP16SNI 0x0009 +#define PCI_DEVICE_ID_RPP4 0x000A +#define PCI_DEVICE_ID_RPP8 0x000B +#define PCI_DEVICE_ID_RP4M 0x000D +#define PCI_DEVICE_ID_RP2_232 0x000E +#define PCI_DEVICE_ID_RP2_422 0x000F +#define PCI_DEVICE_ID_URP32INTF 0x0801 +#define PCI_DEVICE_ID_URP8INTF 0x0802 +#define PCI_DEVICE_ID_URP16INTF 0x0803 +#define PCI_DEVICE_ID_URP8OCTA 0x0805 +#define PCI_DEVICE_ID_UPCI_RM3_8PORT 0x080C +#define PCI_DEVICE_ID_UPCI_RM3_4PORT 0x080D +#define PCI_DEVICE_ID_CRP16INTF 0x0903 + +#define PCI_VENDOR_ID_CYCLADES 0x120e +#define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100 +#define PCI_DEVICE_ID_CYCLOM_Y_Hi 0x0101 +#define PCI_DEVICE_ID_CYCLOM_4Y_Lo 0x0102 +#define PCI_DEVICE_ID_CYCLOM_4Y_Hi 0x0103 +#define PCI_DEVICE_ID_CYCLOM_8Y_Lo 0x0104 +#define PCI_DEVICE_ID_CYCLOM_8Y_Hi 0x0105 +#define PCI_DEVICE_ID_CYCLOM_Z_Lo 0x0200 +#define PCI_DEVICE_ID_CYCLOM_Z_Hi 0x0201 +#define PCI_DEVICE_ID_PC300_RX_2 0x0300 +#define PCI_DEVICE_ID_PC300_RX_1 0x0301 +#define PCI_DEVICE_ID_PC300_TE_2 0x0310 +#define PCI_DEVICE_ID_PC300_TE_1 0x0311 +#define PCI_DEVICE_ID_PC300_TE_M_2 0x0320 +#define PCI_DEVICE_ID_PC300_TE_M_1 0x0321 + +#define PCI_VENDOR_ID_ESSENTIAL 0x120f +#define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER 0x0001 + +#define PCI_VENDOR_ID_O2 0x1217 +#define PCI_DEVICE_ID_O2_6729 0x6729 +#define PCI_DEVICE_ID_O2_6730 0x673a +#define PCI_DEVICE_ID_O2_6832 0x6832 +#define PCI_DEVICE_ID_O2_6836 0x6836 + +#define PCI_VENDOR_ID_3DFX 0x121a +#define PCI_DEVICE_ID_3DFX_VOODOO 0x0001 +#define PCI_DEVICE_ID_3DFX_VOODOO2 0x0002 +#define PCI_DEVICE_ID_3DFX_BANSHEE 0x0003 +#define PCI_DEVICE_ID_3DFX_VOODOO3 0x0005 +#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009 + + + +#define PCI_VENDOR_ID_AVM 0x1244 +#define PCI_DEVICE_ID_AVM_B1 0x0700 +#define PCI_DEVICE_ID_AVM_C4 0x0800 +#define PCI_DEVICE_ID_AVM_A1 0x0a00 +#define PCI_DEVICE_ID_AVM_A1_V2 0x0e00 +#define PCI_DEVICE_ID_AVM_C2 0x1100 +#define PCI_DEVICE_ID_AVM_T1 0x1200 + + +#define PCI_VENDOR_ID_STALLION 0x124d + +/* Allied Telesyn */ +#define PCI_VENDOR_ID_AT 0x1259 +#define PCI_SUBDEVICE_ID_AT_2700FX 0x2701 +#define PCI_SUBDEVICE_ID_AT_2701FX 0x2703 + +#define PCI_VENDOR_ID_ESS 0x125d +#define PCI_DEVICE_ID_ESS_ESS1968 0x1968 +#define PCI_DEVICE_ID_ESS_ESS1978 0x1978 +#define PCI_DEVICE_ID_ESS_ALLEGRO_1 0x1988 +#define PCI_DEVICE_ID_ESS_ALLEGRO 0x1989 +#define PCI_DEVICE_ID_ESS_CANYON3D_2LE 0x1990 +#define PCI_DEVICE_ID_ESS_CANYON3D_2 0x1992 +#define PCI_DEVICE_ID_ESS_MAESTRO3 0x1998 +#define PCI_DEVICE_ID_ESS_MAESTRO3_1 0x1999 +#define PCI_DEVICE_ID_ESS_MAESTRO3_HW 0x199a +#define PCI_DEVICE_ID_ESS_MAESTRO3_2 0x199b + +#define PCI_VENDOR_ID_SATSAGEM 0x1267 +#define PCI_DEVICE_ID_SATSAGEM_NICCY 0x1016 + + +#define PCI_VENDOR_ID_ENSONIQ 0x1274 +#define PCI_DEVICE_ID_ENSONIQ_CT5880 0x5880 +#define PCI_DEVICE_ID_ENSONIQ_ES1370 0x5000 +#define PCI_DEVICE_ID_ENSONIQ_ES1371 0x1371 + +#define PCI_VENDOR_ID_TRANSMETA 0x1279 +#define PCI_DEVICE_ID_EFFICEON 0x0060 + +#define PCI_VENDOR_ID_ROCKWELL 0x127A + +#define PCI_VENDOR_ID_ITE 0x1283 +#define PCI_DEVICE_ID_ITE_8211 0x8211 +#define PCI_DEVICE_ID_ITE_8212 0x8212 +#define PCI_DEVICE_ID_ITE_8872 0x8872 +#define PCI_DEVICE_ID_ITE_IT8330G_0 0xe886 + +/* formerly Platform Tech */ +#define PCI_DEVICE_ID_ESS_ESS0100 0x0100 + +#define PCI_VENDOR_ID_ALTEON 0x12ae + + +#define PCI_SUBVENDOR_ID_CONNECT_TECH 0x12c4 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_232 0x0001 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_232 0x0002 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_232 0x0003 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485 0x0004 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_4_4 0x0005 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485 0x0006 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH4_485_2_2 0x0007 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_485 0x0008 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH8_485_2_6 0x0009 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH081101V1 0x000A +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH041101V1 0x000B +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_20MHZ 0x000C +#define PCI_SUBDEVICE_ID_CONNECT_TECH_BH2_PTM 0x000D +#define PCI_SUBDEVICE_ID_CONNECT_TECH_NT960PCI 0x0100 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_2 0x0201 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_TITAN_4 0x0202 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_232 0x0300 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_232 0x0301 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_232 0x0302 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_1_1 0x0310 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_2 0x0311 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_4 0x0312 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2 0x0320 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4 0x0321 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8 0x0322 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_2_485 0x0330 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_4_485 0x0331 +#define PCI_SUBDEVICE_ID_CONNECT_TECH_PCI_UART_8_485 0x0332 + + +#define PCI_VENDOR_ID_NVIDIA_SGS 0x12d2 +#define PCI_DEVICE_ID_NVIDIA_SGS_RIVA128 0x0018 + +#define PCI_SUBVENDOR_ID_CHASE_PCIFAST 0x12E0 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST4 0x0031 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST8 0x0021 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16 0x0011 +#define PCI_SUBDEVICE_ID_CHASE_PCIFAST16FMC 0x0041 +#define PCI_SUBVENDOR_ID_CHASE_PCIRAS 0x124D +#define PCI_SUBDEVICE_ID_CHASE_PCIRAS4 0xF001 +#define PCI_SUBDEVICE_ID_CHASE_PCIRAS8 0xF010 + +#define PCI_VENDOR_ID_AUREAL 0x12eb +#define PCI_DEVICE_ID_AUREAL_VORTEX_1 0x0001 +#define PCI_DEVICE_ID_AUREAL_VORTEX_2 0x0002 +#define PCI_DEVICE_ID_AUREAL_ADVANTAGE 0x0003 + +#define PCI_VENDOR_ID_ELECTRONICDESIGNGMBH 0x12f8 +#define PCI_DEVICE_ID_LML_33R10 0x8a02 + + +#define PCI_VENDOR_ID_SIIG 0x131f +#define PCI_SUBVENDOR_ID_SIIG 0x131f +#define PCI_DEVICE_ID_SIIG_1S_10x_550 0x1000 +#define PCI_DEVICE_ID_SIIG_1S_10x_650 0x1001 +#define PCI_DEVICE_ID_SIIG_1S_10x_850 0x1002 +#define PCI_DEVICE_ID_SIIG_1S1P_10x_550 0x1010 +#define PCI_DEVICE_ID_SIIG_1S1P_10x_650 0x1011 +#define PCI_DEVICE_ID_SIIG_1S1P_10x_850 0x1012 +#define PCI_DEVICE_ID_SIIG_1P_10x 0x1020 +#define PCI_DEVICE_ID_SIIG_2P_10x 0x1021 +#define PCI_DEVICE_ID_SIIG_2S_10x_550 0x1030 +#define PCI_DEVICE_ID_SIIG_2S_10x_650 0x1031 +#define PCI_DEVICE_ID_SIIG_2S_10x_850 0x1032 +#define PCI_DEVICE_ID_SIIG_2S1P_10x_550 0x1034 +#define PCI_DEVICE_ID_SIIG_2S1P_10x_650 0x1035 +#define PCI_DEVICE_ID_SIIG_2S1P_10x_850 0x1036 +#define PCI_DEVICE_ID_SIIG_4S_10x_550 0x1050 +#define PCI_DEVICE_ID_SIIG_4S_10x_650 0x1051 +#define PCI_DEVICE_ID_SIIG_4S_10x_850 0x1052 +#define PCI_DEVICE_ID_SIIG_1S_20x_550 0x2000 +#define PCI_DEVICE_ID_SIIG_1S_20x_650 0x2001 +#define PCI_DEVICE_ID_SIIG_1S_20x_850 0x2002 +#define PCI_DEVICE_ID_SIIG_1P_20x 0x2020 +#define PCI_DEVICE_ID_SIIG_2P_20x 0x2021 +#define PCI_DEVICE_ID_SIIG_2S_20x_550 0x2030 +#define PCI_DEVICE_ID_SIIG_2S_20x_650 0x2031 +#define PCI_DEVICE_ID_SIIG_2S_20x_850 0x2032 +#define PCI_DEVICE_ID_SIIG_2P1S_20x_550 0x2040 +#define PCI_DEVICE_ID_SIIG_2P1S_20x_650 0x2041 +#define PCI_DEVICE_ID_SIIG_2P1S_20x_850 0x2042 +#define PCI_DEVICE_ID_SIIG_1S1P_20x_550 0x2010 +#define PCI_DEVICE_ID_SIIG_1S1P_20x_650 0x2011 +#define PCI_DEVICE_ID_SIIG_1S1P_20x_850 0x2012 +#define PCI_DEVICE_ID_SIIG_4S_20x_550 0x2050 +#define PCI_DEVICE_ID_SIIG_4S_20x_650 0x2051 +#define PCI_DEVICE_ID_SIIG_4S_20x_850 0x2052 +#define PCI_DEVICE_ID_SIIG_2S1P_20x_550 0x2060 +#define PCI_DEVICE_ID_SIIG_2S1P_20x_650 0x2061 +#define PCI_DEVICE_ID_SIIG_2S1P_20x_850 0x2062 +#define PCI_DEVICE_ID_SIIG_8S_20x_550 0x2080 +#define PCI_DEVICE_ID_SIIG_8S_20x_650 0x2081 +#define PCI_DEVICE_ID_SIIG_8S_20x_850 0x2082 +#define PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL 0x2050 + +#define PCI_VENDOR_ID_RADISYS 0x1331 + +#define PCI_VENDOR_ID_DOMEX 0x134a +#define PCI_DEVICE_ID_DOMEX_DMX3191D 0x0001 + +#define PCI_VENDOR_ID_INTASHIELD 0x135a +#define PCI_DEVICE_ID_INTASHIELD_IS200 0x0d80 + +#define PCI_VENDOR_ID_QUATECH 0x135C +#define PCI_DEVICE_ID_QUATECH_QSC100 0x0010 +#define PCI_DEVICE_ID_QUATECH_DSC100 0x0020 +#define PCI_DEVICE_ID_QUATECH_ESC100D 0x0050 +#define PCI_DEVICE_ID_QUATECH_ESC100M 0x0060 + +#define PCI_VENDOR_ID_SEALEVEL 0x135e +#define PCI_DEVICE_ID_SEALEVEL_U530 0x7101 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM2 0x7201 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM422 0x7402 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM232 0x7202 +#define PCI_DEVICE_ID_SEALEVEL_COMM4 0x7401 +#define PCI_DEVICE_ID_SEALEVEL_COMM8 0x7801 +#define PCI_DEVICE_ID_SEALEVEL_UCOMM8 0x7804 + +#define PCI_VENDOR_ID_HYPERCOPE 0x1365 +#define PCI_DEVICE_ID_HYPERCOPE_PLX 0x9050 +#define PCI_SUBDEVICE_ID_HYPERCOPE_OLD_ERGO 0x0104 +#define PCI_SUBDEVICE_ID_HYPERCOPE_ERGO 0x0106 +#define PCI_SUBDEVICE_ID_HYPERCOPE_METRO 0x0107 +#define PCI_SUBDEVICE_ID_HYPERCOPE_CHAMP2 0x0108 + +#define PCI_VENDOR_ID_KAWASAKI 0x136b +#define PCI_DEVICE_ID_MCHIP_KL5A72002 0xff01 + +#define PCI_VENDOR_ID_CNET 0x1371 +#define PCI_DEVICE_ID_CNET_GIGACARD 0x434e + +#define PCI_VENDOR_ID_LMC 0x1376 +#define PCI_DEVICE_ID_LMC_HSSI 0x0003 +#define PCI_DEVICE_ID_LMC_DS3 0x0004 +#define PCI_DEVICE_ID_LMC_SSI 0x0005 +#define PCI_DEVICE_ID_LMC_T1 0x0006 + + +#define PCI_VENDOR_ID_NETGEAR 0x1385 +#define PCI_DEVICE_ID_NETGEAR_GA620 0x620a + +#define PCI_VENDOR_ID_APPLICOM 0x1389 +#define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001 +#define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002 +#define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003 + +#define PCI_VENDOR_ID_MOXA 0x1393 +#define PCI_DEVICE_ID_MOXA_RC7000 0x0001 +#define PCI_DEVICE_ID_MOXA_CP102 0x1020 +#define PCI_DEVICE_ID_MOXA_CP102UL 0x1021 +#define PCI_DEVICE_ID_MOXA_CP102U 0x1022 +#define PCI_DEVICE_ID_MOXA_C104 0x1040 +#define PCI_DEVICE_ID_MOXA_CP104U 0x1041 +#define PCI_DEVICE_ID_MOXA_CP104JU 0x1042 +#define PCI_DEVICE_ID_MOXA_CT114 0x1140 +#define PCI_DEVICE_ID_MOXA_CP114 0x1141 +#define PCI_DEVICE_ID_MOXA_CP118U 0x1180 +#define PCI_DEVICE_ID_MOXA_CP132 0x1320 +#define PCI_DEVICE_ID_MOXA_CP132U 0x1321 +#define PCI_DEVICE_ID_MOXA_CP134U 0x1340 +#define PCI_DEVICE_ID_MOXA_C168 0x1680 +#define PCI_DEVICE_ID_MOXA_CP168U 0x1681 + +#define PCI_VENDOR_ID_CCD 0x1397 +#define PCI_DEVICE_ID_CCD_2BD0 0x2bd0 +#define PCI_DEVICE_ID_CCD_B000 0xb000 +#define PCI_DEVICE_ID_CCD_B006 0xb006 +#define PCI_DEVICE_ID_CCD_B007 0xb007 +#define PCI_DEVICE_ID_CCD_B008 0xb008 +#define PCI_DEVICE_ID_CCD_B009 0xb009 +#define PCI_DEVICE_ID_CCD_B00A 0xb00a +#define PCI_DEVICE_ID_CCD_B00B 0xb00b +#define PCI_DEVICE_ID_CCD_B00C 0xb00c +#define PCI_DEVICE_ID_CCD_B100 0xb100 +#define PCI_DEVICE_ID_CCD_B700 0xb700 +#define PCI_DEVICE_ID_CCD_B701 0xb701 + +#define PCI_VENDOR_ID_EXAR 0x13a8 +#define PCI_DEVICE_ID_EXAR_XR17C152 0x0152 +#define PCI_DEVICE_ID_EXAR_XR17C154 0x0154 +#define PCI_DEVICE_ID_EXAR_XR17C158 0x0158 + +#define PCI_VENDOR_ID_MICROGATE 0x13c0 +#define PCI_DEVICE_ID_MICROGATE_USC 0x0010 +#define PCI_DEVICE_ID_MICROGATE_SCA 0x0030 + +#define PCI_VENDOR_ID_3WARE 0x13C1 +#define PCI_DEVICE_ID_3WARE_1000 0x1000 +#define PCI_DEVICE_ID_3WARE_7000 0x1001 +#define PCI_DEVICE_ID_3WARE_9000 0x1002 + +#define PCI_VENDOR_ID_IOMEGA 0x13ca +#define PCI_DEVICE_ID_IOMEGA_BUZ 0x4231 + +#define PCI_VENDOR_ID_ABOCOM 0x13D1 +#define PCI_DEVICE_ID_ABOCOM_2BD1 0x2BD1 + +#define PCI_VENDOR_ID_CMEDIA 0x13f6 +#define PCI_DEVICE_ID_CMEDIA_CM8338A 0x0100 +#define PCI_DEVICE_ID_CMEDIA_CM8338B 0x0101 +#define PCI_DEVICE_ID_CMEDIA_CM8738 0x0111 +#define PCI_DEVICE_ID_CMEDIA_CM8738B 0x0112 + +#define PCI_VENDOR_ID_LAVA 0x1407 +#define PCI_DEVICE_ID_LAVA_DSERIAL 0x0100 /* 2x 16550 */ +#define PCI_DEVICE_ID_LAVA_QUATRO_A 0x0101 /* 2x 16550, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_QUATRO_B 0x0102 /* 2x 16550, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_OCTO_A 0x0180 /* 4x 16550A, half of 8 port */ +#define PCI_DEVICE_ID_LAVA_OCTO_B 0x0181 /* 4x 16550A, half of 8 port */ +#define PCI_DEVICE_ID_LAVA_PORT_PLUS 0x0200 /* 2x 16650 */ +#define PCI_DEVICE_ID_LAVA_QUAD_A 0x0201 /* 2x 16650, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_QUAD_B 0x0202 /* 2x 16650, half of 4 port */ +#define PCI_DEVICE_ID_LAVA_SSERIAL 0x0500 /* 1x 16550 */ +#define PCI_DEVICE_ID_LAVA_PORT_650 0x0600 /* 1x 16650 */ +#define PCI_DEVICE_ID_LAVA_PARALLEL 0x8000 +#define PCI_DEVICE_ID_LAVA_DUAL_PAR_A 0x8002 /* The Lava Dual Parallel is */ +#define PCI_DEVICE_ID_LAVA_DUAL_PAR_B 0x8003 /* two PCI devices on a card */ +#define PCI_DEVICE_ID_LAVA_BOCA_IOPPAR 0x8800 + +#define PCI_VENDOR_ID_TIMEDIA 0x1409 +#define PCI_DEVICE_ID_TIMEDIA_1889 0x7168 + +#define PCI_VENDOR_ID_ICE 0x1412 +#define PCI_DEVICE_ID_ICE_1712 0x1712 +#define PCI_DEVICE_ID_VT1724 0x1724 + +#define PCI_VENDOR_ID_OXSEMI 0x1415 +#define PCI_DEVICE_ID_OXSEMI_12PCI840 0x8403 +#define PCI_DEVICE_ID_OXSEMI_16PCI954 0x9501 +#define PCI_DEVICE_ID_OXSEMI_16PCI95N 0x9511 +#define PCI_DEVICE_ID_OXSEMI_16PCI954PP 0x9513 +#define PCI_DEVICE_ID_OXSEMI_16PCI952 0x9521 + +#define PCI_VENDOR_ID_SAMSUNG 0x144d + +#define PCI_VENDOR_ID_MYRICOM 0x14c1 + +#define PCI_VENDOR_ID_TITAN 0x14D2 +#define PCI_DEVICE_ID_TITAN_010L 0x8001 +#define PCI_DEVICE_ID_TITAN_100L 0x8010 +#define PCI_DEVICE_ID_TITAN_110L 0x8011 +#define PCI_DEVICE_ID_TITAN_200L 0x8020 +#define PCI_DEVICE_ID_TITAN_210L 0x8021 +#define PCI_DEVICE_ID_TITAN_400L 0x8040 +#define PCI_DEVICE_ID_TITAN_800L 0x8080 +#define PCI_DEVICE_ID_TITAN_100 0xA001 +#define PCI_DEVICE_ID_TITAN_200 0xA005 +#define PCI_DEVICE_ID_TITAN_400 0xA003 +#define PCI_DEVICE_ID_TITAN_800B 0xA004 + +#define PCI_VENDOR_ID_PANACOM 0x14d4 +#define PCI_DEVICE_ID_PANACOM_QUADMODEM 0x0400 +#define PCI_DEVICE_ID_PANACOM_DUALMODEM 0x0402 + +#define PCI_VENDOR_ID_SIPACKETS 0x14d9 +#define PCI_DEVICE_ID_SP1011 0x0010 + +#define PCI_VENDOR_ID_AFAVLAB 0x14db +#define PCI_DEVICE_ID_AFAVLAB_P028 0x2180 +#define PCI_DEVICE_ID_AFAVLAB_P030 0x2182 +#define PCI_SUBDEVICE_ID_AFAVLAB_P061 0x2150 + +#define PCI_VENDOR_ID_BROADCOM 0x14e4 +#define PCI_DEVICE_ID_TIGON3_5752 0x1600 +#define PCI_DEVICE_ID_TIGON3_5752M 0x1601 +#define PCI_DEVICE_ID_TIGON3_5700 0x1644 +#define PCI_DEVICE_ID_TIGON3_5701 0x1645 +#define PCI_DEVICE_ID_TIGON3_5702 0x1646 +#define PCI_DEVICE_ID_TIGON3_5703 0x1647 +#define PCI_DEVICE_ID_TIGON3_5704 0x1648 +#define PCI_DEVICE_ID_TIGON3_5704S_2 0x1649 +#define PCI_DEVICE_ID_NX2_5706 0x164a +#define PCI_DEVICE_ID_NX2_5708 0x164c +#define PCI_DEVICE_ID_TIGON3_5702FE 0x164d +#define PCI_DEVICE_ID_TIGON3_5705 0x1653 +#define PCI_DEVICE_ID_TIGON3_5705_2 0x1654 +#define PCI_DEVICE_ID_TIGON3_5720 0x1658 +#define PCI_DEVICE_ID_TIGON3_5721 0x1659 +#define PCI_DEVICE_ID_TIGON3_5722 0x165a +#define PCI_DEVICE_ID_TIGON3_5705M 0x165d +#define PCI_DEVICE_ID_TIGON3_5705M_2 0x165e +#define PCI_DEVICE_ID_TIGON3_5714 0x1668 +#define PCI_DEVICE_ID_TIGON3_5714S 0x1669 +#define PCI_DEVICE_ID_TIGON3_5780 0x166a +#define PCI_DEVICE_ID_TIGON3_5780S 0x166b +#define PCI_DEVICE_ID_TIGON3_5705F 0x166e +#define PCI_DEVICE_ID_TIGON3_5754M 0x1672 +#define PCI_DEVICE_ID_TIGON3_5755M 0x1673 +#define PCI_DEVICE_ID_TIGON3_5756 0x1674 +#define PCI_DEVICE_ID_TIGON3_5750 0x1676 +#define PCI_DEVICE_ID_TIGON3_5751 0x1677 +#define PCI_DEVICE_ID_TIGON3_5715 0x1678 +#define PCI_DEVICE_ID_TIGON3_5715S 0x1679 +#define PCI_DEVICE_ID_TIGON3_5754 0x167a +#define PCI_DEVICE_ID_TIGON3_5755 0x167b +#define PCI_DEVICE_ID_TIGON3_5750M 0x167c +#define PCI_DEVICE_ID_TIGON3_5751M 0x167d +#define PCI_DEVICE_ID_TIGON3_5751F 0x167e +#define PCI_DEVICE_ID_TIGON3_5787M 0x1693 +#define PCI_DEVICE_ID_TIGON3_5782 0x1696 +#define PCI_DEVICE_ID_TIGON3_5786 0x169a +#define PCI_DEVICE_ID_TIGON3_5787 0x169b +#define PCI_DEVICE_ID_TIGON3_5788 0x169c +#define PCI_DEVICE_ID_TIGON3_5789 0x169d +#define PCI_DEVICE_ID_TIGON3_5702X 0x16a6 +#define PCI_DEVICE_ID_TIGON3_5703X 0x16a7 +#define PCI_DEVICE_ID_TIGON3_5704S 0x16a8 +#define PCI_DEVICE_ID_NX2_5706S 0x16aa +#define PCI_DEVICE_ID_NX2_5708S 0x16ac +#define PCI_DEVICE_ID_TIGON3_5702A3 0x16c6 +#define PCI_DEVICE_ID_TIGON3_5703A3 0x16c7 +#define PCI_DEVICE_ID_TIGON3_5781 0x16dd +#define PCI_DEVICE_ID_TIGON3_5753 0x16f7 +#define PCI_DEVICE_ID_TIGON3_5753M 0x16fd +#define PCI_DEVICE_ID_TIGON3_5753F 0x16fe +#define PCI_DEVICE_ID_TIGON3_5901 0x170d +#define PCI_DEVICE_ID_BCM4401B1 0x170c +#define PCI_DEVICE_ID_TIGON3_5901_2 0x170e +#define PCI_DEVICE_ID_TIGON3_5906 0x1712 +#define PCI_DEVICE_ID_TIGON3_5906M 0x1713 +#define PCI_DEVICE_ID_BCM4401 0x4401 +#define PCI_DEVICE_ID_BCM4401B0 0x4402 + +#define PCI_VENDOR_ID_TOPIC 0x151f +#define PCI_DEVICE_ID_TOPIC_TP560 0x0000 + +#define PCI_VENDOR_ID_ENE 0x1524 +#define PCI_DEVICE_ID_ENE_1211 0x1211 +#define PCI_DEVICE_ID_ENE_1225 0x1225 +#define PCI_DEVICE_ID_ENE_1410 0x1410 +#define PCI_DEVICE_ID_ENE_710 0x1411 +#define PCI_DEVICE_ID_ENE_712 0x1412 +#define PCI_DEVICE_ID_ENE_1420 0x1420 +#define PCI_DEVICE_ID_ENE_720 0x1421 +#define PCI_DEVICE_ID_ENE_722 0x1422 + +#define PCI_VENDOR_ID_CHELSIO 0x1425 + + +#define PCI_VENDOR_ID_SYBA 0x1592 +#define PCI_DEVICE_ID_SYBA_2P_EPP 0x0782 +#define PCI_DEVICE_ID_SYBA_1P_ECP 0x0783 + +#define PCI_VENDOR_ID_MORETON 0x15aa +#define PCI_DEVICE_ID_RASTEL_2PORT 0x2000 + +#define PCI_VENDOR_ID_ZOLTRIX 0x15b0 +#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 + +#define PCI_VENDOR_ID_MELLANOX 0x15b3 +#define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44 +#define PCI_DEVICE_ID_MELLANOX_TAVOR_BRIDGE 0x5a46 +#define PCI_DEVICE_ID_MELLANOX_ARBEL_COMPAT 0x6278 +#define PCI_DEVICE_ID_MELLANOX_ARBEL 0x6282 +#define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c +#define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274 + +#define PCI_VENDOR_ID_PDC 0x15e9 + + +#define PCI_VENDOR_ID_FARSITE 0x1619 +#define PCI_DEVICE_ID_FARSITE_T2P 0x0400 +#define PCI_DEVICE_ID_FARSITE_T4P 0x0440 +#define PCI_DEVICE_ID_FARSITE_T1U 0x0610 +#define PCI_DEVICE_ID_FARSITE_T2U 0x0620 +#define PCI_DEVICE_ID_FARSITE_T4U 0x0640 +#define PCI_DEVICE_ID_FARSITE_TE1 0x1610 +#define PCI_DEVICE_ID_FARSITE_TE1C 0x1612 + +#define PCI_VENDOR_ID_SIBYTE 0x166d +#define PCI_DEVICE_ID_BCM1250_PCI 0x0001 +#define PCI_DEVICE_ID_BCM1250_HT 0x0002 + +#define PCI_VENDOR_ID_NETCELL 0x169c +#define PCI_DEVICE_ID_REVOLUTION 0x0044 + +#define PCI_VENDOR_ID_VITESSE 0x1725 +#define PCI_DEVICE_ID_VITESSE_VSC7174 0x7174 + +#define PCI_VENDOR_ID_LINKSYS 0x1737 +#define PCI_DEVICE_ID_LINKSYS_EG1064 0x1064 + +#define PCI_VENDOR_ID_ALTIMA 0x173b +#define PCI_DEVICE_ID_ALTIMA_AC1000 0x03e8 +#define PCI_DEVICE_ID_ALTIMA_AC1001 0x03e9 +#define PCI_DEVICE_ID_ALTIMA_AC9100 0x03ea +#define PCI_DEVICE_ID_ALTIMA_AC1003 0x03eb + +#define PCI_VENDOR_ID_ARECA 0x17d3 +#define PCI_DEVICE_ID_ARECA_1110 0x1110 +#define PCI_DEVICE_ID_ARECA_1120 0x1120 +#define PCI_DEVICE_ID_ARECA_1130 0x1130 +#define PCI_DEVICE_ID_ARECA_1160 0x1160 +#define PCI_DEVICE_ID_ARECA_1170 0x1170 +#define PCI_DEVICE_ID_ARECA_1210 0x1210 +#define PCI_DEVICE_ID_ARECA_1220 0x1220 +#define PCI_DEVICE_ID_ARECA_1230 0x1230 +#define PCI_DEVICE_ID_ARECA_1260 0x1260 +#define PCI_DEVICE_ID_ARECA_1270 0x1270 +#define PCI_DEVICE_ID_ARECA_1280 0x1280 +#define PCI_DEVICE_ID_ARECA_1380 0x1380 +#define PCI_DEVICE_ID_ARECA_1381 0x1381 +#define PCI_DEVICE_ID_ARECA_1680 0x1680 +#define PCI_DEVICE_ID_ARECA_1681 0x1681 + +#define PCI_VENDOR_ID_S2IO 0x17d5 +#define PCI_DEVICE_ID_S2IO_WIN 0x5731 +#define PCI_DEVICE_ID_S2IO_UNI 0x5831 +#define PCI_DEVICE_ID_HERC_WIN 0x5732 +#define PCI_DEVICE_ID_HERC_UNI 0x5832 + + +#define PCI_VENDOR_ID_SITECOM 0x182d +#define PCI_DEVICE_ID_SITECOM_DC105V2 0x3069 + +#define PCI_VENDOR_ID_TOPSPIN 0x1867 + +#define PCI_VENDOR_ID_TDI 0x192E +#define PCI_DEVICE_ID_TDI_EHCI 0x0101 + +#define PCI_VENDOR_ID_JMICRON 0x197B +#define PCI_DEVICE_ID_JMICRON_JMB360 0x2360 +#define PCI_DEVICE_ID_JMICRON_JMB361 0x2361 +#define PCI_DEVICE_ID_JMICRON_JMB363 0x2363 +#define PCI_DEVICE_ID_JMICRON_JMB365 0x2365 +#define PCI_DEVICE_ID_JMICRON_JMB366 0x2366 +#define PCI_DEVICE_ID_JMICRON_JMB368 0x2368 + +#define PCI_VENDOR_ID_TEKRAM 0x1de1 +#define PCI_DEVICE_ID_TEKRAM_DC290 0xdc29 + +#define PCI_VENDOR_ID_HINT 0x3388 +#define PCI_DEVICE_ID_HINT_VXPROII_IDE 0x8013 + +#define PCI_VENDOR_ID_3DLABS 0x3d3d +#define PCI_DEVICE_ID_3DLABS_PERMEDIA2 0x0007 +#define PCI_DEVICE_ID_3DLABS_PERMEDIA2V 0x0009 + + +#define PCI_VENDOR_ID_AKS 0x416c +#define PCI_DEVICE_ID_AKS_ALADDINCARD 0x0100 + + + +#define PCI_VENDOR_ID_S3 0x5333 +#define PCI_DEVICE_ID_S3_TRIO 0x8811 +#define PCI_DEVICE_ID_S3_868 0x8880 +#define PCI_DEVICE_ID_S3_968 0x88f0 +#define PCI_DEVICE_ID_S3_SAVAGE4 0x8a25 +#define PCI_DEVICE_ID_S3_PROSAVAGE8 0x8d04 +#define PCI_DEVICE_ID_S3_SONICVIBES 0xca00 + +#define PCI_VENDOR_ID_DUNORD 0x5544 +#define PCI_DEVICE_ID_DUNORD_I3000 0x0001 + + +#define PCI_VENDOR_ID_DCI 0x6666 +#define PCI_DEVICE_ID_DCI_PCCOM4 0x0001 +#define PCI_DEVICE_ID_DCI_PCCOM8 0x0002 +#define PCI_DEVICE_ID_DCI_PCCOM2 0x0004 + +#define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_DEVICE_ID_INTEL_EESSC 0x0008 +#define PCI_DEVICE_ID_INTEL_PXHD_0 0x0320 +#define PCI_DEVICE_ID_INTEL_PXHD_1 0x0321 +#define PCI_DEVICE_ID_INTEL_PXH_0 0x0329 +#define PCI_DEVICE_ID_INTEL_PXH_1 0x032A +#define PCI_DEVICE_ID_INTEL_PXHV 0x032C +#define PCI_DEVICE_ID_INTEL_82375 0x0482 +#define PCI_DEVICE_ID_INTEL_82424 0x0483 +#define PCI_DEVICE_ID_INTEL_82378 0x0484 +#define PCI_DEVICE_ID_INTEL_I960 0x0960 +#define PCI_DEVICE_ID_INTEL_I960RM 0x0962 +#define PCI_DEVICE_ID_INTEL_82815_MC 0x1130 +#define PCI_DEVICE_ID_INTEL_82815_CGC 0x1132 +#define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 +#define PCI_DEVICE_ID_INTEL_7505_0 0x2550 +#define PCI_DEVICE_ID_INTEL_7205_0 0x255d +#define PCI_DEVICE_ID_INTEL_82437 0x122d +#define PCI_DEVICE_ID_INTEL_82371FB_0 0x122e +#define PCI_DEVICE_ID_INTEL_82371FB_1 0x1230 +#define PCI_DEVICE_ID_INTEL_82371MX 0x1234 +#define PCI_DEVICE_ID_INTEL_82441 0x1237 +#define PCI_DEVICE_ID_INTEL_82380FB 0x124b +#define PCI_DEVICE_ID_INTEL_82439 0x1250 +#define PCI_DEVICE_ID_INTEL_80960_RP 0x1960 +#define PCI_DEVICE_ID_INTEL_82840_HB 0x1a21 +#define PCI_DEVICE_ID_INTEL_82845_HB 0x1a30 +#define PCI_DEVICE_ID_INTEL_IOAT 0x1a38 +#define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 +#define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 +#define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 +#define PCI_DEVICE_ID_INTEL_82801AA_5 0x2415 +#define PCI_DEVICE_ID_INTEL_82801AA_6 0x2416 +#define PCI_DEVICE_ID_INTEL_82801AA_8 0x2418 +#define PCI_DEVICE_ID_INTEL_82801AB_0 0x2420 +#define PCI_DEVICE_ID_INTEL_82801AB_1 0x2421 +#define PCI_DEVICE_ID_INTEL_82801AB_3 0x2423 +#define PCI_DEVICE_ID_INTEL_82801AB_5 0x2425 +#define PCI_DEVICE_ID_INTEL_82801AB_6 0x2426 +#define PCI_DEVICE_ID_INTEL_82801AB_8 0x2428 +#define PCI_DEVICE_ID_INTEL_82801BA_0 0x2440 +#define PCI_DEVICE_ID_INTEL_82801BA_2 0x2443 +#define PCI_DEVICE_ID_INTEL_82801BA_4 0x2445 +#define PCI_DEVICE_ID_INTEL_82801BA_6 0x2448 +#define PCI_DEVICE_ID_INTEL_82801BA_8 0x244a +#define PCI_DEVICE_ID_INTEL_82801BA_9 0x244b +#define PCI_DEVICE_ID_INTEL_82801BA_10 0x244c +#define PCI_DEVICE_ID_INTEL_82801BA_11 0x244e +#define PCI_DEVICE_ID_INTEL_82801E_0 0x2450 +#define PCI_DEVICE_ID_INTEL_82801E_11 0x245b +#define PCI_DEVICE_ID_INTEL_82801CA_0 0x2480 +#define PCI_DEVICE_ID_INTEL_82801CA_3 0x2483 +#define PCI_DEVICE_ID_INTEL_82801CA_5 0x2485 +#define PCI_DEVICE_ID_INTEL_82801CA_6 0x2486 +#define PCI_DEVICE_ID_INTEL_82801CA_10 0x248a +#define PCI_DEVICE_ID_INTEL_82801CA_11 0x248b +#define PCI_DEVICE_ID_INTEL_82801CA_12 0x248c +#define PCI_DEVICE_ID_INTEL_82801DB_0 0x24c0 +#define PCI_DEVICE_ID_INTEL_82801DB_1 0x24c1 +#define PCI_DEVICE_ID_INTEL_82801DB_3 0x24c3 +#define PCI_DEVICE_ID_INTEL_82801DB_5 0x24c5 +#define PCI_DEVICE_ID_INTEL_82801DB_6 0x24c6 +#define PCI_DEVICE_ID_INTEL_82801DB_9 0x24c9 +#define PCI_DEVICE_ID_INTEL_82801DB_10 0x24ca +#define PCI_DEVICE_ID_INTEL_82801DB_11 0x24cb +#define PCI_DEVICE_ID_INTEL_82801DB_12 0x24cc +#define PCI_DEVICE_ID_INTEL_82801EB_0 0x24d0 +#define PCI_DEVICE_ID_INTEL_82801EB_1 0x24d1 +#define PCI_DEVICE_ID_INTEL_82801EB_3 0x24d3 +#define PCI_DEVICE_ID_INTEL_82801EB_5 0x24d5 +#define PCI_DEVICE_ID_INTEL_82801EB_6 0x24d6 +#define PCI_DEVICE_ID_INTEL_82801EB_11 0x24db +#define PCI_DEVICE_ID_INTEL_82801EB_13 0x24dd +#define PCI_DEVICE_ID_INTEL_ESB_1 0x25a1 +#define PCI_DEVICE_ID_INTEL_ESB_2 0x25a2 +#define PCI_DEVICE_ID_INTEL_ESB_4 0x25a4 +#define PCI_DEVICE_ID_INTEL_ESB_5 0x25a6 +#define PCI_DEVICE_ID_INTEL_ESB_9 0x25ab +#define PCI_DEVICE_ID_INTEL_82820_HB 0x2500 +#define PCI_DEVICE_ID_INTEL_82820_UP_HB 0x2501 +#define PCI_DEVICE_ID_INTEL_82850_HB 0x2530 +#define PCI_DEVICE_ID_INTEL_82860_HB 0x2531 +#define PCI_DEVICE_ID_INTEL_E7501_MCH 0x254c +#define PCI_DEVICE_ID_INTEL_82845G_HB 0x2560 +#define PCI_DEVICE_ID_INTEL_82845G_IG 0x2562 +#define PCI_DEVICE_ID_INTEL_82865_HB 0x2570 +#define PCI_DEVICE_ID_INTEL_82865_IG 0x2572 +#define PCI_DEVICE_ID_INTEL_82875_HB 0x2578 +#define PCI_DEVICE_ID_INTEL_82915G_HB 0x2580 +#define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 +#define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 +#define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 +#define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 +#define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 +#define PCI_DEVICE_ID_INTEL_82945GM_HB 0x27A0 +#define PCI_DEVICE_ID_INTEL_82945GM_IG 0x27A2 +#define PCI_DEVICE_ID_INTEL_ICH6_0 0x2640 +#define PCI_DEVICE_ID_INTEL_ICH6_1 0x2641 +#define PCI_DEVICE_ID_INTEL_ICH6_2 0x2642 +#define PCI_DEVICE_ID_INTEL_ICH6_16 0x266a +#define PCI_DEVICE_ID_INTEL_ICH6_17 0x266d +#define PCI_DEVICE_ID_INTEL_ICH6_18 0x266e +#define PCI_DEVICE_ID_INTEL_ICH6_19 0x266f +#define PCI_DEVICE_ID_INTEL_ESB2_0 0x2670 +#define PCI_DEVICE_ID_INTEL_ESB2_14 0x2698 +#define PCI_DEVICE_ID_INTEL_ESB2_17 0x269b +#define PCI_DEVICE_ID_INTEL_ESB2_18 0x269e +#define PCI_DEVICE_ID_INTEL_ICH7_0 0x27b8 +#define PCI_DEVICE_ID_INTEL_ICH7_1 0x27b9 +#define PCI_DEVICE_ID_INTEL_ICH7_30 0x27b0 +#define PCI_DEVICE_ID_INTEL_ICH7_31 0x27bd +#define PCI_DEVICE_ID_INTEL_ICH7_17 0x27da +#define PCI_DEVICE_ID_INTEL_ICH7_19 0x27dd +#define PCI_DEVICE_ID_INTEL_ICH7_20 0x27de +#define PCI_DEVICE_ID_INTEL_ICH7_21 0x27df +#define PCI_DEVICE_ID_INTEL_ICH8_0 0x2810 +#define PCI_DEVICE_ID_INTEL_ICH8_1 0x2811 +#define PCI_DEVICE_ID_INTEL_ICH8_2 0x2812 +#define PCI_DEVICE_ID_INTEL_ICH8_3 0x2814 +#define PCI_DEVICE_ID_INTEL_ICH8_4 0x2815 +#define PCI_DEVICE_ID_INTEL_ICH8_5 0x283e +#define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 +#define PCI_DEVICE_ID_INTEL_82855PM_HB 0x3340 +#define PCI_DEVICE_ID_INTEL_82830_HB 0x3575 +#define PCI_DEVICE_ID_INTEL_82830_CGC 0x3577 +#define PCI_DEVICE_ID_INTEL_82855GM_HB 0x3580 +#define PCI_DEVICE_ID_INTEL_82855GM_IG 0x3582 +#define PCI_DEVICE_ID_INTEL_E7520_MCH 0x3590 +#define PCI_DEVICE_ID_INTEL_E7320_MCH 0x3592 +#define PCI_DEVICE_ID_INTEL_MCH_PA 0x3595 +#define PCI_DEVICE_ID_INTEL_MCH_PA1 0x3596 +#define PCI_DEVICE_ID_INTEL_MCH_PB 0x3597 +#define PCI_DEVICE_ID_INTEL_MCH_PB1 0x3598 +#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599 +#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a +#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e +#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 +#define PCI_DEVICE_ID_INTEL_82371SB_1 0x7010 +#define PCI_DEVICE_ID_INTEL_82371SB_2 0x7020 +#define PCI_DEVICE_ID_INTEL_82437VX 0x7030 +#define PCI_DEVICE_ID_INTEL_82439TX 0x7100 +#define PCI_DEVICE_ID_INTEL_82371AB_0 0x7110 +#define PCI_DEVICE_ID_INTEL_82371AB 0x7111 +#define PCI_DEVICE_ID_INTEL_82371AB_2 0x7112 +#define PCI_DEVICE_ID_INTEL_82371AB_3 0x7113 +#define PCI_DEVICE_ID_INTEL_82810_MC1 0x7120 +#define PCI_DEVICE_ID_INTEL_82810_IG1 0x7121 +#define PCI_DEVICE_ID_INTEL_82810_MC3 0x7122 +#define PCI_DEVICE_ID_INTEL_82810_IG3 0x7123 +#define PCI_DEVICE_ID_INTEL_82810E_MC 0x7124 +#define PCI_DEVICE_ID_INTEL_82810E_IG 0x7125 +#define PCI_DEVICE_ID_INTEL_82443LX_0 0x7180 +#define PCI_DEVICE_ID_INTEL_82443LX_1 0x7181 +#define PCI_DEVICE_ID_INTEL_82443BX_0 0x7190 +#define PCI_DEVICE_ID_INTEL_82443BX_1 0x7191 +#define PCI_DEVICE_ID_INTEL_82443BX_2 0x7192 +#define PCI_DEVICE_ID_INTEL_440MX 0x7195 +#define PCI_DEVICE_ID_INTEL_440MX_6 0x7196 +#define PCI_DEVICE_ID_INTEL_82443MX_0 0x7198 +#define PCI_DEVICE_ID_INTEL_82443MX_1 0x7199 +#define PCI_DEVICE_ID_INTEL_82443MX_3 0x719b +#define PCI_DEVICE_ID_INTEL_82443GX_0 0x71a0 +#define PCI_DEVICE_ID_INTEL_82443GX_2 0x71a2 +#define PCI_DEVICE_ID_INTEL_82372FB_1 0x7601 +#define PCI_DEVICE_ID_INTEL_82454GX 0x84c4 +#define PCI_DEVICE_ID_INTEL_82450GX 0x84c5 +#define PCI_DEVICE_ID_INTEL_82451NX 0x84ca +#define PCI_DEVICE_ID_INTEL_82454NX 0x84cb +#define PCI_DEVICE_ID_INTEL_84460GX 0x84ea +#define PCI_DEVICE_ID_INTEL_IXP4XX 0x8500 +#define PCI_DEVICE_ID_INTEL_IXP2800 0x9004 +#define PCI_DEVICE_ID_INTEL_S21152BB 0xb152 + +#define PCI_VENDOR_ID_SCALEMP 0x8686 +#define PCI_DEVICE_ID_SCALEMP_VSMP_CTL 0x1010 + +#define PCI_VENDOR_ID_COMPUTONE 0x8e0e +#define PCI_DEVICE_ID_COMPUTONE_IP2EX 0x0291 +#define PCI_DEVICE_ID_COMPUTONE_PG 0x0302 +#define PCI_SUBVENDOR_ID_COMPUTONE 0x8e0e +#define PCI_SUBDEVICE_ID_COMPUTONE_PG4 0x0001 +#define PCI_SUBDEVICE_ID_COMPUTONE_PG8 0x0002 +#define PCI_SUBDEVICE_ID_COMPUTONE_PG6 0x0003 + +#define PCI_VENDOR_ID_KTI 0x8e2e + +#define PCI_VENDOR_ID_ADAPTEC 0x9004 +#define PCI_DEVICE_ID_ADAPTEC_7810 0x1078 +#define PCI_DEVICE_ID_ADAPTEC_7821 0x2178 +#define PCI_DEVICE_ID_ADAPTEC_38602 0x3860 +#define PCI_DEVICE_ID_ADAPTEC_7850 0x5078 +#define PCI_DEVICE_ID_ADAPTEC_7855 0x5578 +#define PCI_DEVICE_ID_ADAPTEC_3860 0x6038 +#define PCI_DEVICE_ID_ADAPTEC_1480A 0x6075 +#define PCI_DEVICE_ID_ADAPTEC_7860 0x6078 +#define PCI_DEVICE_ID_ADAPTEC_7861 0x6178 +#define PCI_DEVICE_ID_ADAPTEC_7870 0x7078 +#define PCI_DEVICE_ID_ADAPTEC_7871 0x7178 +#define PCI_DEVICE_ID_ADAPTEC_7872 0x7278 +#define PCI_DEVICE_ID_ADAPTEC_7873 0x7378 +#define PCI_DEVICE_ID_ADAPTEC_7874 0x7478 +#define PCI_DEVICE_ID_ADAPTEC_7895 0x7895 +#define PCI_DEVICE_ID_ADAPTEC_7880 0x8078 +#define PCI_DEVICE_ID_ADAPTEC_7881 0x8178 +#define PCI_DEVICE_ID_ADAPTEC_7882 0x8278 +#define PCI_DEVICE_ID_ADAPTEC_7883 0x8378 +#define PCI_DEVICE_ID_ADAPTEC_7884 0x8478 +#define PCI_DEVICE_ID_ADAPTEC_7885 0x8578 +#define PCI_DEVICE_ID_ADAPTEC_7886 0x8678 +#define PCI_DEVICE_ID_ADAPTEC_7887 0x8778 +#define PCI_DEVICE_ID_ADAPTEC_7888 0x8878 + +#define PCI_VENDOR_ID_ADAPTEC2 0x9005 +#define PCI_DEVICE_ID_ADAPTEC2_2940U2 0x0010 +#define PCI_DEVICE_ID_ADAPTEC2_2930U2 0x0011 +#define PCI_DEVICE_ID_ADAPTEC2_7890B 0x0013 +#define PCI_DEVICE_ID_ADAPTEC2_7890 0x001f +#define PCI_DEVICE_ID_ADAPTEC2_3940U2 0x0050 +#define PCI_DEVICE_ID_ADAPTEC2_3950U2D 0x0051 +#define PCI_DEVICE_ID_ADAPTEC2_7896 0x005f +#define PCI_DEVICE_ID_ADAPTEC2_7892A 0x0080 +#define PCI_DEVICE_ID_ADAPTEC2_7892B 0x0081 +#define PCI_DEVICE_ID_ADAPTEC2_7892D 0x0083 +#define PCI_DEVICE_ID_ADAPTEC2_7892P 0x008f +#define PCI_DEVICE_ID_ADAPTEC2_7899A 0x00c0 +#define PCI_DEVICE_ID_ADAPTEC2_7899B 0x00c1 +#define PCI_DEVICE_ID_ADAPTEC2_7899D 0x00c3 +#define PCI_DEVICE_ID_ADAPTEC2_7899P 0x00cf +#define PCI_DEVICE_ID_ADAPTEC2_OBSIDIAN 0x0500 +#define PCI_DEVICE_ID_ADAPTEC2_SCAMP 0x0503 + + +#define PCI_VENDOR_ID_HOLTEK 0x9412 +#define PCI_DEVICE_ID_HOLTEK_6565 0x6565 + +#define PCI_VENDOR_ID_NETMOS 0x9710 +#define PCI_DEVICE_ID_NETMOS_9705 0x9705 +#define PCI_DEVICE_ID_NETMOS_9715 0x9715 +#define PCI_DEVICE_ID_NETMOS_9735 0x9735 +#define PCI_DEVICE_ID_NETMOS_9745 0x9745 +#define PCI_DEVICE_ID_NETMOS_9755 0x9755 +#define PCI_DEVICE_ID_NETMOS_9805 0x9805 +#define PCI_DEVICE_ID_NETMOS_9815 0x9815 +#define PCI_DEVICE_ID_NETMOS_9835 0x9835 +#define PCI_DEVICE_ID_NETMOS_9845 0x9845 +#define PCI_DEVICE_ID_NETMOS_9855 0x9855 + +#define PCI_SUBVENDOR_ID_EXSYS 0xd84d +#define PCI_SUBDEVICE_ID_EXSYS_4014 0x4014 +#define PCI_SUBDEVICE_ID_EXSYS_4055 0x4055 + +#define PCI_VENDOR_ID_TIGERJET 0xe159 +#define PCI_DEVICE_ID_TIGERJET_300 0x0001 +#define PCI_DEVICE_ID_TIGERJET_100 0x0002 + +#define PCI_VENDOR_ID_TTTECH 0x0357 +#define PCI_DEVICE_ID_TTTECH_MC322 0x000A + +#define PCI_VENDOR_ID_XILINX_RME 0xea60 +#define PCI_DEVICE_ID_RME_DIGI32 0x9896 +#define PCI_DEVICE_ID_RME_DIGI32_PRO 0x9897 +#define PCI_DEVICE_ID_RME_DIGI32_8 0x9898 + +#define PCI_VENDOR_ID_QUICKNET 0x15E2 +#define PCI_DEVICE_ID_QUICKNET_XJ 0x0500 diff --git a/xen/include/asm-ia64/linux/pci_regs.h b/xen/include/asm-ia64/linux/pci_regs.h new file mode 100644 index 0000000000..c321316f1b --- /dev/null +++ b/xen/include/asm-ia64/linux/pci_regs.h @@ -0,0 +1,488 @@ +/* + * pci_regs.h + * + * PCI standard defines + * Copyright 1994, Drew Eckhardt + * Copyright 1997--1999 Martin Mares + * + * For more information, please consult the following manuals (look at + * http://www.pcisig.com/ for how to get them): + * + * PCI BIOS Specification + * PCI Local Bus Specification + * PCI to PCI Bridge Specification + * PCI System Design Guide + * + * For hypertransport information, please consult the following manuals + * from http://www.hypertransport.org + * + * The Hypertransport I/O Link Specification + */ + +#ifndef LINUX_PCI_REGS_H +#define LINUX_PCI_REGS_H + +/* + * Under PCI, each device has 256 bytes of configuration address space, + * of which the first 64 bytes are standardized as follows: + */ +#define PCI_VENDOR_ID 0x00 /* 16 bits */ +#define PCI_DEVICE_ID 0x02 /* 16 bits */ +#define PCI_COMMAND 0x04 /* 16 bits */ +#define PCI_COMMAND_IO 0x1 /* Enable response in I/O space */ +#define PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */ +#define PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */ +#define PCI_COMMAND_SPECIAL 0x8 /* Enable response to special cycles */ +#define PCI_COMMAND_INVALIDATE 0x10 /* Use memory write and invalidate */ +#define PCI_COMMAND_VGA_PALETTE 0x20 /* Enable palette snooping */ +#define PCI_COMMAND_PARITY 0x40 /* Enable parity checking */ +#define PCI_COMMAND_WAIT 0x80 /* Enable address/data stepping */ +#define PCI_COMMAND_SERR 0x100 /* Enable SERR */ +#define PCI_COMMAND_FAST_BACK 0x200 /* Enable back-to-back writes */ +#define PCI_COMMAND_INTX_DISABLE 0x400 /* INTx Emulation Disable */ + +#define PCI_STATUS 0x06 /* 16 bits */ +#define PCI_STATUS_CAP_LIST 0x10 /* Support Capability List */ +#define PCI_STATUS_66MHZ 0x20 /* Support 66 Mhz PCI 2.1 bus */ +#define PCI_STATUS_UDF 0x40 /* Support User Definable Features [obsolete] */ +#define PCI_STATUS_FAST_BACK 0x80 /* Accept fast-back to back */ +#define PCI_STATUS_PARITY 0x100 /* Detected parity error */ +#define PCI_STATUS_DEVSEL_MASK 0x600 /* DEVSEL timing */ +#define PCI_STATUS_DEVSEL_FAST 0x000 +#define PCI_STATUS_DEVSEL_MEDIUM 0x200 +#define PCI_STATUS_DEVSEL_SLOW 0x400 +#define PCI_STATUS_SIG_TARGET_ABORT 0x800 /* Set on target abort */ +#define PCI_STATUS_REC_TARGET_ABORT 0x1000 /* Master ack of " */ +#define PCI_STATUS_REC_MASTER_ABORT 0x2000 /* Set on master abort */ +#define PCI_STATUS_SIG_SYSTEM_ERROR 0x4000 /* Set when we drive SERR */ +#define PCI_STATUS_DETECTED_PARITY 0x8000 /* Set on parity error */ + +#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */ +#define PCI_REVISION_ID 0x08 /* Revision ID */ +#define PCI_CLASS_PROG 0x09 /* Reg. Level Programming Interface */ +#define PCI_CLASS_DEVICE 0x0a /* Device class */ + +#define PCI_CACHE_LINE_SIZE 0x0c /* 8 bits */ +#define PCI_LATENCY_TIMER 0x0d /* 8 bits */ +#define PCI_HEADER_TYPE 0x0e /* 8 bits */ +#define PCI_HEADER_TYPE_NORMAL 0 +#define PCI_HEADER_TYPE_BRIDGE 1 +#define PCI_HEADER_TYPE_CARDBUS 2 + +#define PCI_BIST 0x0f /* 8 bits */ +#define PCI_BIST_CODE_MASK 0x0f /* Return result */ +#define PCI_BIST_START 0x40 /* 1 to start BIST, 2 secs or less */ +#define PCI_BIST_CAPABLE 0x80 /* 1 if BIST capable */ + +/* + * Base addresses specify locations in memory or I/O space. + * Decoded size can be determined by writing a value of + * 0xffffffff to the register, and reading it back. Only + * 1 bits are decoded. + */ +#define PCI_BASE_ADDRESS_0 0x10 /* 32 bits */ +#define PCI_BASE_ADDRESS_1 0x14 /* 32 bits [htype 0,1 only] */ +#define PCI_BASE_ADDRESS_2 0x18 /* 32 bits [htype 0 only] */ +#define PCI_BASE_ADDRESS_3 0x1c /* 32 bits */ +#define PCI_BASE_ADDRESS_4 0x20 /* 32 bits */ +#define PCI_BASE_ADDRESS_5 0x24 /* 32 bits */ +#define PCI_BASE_ADDRESS_SPACE 0x01 /* 0 = memory, 1 = I/O */ +#define PCI_BASE_ADDRESS_SPACE_IO 0x01 +#define PCI_BASE_ADDRESS_SPACE_MEMORY 0x00 +#define PCI_BASE_ADDRESS_MEM_TYPE_MASK 0x06 +#define PCI_BASE_ADDRESS_MEM_TYPE_32 0x00 /* 32 bit address */ +#define PCI_BASE_ADDRESS_MEM_TYPE_1M 0x02 /* Below 1M [obsolete] */ +#define PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */ +#define PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */ +#define PCI_BASE_ADDRESS_MEM_MASK (~0x0fUL) +#define PCI_BASE_ADDRESS_IO_MASK (~0x03UL) +/* bit 1 is reserved if address_space = 1 */ + +/* Header type 0 (normal devices) */ +#define PCI_CARDBUS_CIS 0x28 +#define PCI_SUBSYSTEM_VENDOR_ID 0x2c +#define PCI_SUBSYSTEM_ID 0x2e +#define PCI_ROM_ADDRESS 0x30 /* Bits 31..11 are address, 10..1 reserved */ +#define PCI_ROM_ADDRESS_ENABLE 0x01 +#define PCI_ROM_ADDRESS_MASK (~0x7ffUL) + +#define PCI_CAPABILITY_LIST 0x34 /* Offset of first capability list entry */ + +/* 0x35-0x3b are reserved */ +#define PCI_INTERRUPT_LINE 0x3c /* 8 bits */ +#define PCI_INTERRUPT_PIN 0x3d /* 8 bits */ +#define PCI_MIN_GNT 0x3e /* 8 bits */ +#define PCI_MAX_LAT 0x3f /* 8 bits */ + +/* Header type 1 (PCI-to-PCI bridges) */ +#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */ +#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */ +#define PCI_SUBORDINATE_BUS 0x1a /* Highest bus number behind the bridge */ +#define PCI_SEC_LATENCY_TIMER 0x1b /* Latency timer for secondary interface */ +#define PCI_IO_BASE 0x1c /* I/O range behind the bridge */ +#define PCI_IO_LIMIT 0x1d +#define PCI_IO_RANGE_TYPE_MASK 0x0fUL /* I/O bridging type */ +#define PCI_IO_RANGE_TYPE_16 0x00 +#define PCI_IO_RANGE_TYPE_32 0x01 +#define PCI_IO_RANGE_MASK (~0x0fUL) +#define PCI_SEC_STATUS 0x1e /* Secondary status register, only bit 14 used */ +#define PCI_MEMORY_BASE 0x20 /* Memory range behind */ +#define PCI_MEMORY_LIMIT 0x22 +#define PCI_MEMORY_RANGE_TYPE_MASK 0x0fUL +#define PCI_MEMORY_RANGE_MASK (~0x0fUL) +#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */ +#define PCI_PREF_MEMORY_LIMIT 0x26 +#define PCI_PREF_RANGE_TYPE_MASK 0x0fUL +#define PCI_PREF_RANGE_TYPE_32 0x00 +#define PCI_PREF_RANGE_TYPE_64 0x01 +#define PCI_PREF_RANGE_MASK (~0x0fUL) +#define PCI_PREF_BASE_UPPER32 0x28 /* Upper half of prefetchable memory range */ +#define PCI_PREF_LIMIT_UPPER32 0x2c +#define PCI_IO_BASE_UPPER16 0x30 /* Upper half of I/O addresses */ +#define PCI_IO_LIMIT_UPPER16 0x32 +/* 0x34 same as for htype 0 */ +/* 0x35-0x3b is reserved */ +#define PCI_ROM_ADDRESS1 0x38 /* Same as PCI_ROM_ADDRESS, but for htype 1 */ +/* 0x3c-0x3d are same as for htype 0 */ +#define PCI_BRIDGE_CONTROL 0x3e +#define PCI_BRIDGE_CTL_PARITY 0x01 /* Enable parity detection on secondary interface */ +#define PCI_BRIDGE_CTL_SERR 0x02 /* The same for SERR forwarding */ +#define PCI_BRIDGE_CTL_NO_ISA 0x04 /* Disable bridging of ISA ports */ +#define PCI_BRIDGE_CTL_VGA 0x08 /* Forward VGA addresses */ +#define PCI_BRIDGE_CTL_MASTER_ABORT 0x20 /* Report master aborts */ +#define PCI_BRIDGE_CTL_BUS_RESET 0x40 /* Secondary bus reset */ +#define PCI_BRIDGE_CTL_FAST_BACK 0x80 /* Fast Back2Back enabled on secondary interface */ + +/* Header type 2 (CardBus bridges) */ +#define PCI_CB_CAPABILITY_LIST 0x14 +/* 0x15 reserved */ +#define PCI_CB_SEC_STATUS 0x16 /* Secondary status */ +#define PCI_CB_PRIMARY_BUS 0x18 /* PCI bus number */ +#define PCI_CB_CARD_BUS 0x19 /* CardBus bus number */ +#define PCI_CB_SUBORDINATE_BUS 0x1a /* Subordinate bus number */ +#define PCI_CB_LATENCY_TIMER 0x1b /* CardBus latency timer */ +#define PCI_CB_MEMORY_BASE_0 0x1c +#define PCI_CB_MEMORY_LIMIT_0 0x20 +#define PCI_CB_MEMORY_BASE_1 0x24 +#define PCI_CB_MEMORY_LIMIT_1 0x28 +#define PCI_CB_IO_BASE_0 0x2c +#define PCI_CB_IO_BASE_0_HI 0x2e +#define PCI_CB_IO_LIMIT_0 0x30 +#define PCI_CB_IO_LIMIT_0_HI 0x32 +#define PCI_CB_IO_BASE_1 0x34 +#define PCI_CB_IO_BASE_1_HI 0x36 +#define PCI_CB_IO_LIMIT_1 0x38 +#define PCI_CB_IO_LIMIT_1_HI 0x3a +#define PCI_CB_IO_RANGE_MASK (~0x03UL) +/* 0x3c-0x3d are same as for htype 0 */ +#define PCI_CB_BRIDGE_CONTROL 0x3e +#define PCI_CB_BRIDGE_CTL_PARITY 0x01 /* Similar to standard bridge control register */ +#define PCI_CB_BRIDGE_CTL_SERR 0x02 +#define PCI_CB_BRIDGE_CTL_ISA 0x04 +#define PCI_CB_BRIDGE_CTL_VGA 0x08 +#define PCI_CB_BRIDGE_CTL_MASTER_ABORT 0x20 +#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */ +#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */ +#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 /* Prefetch enable for both memory regions */ +#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200 +#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400 +#define PCI_CB_SUBSYSTEM_VENDOR_ID 0x40 +#define PCI_CB_SUBSYSTEM_ID 0x42 +#define PCI_CB_LEGACY_MODE_BASE 0x44 /* 16-bit PC Card legacy mode base address (ExCa) */ +/* 0x48-0x7f reserved */ + +/* Capability lists */ + +#define PCI_CAP_LIST_ID 0 /* Capability ID */ +#define PCI_CAP_ID_PM 0x01 /* Power Management */ +#define PCI_CAP_ID_AGP 0x02 /* Accelerated Graphics Port */ +#define PCI_CAP_ID_VPD 0x03 /* Vital Product Data */ +#define PCI_CAP_ID_SLOTID 0x04 /* Slot Identification */ +#define PCI_CAP_ID_MSI 0x05 /* Message Signalled Interrupts */ +#define PCI_CAP_ID_CHSWP 0x06 /* CompactPCI HotSwap */ +#define PCI_CAP_ID_PCIX 0x07 /* PCI-X */ +#define PCI_CAP_ID_HT 0x08 /* HyperTransport */ +#define PCI_CAP_ID_VNDR 0x09 /* Vendor specific capability */ +#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */ +#define PCI_CAP_ID_EXP 0x10 /* PCI Express */ +#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */ +#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */ +#define PCI_CAP_FLAGS 2 /* Capability defined flags (16 bits) */ +#define PCI_CAP_SIZEOF 4 + +/* Power Management Registers */ + +#define PCI_PM_PMC 2 /* PM Capabilities Register */ +#define PCI_PM_CAP_VER_MASK 0x0007 /* Version */ +#define PCI_PM_CAP_PME_CLOCK 0x0008 /* PME clock required */ +#define PCI_PM_CAP_RESERVED 0x0010 /* Reserved field */ +#define PCI_PM_CAP_DSI 0x0020 /* Device specific initialization */ +#define PCI_PM_CAP_AUX_POWER 0x01C0 /* Auxilliary power support mask */ +#define PCI_PM_CAP_D1 0x0200 /* D1 power state support */ +#define PCI_PM_CAP_D2 0x0400 /* D2 power state support */ +#define PCI_PM_CAP_PME 0x0800 /* PME pin supported */ +#define PCI_PM_CAP_PME_MASK 0xF800 /* PME Mask of all supported states */ +#define PCI_PM_CAP_PME_D0 0x0800 /* PME# from D0 */ +#define PCI_PM_CAP_PME_D1 0x1000 /* PME# from D1 */ +#define PCI_PM_CAP_PME_D2 0x2000 /* PME# from D2 */ +#define PCI_PM_CAP_PME_D3 0x4000 /* PME# from D3 (hot) */ +#define PCI_PM_CAP_PME_D3cold 0x8000 /* PME# from D3 (cold) */ +#define PCI_PM_CTRL 4 /* PM control and status register */ +#define PCI_PM_CTRL_STATE_MASK 0x0003 /* Current power state (D0 to D3) */ +#define PCI_PM_CTRL_NO_SOFT_RESET 0x0004 /* No reset for D3hot->D0 */ +#define PCI_PM_CTRL_PME_ENABLE 0x0100 /* PME pin enable */ +#define PCI_PM_CTRL_DATA_SEL_MASK 0x1e00 /* Data select (??) */ +#define PCI_PM_CTRL_DATA_SCALE_MASK 0x6000 /* Data scale (??) */ +#define PCI_PM_CTRL_PME_STATUS 0x8000 /* PME pin status */ +#define PCI_PM_PPB_EXTENSIONS 6 /* PPB support extensions (??) */ +#define PCI_PM_PPB_B2_B3 0x40 /* Stop clock when in D3hot (??) */ +#define PCI_PM_BPCC_ENABLE 0x80 /* Bus power/clock control enable (??) */ +#define PCI_PM_DATA_REGISTER 7 /* (??) */ +#define PCI_PM_SIZEOF 8 + +/* AGP registers */ + +#define PCI_AGP_VERSION 2 /* BCD version number */ +#define PCI_AGP_RFU 3 /* Rest of capability flags */ +#define PCI_AGP_STATUS 4 /* Status register */ +#define PCI_AGP_STATUS_RQ_MASK 0xff000000 /* Maximum number of requests - 1 */ +#define PCI_AGP_STATUS_SBA 0x0200 /* Sideband addressing supported */ +#define PCI_AGP_STATUS_64BIT 0x0020 /* 64-bit addressing supported */ +#define PCI_AGP_STATUS_FW 0x0010 /* FW transfers supported */ +#define PCI_AGP_STATUS_RATE4 0x0004 /* 4x transfer rate supported */ +#define PCI_AGP_STATUS_RATE2 0x0002 /* 2x transfer rate supported */ +#define PCI_AGP_STATUS_RATE1 0x0001 /* 1x transfer rate supported */ +#define PCI_AGP_COMMAND 8 /* Control register */ +#define PCI_AGP_COMMAND_RQ_MASK 0xff000000 /* Master: Maximum number of requests */ +#define PCI_AGP_COMMAND_SBA 0x0200 /* Sideband addressing enabled */ +#define PCI_AGP_COMMAND_AGP 0x0100 /* Allow processing of AGP transactions */ +#define PCI_AGP_COMMAND_64BIT 0x0020 /* Allow processing of 64-bit addresses */ +#define PCI_AGP_COMMAND_FW 0x0010 /* Force FW transfers */ +#define PCI_AGP_COMMAND_RATE4 0x0004 /* Use 4x rate */ +#define PCI_AGP_COMMAND_RATE2 0x0002 /* Use 2x rate */ +#define PCI_AGP_COMMAND_RATE1 0x0001 /* Use 1x rate */ +#define PCI_AGP_SIZEOF 12 + +/* Vital Product Data */ + +#define PCI_VPD_ADDR 2 /* Address to access (15 bits!) */ +#define PCI_VPD_ADDR_MASK 0x7fff /* Address mask */ +#define PCI_VPD_ADDR_F 0x8000 /* Write 0, 1 indicates completion */ +#define PCI_VPD_DATA 4 /* 32-bits of data returned here */ + +/* Slot Identification */ + +#define PCI_SID_ESR 2 /* Expansion Slot Register */ +#define PCI_SID_ESR_NSLOTS 0x1f /* Number of expansion slots available */ +#define PCI_SID_ESR_FIC 0x20 /* First In Chassis Flag */ +#define PCI_SID_CHASSIS_NR 3 /* Chassis Number */ + +/* Message Signalled Interrupts registers */ + +#define PCI_MSI_FLAGS 2 /* Various flags */ +#define PCI_MSI_FLAGS_64BIT 0x80 /* 64-bit addresses allowed */ +#define PCI_MSI_FLAGS_QSIZE 0x70 /* Message queue size configured */ +#define PCI_MSI_FLAGS_QMASK 0x0e /* Maximum queue size available */ +#define PCI_MSI_FLAGS_ENABLE 0x01 /* MSI feature enabled */ +#define PCI_MSI_FLAGS_MASKBIT 0x100 /* 64-bit mask bits allowed */ +#define PCI_MSI_RFU 3 /* Rest of capability flags */ +#define PCI_MSI_ADDRESS_LO 4 /* Lower 32 bits */ +#define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ +#define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ +#define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ +#define PCI_MSI_MASK_BIT 16 /* Mask bits register */ + +/* CompactPCI Hotswap Register */ + +#define PCI_CHSWP_CSR 2 /* Control and Status Register */ +#define PCI_CHSWP_DHA 0x01 /* Device Hiding Arm */ +#define PCI_CHSWP_EIM 0x02 /* ENUM# Signal Mask */ +#define PCI_CHSWP_PIE 0x04 /* Pending Insert or Extract */ +#define PCI_CHSWP_LOO 0x08 /* LED On / Off */ +#define PCI_CHSWP_PI 0x30 /* Programming Interface */ +#define PCI_CHSWP_EXT 0x40 /* ENUM# status - extraction */ +#define PCI_CHSWP_INS 0x80 /* ENUM# status - insertion */ + +/* PCI-X registers */ + +#define PCI_X_CMD 2 /* Modes & Features */ +#define PCI_X_CMD_DPERR_E 0x0001 /* Data Parity Error Recovery Enable */ +#define PCI_X_CMD_ERO 0x0002 /* Enable Relaxed Ordering */ +#define PCI_X_CMD_MAX_READ 0x000c /* Max Memory Read Byte Count */ +#define PCI_X_CMD_MAX_SPLIT 0x0070 /* Max Outstanding Split Transactions */ +#define PCI_X_CMD_VERSION(x) (((x) >> 12) & 3) /* Version */ +#define PCI_X_STATUS 4 /* PCI-X capabilities */ +#define PCI_X_STATUS_DEVFN 0x000000ff /* A copy of devfn */ +#define PCI_X_STATUS_BUS 0x0000ff00 /* A copy of bus nr */ +#define PCI_X_STATUS_64BIT 0x00010000 /* 64-bit device */ +#define PCI_X_STATUS_133MHZ 0x00020000 /* 133 MHz capable */ +#define PCI_X_STATUS_SPL_DISC 0x00040000 /* Split Completion Discarded */ +#define PCI_X_STATUS_UNX_SPL 0x00080000 /* Unexpected Split Completion */ +#define PCI_X_STATUS_COMPLEX 0x00100000 /* Device Complexity */ +#define PCI_X_STATUS_MAX_READ 0x00600000 /* Designed Max Memory Read Count */ +#define PCI_X_STATUS_MAX_SPLIT 0x03800000 /* Designed Max Outstanding Split Transactions */ +#define PCI_X_STATUS_MAX_CUM 0x1c000000 /* Designed Max Cumulative Read Size */ +#define PCI_X_STATUS_SPL_ERR 0x20000000 /* Rcvd Split Completion Error Msg */ +#define PCI_X_STATUS_266MHZ 0x40000000 /* 266 MHz capable */ +#define PCI_X_STATUS_533MHZ 0x80000000 /* 533 MHz capable */ + +/* PCI Express capability registers */ + +#define PCI_EXP_FLAGS 2 /* Capabilities register */ +#define PCI_EXP_FLAGS_VERS 0x000f /* Capability version */ +#define PCI_EXP_FLAGS_TYPE 0x00f0 /* Device/Port type */ +#define PCI_EXP_TYPE_ENDPOINT 0x0 /* Express Endpoint */ +#define PCI_EXP_TYPE_LEG_END 0x1 /* Legacy Endpoint */ +#define PCI_EXP_TYPE_ROOT_PORT 0x4 /* Root Port */ +#define PCI_EXP_TYPE_UPSTREAM 0x5 /* Upstream Port */ +#define PCI_EXP_TYPE_DOWNSTREAM 0x6 /* Downstream Port */ +#define PCI_EXP_TYPE_PCI_BRIDGE 0x7 /* PCI/PCI-X Bridge */ +#define PCI_EXP_FLAGS_SLOT 0x0100 /* Slot implemented */ +#define PCI_EXP_FLAGS_IRQ 0x3e00 /* Interrupt message number */ +#define PCI_EXP_DEVCAP 4 /* Device capabilities */ +#define PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */ +#define PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */ +#define PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */ +#define PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */ +#define PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */ +#define PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */ +#define PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */ +#define PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */ +#define PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */ +#define PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */ +#define PCI_EXP_DEVCTL 8 /* Device Control */ +#define PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */ +#define PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */ +#define PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */ +#define PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */ +#define PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */ +#define PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */ +#define PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */ +#define PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */ +#define PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */ +#define PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */ +#define PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */ +#define PCI_EXP_DEVSTA 10 /* Device Status */ +#define PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */ +#define PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */ +#define PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */ +#define PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */ +#define PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */ +#define PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */ +#define PCI_EXP_LNKCAP 12 /* Link Capabilities */ +#define PCI_EXP_LNKCTL 16 /* Link Control */ +#define PCI_EXP_LNKCTL_CLKREQ_EN 0x100 /* Enable clkreq */ +#define PCI_EXP_LNKSTA 18 /* Link Status */ +#define PCI_EXP_SLTCAP 20 /* Slot Capabilities */ +#define PCI_EXP_SLTCTL 24 /* Slot Control */ +#define PCI_EXP_SLTSTA 26 /* Slot Status */ +#define PCI_EXP_RTCTL 28 /* Root Control */ +#define PCI_EXP_RTCTL_SECEE 0x01 /* System Error on Correctable Error */ +#define PCI_EXP_RTCTL_SENFEE 0x02 /* System Error on Non-Fatal Error */ +#define PCI_EXP_RTCTL_SEFEE 0x04 /* System Error on Fatal Error */ +#define PCI_EXP_RTCTL_PMEIE 0x08 /* PME Interrupt Enable */ +#define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ +#define PCI_EXP_RTCAP 30 /* Root Capabilities */ +#define PCI_EXP_RTSTA 32 /* Root Status */ + +/* Extended Capabilities (PCI-X 2.0 and Express) */ +#define PCI_EXT_CAP_ID(header) (header & 0x0000ffff) +#define PCI_EXT_CAP_VER(header) ((header >> 16) & 0xf) +#define PCI_EXT_CAP_NEXT(header) ((header >> 20) & 0xffc) + +#define PCI_EXT_CAP_ID_ERR 1 +#define PCI_EXT_CAP_ID_VC 2 +#define PCI_EXT_CAP_ID_DSN 3 +#define PCI_EXT_CAP_ID_PWR 4 + +/* Advanced Error Reporting */ +#define PCI_ERR_UNCOR_STATUS 4 /* Uncorrectable Error Status */ +#define PCI_ERR_UNC_TRAIN 0x00000001 /* Training */ +#define PCI_ERR_UNC_DLP 0x00000010 /* Data Link Protocol */ +#define PCI_ERR_UNC_POISON_TLP 0x00001000 /* Poisoned TLP */ +#define PCI_ERR_UNC_FCP 0x00002000 /* Flow Control Protocol */ +#define PCI_ERR_UNC_COMP_TIME 0x00004000 /* Completion Timeout */ +#define PCI_ERR_UNC_COMP_ABORT 0x00008000 /* Completer Abort */ +#define PCI_ERR_UNC_UNX_COMP 0x00010000 /* Unexpected Completion */ +#define PCI_ERR_UNC_RX_OVER 0x00020000 /* Receiver Overflow */ +#define PCI_ERR_UNC_MALF_TLP 0x00040000 /* Malformed TLP */ +#define PCI_ERR_UNC_ECRC 0x00080000 /* ECRC Error Status */ +#define PCI_ERR_UNC_UNSUP 0x00100000 /* Unsupported Request */ +#define PCI_ERR_UNCOR_MASK 8 /* Uncorrectable Error Mask */ + /* Same bits as above */ +#define PCI_ERR_UNCOR_SEVER 12 /* Uncorrectable Error Severity */ + /* Same bits as above */ +#define PCI_ERR_COR_STATUS 16 /* Correctable Error Status */ +#define PCI_ERR_COR_RCVR 0x00000001 /* Receiver Error Status */ +#define PCI_ERR_COR_BAD_TLP 0x00000040 /* Bad TLP Status */ +#define PCI_ERR_COR_BAD_DLLP 0x00000080 /* Bad DLLP Status */ +#define PCI_ERR_COR_REP_ROLL 0x00000100 /* REPLAY_NUM Rollover */ +#define PCI_ERR_COR_REP_TIMER 0x00001000 /* Replay Timer Timeout */ +#define PCI_ERR_COR_MASK 20 /* Correctable Error Mask */ + /* Same bits as above */ +#define PCI_ERR_CAP 24 /* Advanced Error Capabilities */ +#define PCI_ERR_CAP_FEP(x) ((x) & 31) /* First Error Pointer */ +#define PCI_ERR_CAP_ECRC_GENC 0x00000020 /* ECRC Generation Capable */ +#define PCI_ERR_CAP_ECRC_GENE 0x00000040 /* ECRC Generation Enable */ +#define PCI_ERR_CAP_ECRC_CHKC 0x00000080 /* ECRC Check Capable */ +#define PCI_ERR_CAP_ECRC_CHKE 0x00000100 /* ECRC Check Enable */ +#define PCI_ERR_HEADER_LOG 28 /* Header Log Register (16 bytes) */ +#define PCI_ERR_ROOT_COMMAND 44 /* Root Error Command */ +/* Correctable Err Reporting Enable */ +#define PCI_ERR_ROOT_CMD_COR_EN 0x00000001 +/* Non-fatal Err Reporting Enable */ +#define PCI_ERR_ROOT_CMD_NONFATAL_EN 0x00000002 +/* Fatal Err Reporting Enable */ +#define PCI_ERR_ROOT_CMD_FATAL_EN 0x00000004 +#define PCI_ERR_ROOT_STATUS 48 +#define PCI_ERR_ROOT_COR_RCV 0x00000001 /* ERR_COR Received */ +/* Multi ERR_COR Received */ +#define PCI_ERR_ROOT_MULTI_COR_RCV 0x00000002 +/* ERR_FATAL/NONFATAL Recevied */ +#define PCI_ERR_ROOT_UNCOR_RCV 0x00000004 +/* Multi ERR_FATAL/NONFATAL Recevied */ +#define PCI_ERR_ROOT_MULTI_UNCOR_RCV 0x00000008 +#define PCI_ERR_ROOT_FIRST_FATAL 0x00000010 /* First Fatal */ +#define PCI_ERR_ROOT_NONFATAL_RCV 0x00000020 /* Non-Fatal Received */ +#define PCI_ERR_ROOT_FATAL_RCV 0x00000040 /* Fatal Received */ +#define PCI_ERR_ROOT_COR_SRC 52 +#define PCI_ERR_ROOT_SRC 54 + +/* Virtual Channel */ +#define PCI_VC_PORT_REG1 4 +#define PCI_VC_PORT_REG2 8 +#define PCI_VC_PORT_CTRL 12 +#define PCI_VC_PORT_STATUS 14 +#define PCI_VC_RES_CAP 16 +#define PCI_VC_RES_CTRL 20 +#define PCI_VC_RES_STATUS 26 + +/* Power Budgeting */ +#define PCI_PWR_DSR 4 /* Data Select Register */ +#define PCI_PWR_DATA 8 /* Data Register */ +#define PCI_PWR_DATA_BASE(x) ((x) & 0xff) /* Base Power */ +#define PCI_PWR_DATA_SCALE(x) (((x) >> 8) & 3) /* Data Scale */ +#define PCI_PWR_DATA_PM_SUB(x) (((x) >> 10) & 7) /* PM Sub State */ +#define PCI_PWR_DATA_PM_STATE(x) (((x) >> 13) & 3) /* PM State */ +#define PCI_PWR_DATA_TYPE(x) (((x) >> 15) & 7) /* Type */ +#define PCI_PWR_DATA_RAIL(x) (((x) >> 18) & 7) /* Power Rail */ +#define PCI_PWR_CAP 12 /* Capability */ +#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */ + +/* Hypertransport sub capability types */ +#define HT_CAPTYPE_SLAVE 0x00 /* Slave/Primary link configuration */ +#define HT_CAPTYPE_HOST 0x20 /* Host/Secondary link configuration */ +#define HT_CAPTYPE_IRQ 0x80 /* IRQ Configuration */ +#define HT_CAPTYPE_REMAPPING_40 0xA0 /* 40 bit address remapping */ +#define HT_CAPTYPE_REMAPPING_64 0xA2 /* 64 bit address remapping */ +#define HT_CAPTYPE_UNITID_CLUMP 0x90 /* Unit ID clumping */ +#define HT_CAPTYPE_EXTCONF 0x98 /* Extended Configuration Space Access */ +#define HT_CAPTYPE_MSI_MAPPING 0xA8 /* MSI Mapping Capability */ +#define HT_CAPTYPE_DIRECT_ROUTE 0xB0 /* Direct routing configuration */ +#define HT_CAPTYPE_VCSET 0xB8 /* Virtual Channel configuration */ +#define HT_CAPTYPE_ERROR_RETRY 0xC0 /* Retry on error configuration */ +#define HT_CAPTYPE_GEN3 0xD0 /* Generation 3 hypertransport configuration */ +#define HT_CAPTYPE_PM 0xE0 /* Hypertransport powermanagement configuration */ + + +#endif /* LINUX_PCI_REGS_H */ diff --git a/xen/include/asm-ia64/linux/pm.h b/xen/include/asm-ia64/linux/pm.h new file mode 100644 index 0000000000..070394e846 --- /dev/null +++ b/xen/include/asm-ia64/linux/pm.h @@ -0,0 +1,279 @@ +/* + * pm.h - Power management interface + * + * Copyright (C) 2000 Andrew Henroid + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef _LINUX_PM_H +#define _LINUX_PM_H + +#ifdef __KERNEL__ + +#include +#include + +/* + * Power management requests... these are passed to pm_send_all() and friends. + * + * these functions are old and deprecated, see below. + */ +typedef int __bitwise pm_request_t; + +#define PM_SUSPEND ((__force pm_request_t) 1) /* enter D1-D3 */ +#define PM_RESUME ((__force pm_request_t) 2) /* enter D0 */ + + +/* + * Device types... these are passed to pm_register + */ +typedef int __bitwise pm_dev_t; + +#define PM_UNKNOWN_DEV ((__force pm_dev_t) 0) /* generic */ +#define PM_SYS_DEV ((__force pm_dev_t) 1) /* system device (fan, KB controller, ...) */ +#define PM_PCI_DEV ((__force pm_dev_t) 2) /* PCI device */ +#define PM_USB_DEV ((__force pm_dev_t) 3) /* USB device */ +#define PM_SCSI_DEV ((__force pm_dev_t) 4) /* SCSI device */ +#define PM_ISA_DEV ((__force pm_dev_t) 5) /* ISA device */ +#define PM_MTD_DEV ((__force pm_dev_t) 6) /* Memory Technology Device */ + +/* + * System device hardware ID (PnP) values + */ +enum +{ + PM_SYS_UNKNOWN = 0x00000000, /* generic */ + PM_SYS_KBC = 0x41d00303, /* keyboard controller */ + PM_SYS_COM = 0x41d00500, /* serial port */ + PM_SYS_IRDA = 0x41d00510, /* IRDA controller */ + PM_SYS_FDC = 0x41d00700, /* floppy controller */ + PM_SYS_VGA = 0x41d00900, /* VGA controller */ + PM_SYS_PCMCIA = 0x41d00e00, /* PCMCIA controller */ +}; + +/* + * Device identifier + */ +#define PM_PCI_ID(dev) ((dev)->bus->number << 16 | (dev)->devfn) + +/* + * Request handler callback + */ +struct pm_dev; + +typedef int (*pm_callback)(struct pm_dev *dev, pm_request_t rqst, void *data); + +/* + * Dynamic device information + */ +struct pm_dev +{ + pm_dev_t type; + unsigned long id; + pm_callback callback; + void *data; + + unsigned long flags; + unsigned long state; + unsigned long prev_state; + + struct list_head entry; +}; + +/* Functions above this comment are list-based old-style power + * managment. Please avoid using them. */ + +/* + * Callbacks for platform drivers to implement. + */ +extern void (*pm_idle)(void); +extern void (*pm_power_off)(void); + +typedef int __bitwise suspend_state_t; + +#define PM_SUSPEND_ON ((__force suspend_state_t) 0) +#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1) +#define PM_SUSPEND_MEM ((__force suspend_state_t) 3) +#define PM_SUSPEND_DISK ((__force suspend_state_t) 4) +#define PM_SUSPEND_MAX ((__force suspend_state_t) 5) + +typedef int __bitwise suspend_disk_method_t; + +#define PM_DISK_FIRMWARE ((__force suspend_disk_method_t) 1) +#define PM_DISK_PLATFORM ((__force suspend_disk_method_t) 2) +#define PM_DISK_SHUTDOWN ((__force suspend_disk_method_t) 3) +#define PM_DISK_REBOOT ((__force suspend_disk_method_t) 4) +#define PM_DISK_TEST ((__force suspend_disk_method_t) 5) +#define PM_DISK_TESTPROC ((__force suspend_disk_method_t) 6) +#define PM_DISK_MAX ((__force suspend_disk_method_t) 7) + +struct pm_ops { + suspend_disk_method_t pm_disk_mode; + int (*valid)(suspend_state_t state); + int (*prepare)(suspend_state_t state); + int (*enter)(suspend_state_t state); + int (*finish)(suspend_state_t state); +}; + +extern void pm_set_ops(struct pm_ops *); +extern struct pm_ops *pm_ops; +extern int pm_suspend(suspend_state_t state); + + +/* + * Device power management + */ + +struct device; + +typedef struct pm_message { + int event; +} pm_message_t; + +/* + * Several driver power state transitions are externally visible, affecting + * the state of pending I/O queues and (for drivers that touch hardware) + * interrupts, wakeups, DMA, and other hardware state. There may also be + * internal transitions to various low power modes, which are transparent + * to the rest of the driver stack (such as a driver that's ON gating off + * clocks which are not in active use). + * + * One transition is triggered by resume(), after a suspend() call; the + * message is implicit: + * + * ON Driver starts working again, responding to hardware events + * and software requests. The hardware may have gone through + * a power-off reset, or it may have maintained state from the + * previous suspend() which the driver will rely on while + * resuming. On most platforms, there are no restrictions on + * availability of resources like clocks during resume(). + * + * Other transitions are triggered by messages sent using suspend(). All + * these transitions quiesce the driver, so that I/O queues are inactive. + * That commonly entails turning off IRQs and DMA; there may be rules + * about how to quiesce that are specific to the bus or the device's type. + * (For example, network drivers mark the link state.) Other details may + * differ according to the message: + * + * SUSPEND Quiesce, enter a low power device state appropriate for + * the upcoming system state (such as PCI_D3hot), and enable + * wakeup events as appropriate. + * + * FREEZE Quiesce operations so that a consistent image can be saved; + * but do NOT otherwise enter a low power device state, and do + * NOT emit system wakeup events. + * + * PRETHAW Quiesce as if for FREEZE; additionally, prepare for restoring + * the system from a snapshot taken after an earlier FREEZE. + * Some drivers will need to reset their hardware state instead + * of preserving it, to ensure that it's never mistaken for the + * state which that earlier snapshot had set up. + * + * A minimally power-aware driver treats all messages as SUSPEND, fully + * reinitializes its device during resume() -- whether or not it was reset + * during the suspend/resume cycle -- and can't issue wakeup events. + * + * More power-aware drivers may also use low power states at runtime as + * well as during system sleep states like PM_SUSPEND_STANDBY. They may + * be able to use wakeup events to exit from runtime low-power states, + * or from system low-power states such as standby or suspend-to-RAM. + */ + +#define PM_EVENT_ON 0 +#define PM_EVENT_FREEZE 1 +#define PM_EVENT_SUSPEND 2 +#define PM_EVENT_PRETHAW 3 + +#define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, }) +#define PMSG_PRETHAW ((struct pm_message){ .event = PM_EVENT_PRETHAW, }) +#define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, }) +#define PMSG_ON ((struct pm_message){ .event = PM_EVENT_ON, }) + +struct dev_pm_info { + pm_message_t power_state; + unsigned can_wakeup:1; +#ifdef CONFIG_PM + unsigned should_wakeup:1; + pm_message_t prev_state; + void * saved_state; + struct device * pm_parent; + struct list_head entry; +#endif +}; + +extern void device_pm_set_parent(struct device * dev, struct device * parent); + +extern int device_power_down(pm_message_t state); +extern void device_power_up(void); +extern void device_resume(void); + +#ifdef CONFIG_PM +extern suspend_disk_method_t pm_disk_mode; + +extern int device_suspend(pm_message_t state); +extern int device_prepare_suspend(pm_message_t state); + +#define device_set_wakeup_enable(dev,val) \ + ((dev)->power.should_wakeup = !!(val)) +#define device_may_wakeup(dev) \ + (device_can_wakeup(dev) && (dev)->power.should_wakeup) + +extern int dpm_runtime_suspend(struct device *, pm_message_t); +extern void dpm_runtime_resume(struct device *); +extern void __suspend_report_result(const char *function, void *fn, int ret); + +#define suspend_report_result(fn, ret) \ + do { \ + __suspend_report_result(__FUNCTION__, fn, ret); \ + } while (0) + +#else /* !CONFIG_PM */ + +static inline int device_suspend(pm_message_t state) +{ + return 0; +} + +#define device_set_wakeup_enable(dev,val) do{}while(0) +#define device_may_wakeup(dev) (0) + +static inline int dpm_runtime_suspend(struct device * dev, pm_message_t state) +{ + return 0; +} + +static inline void dpm_runtime_resume(struct device * dev) +{ +} + +#define suspend_report_result(fn, ret) do { } while (0) + +#endif + +/* changes to device_may_wakeup take effect on the next pm state change. + * by default, devices should wakeup if they can. + */ +#define device_can_wakeup(dev) \ + ((dev)->power.can_wakeup) +#define device_init_wakeup(dev,val) \ + do { \ + device_can_wakeup(dev) = !!(val); \ + device_set_wakeup_enable(dev,val); \ + } while(0) + +#endif /* __KERNEL__ */ + +#endif /* _LINUX_PM_H */ diff --git a/xen/include/asm-ia64/linux/sysfs.h b/xen/include/asm-ia64/linux/sysfs.h new file mode 100644 index 0000000000..6d5c43d31d --- /dev/null +++ b/xen/include/asm-ia64/linux/sysfs.h @@ -0,0 +1,206 @@ +/* + * sysfs.h - definitions for the device driver filesystem + * + * Copyright (c) 2001,2002 Patrick Mochel + * Copyright (c) 2004 Silicon Graphics, Inc. + * + * Please see Documentation/filesystems/sysfs.txt for more information. + */ + +#ifndef _SYSFS_H_ +#define _SYSFS_H_ + +#include +#include + +struct kobject; +struct module; + +struct attribute { + const char * name; + struct module * owner; + mode_t mode; +}; + +struct attribute_group { + const char * name; + struct attribute ** attrs; +}; + + + +/** + * Use these macros to make defining attributes easier. See include/linux/device.h + * for examples.. + */ + +#define __ATTR(_name,_mode,_show,_store) { \ + .attr = {.name = __stringify(_name), .mode = _mode, .owner = THIS_MODULE }, \ + .show = _show, \ + .store = _store, \ +} + +#define __ATTR_RO(_name) { \ + .attr = { .name = __stringify(_name), .mode = 0444, .owner = THIS_MODULE }, \ + .show = _name##_show, \ +} + +#define __ATTR_NULL { .attr = { .name = NULL } } + +#define attr_name(_attr) (_attr).attr.name + +struct vm_area_struct; + +struct bin_attribute { + struct attribute attr; + size_t size; + void *private; + ssize_t (*read)(struct kobject *, char *, loff_t, size_t); + ssize_t (*write)(struct kobject *, char *, loff_t, size_t); + int (*mmap)(struct kobject *, struct bin_attribute *attr, + struct vm_area_struct *vma); +}; + +struct sysfs_ops { + ssize_t (*show)(struct kobject *, struct attribute *,char *); + ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); +}; + +struct sysfs_dirent { + atomic_t s_count; + struct list_head s_sibling; + struct list_head s_children; + void * s_element; + int s_type; + umode_t s_mode; + struct dentry * s_dentry; + struct iattr * s_iattr; + atomic_t s_event; +}; + +#define SYSFS_ROOT 0x0001 +#define SYSFS_DIR 0x0002 +#define SYSFS_KOBJ_ATTR 0x0004 +#define SYSFS_KOBJ_BIN_ATTR 0x0008 +#define SYSFS_KOBJ_LINK 0x0020 +#define SYSFS_NOT_PINNED (SYSFS_KOBJ_ATTR | SYSFS_KOBJ_BIN_ATTR | SYSFS_KOBJ_LINK) + +#ifdef CONFIG_SYSFS + +extern int __must_check +sysfs_create_dir(struct kobject *); + +extern void +sysfs_remove_dir(struct kobject *); + +extern int __must_check +sysfs_rename_dir(struct kobject *, const char *new_name); + +extern int __must_check +sysfs_create_file(struct kobject *, const struct attribute *); + +extern int __must_check +sysfs_update_file(struct kobject *, const struct attribute *); + +extern int __must_check +sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode); + +extern void +sysfs_remove_file(struct kobject *, const struct attribute *); + +extern int __must_check +sysfs_create_link(struct kobject * kobj, struct kobject * target, const char * name); + +extern void +sysfs_remove_link(struct kobject *, const char * name); + +int __must_check sysfs_create_bin_file(struct kobject *kobj, + struct bin_attribute *attr); +void sysfs_remove_bin_file(struct kobject *kobj, struct bin_attribute *attr); + +int __must_check sysfs_create_group(struct kobject *, + const struct attribute_group *); +void sysfs_remove_group(struct kobject *, const struct attribute_group *); +void sysfs_notify(struct kobject * k, char *dir, char *attr); + +extern int __must_check sysfs_init(void); + +#else /* CONFIG_SYSFS */ + +static inline int sysfs_create_dir(struct kobject * k) +{ + return 0; +} + +static inline void sysfs_remove_dir(struct kobject * k) +{ + ; +} + +static inline int sysfs_rename_dir(struct kobject * k, const char *new_name) +{ + return 0; +} + +static inline int sysfs_create_file(struct kobject * k, const struct attribute * a) +{ + return 0; +} + +static inline int sysfs_update_file(struct kobject * k, const struct attribute * a) +{ + return 0; +} +static inline int sysfs_chmod_file(struct kobject *kobj, struct attribute *attr, mode_t mode) +{ + return 0; +} + +static inline void sysfs_remove_file(struct kobject * k, const struct attribute * a) +{ + ; +} + +static inline int sysfs_create_link(struct kobject * k, struct kobject * t, const char * n) +{ + return 0; +} + +static inline void sysfs_remove_link(struct kobject * k, const char * name) +{ + ; +} + + +static inline int sysfs_create_bin_file(struct kobject * k, struct bin_attribute * a) +{ + return 0; +} + +static inline int sysfs_remove_bin_file(struct kobject * k, struct bin_attribute * a) +{ + return 0; +} + +static inline int sysfs_create_group(struct kobject * k, const struct attribute_group *g) +{ + return 0; +} + +static inline void sysfs_remove_group(struct kobject * k, const struct attribute_group * g) +{ + ; +} + +static inline void sysfs_notify(struct kobject * k, char *dir, char *attr) +{ +} + +static inline int __must_check sysfs_init(void) +{ + return 0; +} + +#endif /* CONFIG_SYSFS */ + +#endif /* _SYSFS_H_ */ From 92ddac9d84e6006d01296de3bb07d9349b71e88d Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 13 Dec 2006 11:11:32 -0700 Subject: [PATCH 002/570] [IA64] add new dummy files needed to build sn2 and machvec support Signed-off-by: Jes Sorensen --- xen/include/asm-ia64/linux-null/linux/dmapool.h | 1 + xen/include/asm-ia64/linux-null/linux/rwsem.h | 1 + 2 files changed, 2 insertions(+) create mode 100644 xen/include/asm-ia64/linux-null/linux/dmapool.h create mode 100644 xen/include/asm-ia64/linux-null/linux/rwsem.h diff --git a/xen/include/asm-ia64/linux-null/linux/dmapool.h b/xen/include/asm-ia64/linux-null/linux/dmapool.h new file mode 100644 index 0000000000..29f4f4cd69 --- /dev/null +++ b/xen/include/asm-ia64/linux-null/linux/dmapool.h @@ -0,0 +1 @@ +/* This file is intentionally left empty. */ diff --git a/xen/include/asm-ia64/linux-null/linux/rwsem.h b/xen/include/asm-ia64/linux-null/linux/rwsem.h new file mode 100644 index 0000000000..29f4f4cd69 --- /dev/null +++ b/xen/include/asm-ia64/linux-null/linux/rwsem.h @@ -0,0 +1 @@ +/* This file is intentionally left empty. */ From be090840c2959a021aa95f5077b799d9e65fabca Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 13 Dec 2006 11:18:16 -0700 Subject: [PATCH 003/570] [IA64] fix build with sn2 and machvec support Initial changes to make tree build again after applying new files for sn2 and machvec support, without actually enabling the new features Signed-off-by: Jes Sorensen --- xen/include/asm-ia64/linux-xen/asm/sn/intr.h | 6 ++++++ xen/include/asm-ia64/linux-xen/asm/sn/nodepda.h | 4 ++++ xen/include/asm-ia64/linux-xen/asm/sn/types.h | 2 ++ xen/include/asm-ia64/linux-xen/asm/types.h | 8 ++++++++ 4 files changed, 20 insertions(+) diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/intr.h b/xen/include/asm-ia64/linux-xen/asm/sn/intr.h index 12b54ddb06..5e7ef5c993 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/intr.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/intr.h @@ -9,7 +9,11 @@ #ifndef _ASM_IA64_SN_INTR_H #define _ASM_IA64_SN_INTR_H +#ifndef XEN #include +#else +#include +#endif #include #define SGI_UART_VECTOR 0xe9 @@ -51,7 +55,9 @@ struct sn_irq_info { int irq_flags; /* flags */ int irq_share_cnt; /* num devices sharing IRQ */ struct list_head list; /* list of sn_irq_info structs */ +#ifndef XEN struct rcu_head rcu; /* rcu callback list */ +#endif }; extern void sn_send_IPI_phys(int, long, int, int); diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/nodepda.h b/xen/include/asm-ia64/linux-xen/asm/sn/nodepda.h index 6f6d69e39f..ffa4302423 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/nodepda.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/nodepda.h @@ -13,7 +13,9 @@ #include #include #include +#ifndef XEN #include +#endif /* * NUMA Node-Specific Data structures are defined in this file. @@ -38,12 +40,14 @@ struct phys_cpuid { struct nodepda_s { void *pdinfo; /* Platform-dependent per-node info */ +#ifndef XEN /* * The BTEs on this node are shared by the local cpus */ struct bteinfo_s bte_if[MAX_BTES_PER_NODE]; /* Virtual Interface */ struct timer_list bte_recovery_timer; spinlock_t bte_recovery_lock; +#endif /* * Array of pointers to the nodepdas for each node. diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/types.h b/xen/include/asm-ia64/linux-xen/asm/sn/types.h index 8e04ee211e..6df228178a 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/types.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/types.h @@ -20,7 +20,9 @@ typedef unsigned char slotid_t; /* slot (blade) within module */ typedef unsigned char slabid_t; /* slab (asic) within slot */ typedef u64 nic_t; typedef unsigned long iopaddr_t; +#ifndef XEN typedef unsigned long paddr_t; +#endif typedef short cnodeid_t; #endif /* _ASM_IA64_SN_TYPES_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/types.h b/xen/include/asm-ia64/linux-xen/asm/types.h index d2c04d3f6a..3dcfa34ae7 100644 --- a/xen/include/asm-ia64/linux-xen/asm/types.h +++ b/xen/include/asm-ia64/linux-xen/asm/types.h @@ -74,6 +74,14 @@ typedef unsigned short kmem_bufctl_t; #ifdef XEN #include + +#ifndef __ASSEMBLY__ +typedef unsigned int gfp_t; +typedef u64 resource_size_t; +typedef u32 dev_t; +typedef unsigned int mode_t; +#define THIS_MODULE NULL +#endif #endif #endif /* _ASM_IA64_TYPES_H */ From 2e23706a80c21d18fce9342fe0e13eb8b4e2bba7 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 13 Dec 2006 12:23:53 -0700 Subject: [PATCH 004/570] [IA64] Update sn_sal.h to 2.6.19 Signed-off-by: Alex Williamson --- .../asm-ia64/linux-xen/asm/sn/README.origin | 1 + .../asm-ia64/linux-xen/asm/sn/sn_sal.h | 371 +++++++++++++----- 2 files changed, 270 insertions(+), 102 deletions(-) diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/README.origin b/xen/include/asm-ia64/linux-xen/asm/sn/README.origin index 762d1f5a9c..3adc60fea0 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/README.origin +++ b/xen/include/asm-ia64/linux-xen/asm/sn/README.origin @@ -13,4 +13,5 @@ io.h -> linux/include/asm-ia64/sn/io.h nodepda.h -> linux/include/asm-ia64/sn/nodepda.h pcibr_provider.h -> linux/include/asm-ia64/sn/pcibr_provider.h rw_mmr.h -> linux/include/asm-ia64/sn/rw_mmr.h +sn_sal.h -> linux/include/asm-ia64/sn/sn_sal.h types.h -> linux/include/asm-ia64/sn/types.h diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/sn_sal.h b/xen/include/asm-ia64/linux-xen/asm/sn/sn_sal.h index 34f669ad55..a87e6592b2 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/sn_sal.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/sn_sal.h @@ -8,16 +8,16 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (c) 2000-2004 Silicon Graphics, Inc. All rights reserved. + * Copyright (c) 2000-2006 Silicon Graphics, Inc. All rights reserved. */ -#include #include #include #include #include #include +#include // SGI Specific Calls #define SN_SAL_POD_MODE 0x02000001 @@ -34,8 +34,8 @@ #define SN_SAL_PRINT_ERROR 0x02000012 #define SN_SAL_SET_ERROR_HANDLING_FEATURES 0x0200001a // reentrant #define SN_SAL_GET_FIT_COMPT 0x0200001b // reentrant -#define SN_SAL_GET_HUB_INFO 0x0200001c #define SN_SAL_GET_SAPIC_INFO 0x0200001d +#define SN_SAL_GET_SN_INFO 0x0200001e #define SN_SAL_CONSOLE_PUTC 0x02000021 #define SN_SAL_CONSOLE_GETC 0x02000022 #define SN_SAL_CONSOLE_PUTS 0x02000023 @@ -46,6 +46,7 @@ #define SN_SAL_CONSOLE_PUTB 0x02000028 #define SN_SAL_CONSOLE_XMIT_CHARS 0x0200002a #define SN_SAL_CONSOLE_READC 0x0200002b +#define SN_SAL_SYSCTL_OP 0x02000030 #define SN_SAL_SYSCTL_MODID_GET 0x02000031 #define SN_SAL_SYSCTL_GET 0x02000032 #define SN_SAL_SYSCTL_IOBRICK_MODULE_GET 0x02000033 @@ -54,7 +55,7 @@ #define SN_SAL_BUS_CONFIG 0x02000037 #define SN_SAL_SYS_SERIAL_GET 0x02000038 #define SN_SAL_PARTITION_SERIAL_GET 0x02000039 -#define SN_SAL_SYSCTL_PARTITION_GET 0x0200003a +#define SN_SAL_SYSCTL_PARTITION_GET 0x0200003a #define SN_SAL_SYSTEM_POWER_DOWN 0x0200003b #define SN_SAL_GET_MASTER_BASEIO_NASID 0x0200003c #define SN_SAL_COHERENCE 0x0200003d @@ -63,19 +64,28 @@ #define SN_SAL_SYSCTL_IOBRICK_PCI_OP 0x02000042 // reentrant #define SN_SAL_IROUTER_OP 0x02000043 +#define SN_SAL_SYSCTL_EVENT 0x02000044 #define SN_SAL_IOIF_INTERRUPT 0x0200004a #define SN_SAL_HWPERF_OP 0x02000050 // lock #define SN_SAL_IOIF_ERROR_INTERRUPT 0x02000051 - +#define SN_SAL_IOIF_PCI_SAFE 0x02000052 #define SN_SAL_IOIF_SLOT_ENABLE 0x02000053 #define SN_SAL_IOIF_SLOT_DISABLE 0x02000054 #define SN_SAL_IOIF_GET_HUBDEV_INFO 0x02000055 #define SN_SAL_IOIF_GET_PCIBUS_INFO 0x02000056 #define SN_SAL_IOIF_GET_PCIDEV_INFO 0x02000057 -#define SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST 0x02000058 +#define SN_SAL_IOIF_GET_WIDGET_DMAFLUSH_LIST 0x02000058 // deprecated +#define SN_SAL_IOIF_GET_DEVICE_DMAFLUSH_LIST 0x0200005a #define SN_SAL_HUB_ERROR_INTERRUPT 0x02000060 +#define SN_SAL_BTE_RECOVER 0x02000061 +#define SN_SAL_RESERVED_DO_NOT_USE 0x02000062 +#define SN_SAL_IOIF_GET_PCI_TOPOLOGY 0x02000064 +#define SN_SAL_GET_PROM_FEATURE_SET 0x02000065 +#define SN_SAL_SET_OS_FEATURE_SET 0x02000066 +#define SN_SAL_INJECT_ERROR 0x02000067 +#define SN_SAL_SET_CPU_NUMBER 0x02000068 /* * Service-specific constants @@ -94,6 +104,13 @@ #define SAL_INTR_ALLOC 1 #define SAL_INTR_FREE 2 +/* + * operations available on the generic SN_SAL_SYSCTL_OP + * runtime service + */ +#define SAL_SYSCTL_OP_IOBOARD 0x0001 /* retrieve board type */ +#define SAL_SYSCTL_OP_TIO_JLCK_RST 0x0002 /* issue TIO clock reset */ + /* * IRouter (i.e. generalized system controller) operations */ @@ -112,6 +129,13 @@ #define SAL_IROUTER_INTR_XMIT SAL_CONSOLE_INTR_XMIT #define SAL_IROUTER_INTR_RECV SAL_CONSOLE_INTR_RECV +/* + * Error Handling Features + */ +#define SAL_ERR_FEAT_MCA_SLV_TO_OS_INIT_SLV 0x1 // obsolete +#define SAL_ERR_FEAT_LOG_SBES 0x2 // obsolete +#define SAL_ERR_FEAT_MFR_OVERRIDE 0x4 +#define SAL_ERR_FEAT_SBE_THRESHOLD 0xffff0000 /* * SAL Error Codes @@ -122,45 +146,26 @@ #define SALRET_INVALID_ARG (-2) #define SALRET_ERROR (-3) +#define SN_SAL_FAKE_PROM 0x02009999 #ifndef XEN /** - * sn_sal_rev_major - get the major SGI SAL revision number - * - * The SGI PROM stores its version in sal_[ab]_rev_(major|minor). - * This routine simply extracts the major value from the - * @ia64_sal_systab structure constructed by ia64_sal_init(). - */ -static inline int -sn_sal_rev_major(void) + * sn_sal_revision - get the SGI SAL revision number + * + * The SGI PROM stores its version in the sal_[ab]_rev_(major|minor). + * This routine simply extracts the major and minor values and + * presents them in a u32 format. + * + * For example, version 4.05 would be represented at 0x0405. + */ +static inline u32 +sn_sal_rev(void) { - struct ia64_sal_systab *systab = efi.sal_systab; + struct ia64_sal_systab *systab = __va(efi.sal_systab); - return (int)systab->sal_b_rev_major; + return (u32)(systab->sal_b_rev_major << 8 | systab->sal_b_rev_minor); } -/** - * sn_sal_rev_minor - get the minor SGI SAL revision number - * - * The SGI PROM stores its version in sal_[ab]_rev_(major|minor). - * This routine simply extracts the minor value from the - * @ia64_sal_systab structure constructed by ia64_sal_init(). - */ -static inline int -sn_sal_rev_minor(void) -{ - struct ia64_sal_systab *systab = efi.sal_systab; - - return (int)systab->sal_b_rev_minor; -} - -/* - * Specify the minimum PROM revsion required for this kernel. - * Note that they're stored in hex format... - */ -#define SN_SAL_MIN_MAJOR 0x4 /* SN2 kernels need at least PROM 4.0 */ -#define SN_SAL_MIN_MINOR 0x0 - /* * Returns the master console nasid, if the call fails, return an illegal * value. @@ -205,26 +210,16 @@ ia64_sn_get_master_baseio_nasid(void) return ret_stuff.v0; } -static inline char * +static inline void * ia64_sn_get_klconfig_addr(nasid_t nasid) { struct ia64_sal_retval ret_stuff; - int cnodeid; - cnodeid = nasid_to_cnodeid(nasid); ret_stuff.status = 0; ret_stuff.v0 = 0; ret_stuff.v1 = 0; ret_stuff.v2 = 0; SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0); - - /* - * We should panic if a valid cnode nasid does not produce - * a klconfig address. - */ - if (ret_stuff.status != 0) { - panic("ia64_sn_get_klconfig_addr: Returned error %lx\n", ret_stuff.status); - } return ret_stuff.v0 ? __va(ret_stuff.v0) : NULL; } #endif /* !XEN */ @@ -281,7 +276,7 @@ ia64_sn_console_putc(char ch) ret_stuff.v0 = 0; ret_stuff.v1 = 0; ret_stuff.v2 = 0; - SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTC, (uint64_t)ch, 0, 0, 0, 0, 0, 0); + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTC, (u64)ch, 0, 0, 0, 0, 0, 0); return ret_stuff.status; } @@ -298,7 +293,7 @@ ia64_sn_console_putb(const char *buf, int len) ret_stuff.v0 = 0; ret_stuff.v1 = 0; ret_stuff.v2 = 0; - SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTB, (uint64_t)buf, (uint64_t)len, 0, 0, 0, 0, 0); + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTB, (u64)buf, (u64)len, 0, 0, 0, 0, 0); if ( ret_stuff.status == 0 ) { return ret_stuff.v0; @@ -319,7 +314,7 @@ ia64_sn_plat_specific_err_print(int (*hook)(const char*, ...), char *rec) ret_stuff.v0 = 0; ret_stuff.v1 = 0; ret_stuff.v2 = 0; - SAL_CALL_REENTRANT(ret_stuff, SN_SAL_PRINT_ERROR, (uint64_t)hook, (uint64_t)rec, 0, 0, 0, 0, 0); + SAL_CALL_REENTRANT(ret_stuff, SN_SAL_PRINT_ERROR, (u64)hook, (u64)rec, 0, 0, 0, 0, 0); return ret_stuff.status; } @@ -341,6 +336,25 @@ ia64_sn_plat_cpei_handler(void) return ret_stuff.status; } +/* + * Set Error Handling Features (Obsolete) + */ +static inline u64 +ia64_sn_plat_set_error_handling_features(void) +{ + struct ia64_sal_retval ret_stuff; + + ret_stuff.status = 0; + ret_stuff.v0 = 0; + ret_stuff.v1 = 0; + ret_stuff.v2 = 0; + SAL_CALL_REENTRANT(ret_stuff, SN_SAL_SET_ERROR_HANDLING_FEATURES, + SAL_ERR_FEAT_LOG_SBES, + 0, 0, 0, 0, 0, 0); + + return ret_stuff.status; +} + /* * Checks for console input. */ @@ -388,7 +402,7 @@ ia64_sn_console_intr_status(void) * Enable an interrupt on the SAL console device. */ static inline void -ia64_sn_console_intr_enable(uint64_t intr) +ia64_sn_console_intr_enable(u64 intr) { struct ia64_sal_retval ret_stuff; @@ -405,7 +419,7 @@ ia64_sn_console_intr_enable(uint64_t intr) * Disable an interrupt on the SAL console device. */ static inline void -ia64_sn_console_intr_disable(uint64_t intr) +ia64_sn_console_intr_disable(u64 intr) { struct ia64_sal_retval ret_stuff; @@ -431,7 +445,7 @@ ia64_sn_console_xmit_chars(char *buf, int len) ret_stuff.v1 = 0; ret_stuff.v2 = 0; SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_XMIT_CHARS, - (uint64_t)buf, (uint64_t)len, + (u64)buf, (u64)len, 0, 0, 0, 0, 0); if (ret_stuff.status == 0) { @@ -472,7 +486,7 @@ static inline u64 ia64_sn_pod_mode(void) { struct ia64_sal_retval isrv; - SAL_CALL(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0); + SAL_CALL_REENTRANT(isrv, SN_SAL_POD_MODE, 0, 0, 0, 0, 0, 0, 0); if (isrv.status) return 0; return isrv.v0; @@ -557,7 +571,8 @@ static inline u64 ia64_sn_partition_serial_get(void) { struct ia64_sal_retval ret_stuff; - SAL_CALL(ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0, 0, 0, 0, 0, 0, 0); + ia64_sal_oemcall_reentrant(&ret_stuff, SN_SAL_PARTITION_SERIAL_GET, 0, + 0, 0, 0, 0, 0, 0); if (ret_stuff.status != 0) return 0; return ret_stuff.v0; @@ -565,11 +580,10 @@ ia64_sn_partition_serial_get(void) static inline u64 sn_partition_serial_number_val(void) { - if (sn_partition_serial_number) { - return(sn_partition_serial_number); - } else { - return(sn_partition_serial_number = ia64_sn_partition_serial_get()); + if (unlikely(sn_partition_serial_number == 0)) { + sn_partition_serial_number = ia64_sn_partition_serial_get(); } + return sn_partition_serial_number; } /* @@ -581,25 +595,38 @@ ia64_sn_sysctl_partition_get(nasid_t nasid) { struct ia64_sal_retval ret_stuff; SAL_CALL(ret_stuff, SN_SAL_SYSCTL_PARTITION_GET, nasid, - 0, 0, 0, 0, 0, 0); + 0, 0, 0, 0, 0, 0); if (ret_stuff.status != 0) - return INVALID_PARTID; + return -1; return ((partid_t)ret_stuff.v0); } /* - * Returns the partition id of the current processor. + * Returns the physical address of the partition's reserved page through + * an iterative number of calls. + * + * On first call, 'cookie' and 'len' should be set to 0, and 'addr' + * set to the nasid of the partition whose reserved page's address is + * being sought. + * On subsequent calls, pass the values, that were passed back on the + * previous call. + * + * While the return status equals SALRET_MORE_PASSES, keep calling + * this function after first copying 'len' bytes starting at 'addr' + * into 'buf'. Once the return status equals SALRET_OK, 'addr' will + * be the physical address of the partition's reserved page. If the + * return status equals neither of these, an error as occurred. */ - -extern partid_t sn_partid; - -static inline partid_t -sn_local_partid(void) { - if (sn_partid < 0) { - return (sn_partid = ia64_sn_sysctl_partition_get(cpuid_to_nasid(smp_processor_id()))); - } else { - return sn_partid; - } +static inline s64 +sn_partition_reserved_page_pa(u64 buf, u64 *cookie, u64 *addr, u64 *len) +{ + struct ia64_sal_retval rv; + ia64_sal_oemcall_reentrant(&rv, SN_SAL_GET_PARTITION_ADDR, *cookie, + *addr, buf, *len, 0, 0, 0); + *cookie = rv.v0; + *addr = rv.v1; + *len = rv.v2; + return rv.status; } /* @@ -621,8 +648,8 @@ static inline int sn_register_xp_addr_region(u64 paddr, u64 len, int operation) { struct ia64_sal_retval ret_stuff; - SAL_CALL(ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len, (u64)operation, - 0, 0, 0, 0); + ia64_sal_oemcall(&ret_stuff, SN_SAL_XP_ADDR_REGION, paddr, len, + (u64)operation, 0, 0, 0, 0); return ret_stuff.status; } @@ -646,8 +673,8 @@ sn_register_nofault_code(u64 start_addr, u64 end_addr, u64 return_addr, } else { call = SN_SAL_NO_FAULT_ZONE_PHYSICAL; } - SAL_CALL(ret_stuff, call, start_addr, end_addr, return_addr, (u64)1, - 0, 0, 0); + ia64_sal_oemcall(&ret_stuff, call, start_addr, end_addr, return_addr, + (u64)1, 0, 0, 0); return ret_stuff.status; } @@ -668,8 +695,8 @@ static inline int sn_change_coherence(u64 *new_domain, u64 *old_domain) { struct ia64_sal_retval ret_stuff; - SAL_CALL(ret_stuff, SN_SAL_COHERENCE, new_domain, old_domain, 0, 0, - 0, 0, 0); + ia64_sal_oemcall(&ret_stuff, SN_SAL_COHERENCE, (u64)new_domain, + (u64)old_domain, 0, 0, 0, 0, 0); return ret_stuff.status; } @@ -682,16 +709,9 @@ static inline int sn_change_memprotect(u64 paddr, u64 len, u64 perms, u64 *nasid_array) { struct ia64_sal_retval ret_stuff; - int cnodeid; - unsigned long irq_flags; - cnodeid = nasid_to_cnodeid(get_node_number(paddr)); - // spin_lock(&NODEPDA(cnodeid)->bist_lock); - local_irq_save(irq_flags); - SAL_CALL_NOLOCK(ret_stuff, SN_SAL_MEMPROTECT, paddr, len, nasid_array, - perms, 0, 0, 0); - local_irq_restore(irq_flags); - // spin_unlock(&NODEPDA(cnodeid)->bist_lock); + ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_MEMPROTECT, paddr, len, + (u64)nasid_array, perms, 0, 0, 0); return ret_stuff.status; } #define SN_MEMPROT_ACCESS_CLASS_0 0x14a080 @@ -709,7 +729,8 @@ ia64_sn_power_down(void) { struct ia64_sal_retval ret_stuff; SAL_CALL(ret_stuff, SN_SAL_SYSTEM_POWER_DOWN, 0, 0, 0, 0, 0, 0, 0); - while(1); + while(1) + cpu_relax(); /* never returns */ } @@ -851,6 +872,58 @@ ia64_sn_irtr_intr_disable(nasid_t nasid, int subch, u64 intr) return (int) rv.v0; } +/* + * Set up a node as the point of contact for system controller + * environmental event delivery. + */ +static inline int +ia64_sn_sysctl_event_init(nasid_t nasid) +{ + struct ia64_sal_retval rv; + SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_EVENT, (u64) nasid, + 0, 0, 0, 0, 0, 0); + return (int) rv.v0; +} + +/* + * Ask the system controller on the specified nasid to reset + * the CX corelet clock. Only valid on TIO nodes. + */ +static inline int +ia64_sn_sysctl_tio_clock_reset(nasid_t nasid) +{ + struct ia64_sal_retval rv; + SAL_CALL_REENTRANT(rv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_TIO_JLCK_RST, + nasid, 0, 0, 0, 0, 0); + if (rv.status != 0) + return (int)rv.status; + if (rv.v0 != 0) + return (int)rv.v0; + + return 0; +} + +/* + * Get the associated ioboard type for a given nasid. + */ +static inline s64 +ia64_sn_sysctl_ioboard_get(nasid_t nasid, u16 *ioboard) +{ + struct ia64_sal_retval isrv; + SAL_CALL_REENTRANT(isrv, SN_SAL_SYSCTL_OP, SAL_SYSCTL_OP_IOBOARD, + nasid, 0, 0, 0, 0, 0); + if (isrv.v0 != 0) { + *ioboard = isrv.v0; + return isrv.status; + } + if (isrv.v1 != 0) { + *ioboard = isrv.v1; + return isrv.status; + } + + return isrv.status; +} + /** * ia64_sn_get_fit_compt - read a FIT entry from the PROM header * @nasid: NASID of node to read @@ -938,15 +1011,24 @@ ia64_sn_get_sapic_info(int sapicid, int *nasid, int *subnode, int *slice) /* * Returns information about the HUB/SHUB. * In: - * arg0 - SN_SAL_GET_HUB_INFO + * arg0 - SN_SAL_GET_SN_INFO * arg1 - 0 (other values reserved for future use) * Out: - * v0 - shub type (0=shub1, 1=shub2) - * v1 - masid mask (ex., 0x7ff for 11 bit nasid) - * v2 - bit position of low nasid bit + * v0 + * [7:0] - shub type (0=shub1, 1=shub2) + * [15:8] - Log2 max number of nodes in entire system (includes + * C-bricks, I-bricks, etc) + * [23:16] - Log2 of nodes per sharing domain + * [31:24] - partition ID + * [39:32] - coherency_id + * [47:40] - regionsize + * v1 + * [15:0] - nasid mask (ex., 0x7ff for 11 bit nasid) + * [23:15] - bit position of low nasid bit */ static inline u64 -ia64_sn_get_hub_info(int fc, u64 *arg1, u64 *arg2, u64 *arg3) +ia64_sn_get_sn_info(int fc, u8 *shubtype, u16 *nasid_bitmask, u8 *nasid_shift, + u8 *systemsize, u8 *sharing_domain_size, u8 *partid, u8 *coher, u8 *reg) { struct ia64_sal_retval ret_stuff; @@ -954,13 +1036,22 @@ ia64_sn_get_hub_info(int fc, u64 *arg1, u64 *arg2, u64 *arg3) ret_stuff.v0 = 0; ret_stuff.v1 = 0; ret_stuff.v2 = 0; - SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_HUB_INFO, fc, 0, 0, 0, 0, 0, 0); + SAL_CALL_NOLOCK(ret_stuff, SN_SAL_GET_SN_INFO, fc, 0, 0, 0, 0, 0, 0); /***** BEGIN HACK - temp til old proms no longer supported ********/ if (ret_stuff.status == SALRET_NOT_IMPLEMENTED) { - if (arg1) *arg1 = 0; - if (arg2) *arg2 = 0x7ff; - if (arg3) *arg3 = 38; + int nasid = get_sapicid() & 0xfff; +#define SH_SHUB_ID_NODES_PER_BIT_MASK 0x001f000000000000UL +#define SH_SHUB_ID_NODES_PER_BIT_SHFT 48 + if (shubtype) *shubtype = 0; + if (nasid_bitmask) *nasid_bitmask = 0x7ff; + if (nasid_shift) *nasid_shift = 38; + if (systemsize) *systemsize = 10; + if (sharing_domain_size) *sharing_domain_size = 8; + if (partid) *partid = ia64_sn_sysctl_partition_get(nasid); + if (coher) *coher = nasid >> 9; + if (reg) *reg = (HUB_L((u64 *) LOCAL_MMR_ADDR(SH1_SHUB_ID)) & SH_SHUB_ID_NODES_PER_BIT_MASK) >> + SH_SHUB_ID_NODES_PER_BIT_SHFT; return 0; } /***** END HACK *******/ @@ -968,9 +1059,14 @@ ia64_sn_get_hub_info(int fc, u64 *arg1, u64 *arg2, u64 *arg3) if (ret_stuff.status < 0) return ret_stuff.status; - if (arg1) *arg1 = ret_stuff.v0; - if (arg2) *arg2 = ret_stuff.v1; - if (arg3) *arg3 = ret_stuff.v2; + if (shubtype) *shubtype = ret_stuff.v0 & 0xff; + if (systemsize) *systemsize = (ret_stuff.v0 >> 8) & 0xff; + if (sharing_domain_size) *sharing_domain_size = (ret_stuff.v0 >> 16) & 0xff; + if (partid) *partid = (ret_stuff.v0 >> 24) & 0xff; + if (coher) *coher = (ret_stuff.v0 >> 32) & 0xff; + if (reg) *reg = (ret_stuff.v0 >> 40) & 0xff; + if (nasid_bitmask) *nasid_bitmask = (ret_stuff.v1 & 0xffff); + if (nasid_shift) *nasid_shift = (ret_stuff.v1 >> 16) & 0xff; return 0; } @@ -991,4 +1087,75 @@ ia64_sn_hwperf_op(nasid_t nasid, u64 opcode, u64 a0, u64 a1, u64 a2, return (int) rv.status; } #endif /* !XEN */ + +static inline int +ia64_sn_ioif_get_pci_topology(u64 buf, u64 len) +{ + struct ia64_sal_retval rv; + SAL_CALL_NOLOCK(rv, SN_SAL_IOIF_GET_PCI_TOPOLOGY, buf, len, 0, 0, 0, 0, 0); + return (int) rv.status; +} + +/* + * BTE error recovery is implemented in SAL + */ +static inline int +ia64_sn_bte_recovery(nasid_t nasid) +{ + struct ia64_sal_retval rv; + + rv.status = 0; + SAL_CALL_NOLOCK(rv, SN_SAL_BTE_RECOVER, (u64)nasid, 0, 0, 0, 0, 0, 0); + if (rv.status == SALRET_NOT_IMPLEMENTED) + return 0; + return (int) rv.status; +} + +static inline int +ia64_sn_is_fake_prom(void) +{ + struct ia64_sal_retval rv; + SAL_CALL_NOLOCK(rv, SN_SAL_FAKE_PROM, 0, 0, 0, 0, 0, 0, 0); + return (rv.status == 0); +} + +static inline int +ia64_sn_get_prom_feature_set(int set, unsigned long *feature_set) +{ + struct ia64_sal_retval rv; + + SAL_CALL_NOLOCK(rv, SN_SAL_GET_PROM_FEATURE_SET, set, 0, 0, 0, 0, 0, 0); + if (rv.status != 0) + return rv.status; + *feature_set = rv.v0; + return 0; +} + +static inline int +ia64_sn_set_os_feature(int feature) +{ + struct ia64_sal_retval rv; + + SAL_CALL_NOLOCK(rv, SN_SAL_SET_OS_FEATURE_SET, feature, 0, 0, 0, 0, 0, 0); + return rv.status; +} + +static inline int +sn_inject_error(u64 paddr, u64 *data, u64 *ecc) +{ + struct ia64_sal_retval ret_stuff; + + ia64_sal_oemcall_nolock(&ret_stuff, SN_SAL_INJECT_ERROR, paddr, (u64)data, + (u64)ecc, 0, 0, 0, 0); + return ret_stuff.status; +} + +static inline int +ia64_sn_set_cpu_number(int cpu) +{ + struct ia64_sal_retval rv; + + SAL_CALL_NOLOCK(rv, SN_SAL_SET_CPU_NUMBER, cpu, 0, 0, 0, 0, 0, 0); + return rv.status; +} #endif /* _ASM_IA64_SN_SN_SAL_H */ From d158f679779198c5e2999cc036377763d386826e Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 13 Dec 2006 15:22:25 -0700 Subject: [PATCH 005/570] [IA64] Updates to new files to be able to build sn2 and machvec support. Signed-off-by: Jes Sorensen --- xen/arch/ia64/linux-xen/sn/kernel/io_init.c | 41 +++++ xen/arch/ia64/linux-xen/sn/kernel/iomv.c | 6 + xen/arch/ia64/linux-xen/sn/kernel/irq.c | 94 ++++++++++ xen/arch/ia64/linux-xen/sn/kernel/setup.c | 49 ++++++ xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c | 56 +++++- xen/arch/ia64/xen/irq.c | 7 + xen/include/asm-ia64/config.h | 23 +-- .../asm-ia64/linux-xen/asm/machvec_dig.h | 26 +++ .../asm-ia64/linux-xen/asm/machvec_hpzx1.h | 25 +++ .../asm-ia64/linux-xen/asm/machvec_sn2.h | 30 ++++ xen/include/asm-ia64/linux-xen/asm/page.h | 10 ++ xen/include/asm-ia64/linux-xen/asm/pci.h | 11 ++ xen/include/asm-ia64/linux-xen/asm/sn/addrs.h | 2 +- xen/include/asm-ia64/linux-xen/asm/sn/arch.h | 11 +- .../asm-ia64/linux-xen/asm/sn/hubdev.h | 4 + xen/include/asm-ia64/linux-xen/asm/sn/io.h | 7 + .../linux-xen/asm/sn/pcibr_provider.h | 4 + .../asm-ia64/linux-xen/asm/sn/rw_mmr.h | 4 + xen/include/asm-ia64/linux-xen/asm/system.h | 1 + xen/include/asm-ia64/linux-xen/linux/device.h | 16 ++ .../asm-ia64/linux-xen/linux/kobject.h | 4 + xen/include/asm-ia64/linux-xen/linux/pci.h | 3 + xen/include/asm-ia64/linux/asm/pci.h | 161 ------------------ 23 files changed, 420 insertions(+), 175 deletions(-) delete mode 100644 xen/include/asm-ia64/linux/asm/pci.h diff --git a/xen/arch/ia64/linux-xen/sn/kernel/io_init.c b/xen/arch/ia64/linux-xen/sn/kernel/io_init.c index dc09a6a28a..973211e721 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/io_init.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/io_init.c @@ -8,6 +8,9 @@ #include #include +#ifdef XEN +#include +#endif #include #include #include @@ -17,17 +20,29 @@ #include #include #include +#ifndef XEN #include +#endif #include #include +#ifndef XEN #include #include +#endif +#ifdef XEN +#include "asm/sn/hubdev.h" +#include "asm/sn/xwidgetdev.h" +#else #include "xtalk/hubdev.h" #include "xtalk/xwidgetdev.h" +#endif extern void sn_init_cpei_timer(void); extern void register_sn_procfs(void); +#ifdef XEN +extern void sn_irq_lh_init(void); +#endif static struct list_head sn_sysdata_list; @@ -50,6 +65,7 @@ int sn_ioif_inited; /* SN I/O infrastructure initialized? */ struct sn_pcibus_provider *sn_pci_provider[PCIIO_ASIC_MAX_TYPES]; /* indexed by asic type */ +#ifndef XEN static int max_segment_number; /* Default highest segment number */ static int max_pcibus_number = 255; /* Default highest pci bus number */ @@ -81,6 +97,7 @@ static struct sn_pcibus_provider sn_pci_default_provider = { .dma_unmap = sn_default_pci_unmap, .bus_fixup = sn_default_pci_bus_fixup, }; +#endif /* * Retrieve the DMA Flush List given nasid, widget, and device. @@ -131,6 +148,7 @@ static inline u64 sal_get_pcibus_info(u64 segment, u64 busnum, u64 address) return ret_stuff.v0; } +#ifndef XEN /* * Retrieve the pci device information given the bus and device|function number. */ @@ -281,9 +299,13 @@ static void __init sn_fixup_ionodes(void) nasid, widget, device, (u64)(dev_entry->common)); else +#ifdef XEN + BUG(); +#else status = sn_device_fixup_war(nasid, widget, device, dev_entry->common); +#endif if (status != SALRET_OK) panic("SAL call failed: %s\n", ia64_sal_strerror(status)); @@ -614,6 +636,7 @@ void sn_bus_free_sysdata(void) } return; } +#endif /* * Ugly hack to get PCI setup until we have a proper ACPI namespace. @@ -629,6 +652,7 @@ static int __init sn_pci_init(void) if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; +#ifndef XEN /* * prime sn_pci_provider[]. Individial provider init routines will * override their respective default entries. @@ -640,14 +664,18 @@ static int __init sn_pci_init(void) pcibr_init_provider(); tioca_init_provider(); tioce_init_provider(); +#endif /* * This is needed to avoid bounce limit checks in the blk layer */ ia64_max_iommu_merge_mask = ~PAGE_MASK; +#ifndef XEN sn_fixup_ionodes(); +#endif sn_irq_lh_init(); INIT_LIST_HEAD(&sn_sysdata_list); +#ifndef XEN sn_init_cpei_timer(); #ifdef CONFIG_PROC_FS @@ -668,6 +696,7 @@ static int __init sn_pci_init(void) while ((pci_dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, pci_dev)) != NULL) sn_pci_fixup_slot(pci_dev); +#endif sn_ioif_inited = 1; /* sn I/O infrastructure now initialized */ @@ -682,7 +711,11 @@ void hubdev_init_node(nodepda_t * npda, cnodeid_t node) { struct hubdev_info *hubdev_info; int size; +#ifndef XEN pg_data_t *pg; +#else + struct pglist_data *pg; +#endif size = sizeof(struct hubdev_info); @@ -705,6 +738,7 @@ cnodeid_get_geoid(cnodeid_t cnode) return hubdev->hdi_geoid; } +#ifndef XEN void sn_generate_path(struct pci_bus *pci_bus, char *address) { nasid_t nasid; @@ -730,11 +764,18 @@ void sn_generate_path(struct pci_bus *pci_bus, char *address) (bricktype == L1_BRICKTYPE_1932)) sprintf(address, "%s^%d", address, geo_slot(geoid)); } +#endif +#ifdef XEN +__initcall(sn_pci_init); +#else subsys_initcall(sn_pci_init); +#endif +#ifndef XEN EXPORT_SYMBOL(sn_pci_fixup_slot); EXPORT_SYMBOL(sn_pci_unfixup_slot); EXPORT_SYMBOL(sn_pci_controller_fixup); EXPORT_SYMBOL(sn_bus_store_sysdata); EXPORT_SYMBOL(sn_bus_free_sysdata); EXPORT_SYMBOL(sn_generate_path); +#endif diff --git a/xen/arch/ia64/linux-xen/sn/kernel/iomv.c b/xen/arch/ia64/linux-xen/sn/kernel/iomv.c index 7ce3cdad62..3e38cb05e0 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/iomv.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/iomv.c @@ -9,7 +9,9 @@ #include #include #include +#ifndef XEN #include +#endif #include #include #include @@ -19,6 +21,10 @@ #define IS_LEGACY_VGA_IOPORT(p) \ (((p) >= 0x3b0 && (p) <= 0x3bb) || ((p) >= 0x3c0 && (p) <= 0x3df)) +#ifdef XEN +#define vga_console_iobase 0 +#endif + /** * sn_io_addr - convert an in/out port to an i/o address * @port: port to convert diff --git a/xen/arch/ia64/linux-xen/sn/kernel/irq.c b/xen/arch/ia64/linux-xen/sn/kernel/irq.c index 0b49459a87..4e55e627e6 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/irq.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/irq.c @@ -11,15 +11,25 @@ #include #include #include +#ifdef XEN +#include +#include +#endif #include #include #include #include #include +#ifndef XEN #include +#endif #include #include +#ifdef XEN +#define move_native_irq(foo) do {} while(0) +#endif + static void force_interrupt(int irq); static void register_intr_pda(struct sn_irq_info *sn_irq_info); static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); @@ -111,6 +121,7 @@ static void sn_end_irq(unsigned int irq) force_interrupt(irq); } +#ifndef XEN static void sn_irq_info_free(struct rcu_head *head); struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, @@ -175,9 +186,15 @@ struct sn_irq_info *sn_retarget_vector(struct sn_irq_info *sn_irq_info, (pci_provider->target_interrupt)(new_irq_info); spin_lock(&sn_irq_info_lock); +#ifdef XEN + list_replace(&sn_irq_info->list, &new_irq_info->list); +#else list_replace_rcu(&sn_irq_info->list, &new_irq_info->list); +#endif spin_unlock(&sn_irq_info_lock); +#ifndef XEN call_rcu(&sn_irq_info->rcu, sn_irq_info_free); +#endif #ifdef CONFIG_SMP set_irq_affinity_info((vector & 0xff), cpuphys, 0); @@ -199,16 +216,21 @@ static void sn_set_affinity_irq(unsigned int irq, cpumask_t mask) sn_irq_lh[irq], list) (void)sn_retarget_vector(sn_irq_info, nasid, slice); } +#endif struct hw_interrupt_type irq_type_sn = { +#ifndef XEN .name = "SN hub", +#endif .startup = sn_startup_irq, .shutdown = sn_shutdown_irq, .enable = sn_enable_irq, .disable = sn_disable_irq, .ack = sn_ack_irq, .end = sn_end_irq, +#ifndef XEN .set_affinity = sn_set_affinity_irq +#endif }; unsigned int sn_local_vector_to_irq(u8 vector) @@ -221,6 +243,7 @@ void sn_irq_init(void) int i; irq_desc_t *base_desc = irq_desc; +#ifndef XEN ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR; ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; @@ -229,6 +252,7 @@ void sn_irq_init(void) base_desc[i].chip = &irq_type_sn; } } +#endif } static void register_intr_pda(struct sn_irq_info *sn_irq_info) @@ -251,14 +275,24 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) struct sn_irq_info *tmp_irq_info; int i, foundmatch; +#ifndef XEN rcu_read_lock(); +#else + spin_lock(&sn_irq_info_lock); +#endif if (pdacpu(cpu)->sn_last_irq == irq) { foundmatch = 0; for (i = pdacpu(cpu)->sn_last_irq - 1; i && !foundmatch; i--) { +#ifdef XEN + list_for_each_entry(tmp_irq_info, + sn_irq_lh[i], + list) { +#else list_for_each_entry_rcu(tmp_irq_info, sn_irq_lh[i], list) { +#endif if (tmp_irq_info->irq_cpuid == cpu) { foundmatch = 1; break; @@ -272,9 +306,15 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) foundmatch = 0; for (i = pdacpu(cpu)->sn_first_irq + 1; i < NR_IRQS && !foundmatch; i++) { +#ifdef XEN + list_for_each_entry(tmp_irq_info, + sn_irq_lh[i], + list) { +#else list_for_each_entry_rcu(tmp_irq_info, sn_irq_lh[i], list) { +#endif if (tmp_irq_info->irq_cpuid == cpu) { foundmatch = 1; break; @@ -283,9 +323,14 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) } pdacpu(cpu)->sn_first_irq = ((i == NR_IRQS) ? 0 : i); } +#ifndef XEN rcu_read_unlock(); +#else + spin_unlock(&sn_irq_info_lock); +#endif } +#ifndef XEN static void sn_irq_info_free(struct rcu_head *head) { struct sn_irq_info *sn_irq_info; @@ -293,7 +338,9 @@ static void sn_irq_info_free(struct rcu_head *head) sn_irq_info = container_of(head, struct sn_irq_info, rcu); kfree(sn_irq_info); } +#endif +#ifndef XEN void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) { nasid_t nasid = sn_irq_info->irq_nasid; @@ -306,8 +353,14 @@ void sn_irq_fixup(struct pci_dev *pci_dev, struct sn_irq_info *sn_irq_info) /* link it into the sn_irq[irq] list */ spin_lock(&sn_irq_info_lock); +#ifdef XEN + list_add(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); +#else list_add_rcu(&sn_irq_info->list, sn_irq_lh[sn_irq_info->irq_irq]); +#endif +#ifndef XEN reserve_irq_vector(sn_irq_info->irq_irq); +#endif spin_unlock(&sn_irq_info_lock); register_intr_pda(sn_irq_info); @@ -331,14 +384,21 @@ void sn_irq_unfixup(struct pci_dev *pci_dev) unregister_intr_pda(sn_irq_info); spin_lock(&sn_irq_info_lock); +#ifdef XEN + list_del(&sn_irq_info->list); +#else list_del_rcu(&sn_irq_info->list); +#endif spin_unlock(&sn_irq_info_lock); if (list_empty(sn_irq_lh[sn_irq_info->irq_irq])) free_irq_vector(sn_irq_info->irq_irq); +#ifndef XEN call_rcu(&sn_irq_info->rcu, sn_irq_info_free); +#endif pci_dev_put(pci_dev); } +#endif static inline void sn_call_force_intr_provider(struct sn_irq_info *sn_irq_info) @@ -354,16 +414,31 @@ static void force_interrupt(int irq) { struct sn_irq_info *sn_irq_info; +#ifndef XEN if (!sn_ioif_inited) return; +#endif +#ifdef XEN + spin_lock(&sn_irq_info_lock); +#else rcu_read_lock(); +#endif +#ifdef XEN + list_for_each_entry(sn_irq_info, sn_irq_lh[irq], list) +#else list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[irq], list) +#endif sn_call_force_intr_provider(sn_irq_info); +#ifdef XEN + spin_unlock(&sn_irq_info_lock); +#else rcu_read_unlock(); +#endif } +#ifndef XEN /* * Check for lost interrupts. If the PIC int_status reg. says that * an interrupt has been sent, but not handled, and the interrupt @@ -408,22 +483,41 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) } sn_irq_info->irq_last_intr = regval; } +#endif void sn_lb_int_war_check(void) { struct sn_irq_info *sn_irq_info; int i; +#ifndef XEN +#ifdef XEN + if (pda->sn_first_irq == 0) +#else if (!sn_ioif_inited || pda->sn_first_irq == 0) +#endif return; +#ifdef XEN + spin_lock(&sn_irq_info_lock); +#else rcu_read_lock(); +#endif for (i = pda->sn_first_irq; i <= pda->sn_last_irq; i++) { +#ifdef XEN + list_for_each_entry(sn_irq_info, sn_irq_lh[i], list) { +#else list_for_each_entry_rcu(sn_irq_info, sn_irq_lh[i], list) { +#endif sn_check_intr(i, sn_irq_info); } } +#ifdef XEN + spin_unlock(&sn_irq_info_lock); +#else rcu_read_unlock(); +#endif +#endif } void __init sn_irq_lh_init(void) diff --git a/xen/arch/ia64/linux-xen/sn/kernel/setup.c b/xen/arch/ia64/linux-xen/sn/kernel/setup.c index 7a2d824c5c..30ba5263ae 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/setup.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/setup.c @@ -10,9 +10,13 @@ #include #include #include +#ifndef XEN #include +#endif #include +#ifndef XEN #include +#endif #include #include #include @@ -26,7 +30,9 @@ #include #include #include +#ifndef XEN #include +#endif #include #include #include @@ -36,7 +42,9 @@ #include #include #include +#ifndef XEN #include +#endif #include #include #include @@ -44,15 +52,32 @@ #include #include #include +#ifndef XEN #include +#endif #include +#ifndef XEN #include +#endif #include #include #include +#ifndef XEN #include "xtalk/xwidgetdev.h" #include "xtalk/hubdev.h" +#else +#include "asm/sn/xwidgetdev.h" +#include "asm/sn/hubdev.h" +#endif #include +#ifdef XEN +#include + +/* Xen has no clue about NUMA .... grrrr */ +#define pxm_to_node(foo) 0 +#define node_to_pxm(foo) 0 +#define numa_node_id() 0 +#endif DEFINE_PER_CPU(struct pda_s, pda_percpu); @@ -107,6 +132,7 @@ static void build_cnode_tables(void); static nodepda_t *nodepdaindr[MAX_COMPACT_NODES]; +#ifndef XEN /* * The format of "screen_info" is strange, and due to early i386-setup * code. This is just enough to make the console code think we're on a @@ -122,6 +148,7 @@ struct screen_info sn_screen_info = { .orig_video_isVGA = 1, .orig_video_points = 16 }; +#endif /* * This routine can only be used during init, since @@ -228,6 +255,7 @@ static void __init sn_check_for_wars(void) } } +#ifndef XEN /* * Scan the EFI PCDP table (if it exists) for an acceptable VGA console * output device. If one exists, pick it and set sn_legacy_{io,mem} to @@ -369,6 +397,7 @@ static unsigned long long ia64_sn2_printk_clock(void) return (rtc_now - sn2_rtc_initial) * (1000000000 / sn_rtc_cycles_per_second); } +#endif /** * sn_setup - SN platform setup routine @@ -378,10 +407,15 @@ static unsigned long long ia64_sn2_printk_clock(void) * the RTC frequency (via a SAL call), initializing secondary CPUs, and * setting up per-node data areas. The console is also initialized here. */ +#ifdef XEN +void __cpuinit sn_cpu_init(void); +#endif + void __init sn_setup(char **cmdline_p) { long status, ticks_per_sec, drift; u32 version = sn_sal_rev(); +#ifndef XEN extern void sn_cpu_init(void); sn2_rtc_initial = rtc_time(); @@ -430,6 +464,7 @@ void __init sn_setup(char **cmdline_p) #endif /* def(CONFIG_VT) && def(CONFIG_VGA_CONSOLE) */ MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY; +#endif /* * Build the tables for managing cnodes. @@ -446,10 +481,12 @@ void __init sn_setup(char **cmdline_p) sn_rtc_cycles_per_second = 1000000000000UL / 30000UL; } else sn_rtc_cycles_per_second = ticks_per_sec; +#ifndef XEN platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_CPE_VECTOR; ia64_printk_clock = ia64_sn2_printk_clock; +#endif printk("SGI SAL version %x.%02x\n", version >> 8, version & 0x00FF); @@ -457,14 +494,18 @@ void __init sn_setup(char **cmdline_p) * we set the default root device to /dev/hda * to make simulation easy */ +#ifndef XEN ROOT_DEV = Root_HDA1; +#endif /* * Create the PDAs and NODEPDAs for all the cpus. */ sn_init_pdas(cmdline_p); +#ifndef XEN ia64_mark_idle = &snidle; +#endif /* * For the bootcpu, we do this here. All other cpus will make the @@ -472,6 +513,7 @@ void __init sn_setup(char **cmdline_p) */ sn_cpu_init(); +#ifndef XEN #ifdef CONFIG_SMP init_smp_config(); #endif @@ -487,6 +529,7 @@ void __init sn_setup(char **cmdline_p) */ pm_power_off = ia64_sn_power_down; current->thread.flags |= IA64_THREAD_MIGRATION; +#endif } /** @@ -526,6 +569,7 @@ static void __init sn_init_pdas(char **cmdline_p) memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr, sizeof(nodepdaindr)); +#ifndef XEN /* * Set up IO related platform-dependent nodepda fields. * The following routine actually sets up the hubinfo struct @@ -542,6 +586,7 @@ static void __init sn_init_pdas(char **cmdline_p) for (cnode = 0; cnode < num_cnodes; cnode++) { hubdev_init_node(nodepdaindr[cnode], cnode); } +#endif } /** @@ -565,6 +610,7 @@ void __cpuinit sn_cpu_init(void) static int wars_have_been_checked; cpuid = smp_processor_id(); +#ifndef XEN if (cpuid == 0 && IS_MEDUSA()) { if (ia64_sn_is_fake_prom()) sn_prom_type = 2; @@ -573,6 +619,7 @@ void __cpuinit sn_cpu_init(void) printk(KERN_INFO "Running on medusa with %s PROM\n", (sn_prom_type == 1) ? "real" : "fake"); } +#endif memset(pda, 0, sizeof(pda)); if (ia64_sn_get_sn_info(0, &sn_hub_info->shub2, @@ -660,6 +707,7 @@ void __cpuinit sn_cpu_init(void) pda->pio_write_status_val = is_shub1() ? SH_PIO_WRITE_STATUS_PENDING_WRITE_COUNT_MASK : 0; } +#ifndef XEN /* local_node_data is not allocated .... yet */ /* * WAR addresses for SHUB 1.x. */ @@ -672,6 +720,7 @@ void __cpuinit sn_cpu_init(void) (volatile unsigned long *)GLOBAL_MMR_ADDR(nasid, SH1_PI_CAM_CONTROL); } +#endif } /* diff --git a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c index d9d306c79f..262e8453f3 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c @@ -34,6 +34,9 @@ #include #include #include +#ifdef XEN +#include +#endif #include #include #include @@ -63,7 +66,11 @@ sn2_ptc_deadlock_recovery(short *, short, short, int, #define local_node_uses_ptc_ga(sh1) ((sh1) ? 1 : 0) #define max_active_pio(sh1) ((sh1) ? 32 : 7) #define reset_max_active_on_deadlock() 1 +#ifndef XEN #define PTC_LOCK(sh1) ((sh1) ? &sn2_global_ptc_lock : &sn_nodepda->ptc_lock) +#else +#define PTC_LOCK(sh1) &sn2_global_ptc_lock +#endif struct ptc_stats { unsigned long ptc_l; @@ -93,6 +100,7 @@ static inline unsigned long wait_piowc(void) return (ws & SH_PIO_WRITE_STATUS_WRITE_DEADLOCK_MASK) != 0; } +#ifndef XEN /* No idea if Xen will ever support this */ /** * sn_migrate - SN-specific task migration actions * @task: Task being migrated to new CPU @@ -117,9 +125,14 @@ void sn_migrate(struct task_struct *task) void sn_tlb_migrate_finish(struct mm_struct *mm) { /* flush_tlb_mm is inefficient if more than 1 users of mm */ +#ifndef XEN if (mm == current->mm && mm && atomic_read(&mm->mm_users) == 1) +#else + if (mm == ¤t->arch.mm && mm && atomic_read(&mm->mm_users) == 1) +#endif flush_tlb_mm(mm); } +#endif /** * sn2_global_tlb_purge - globally purge translation cache of virtual address range @@ -143,12 +156,25 @@ void sn_tlb_migrate_finish(struct mm_struct *mm) * done with ptc.g/MMRs under protection of the global ptc_lock. */ +#ifdef XEN /* Xen is soooooooo stupid! */ +static cpumask_t mask_all = CPU_MASK_ALL; +#endif + void +#ifndef XEN sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, +#else +sn2_global_tlb_purge(unsigned long start, +#endif unsigned long end, unsigned long nbits) { int i, ibegin, shub1, cnode, mynasid, cpu, lcpu = 0, nasid; +#ifndef XEN int mymm = (mm == current->active_mm && mm == current->mm); +#else + struct mm_struct *mm; + int mymm = 1; +#endif int use_cpu_ptcga; volatile unsigned long *ptc0, *ptc1; unsigned long itc, itc2, flags, data0 = 0, data1 = 0, rr_value, old_rr = 0; @@ -159,12 +185,21 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, nodes_clear(nodes_flushed); i = 0; +#ifndef XEN /* One day Xen will grow up! */ for_each_cpu_mask(cpu, mm->cpu_vm_mask) { cnode = cpu_to_node(cpu); node_set(cnode, nodes_flushed); lcpu = cpu; i++; } +#else + for_each_cpu(cpu) { + cnode = cpu_to_node(cpu); + node_set(cnode, nodes_flushed); + lcpu = cpu; + i++; + } +#endif if (i == 0) return; @@ -182,19 +217,29 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, return; } +#ifndef XEN if (atomic_read(&mm->mm_users) == 1 && mymm) { +#ifndef XEN /* I hate Xen! */ flush_tlb_mm(mm); +#else + flush_tlb_mask(mask_all); +#endif __get_cpu_var(ptcstats).change_rid++; preempt_enable(); return; } +#endif itc = ia64_get_itc(); nix = 0; for_each_node_mask(cnode, nodes_flushed) nasids[nix++] = cnodeid_to_nasid(cnode); +#ifndef XEN rr_value = (mm->context << 3) | REGION_NUMBER(start); +#else + rr_value = REGION_NUMBER(start); +#endif shub1 = is_shub1(); if (shub1) { @@ -202,13 +247,22 @@ sn2_global_tlb_purge(struct mm_struct *mm, unsigned long start, (nbits << SH1_PTC_0_PS_SHFT) | (rr_value << SH1_PTC_0_RID_SHFT) | (1UL << SH1_PTC_0_START_SHFT); +#ifndef XEN ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0); ptc1 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1); +#else + ptc0 = (unsigned long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_0); + ptc1 = (unsigned long *)GLOBAL_MMR_PHYS_ADDR(0, SH1_PTC_1); +#endif } else { data0 = (1UL << SH2_PTC_A_SHFT) | (nbits << SH2_PTC_PS_SHFT) | (1UL << SH2_PTC_START_SHFT); +#ifndef XEN ptc0 = (long *)GLOBAL_MMR_PHYS_ADDR(0, SH2_PTC + +#else + ptc0 = (unsigned long *)GLOBAL_MMR_PHYS_ADDR(0, SH2_PTC + +#endif (rr_value << SH2_PTC_RID_SHFT)); ptc1 = NULL; } @@ -390,7 +444,7 @@ void sn2_send_IPI(int cpuid, int vector, int delivery_mode, int redirect) if (unlikely(nasid == -1)) ia64_sn_get_sapic_info(physid, &nasid, NULL, NULL); - sn_send_IPI_phys(nasid, physid, vector, delivery_mode); + sn_send_IPI_phys(nasid, physid, vector, delivery_mode); } #ifdef CONFIG_PROC_FS diff --git a/xen/arch/ia64/xen/irq.c b/xen/arch/ia64/xen/irq.c index 6211e9b418..079f445def 100644 --- a/xen/arch/ia64/xen/irq.c +++ b/xen/arch/ia64/xen/irq.c @@ -48,6 +48,13 @@ #include #define apicid_to_phys_cpu_present(x) 1 +#ifdef CONFIG_IA64_GENERIC +unsigned int __ia64_local_vector_to_irq (ia64_vector vec) +{ + return (unsigned int) vec; +} +#endif + /* * Linux has a controller-independent x86 interrupt architecture. * every controller has a 'controller-template', that is used diff --git a/xen/include/asm-ia64/config.h b/xen/include/asm-ia64/config.h index e1306d744b..65aeb5bbb9 100644 --- a/xen/include/asm-ia64/config.h +++ b/xen/include/asm-ia64/config.h @@ -8,8 +8,9 @@ // manufactured from component pieces // defined in linux/arch/ia64/defconfig -//#define CONFIG_IA64_GENERIC -#define CONFIG_IA64_HP_SIM +#define CONFIG_IA64_GENERIC +#define CONFIG_HZ 32 + #define CONFIG_IA64_L1_CACHE_SHIFT 7 // needed by include/asm-ia64/page.h #define CONFIG_IA64_PAGE_SIZE_16KB // 4KB doesn't work?!? @@ -145,14 +146,6 @@ extern int smp_num_siblings; // avoid redefining task_struct in asm/current.h #define task_struct vcpu -// linux/include/asm-ia64/machvec.h (linux/arch/ia64/lib/io.c) -#define platform_inb __ia64_inb -#define platform_inw __ia64_inw -#define platform_inl __ia64_inl -#define platform_outb __ia64_outb -#define platform_outw __ia64_outw -#define platform_outl __ia64_outl - #include #ifndef CONFIG_SMP #define __cacheline_aligned_in_smp @@ -206,6 +199,16 @@ void sort_main_extable(void); // Deprivated linux inf and put here for short time compatibility #define kmalloc(s, t) xmalloc_bytes((s)) #define kfree(s) xfree((s)) +#define kzalloc(size, flags) \ +({ \ + unsigned char *mem; \ + mem = (unsigned char *)xmalloc_bytes(size); \ + if (mem) \ + memset(mem, 0, size); \ + (void *)mem; \ +}) +#define kcalloc(n, size, flags) kzalloc(n * size, flags) +#define alloc_bootmem_node(pg, size) xmalloc_bytes(size) // see common/keyhandler.c #define nop() asm volatile ("nop 0") diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h b/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h index 8a0752f409..9872a3458d 100644 --- a/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h @@ -11,6 +11,32 @@ extern ia64_mv_setup_t dig_setup; * the macros are used directly. */ #define platform_name "dig" +#ifdef XEN +/* + * All the World is a PC .... yay! yay! yay! + */ +extern ia64_mv_setup_t hpsim_setup; +#define platform_setup hpsim_setup + +#define platform_dma_init machvec_noop +#define platform_dma_alloc_coherent machvec_noop +#define platform_dma_free_coherent machvec_noop +#define platform_dma_map_single machvec_noop +#define platform_dma_unmap_single machvec_noop +#define platform_dma_map_sg machvec_noop +#define platform_dma_unmap_sg machvec_noop +#define platform_dma_sync_single_for_cpu machvec_noop +#define platform_dma_sync_sg_for_cpu machvec_noop +#define platform_dma_sync_single_for_device machvec_noop +#define platform_dma_sync_sg_for_device machvec_noop +#define platform_dma_mapping_error machvec_noop +#define platform_dma_supported machvec_noop + +#define platform_pci_get_legacy_mem machvec_noop +#define platform_pci_legacy_read machvec_noop +#define platform_pci_legacy_write machvec_noop +#else #define platform_setup dig_setup +#endif #endif /* _ASM_IA64_MACHVEC_DIG_h */ diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h b/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h index e90daf9ce3..675c6b8cce 100644 --- a/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h @@ -19,6 +19,30 @@ extern ia64_mv_dma_mapping_error sba_dma_mapping_error; * the macros are used directly. */ #define platform_name "hpzx1" +#ifdef XEN +extern ia64_mv_setup_t hpsim_setup; +extern ia64_mv_irq_init_t hpsim_irq_init; +#define platform_setup hpsim_setup +#define platform_irq_init hpsim_irq_init + +#define platform_dma_init machvec_noop +#define platform_dma_alloc_coherent machvec_noop +#define platform_dma_free_coherent machvec_noop +#define platform_dma_map_single machvec_noop +#define platform_dma_unmap_single machvec_noop +#define platform_dma_map_sg machvec_noop +#define platform_dma_unmap_sg machvec_noop +#define platform_dma_sync_single_for_cpu machvec_noop +#define platform_dma_sync_sg_for_cpu machvec_noop +#define platform_dma_sync_single_for_device machvec_noop +#define platform_dma_sync_sg_for_device machvec_noop +#define platform_dma_mapping_error machvec_noop +#define platform_dma_supported machvec_noop + +#define platform_pci_get_legacy_mem machvec_noop +#define platform_pci_legacy_read machvec_noop +#define platform_pci_legacy_write machvec_noop +#else #define platform_setup dig_setup #define platform_dma_init machvec_noop #define platform_dma_alloc_coherent sba_alloc_coherent @@ -33,5 +57,6 @@ extern ia64_mv_dma_mapping_error sba_dma_mapping_error; #define platform_dma_sync_sg_for_device machvec_dma_sync_sg #define platform_dma_supported sba_dma_supported #define platform_dma_mapping_error sba_dma_mapping_error +#endif #endif /* _ASM_IA64_MACHVEC_HPZX1_h */ diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h b/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h index c54b165b1c..fbbae81086 100644 --- a/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h @@ -66,9 +66,11 @@ extern ia64_mv_dma_sync_single_for_device sn_dma_sync_single_for_device; extern ia64_mv_dma_sync_sg_for_device sn_dma_sync_sg_for_device; extern ia64_mv_dma_mapping_error sn_dma_mapping_error; extern ia64_mv_dma_supported sn_dma_supported; +#ifndef XEN extern ia64_mv_migrate_t sn_migrate; extern ia64_mv_setup_msi_irq_t sn_setup_msi_irq; extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; +#endif /* @@ -83,9 +85,13 @@ extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; #define platform_cpu_init sn_cpu_init #define platform_irq_init sn_irq_init #define platform_send_ipi sn2_send_IPI +#ifndef XEN #define platform_timer_interrupt sn_timer_interrupt +#endif #define platform_global_tlb_purge sn2_global_tlb_purge +#ifndef XEN #define platform_tlb_migrate_finish sn_tlb_migrate_finish +#endif #define platform_pci_fixup sn_pci_fixup #define platform_inb __sn_inb #define platform_inw __sn_inw @@ -103,10 +109,30 @@ extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; #define platform_readl_relaxed __sn_readl_relaxed #define platform_readq_relaxed __sn_readq_relaxed #define platform_local_vector_to_irq sn_local_vector_to_irq +#ifdef XEN +#define platform_pci_get_legacy_mem machvec_noop +#define platform_pci_legacy_read machvec_noop +#define platform_pci_legacy_write machvec_noop +#else #define platform_pci_get_legacy_mem sn_pci_get_legacy_mem #define platform_pci_legacy_read sn_pci_legacy_read #define platform_pci_legacy_write sn_pci_legacy_write +#endif #define platform_dma_init machvec_noop +#ifdef XEN +#define platform_dma_alloc_coherent machvec_noop +#define platform_dma_free_coherent machvec_noop +#define platform_dma_map_single machvec_noop +#define platform_dma_unmap_single machvec_noop +#define platform_dma_map_sg machvec_noop +#define platform_dma_unmap_sg machvec_noop +#define platform_dma_sync_single_for_cpu machvec_noop +#define platform_dma_sync_sg_for_cpu machvec_noop +#define platform_dma_sync_single_for_device machvec_noop +#define platform_dma_sync_sg_for_device machvec_noop +#define platform_dma_mapping_error machvec_noop +#define platform_dma_supported machvec_noop +#else #define platform_dma_alloc_coherent sn_dma_alloc_coherent #define platform_dma_free_coherent sn_dma_free_coherent #define platform_dma_map_single sn_dma_map_single @@ -120,6 +146,9 @@ extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; #define platform_dma_mapping_error sn_dma_mapping_error #define platform_dma_supported sn_dma_supported #define platform_migrate sn_migrate +#endif + +#ifndef XEN #ifdef CONFIG_PCI_MSI #define platform_setup_msi_irq sn_setup_msi_irq #define platform_teardown_msi_irq sn_teardown_msi_irq @@ -127,6 +156,7 @@ extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; #define platform_setup_msi_irq ((ia64_mv_setup_msi_irq_t*)NULL) #define platform_teardown_msi_irq ((ia64_mv_teardown_msi_irq_t*)NULL) #endif +#endif #include diff --git a/xen/include/asm-ia64/linux-xen/asm/page.h b/xen/include/asm-ia64/linux-xen/asm/page.h index 84e1c320d0..28ec059605 100644 --- a/xen/include/asm-ia64/linux-xen/asm/page.h +++ b/xen/include/asm-ia64/linux-xen/asm/page.h @@ -12,6 +12,16 @@ #include #include +#ifdef XEN /* This will go away with newer upstream */ +#define RGN_SHIFT 61 +#define RGN_BASE(r) (r << RGN_SHIFT) +#define RGN_BITS RGN_BASE(-1) +#define RGN_HPAGE REGION_HPAGE +#ifndef CONFIG_HUGETLB_PAGE +# define REGION_HPAGE (4UL) +#endif +#endif + /* * PAGE_SHIFT determines the actual kernel page size. */ diff --git a/xen/include/asm-ia64/linux-xen/asm/pci.h b/xen/include/asm-ia64/linux-xen/asm/pci.h index ef616fd4cb..0e4e0d85d1 100644 --- a/xen/include/asm-ia64/linux-xen/asm/pci.h +++ b/xen/include/asm-ia64/linux-xen/asm/pci.h @@ -6,9 +6,14 @@ #include #include #include +#ifdef XEN +#include +#endif #include +#ifndef XEN #include +#endif /* * Can be used to override the logic in pci_scan_bus for skipping already-configured bus @@ -55,7 +60,9 @@ pcibios_penalize_isa_irq (int irq, int active) #define HAVE_ARCH_PCI_MWI 1 extern int pcibios_prep_mwi (struct pci_dev *); +#ifndef XEN #include +#endif /* pci_unmap_{single,page} is not a nop, thus... */ #define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ @@ -107,6 +114,7 @@ extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, #define HAVE_PCI_LEGACY extern int pci_mmap_legacy_page_range(struct pci_bus *bus, struct vm_area_struct *vma); +#ifndef XEN extern ssize_t pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, size_t count); extern ssize_t pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, @@ -114,6 +122,7 @@ extern ssize_t pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, extern int pci_mmap_legacy_mem(struct kobject *kobj, struct bin_attribute *attr, struct vm_area_struct *vma); +#endif #define pci_get_legacy_mem platform_pci_get_legacy_mem #define pci_legacy_read platform_pci_legacy_read @@ -156,6 +165,7 @@ extern void pcibios_resource_to_bus(struct pci_dev *dev, extern void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, struct pci_bus_region *region); +#ifndef XEN static inline struct resource * pcibios_select_root(struct pci_dev *pdev, struct resource *res) { @@ -168,6 +178,7 @@ pcibios_select_root(struct pci_dev *pdev, struct resource *res) return root; } +#endif #define pcibios_scan_all_fns(a, b) 0 diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/addrs.h b/xen/include/asm-ia64/linux-xen/asm/sn/addrs.h index e715c794b1..531a880a7b 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/addrs.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/addrs.h @@ -136,7 +136,7 @@ */ #define TO_PHYS(x) (TO_PHYS_MASK & (x)) #define TO_CAC(x) (CAC_BASE | TO_PHYS(x)) -#ifdef CONFIG_SGI_SN +#if defined(CONFIG_SGI_SN) || defined(XEN) #define TO_AMO(x) (AMO_BASE | TO_PHYS(x)) #define TO_GET(x) (GET_BASE | TO_PHYS(x)) #else diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/arch.h b/xen/include/asm-ia64/linux-xen/asm/sn/arch.h index 16adc93d7a..a159c728b9 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/arch.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/arch.h @@ -11,10 +11,12 @@ #ifndef _ASM_IA64_SN_ARCH_H #define _ASM_IA64_SN_ARCH_H +#ifndef XEN #include #include #include #include +#endif #include /* @@ -58,8 +60,13 @@ struct sn_hub_info_s { }; DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); #define sn_hub_info (&__get_cpu_var(__sn_hub_info)) +#ifndef XEN #define is_shub2() (sn_hub_info->shub2) #define is_shub1() (sn_hub_info->shub2 == 0) +#else +#define is_shub2() 0 +#define is_shub1() 1 +#endif /* * Use this macro to test if shub 1.1 wars should be enabled @@ -74,12 +81,12 @@ DECLARE_PER_CPU(struct sn_hub_info_s, __sn_hub_info); DECLARE_PER_CPU(short, __sn_cnodeid_to_nasid[MAX_COMPACT_NODES]); #define sn_cnodeid_to_nasid (&__get_cpu_var(__sn_cnodeid_to_nasid[0])) - +#ifndef XEN extern u8 sn_partition_id; extern u8 sn_system_size; extern u8 sn_sharing_domain_size; extern u8 sn_region_size; extern void sn_flush_all_caches(long addr, long bytes); - +#endif #endif /* _ASM_IA64_SN_ARCH_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/hubdev.h b/xen/include/asm-ia64/linux-xen/asm/sn/hubdev.h index 8182583c76..96bbfe2a1f 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/hubdev.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/hubdev.h @@ -8,7 +8,11 @@ #ifndef _ASM_IA64_SN_XTALK_HUBDEV_H #define _ASM_IA64_SN_XTALK_HUBDEV_H +#ifndef XEN #include "xtalk/xwidgetdev.h" +#else +#include +#endif #define HUB_WIDGET_ID_MAX 0xf #define DEV_PER_WIDGET (2*2*8) diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/io.h b/xen/include/asm-ia64/linux-xen/asm/sn/io.h index 41c73a7356..78585a22cf 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/io.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/io.h @@ -18,7 +18,14 @@ extern int num_cnodes; #define __sn_mf_a() ia64_mfa() +#ifdef XEN +/* + * Xen doesn't deal with any PIC devices directly, it's all handled in dom0 + */ +#define sn_dma_flush(foo) do {} while(0) +#else extern void sn_dma_flush(unsigned long); +#endif #define __sn_inb ___sn_inb #define __sn_inw ___sn_inw diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/pcibr_provider.h b/xen/include/asm-ia64/linux-xen/asm/sn/pcibr_provider.h index da3eade0ca..8f88ecd3a7 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/pcibr_provider.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/pcibr_provider.h @@ -8,6 +8,10 @@ #ifndef _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H #define _ASM_IA64_SN_PCI_PCIBR_PROVIDER_H +#ifdef XEN +#include +#include +#endif #include #include diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/rw_mmr.h b/xen/include/asm-ia64/linux-xen/asm/sn/rw_mmr.h index 2d78f4c5a4..cccef83367 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/rw_mmr.h +++ b/xen/include/asm-ia64/linux-xen/asm/sn/rw_mmr.h @@ -23,6 +23,10 @@ extern long pio_phys_read_mmr(volatile long *mmr); extern void pio_phys_write_mmr(volatile long *mmr, long val); +#ifndef XEN extern void pio_atomic_phys_write_mmrs(volatile long *mmr1, long val1, volatile long *mmr2, long val2); +#else +extern void pio_atomic_phys_write_mmrs(volatile unsigned long *mmr1, long val1, volatile unsigned long *mmr2, long val2); +#endif #endif /* _ASM_IA64_SN_RW_MMR_H */ diff --git a/xen/include/asm-ia64/linux-xen/asm/system.h b/xen/include/asm-ia64/linux-xen/asm/system.h index 9f98e2a743..c1138c56fb 100644 --- a/xen/include/asm-ia64/linux-xen/asm/system.h +++ b/xen/include/asm-ia64/linux-xen/asm/system.h @@ -190,6 +190,7 @@ do { \ #ifdef XEN #define local_irq_is_enabled() (!irqs_disabled()) extern struct vcpu *ia64_switch_to(struct vcpu *next_task); +#define ia64_platform_is(x) (strcmp(x, platform_name) == 0) #else #ifdef __KERNEL__ diff --git a/xen/include/asm-ia64/linux-xen/linux/device.h b/xen/include/asm-ia64/linux-xen/linux/device.h index 9d4f6a9639..8ebe998659 100644 --- a/xen/include/asm-ia64/linux-xen/linux/device.h +++ b/xen/include/asm-ia64/linux-xen/linux/device.h @@ -78,7 +78,9 @@ int __must_check bus_for_each_drv(struct bus_type *bus, /* driverfs interface for exporting bus attributes */ struct bus_attribute { +#ifndef XEN struct attribute attr; +#endif ssize_t (*show)(struct bus_type *, char * buf); ssize_t (*store)(struct bus_type *, const char * buf, size_t count); }; @@ -122,7 +124,9 @@ extern int driver_probe_done(void); /* driverfs interface for exporting driver attributes */ struct driver_attribute { +#ifndef XEN struct attribute attr; +#endif ssize_t (*show)(struct device_driver *, char * buf); ssize_t (*store)(struct device_driver *, const char * buf, size_t count); }; @@ -152,7 +156,11 @@ struct class { struct list_head children; struct list_head devices; struct list_head interfaces; +#ifdef XEN + spinlock_t sem; +#else struct semaphore sem; /* locks both the children and interfaces lists */ +#endif struct kobject *virtual_dir; @@ -178,7 +186,9 @@ extern void class_unregister(struct class *); struct class_attribute { +#ifndef XEN struct attribute attr; +#endif ssize_t (*show)(struct class *, char * buf); ssize_t (*store)(struct class *, const char * buf, size_t count); }; @@ -191,7 +201,9 @@ extern int __must_check class_create_file(struct class *, extern void class_remove_file(struct class *, const struct class_attribute *); struct class_device_attribute { +#ifndef XEN struct attribute attr; +#endif ssize_t (*show)(struct class_device *, char * buf); ssize_t (*store)(struct class_device *, const char * buf, size_t count); }; @@ -333,9 +345,13 @@ struct device { struct device_attribute uevent_attr; struct device_attribute *devt_attr; +#ifdef XEN + spinlock_t sem; +#else struct semaphore sem; /* semaphore to synchronize calls to * its driver. */ +#endif struct bus_type * bus; /* type of bus device is on */ struct device_driver *driver; /* which driver has allocated this diff --git a/xen/include/asm-ia64/linux-xen/linux/kobject.h b/xen/include/asm-ia64/linux-xen/linux/kobject.h index bcd9cd173c..d072d2a90c 100644 --- a/xen/include/asm-ia64/linux-xen/linux/kobject.h +++ b/xen/include/asm-ia64/linux-xen/linux/kobject.h @@ -169,7 +169,9 @@ extern struct kobject * kset_find_obj(struct kset *, const char *); struct subsystem { struct kset kset; +#ifndef XEN struct rw_semaphore rwsem; +#endif }; #define decl_subsys(_name,_type,_uevent_ops) \ @@ -254,7 +256,9 @@ static inline void subsys_put(struct subsystem * s) } struct subsys_attribute { +#ifndef XEN struct attribute attr; +#endif ssize_t (*show)(struct subsystem *, char *); ssize_t (*store)(struct subsystem *, const char *, size_t); }; diff --git a/xen/include/asm-ia64/linux-xen/linux/pci.h b/xen/include/asm-ia64/linux-xen/linux/pci.h index 09be0f81b2..118201a9a7 100644 --- a/xen/include/asm-ia64/linux-xen/linux/pci.h +++ b/xen/include/asm-ia64/linux-xen/linux/pci.h @@ -22,6 +22,9 @@ /* Include the ID list */ #include +#ifdef XEN +#include +#endif /* * The PCI interface treats multi-function devices as independent diff --git a/xen/include/asm-ia64/linux/asm/pci.h b/xen/include/asm-ia64/linux/asm/pci.h deleted file mode 100644 index dba9f220be..0000000000 --- a/xen/include/asm-ia64/linux/asm/pci.h +++ /dev/null @@ -1,161 +0,0 @@ -#ifndef _ASM_IA64_PCI_H -#define _ASM_IA64_PCI_H - -#include -#include -#include -#include -#include - -#include -#include - -/* - * Can be used to override the logic in pci_scan_bus for skipping already-configured bus - * numbers - to be used for buggy BIOSes or architectures with incomplete PCI setup by the - * loader. - */ -#define pcibios_assign_all_busses() 0 -#define pcibios_scan_all_fns(a, b) 0 - -#define PCIBIOS_MIN_IO 0x1000 -#define PCIBIOS_MIN_MEM 0x10000000 - -void pcibios_config_init(void); - -struct pci_dev; - -/* - * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct correspondence - * between device bus addresses and CPU physical addresses. Platforms with a hardware I/O - * MMU _must_ turn this off to suppress the bounce buffer handling code in the block and - * network device layers. Platforms with separate bus address spaces _must_ turn this off - * and provide a device DMA mapping implementation that takes care of the necessary - * address translation. - * - * For now, the ia64 platforms which may have separate/multiple bus address spaces all - * have I/O MMUs which support the merging of physically discontiguous buffers, so we can - * use that as the sole factor to determine the setting of PCI_DMA_BUS_IS_PHYS. - */ -extern unsigned long ia64_max_iommu_merge_mask; -#define PCI_DMA_BUS_IS_PHYS (ia64_max_iommu_merge_mask == ~0UL) - -static inline void -pcibios_set_master (struct pci_dev *dev) -{ - /* No special bus mastering setup handling */ -} - -static inline void -pcibios_penalize_isa_irq (int irq, int active) -{ - /* We don't do dynamic PCI IRQ allocation */ -} - -#define HAVE_ARCH_PCI_MWI 1 -extern int pcibios_prep_mwi (struct pci_dev *); - -#include - -/* pci_unmap_{single,page} is not a nop, thus... */ -#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) \ - dma_addr_t ADDR_NAME; -#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) \ - __u32 LEN_NAME; -#define pci_unmap_addr(PTR, ADDR_NAME) \ - ((PTR)->ADDR_NAME) -#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) \ - (((PTR)->ADDR_NAME) = (VAL)) -#define pci_unmap_len(PTR, LEN_NAME) \ - ((PTR)->LEN_NAME) -#define pci_unmap_len_set(PTR, LEN_NAME, VAL) \ - (((PTR)->LEN_NAME) = (VAL)) - -/* The ia64 platform always supports 64-bit addressing. */ -#define pci_dac_dma_supported(pci_dev, mask) (1) -#define pci_dac_page_to_dma(dev,pg,off,dir) ((dma_addr_t) page_to_bus(pg) + (off)) -#define pci_dac_dma_to_page(dev,dma_addr) (virt_to_page(bus_to_virt(dma_addr))) -#define pci_dac_dma_to_offset(dev,dma_addr) offset_in_page(dma_addr) -#define pci_dac_dma_sync_single_for_cpu(dev,dma_addr,len,dir) do { } while (0) -#define pci_dac_dma_sync_single_for_device(dev,dma_addr,len,dir) do { mb(); } while (0) - -#define sg_dma_len(sg) ((sg)->dma_length) -#define sg_dma_address(sg) ((sg)->dma_address) - -#ifdef CONFIG_PCI -static inline void pci_dma_burst_advice(struct pci_dev *pdev, - enum pci_dma_burst_strategy *strat, - unsigned long *strategy_parameter) -{ - unsigned long cacheline_size; - u8 byte; - - pci_read_config_byte(pdev, PCI_CACHE_LINE_SIZE, &byte); - if (byte == 0) - cacheline_size = 1024; - else - cacheline_size = (int) byte * 4; - - *strat = PCI_DMA_BURST_MULTIPLE; - *strategy_parameter = cacheline_size; -} -#endif - -#define HAVE_PCI_MMAP -extern int pci_mmap_page_range (struct pci_dev *dev, struct vm_area_struct *vma, - enum pci_mmap_state mmap_state, int write_combine); -#define HAVE_PCI_LEGACY -extern int pci_mmap_legacy_page_range(struct pci_bus *bus, - struct vm_area_struct *vma); -extern ssize_t pci_read_legacy_io(struct kobject *kobj, char *buf, loff_t off, - size_t count); -extern ssize_t pci_write_legacy_io(struct kobject *kobj, char *buf, loff_t off, - size_t count); -extern int pci_mmap_legacy_mem(struct kobject *kobj, - struct bin_attribute *attr, - struct vm_area_struct *vma); - -#define pci_get_legacy_mem platform_pci_get_legacy_mem -#define pci_legacy_read platform_pci_legacy_read -#define pci_legacy_write platform_pci_legacy_write - -struct pci_window { - struct resource resource; - u64 offset; -}; - -struct pci_controller { - void *acpi_handle; - void *iommu; - int segment; - int node; /* nearest node with memory or -1 for global allocation */ - - unsigned int windows; - struct pci_window *window; - - void *platform_data; -}; - -#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata) -#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment) - -extern struct pci_ops pci_root_ops; - -static inline int pci_proc_domain(struct pci_bus *bus) -{ - return (pci_domain_nr(bus) != 0); -} - -static inline void pcibios_add_platform_entries(struct pci_dev *dev) -{ -} - -extern void pcibios_resource_to_bus(struct pci_dev *dev, - struct pci_bus_region *region, struct resource *res); - -extern void pcibios_bus_to_resource(struct pci_dev *dev, - struct resource *res, struct pci_bus_region *region); - -#define pcibios_scan_all_fns(a, b) 0 - -#endif /* _ASM_IA64_PCI_H */ From bbe1791c798de2bb7ec5d45fd70e1635784279f7 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 13 Dec 2006 15:23:28 -0700 Subject: [PATCH 006/570] [IA64] enable build of sn2 + machvec support Signed-off-by: Jes Sorensen --- xen/arch/ia64/linux-xen/Makefile | 2 ++ xen/arch/ia64/linux/Makefile | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/xen/arch/ia64/linux-xen/Makefile b/xen/arch/ia64/linux-xen/Makefile index 980ea8e746..182cc8ebbf 100644 --- a/xen/arch/ia64/linux-xen/Makefile +++ b/xen/arch/ia64/linux-xen/Makefile @@ -1,3 +1,5 @@ +subdir-y += sn + obj-y += efi.o obj-y += entry.o obj-y += irq_ia64.o diff --git a/xen/arch/ia64/linux/Makefile b/xen/arch/ia64/linux/Makefile index 4f7cd5a83b..843c849fb9 100644 --- a/xen/arch/ia64/linux/Makefile +++ b/xen/arch/ia64/linux/Makefile @@ -1,3 +1,7 @@ +subdir-y += dig +subdir-y += hp +subdir-y += sn + obj-y += bitop.o obj-y += clear_page.o obj-y += cmdline.o From 826c9da7277a36bfa28623d17e7e37c2967b1a7e Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 14 Dec 2006 11:01:37 -0700 Subject: [PATCH 007/570] [IA64] Use sn_sal.h directly from upstream Linux Take a straight copy of sn_sal.h from linux 2.6.19 - there is no reason to hide parts of this file as it's all macros and inline functions Signed-off-by: Jes Sorensen --- xen/include/asm-ia64/linux-xen/asm/sn/README.origin | 1 - xen/include/asm-ia64/linux/asm/sn/README.origin | 1 + xen/include/asm-ia64/{linux-xen => linux}/asm/sn/sn_sal.h | 4 ---- 3 files changed, 1 insertion(+), 5 deletions(-) rename xen/include/asm-ia64/{linux-xen => linux}/asm/sn/sn_sal.h (99%) diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/README.origin b/xen/include/asm-ia64/linux-xen/asm/sn/README.origin index 3adc60fea0..762d1f5a9c 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/README.origin +++ b/xen/include/asm-ia64/linux-xen/asm/sn/README.origin @@ -13,5 +13,4 @@ io.h -> linux/include/asm-ia64/sn/io.h nodepda.h -> linux/include/asm-ia64/sn/nodepda.h pcibr_provider.h -> linux/include/asm-ia64/sn/pcibr_provider.h rw_mmr.h -> linux/include/asm-ia64/sn/rw_mmr.h -sn_sal.h -> linux/include/asm-ia64/sn/sn_sal.h types.h -> linux/include/asm-ia64/sn/types.h diff --git a/xen/include/asm-ia64/linux/asm/sn/README.origin b/xen/include/asm-ia64/linux/asm/sn/README.origin index da44c15c0a..5d8d7cb671 100644 --- a/xen/include/asm-ia64/linux/asm/sn/README.origin +++ b/xen/include/asm-ia64/linux/asm/sn/README.origin @@ -18,6 +18,7 @@ shubio.h -> linux/include/asm-ia64/sn/shubio.h simulator.h -> linux/include/asm-ia64/sn/simulator.h sn_cpuid.h -> linux/include/asm-ia64/sn/sn_cpuid.h sn_feature_sets.h -> linux/include/asm-ia64/sn/sn_feature_sets.h +sn_sal.h -> linux/include/asm-ia64/sn/sn_sal.h tiocp.h -> linux/include/asm-ia64/sn/tiocp.h xbow.h -> linux/arch/ia64/sn/include/xtalk/xbow.h xwidgetdev.h -> linux/arch/ia64/sn/include/xtalk/xwidgetdev.h diff --git a/xen/include/asm-ia64/linux-xen/asm/sn/sn_sal.h b/xen/include/asm-ia64/linux/asm/sn/sn_sal.h similarity index 99% rename from xen/include/asm-ia64/linux-xen/asm/sn/sn_sal.h rename to xen/include/asm-ia64/linux/asm/sn/sn_sal.h index a87e6592b2..ba826b3f75 100644 --- a/xen/include/asm-ia64/linux-xen/asm/sn/sn_sal.h +++ b/xen/include/asm-ia64/linux/asm/sn/sn_sal.h @@ -148,7 +148,6 @@ #define SN_SAL_FAKE_PROM 0x02009999 -#ifndef XEN /** * sn_sal_revision - get the SGI SAL revision number * @@ -222,7 +221,6 @@ ia64_sn_get_klconfig_addr(nasid_t nasid) SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0); return ret_stuff.v0 ? __va(ret_stuff.v0) : NULL; } -#endif /* !XEN */ /* * Returns the next console character. @@ -301,7 +299,6 @@ ia64_sn_console_putb(const char *buf, int len) return (u64)0; } -#ifndef XEN /* * Print a platform error record */ @@ -1086,7 +1083,6 @@ ia64_sn_hwperf_op(nasid_t nasid, u64 opcode, u64 a0, u64 a1, u64 a2, *v0 = (int) rv.v0; return (int) rv.status; } -#endif /* !XEN */ static inline int ia64_sn_ioif_get_pci_topology(u64 buf, u64 len) From 6bfc638774f431490d3ba136ca6b606eddb401c1 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 14 Dec 2006 13:23:33 -0700 Subject: [PATCH 008/570] [IA64] Move machvec.h to linux-xen Necessary to clean up warnings Signed-off-by: Alex Williamson --- xen/include/asm-ia64/linux-xen/asm/README.origin | 1 + xen/include/asm-ia64/{linux => linux-xen}/asm/machvec.h | 0 xen/include/asm-ia64/linux/asm/README.origin | 1 - 3 files changed, 1 insertion(+), 1 deletion(-) rename xen/include/asm-ia64/{linux => linux-xen}/asm/machvec.h (100%) diff --git a/xen/include/asm-ia64/linux-xen/asm/README.origin b/xen/include/asm-ia64/linux-xen/asm/README.origin index e3c092976c..23aa5b3ef4 100644 --- a/xen/include/asm-ia64/linux-xen/asm/README.origin +++ b/xen/include/asm-ia64/linux-xen/asm/README.origin @@ -36,6 +36,7 @@ perfmon.h -> linux/include/asm-ia64/perfmon.h perfmon_default_smpl.h -> linux/include/asm-ia64/perfmon_default_smpl.h # The files below are from Linux-2.6.19 +machvec.h -> linux/include/asm-ia64/machvec.h machvec_dig.h -> linux/include/asm-ia64/machvec_dig.h machvec_sn2.h -> linux/include/asm-ia64/machvec_sn2.h machvec_hpzx1.h -> linux/include/asm-ia64/machvec_hpzx1.h diff --git a/xen/include/asm-ia64/linux/asm/machvec.h b/xen/include/asm-ia64/linux-xen/asm/machvec.h similarity index 100% rename from xen/include/asm-ia64/linux/asm/machvec.h rename to xen/include/asm-ia64/linux-xen/asm/machvec.h diff --git a/xen/include/asm-ia64/linux/asm/README.origin b/xen/include/asm-ia64/linux/asm/README.origin index b7228fae33..48ca126508 100644 --- a/xen/include/asm-ia64/linux/asm/README.origin +++ b/xen/include/asm-ia64/linux/asm/README.origin @@ -21,7 +21,6 @@ intrinsics.h -> linux/include/asm-ia64/intrinsics.h ioctl.h -> linux/include/asm-ia64/ioctl.h irq.h -> linux/include/asm-ia64/irq.h linkage.h -> linux/include/asm-ia64/linkage.h -machvec.h -> linux/include/asm-ia64/machvec.h machvec_hpsim.h -> linux/include/asm-ia64/machvec_hpsim.h mca.h -> linux/include/asm-ia64/mca.h nodedata.h -> linux/include/asm-ia64/nodedate.h From 0e6813beaa1310885e358139a8cab33643b2679e Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 14 Dec 2006 13:25:49 -0700 Subject: [PATCH 009/570] [IA64] Machvec warning fixes The compiler doesn't like using machvec_noop for everything Signed-off-by: Alex Williamson --- xen/include/asm-ia64/linux-xen/asm/machvec.h | 108 ++++++++++++++++++ .../asm-ia64/linux-xen/asm/machvec_dig.h | 34 +++--- .../asm-ia64/linux-xen/asm/machvec_hpzx1.h | 34 +++--- .../asm-ia64/linux-xen/asm/machvec_sn2.h | 33 +++--- 4 files changed, 164 insertions(+), 45 deletions(-) diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec.h b/xen/include/asm-ia64/linux-xen/asm/machvec.h index 79e89a7db5..fd1f883b63 100644 --- a/xen/include/asm-ia64/linux-xen/asm/machvec.h +++ b/xen/include/asm-ia64/linux-xen/asm/machvec.h @@ -85,6 +85,114 @@ machvec_noop_mm (struct mm_struct *mm) { } +#ifdef XEN +#include +/* + * These should never get called, they just fill out the machine + * vectors and make the compiler happy. + */ +static inline void* +machvec_noop_dma_alloc_coherent (struct device *dev, size_t size, + dma_addr_t *addr, int dir) +{ + panic("%s() called", __FUNCTION__); + return (void *)0; +} + +static inline void +machvec_noop_dma_free_coherent (struct device *dev, size_t size, + void *vaddr, dma_addr_t handle) +{ + panic("%s() called", __FUNCTION__); +} + +static inline dma_addr_t +machvec_noop_dma_map_single (struct device *dev, void *addr, + size_t size, int dir) +{ + panic("%s() called", __FUNCTION__); + return (dma_addr_t)0; +} + +static inline void +machvec_noop_dma_unmap_single (struct device *dev, dma_addr_t vaddr, + size_t size, int dir) +{ + panic("%s() called", __FUNCTION__); +} + +static inline int +machvec_noop_dma_map_sg (struct device *dev, struct scatterlist *sglist, + int nents, int dir) +{ + panic("%s() called", __FUNCTION__); + return 0; +} + +static inline void +machvec_noop_dma_unmap_sg (struct device *dev, struct scatterlist *sglist, + int nents, int dir) +{ + panic("%s() called", __FUNCTION__); +} + +static inline void +machvec_noop_dma_sync_single_for_cpu (struct device *dev, dma_addr_t vaddr, + size_t size, int dir) +{ + panic("%s() called", __FUNCTION__); +} + +#define machvec_noop_dma_sync_single_for_device \ + machvec_noop_dma_sync_single_for_cpu + +static inline void +machvec_noop_dma_sync_sg_for_cpu (struct device *dev, + struct scatterlist *sglist, + int nents, int dir) +{ + panic("%s() called", __FUNCTION__); +} + +#define machvec_noop_dma_sync_sg_for_device \ + machvec_noop_dma_sync_sg_for_cpu + +static inline int +machvec_noop_dma_mapping_error (dma_addr_t dma_addr) +{ + panic("%s() called", __FUNCTION__); + return 1; +} + +static inline int +machvec_noop_dma_supported (struct device *dev, u64 mask) +{ + panic("%s() called", __FUNCTION__); + return 0; +} + +static inline char* +machvec_noop_pci_get_legacy_mem (struct pci_bus *bus) +{ + panic("%s() called", __FUNCTION__); + return 0; +} + +static inline int +machvec_noop_pci_legacy_read (struct pci_bus *bus, u16 port, u32 *val, u8 size) +{ + panic("%s() called", __FUNCTION__); + return 0; +} + +static inline int +machvec_noop_pci_legacy_write (struct pci_bus *bus, u16 port, u32 val, u8 size) +{ + panic("%s() called", __FUNCTION__); + return 0; +} +#endif + extern void machvec_setup (char **); extern void machvec_timer_interrupt (int, void *, struct pt_regs *); extern void machvec_dma_sync_single (struct device *, dma_addr_t, size_t, int); diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h b/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h index 9872a3458d..a8b658720f 100644 --- a/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_dig.h @@ -19,22 +19,26 @@ extern ia64_mv_setup_t hpsim_setup; #define platform_setup hpsim_setup #define platform_dma_init machvec_noop -#define platform_dma_alloc_coherent machvec_noop -#define platform_dma_free_coherent machvec_noop -#define platform_dma_map_single machvec_noop -#define platform_dma_unmap_single machvec_noop -#define platform_dma_map_sg machvec_noop -#define platform_dma_unmap_sg machvec_noop -#define platform_dma_sync_single_for_cpu machvec_noop -#define platform_dma_sync_sg_for_cpu machvec_noop -#define platform_dma_sync_single_for_device machvec_noop -#define platform_dma_sync_sg_for_device machvec_noop -#define platform_dma_mapping_error machvec_noop -#define platform_dma_supported machvec_noop +#define platform_dma_alloc_coherent machvec_noop_dma_alloc_coherent +#define platform_dma_free_coherent machvec_noop_dma_free_coherent +#define platform_dma_map_single machvec_noop_dma_map_single +#define platform_dma_unmap_single machvec_noop_dma_unmap_single +#define platform_dma_map_sg machvec_noop_dma_map_sg +#define platform_dma_unmap_sg machvec_noop_dma_unmap_sg +#define platform_dma_sync_single_for_cpu \ + machvec_noop_dma_sync_single_for_cpu +#define platform_dma_sync_sg_for_cpu \ + machvec_noop_dma_sync_sg_for_cpu +#define platform_dma_sync_single_for_device \ + machvec_noop_dma_sync_single_for_device +#define platform_dma_sync_sg_for_device \ + machvec_noop_dma_sync_sg_for_device +#define platform_dma_mapping_error machvec_noop_dma_mapping_error +#define platform_dma_supported machvec_noop_dma_supported -#define platform_pci_get_legacy_mem machvec_noop -#define platform_pci_legacy_read machvec_noop -#define platform_pci_legacy_write machvec_noop +#define platform_pci_get_legacy_mem machvec_noop_pci_get_legacy_mem +#define platform_pci_legacy_read machvec_noop_pci_legacy_read +#define platform_pci_legacy_write machvec_noop_pci_legacy_write #else #define platform_setup dig_setup #endif diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h b/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h index 675c6b8cce..96a85ce2ce 100644 --- a/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_hpzx1.h @@ -26,22 +26,26 @@ extern ia64_mv_irq_init_t hpsim_irq_init; #define platform_irq_init hpsim_irq_init #define platform_dma_init machvec_noop -#define platform_dma_alloc_coherent machvec_noop -#define platform_dma_free_coherent machvec_noop -#define platform_dma_map_single machvec_noop -#define platform_dma_unmap_single machvec_noop -#define platform_dma_map_sg machvec_noop -#define platform_dma_unmap_sg machvec_noop -#define platform_dma_sync_single_for_cpu machvec_noop -#define platform_dma_sync_sg_for_cpu machvec_noop -#define platform_dma_sync_single_for_device machvec_noop -#define platform_dma_sync_sg_for_device machvec_noop -#define platform_dma_mapping_error machvec_noop -#define platform_dma_supported machvec_noop +#define platform_dma_alloc_coherent machvec_noop_dma_alloc_coherent +#define platform_dma_free_coherent machvec_noop_dma_free_coherent +#define platform_dma_map_single machvec_noop_dma_map_single +#define platform_dma_unmap_single machvec_noop_dma_unmap_single +#define platform_dma_map_sg machvec_noop_dma_map_sg +#define platform_dma_unmap_sg machvec_noop_dma_unmap_sg +#define platform_dma_sync_single_for_cpu \ + machvec_noop_dma_sync_single_for_cpu +#define platform_dma_sync_sg_for_cpu \ + machvec_noop_dma_sync_sg_for_cpu +#define platform_dma_sync_single_for_device \ + machvec_noop_dma_sync_single_for_device +#define platform_dma_sync_sg_for_device \ + machvec_noop_dma_sync_sg_for_device +#define platform_dma_mapping_error machvec_noop_dma_mapping_error +#define platform_dma_supported machvec_noop_dma_supported -#define platform_pci_get_legacy_mem machvec_noop -#define platform_pci_legacy_read machvec_noop -#define platform_pci_legacy_write machvec_noop +#define platform_pci_get_legacy_mem machvec_noop_pci_get_legacy_mem +#define platform_pci_legacy_read machvec_noop_pci_legacy_read +#define platform_pci_legacy_write machvec_noop_pci_legacy_write #else #define platform_setup dig_setup #define platform_dma_init machvec_noop diff --git a/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h b/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h index fbbae81086..4af484a7d9 100644 --- a/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h +++ b/xen/include/asm-ia64/linux-xen/asm/machvec_sn2.h @@ -110,9 +110,9 @@ extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; #define platform_readq_relaxed __sn_readq_relaxed #define platform_local_vector_to_irq sn_local_vector_to_irq #ifdef XEN -#define platform_pci_get_legacy_mem machvec_noop -#define platform_pci_legacy_read machvec_noop -#define platform_pci_legacy_write machvec_noop +#define platform_pci_get_legacy_mem machvec_noop_pci_get_legacy_mem +#define platform_pci_legacy_read machvec_noop_pci_legacy_read +#define platform_pci_legacy_write machvec_noop_pci_legacy_write #else #define platform_pci_get_legacy_mem sn_pci_get_legacy_mem #define platform_pci_legacy_read sn_pci_legacy_read @@ -120,18 +120,21 @@ extern ia64_mv_teardown_msi_irq_t sn_teardown_msi_irq; #endif #define platform_dma_init machvec_noop #ifdef XEN -#define platform_dma_alloc_coherent machvec_noop -#define platform_dma_free_coherent machvec_noop -#define platform_dma_map_single machvec_noop -#define platform_dma_unmap_single machvec_noop -#define platform_dma_map_sg machvec_noop -#define platform_dma_unmap_sg machvec_noop -#define platform_dma_sync_single_for_cpu machvec_noop -#define platform_dma_sync_sg_for_cpu machvec_noop -#define platform_dma_sync_single_for_device machvec_noop -#define platform_dma_sync_sg_for_device machvec_noop -#define platform_dma_mapping_error machvec_noop -#define platform_dma_supported machvec_noop +#define platform_dma_alloc_coherent machvec_noop_dma_alloc_coherent +#define platform_dma_free_coherent machvec_noop_dma_free_coherent +#define platform_dma_map_single machvec_noop_dma_map_single +#define platform_dma_unmap_single machvec_noop_dma_unmap_single +#define platform_dma_map_sg machvec_noop_dma_map_sg +#define platform_dma_unmap_sg machvec_noop_dma_unmap_sg +#define platform_dma_sync_single_for_cpu \ + machvec_noop_dma_sync_single_for_cpu +#define platform_dma_sync_sg_for_cpu \ + machvec_noop_dma_sync_sg_for_cpu +#define platform_dma_sync_single_for_device \ + machvec_noop_dma_sync_single_for_device +#define platform_dma_sync_sg_for_device machvec_noop_dma_sync_sg_for_device +#define platform_dma_mapping_error machvec_noop_dma_mapping_error +#define platform_dma_supported machvec_noop_dma_supported #else #define platform_dma_alloc_coherent sn_dma_alloc_coherent #define platform_dma_free_coherent sn_dma_free_coherent From 82c67ef684a42eb0d8d37e3254234fff6bf4c253 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 14 Dec 2006 13:29:17 -0700 Subject: [PATCH 010/570] [IA64] SN2 warning fixes Mainly unused variable removal Signed-off-by: Alex Williamson --- xen/arch/ia64/linux-xen/sn/kernel/io_init.c | 2 ++ xen/arch/ia64/linux-xen/sn/kernel/irq.c | 8 ++++++-- xen/arch/ia64/linux-xen/sn/kernel/setup.c | 4 ++++ xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c | 4 ++-- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/xen/arch/ia64/linux-xen/sn/kernel/io_init.c b/xen/arch/ia64/linux-xen/sn/kernel/io_init.c index 973211e721..3f1f5b7a3c 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/io_init.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/io_init.c @@ -646,8 +646,10 @@ void sn_bus_free_sysdata(void) static int __init sn_pci_init(void) { +#ifndef XEN int i, j; struct pci_dev *pci_dev = NULL; +#endif if (!ia64_platform_is("sn2") || IS_RUNNING_ON_FAKE_PROM()) return 0; diff --git a/xen/arch/ia64/linux-xen/sn/kernel/irq.c b/xen/arch/ia64/linux-xen/sn/kernel/irq.c index 4e55e627e6..cc126d71ee 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/irq.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/irq.c @@ -31,8 +31,10 @@ #endif static void force_interrupt(int irq); +#ifndef XEN static void register_intr_pda(struct sn_irq_info *sn_irq_info); static void unregister_intr_pda(struct sn_irq_info *sn_irq_info); +#endif int sn_force_interrupt_flag = 1; extern int sn_ioif_inited; @@ -240,10 +242,10 @@ unsigned int sn_local_vector_to_irq(u8 vector) void sn_irq_init(void) { +#ifndef XEN int i; irq_desc_t *base_desc = irq_desc; -#ifndef XEN ia64_first_device_vector = IA64_SN2_FIRST_DEVICE_VECTOR; ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; @@ -255,6 +257,7 @@ void sn_irq_init(void) #endif } +#ifndef XEN static void register_intr_pda(struct sn_irq_info *sn_irq_info) { int irq = sn_irq_info->irq_irq; @@ -329,6 +332,7 @@ static void unregister_intr_pda(struct sn_irq_info *sn_irq_info) spin_unlock(&sn_irq_info_lock); #endif } +#endif /* XEN */ #ifndef XEN static void sn_irq_info_free(struct rcu_head *head) @@ -487,10 +491,10 @@ static void sn_check_intr(int irq, struct sn_irq_info *sn_irq_info) void sn_lb_int_war_check(void) { +#ifndef XEN struct sn_irq_info *sn_irq_info; int i; -#ifndef XEN #ifdef XEN if (pda->sn_first_irq == 0) #else diff --git a/xen/arch/ia64/linux-xen/sn/kernel/setup.c b/xen/arch/ia64/linux-xen/sn/kernel/setup.c index 30ba5263ae..e1d48fa9fd 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/setup.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/setup.c @@ -413,7 +413,11 @@ void __cpuinit sn_cpu_init(void); void __init sn_setup(char **cmdline_p) { +#ifndef XEN long status, ticks_per_sec, drift; +#else + unsigned long status, ticks_per_sec, drift; +#endif u32 version = sn_sal_rev(); #ifndef XEN extern void sn_cpu_init(void); diff --git a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c index 262e8453f3..71bef9e9ab 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c @@ -157,7 +157,7 @@ void sn_tlb_migrate_finish(struct mm_struct *mm) */ #ifdef XEN /* Xen is soooooooo stupid! */ -static cpumask_t mask_all = CPU_MASK_ALL; +// static cpumask_t mask_all = CPU_MASK_ALL; #endif void @@ -172,7 +172,7 @@ sn2_global_tlb_purge(unsigned long start, #ifndef XEN int mymm = (mm == current->active_mm && mm == current->mm); #else - struct mm_struct *mm; + // struct mm_struct *mm; int mymm = 1; #endif int use_cpu_ptcga; From 4d803dc258b8d596d6a040077baf53892af466ed Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Fri, 15 Dec 2006 10:59:33 -0700 Subject: [PATCH 011/570] [IA64] Use machine vector for global tlb purge Switch to using the platform vector for global tlb purges. In fact nothing should be calling ia64_global_tlb_purge() directly. Signed-off-by: Jes Sorensen --- xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c | 2 +- xen/arch/ia64/xen/vhpt.c | 8 +++----- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c index 71bef9e9ab..ec7c45ef1e 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c @@ -173,7 +173,7 @@ sn2_global_tlb_purge(unsigned long start, int mymm = (mm == current->active_mm && mm == current->mm); #else // struct mm_struct *mm; - int mymm = 1; + int mymm = 0; #endif int use_cpu_ptcga; volatile unsigned long *ptc0, *ptc1; diff --git a/xen/arch/ia64/xen/vhpt.c b/xen/arch/ia64/xen/vhpt.c index 05382370cc..0ba1f93a9b 100644 --- a/xen/arch/ia64/xen/vhpt.c +++ b/xen/arch/ia64/xen/vhpt.c @@ -21,9 +21,6 @@ #include #include -/* Defined in tlb.c */ -extern void ia64_global_tlb_purge(u64 start, u64 end, u64 nbits); - extern long running_on_sim; DEFINE_PER_CPU (unsigned long, vhpt_paddr); @@ -364,7 +361,7 @@ void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range) // ptc.ga has release semantics. /* ptc.ga */ - ia64_global_tlb_purge(vadr,vadr+addr_range,PAGE_SHIFT); + platform_global_tlb_purge(vadr, vadr + addr_range, PAGE_SHIFT); perfc_incrc(domain_flush_vtlb_range); } @@ -442,7 +439,8 @@ __domain_flush_vtlb_track_entry(struct domain* d, perfc_incrc(domain_flush_vtlb_local); } else { /* ptc.ga has release semantics. */ - ia64_global_tlb_purge(vaddr, vaddr + PAGE_SIZE, PAGE_SHIFT); + platform_global_tlb_purge(vaddr, vaddr + PAGE_SIZE, + PAGE_SHIFT); perfc_incrc(domain_flush_vtlb_global); } From afdb8d0deb4850411b9774dec8e201e12ea0b73a Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Tue, 19 Dec 2006 12:40:06 -0700 Subject: [PATCH 012/570] [IA64] don't dereference xen_start_info when running on raw hardware Check we are running under Xen before trying to dereference xen_start_info! xen_start_info is NULL on ia64 if running raw hardware. Based on patch by Jes Sorensen Signed-off-by: Alex Williamson --- linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h index 083884c130..6485dd87f0 100644 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypervisor.h @@ -215,7 +215,8 @@ asmlinkage int xprintk(const char *fmt, ...); #endif /* CONFIG_XEN || CONFIG_VMX_GUEST */ #ifdef CONFIG_XEN_PRIVILEGED_GUEST -#define is_initial_xendomain() (xen_start_info->flags & SIF_INITDOMAIN) +#define is_initial_xendomain() \ + (is_running_on_xen() ? xen_start_info->flags & SIF_INITDOMAIN : 0) #else #define is_initial_xendomain() 0 #endif From b2f52ec827d5cfb85e385eb6f2045b2360622943 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Tue, 19 Dec 2006 12:41:30 -0700 Subject: [PATCH 013/570] [IA64] don't allocate bitmap from low pool No need to allocate contiguous_bitmap out of the low pages pool as all pages are directly accessible on an ia64. Signed-off-by: Jes Sorensen --- linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c index 9bd507a6bf..173a4f613a 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c @@ -60,7 +60,7 @@ void contiguous_bitmap_init(unsigned long end_pfn) { unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3; - contiguous_bitmap = alloc_bootmem_low_pages(size); + contiguous_bitmap = alloc_bootmem_pages(size); BUG_ON(!contiguous_bitmap); memset(contiguous_bitmap, 0, size); } From dd02fb54d00efdb57111d031879b37dcfa93b755 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Tue, 19 Dec 2006 13:21:24 -0700 Subject: [PATCH 014/570] [IA64] sn2 - only get nasid from nodepda if sn_nodepda is available fall back to getting nasid from sal cal if sn_nodepda is not yet available Signed-off-by: Jes Sorensen --- xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c index ec7c45ef1e..954a2f4bd8 100644 --- a/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c +++ b/xen/arch/ia64/linux-xen/sn/kernel/sn2_smp.c @@ -438,6 +438,11 @@ void sn2_send_IPI(int cpuid, int vector, int delivery_mode, int redirect) int nasid; physid = cpu_physical_id(cpuid); +#ifdef XEN + if (!sn_nodepda) { + ia64_sn_get_sapic_info(physid, &nasid, NULL, NULL); + } else +#endif nasid = cpuid_to_nasid(cpuid); /* the following is used only when starting cpus at boot time */ From 5a0c8b2704b70e808742f1ec968f3b396733a77c Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 20 Dec 2006 08:53:42 -0700 Subject: [PATCH 015/570] [IA64] Follow new interrupt deliver mechanism for PV-on-HVM/IPF This fixes PV-on-HVM drivers for ia64 Signed-off-by: Tsunehisa Doi --- .../linux-2.6/platform-pci/platform-pci.c | 9 +++++++-- xen/arch/ia64/vmx/vmx_process.c | 13 +++++++++++-- xen/include/public/arch-ia64.h | 4 ++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c index 3a2453a25c..b529ce1308 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c @@ -182,12 +182,17 @@ static int get_hypercall_stubs(void) static int get_callback_irq(struct pci_dev *pdev) { #ifdef __ia64__ - int irq; + int irq, rid; for (irq = 0; irq < 16; irq++) { if (isa_irq_to_vector(irq) == pdev->irq) return irq; } - return 0; + /* use Requester-ID as callback_irq */ + /* RID: '<#bus(8)><#dev(5)><#func(3)>' (cf. PCI-Express spec) */ + rid = ((pdev->bus->number & 0xff) << 8) | pdev->devfn; + printk(KERN_INFO DRV_NAME ":use Requester-ID(%04x) as callback irq\n", + rid); + return rid | HVM_PARAM_CALLBACK_IRQ_RID; #else /* !__ia64__ */ return pdev->irq; #endif diff --git a/xen/arch/ia64/vmx/vmx_process.c b/xen/arch/ia64/vmx/vmx_process.c index 94011beb71..1fce5524b5 100644 --- a/xen/arch/ia64/vmx/vmx_process.c +++ b/xen/arch/ia64/vmx/vmx_process.c @@ -212,8 +212,17 @@ void leave_hypervisor_tail(struct pt_regs *regs) if (callback_irq != 0 && local_events_need_delivery()) { /* change level for para-device callback irq */ /* use level irq to send discrete event */ - viosapic_set_irq(d, callback_irq, 1); - viosapic_set_irq(d, callback_irq, 0); + if (callback_irq & HVM_PARAM_CALLBACK_IRQ_RID) { + /* case of using Requester-ID as callback irq */ + /* RID: '<#bus(8)><#dev(5)><#func(3)>' */ + int dev = (callback_irq >> 3) & 0x1f; + viosapic_set_pci_irq(d, dev, 0, 1); + viosapic_set_pci_irq(d, dev, 0, 0); + } else { + /* case of using GSI as callback irq */ + viosapic_set_irq(d, callback_irq, 1); + viosapic_set_irq(d, callback_irq, 0); + } } } diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index 65cc233af3..b2830f6c66 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -62,6 +62,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); #define VIRQ_MCA_CMC VIRQ_ARCH_1 /* MCA cmc interrupt */ #define VIRQ_MCA_CPE VIRQ_ARCH_2 /* MCA cpe interrupt */ +/* Arch specific callback irq definition */ +/* using Requester-ID(RID) as callback irq */ +#define HVM_PARAM_CALLBACK_IRQ_RID (1 << 31) + /* Maximum number of virtual CPUs in multi-processor guests. */ /* WARNING: before changing this, check that shared_info fits on a page */ #define MAX_VIRT_CPUS 64 From 55bf8132094b08561481264eb433bfedb1bd4286 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Tue, 2 Jan 2007 14:45:32 +0000 Subject: [PATCH 016/570] Minor extra logging. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomainInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 46eb9cda9b..2df5316fcf 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -439,7 +439,7 @@ class XendDomainInfo: def shutdown(self, reason): """Shutdown a domain by signalling this via xenstored.""" - log.debug('XendDomainInfo.shutdown') + log.debug('XendDomainInfo.shutdown(%s)', reason) if self.state in (DOM_STATE_SHUTDOWN, DOM_STATE_HALTED,): raise XendError('Domain cannot be shutdown') From 7f015ff4a50c366e94ad4955c44972a1adf5bf47 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Tue, 2 Jan 2007 14:46:13 +0000 Subject: [PATCH 017/570] Reset the option-parsing object before using it -- this means that the option parsing works when using xm shell. Signed-off-by: Ewan Mellor --- tools/python/xen/xm/migrate.py | 1 + tools/python/xen/xm/shutdown.py | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/python/xen/xm/migrate.py b/tools/python/xen/xm/migrate.py index 72aca71932..2b77e6b1ab 100644 --- a/tools/python/xen/xm/migrate.py +++ b/tools/python/xen/xm/migrate.py @@ -52,6 +52,7 @@ def help(): def main(argv): opts = gopts + opts.reset() args = opts.parse(argv) if len(args) != 2: diff --git a/tools/python/xen/xm/shutdown.py b/tools/python/xen/xm/shutdown.py index b5542d9611..88d36dfba1 100644 --- a/tools/python/xen/xm/shutdown.py +++ b/tools/python/xen/xm/shutdown.py @@ -118,6 +118,7 @@ def main_dom(opts, args): def main(argv): opts = gopts + opts.reset() args = opts.parse(argv) if opts.vals.help: return From 4ab431ac50ebefac978a5fea59be602a173ac874 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Tue, 2 Jan 2007 15:19:44 -0700 Subject: [PATCH 018/570] [IA64] vcpu_get_psr fix mov r1=psr only return PSR{36:35,31:0} Signed-off-by: Anthony Xu --- xen/arch/ia64/xen/vcpu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index 6c3861a3a9..da609c8a8e 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -450,8 +450,6 @@ IA64FAULT vcpu_get_psr(VCPU * vcpu, u64 * pval) struct ia64_psr newpsr; newpsr = *(struct ia64_psr *)®s->cr_ipsr; - if (newpsr.cpl == 2) - newpsr.cpl = 0; if (!vcpu->vcpu_info->evtchn_upcall_mask) newpsr.i = 1; else @@ -469,6 +467,7 @@ IA64FAULT vcpu_get_psr(VCPU * vcpu, u64 * pval) else newpsr.pp = 0; *pval = *(unsigned long *)&newpsr; + *pval &= (MASK(0, 32) | MASK(35, 2)); return IA64_NO_FAULT; } From 571d6c1772bc8cc6d8967552af8bbd26a4b4971e Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Tue, 2 Jan 2007 16:27:50 -0700 Subject: [PATCH 019/570] [IA64] remove the requirement (vpsr.ic==0) from hyperprivop remove the requirement (vpsr.ic==0) from hyperprivop There two reasons for this. 1. make xen-parse code more readable. 2. a little bit performance improvement Signed-off-by: Anthony Xu --- linux-2.6-xen-sparse/arch/ia64/kernel/gate.S | 24 +--- .../arch/ia64/kernel/gate.lds.S | 8 -- linux-2.6-xen-sparse/arch/ia64/kernel/patch.c | 4 - .../arch/ia64/xen/hypercall.S | 103 ------------------ linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S | 27 ++--- linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S | 48 ++++---- linux-2.6-xen-sparse/arch/ia64/xen/xenpal.S | 14 +-- .../include/asm-ia64/xen/privop.h | 10 +- xen/arch/ia64/xen/faults.c | 3 +- xen/arch/ia64/xen/ivt.S | 25 +++-- xen/include/public/arch-ia64.h | 53 ++++----- 11 files changed, 97 insertions(+), 222 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S b/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S index ae8c2ef88e..6a13812893 100644 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S @@ -57,18 +57,6 @@ [1:] movl reg=0; \ .xdata4 ".data.patch.running_on_xen", 1b-. - .section ".data.patch.brl_xen_rsm_be_i", "a" - .previous -#define BRL_COND_XEN_RSM_BE_I(pr) \ -[1:](pr)brl.cond.sptk 0; \ - .xdata4 ".data.patch.brl_xen_rsm_be_i", 1b-. - - .section ".data.patch.brl_xen_get_psr", "a" - .previous -#define BRL_COND_XEN_GET_PSR(pr) \ -[1:](pr)brl.cond.sptk 0; \ - .xdata4 ".data.patch.brl_xen_get_psr", 1b-. - .section ".data.patch.brl_xen_ssm_i_0", "a" .previous #define BRL_COND_XEN_SSM_I_0(pr) \ @@ -156,9 +144,9 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) cmp.ne isXen,isRaw=r0,r30 ;; (isRaw) rsm psr.be | psr.i - BRL_COND_XEN_RSM_BE_I(isXen) - .global .vdso_rsm_be_i_ret -.vdso_rsm_be_i_ret: +(isXen) st1 [r22]=r20 +(isXen) XEN_HYPER_RSM_BE + ;; #else rsm psr.be | psr.i // M2 (5 cyc to srlz.d) #endif @@ -171,9 +159,9 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) lfetch [r18] // M0|1 #ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT (isRaw) mov r29=psr - BRL_COND_XEN_GET_PSR(isXen) - .global .vdso_get_psr_ret -.vdso_get_psr_ret: +(isXen) XEN_HYPER_GET_PSR + ;; +(isXen) mov r29=r8 #else mov r29=psr // M2 (12 cyc) #endif diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/gate.lds.S b/linux-2.6-xen-sparse/arch/ia64/kernel/gate.lds.S index 45377beaa4..1e38ab3d7a 100644 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/gate.lds.S +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/gate.lds.S @@ -50,14 +50,6 @@ SECTIONS *(.data.patch.running_on_xen) __end_gate_running_on_xen_patchlist = .; - __start_gate_brl_xen_rsm_be_i_patchlist = .; - *(.data.patch.brl_xen_rsm_be_i) - __end_gate_brl_xen_rsm_be_i_patchlist = .; - - __start_gate_brl_xen_get_psr_patchlist = .; - *(.data.patch.brl_xen_get_psr) - __end_gate_brl_xen_get_psr_patchlist = .; - __start_gate_brl_xen_ssm_i_0_patchlist = .; *(.data.patch.brl_xen_ssm_i_0) __end_gate_brl_xen_ssm_i_0_patchlist = .; diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/patch.c b/linux-2.6-xen-sparse/arch/ia64/kernel/patch.c index 6e277e494d..a880c34799 100644 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/patch.c +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/patch.c @@ -236,13 +236,9 @@ patch_brl_symaddr(unsigned long start, unsigned long end, static void patch_brl_in_vdso(void) { - EXTERN_PATCHLIST(xen_rsm_be_i); - EXTERN_PATCHLIST(xen_get_psr); EXTERN_PATCHLIST(xen_ssm_i_0); EXTERN_PATCHLIST(xen_ssm_i_1); - PATCH_BRL_SYMADDR(xen_rsm_be_i); - PATCH_BRL_SYMADDR(xen_get_psr); PATCH_BRL_SYMADDR(xen_ssm_i_0); PATCH_BRL_SYMADDR(xen_ssm_i_1); } diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S index 1aff9c6564..fd266d0d17 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S @@ -8,40 +8,15 @@ #include #include -/* To clear vpsr.ic, vpsr.i needs to be cleared first */ -#define XEN_CLEAR_PSR_IC \ - mov r14=1; \ - movl r15=XSI_PSR_I_ADDR; \ - movl r2=XSI_PSR_IC; \ - ;; \ - ld8 r15=[r15]; \ - ld4 r3=[r2]; \ - ;; \ - ld1 r16=[r15]; \ - ;; \ - st1 [r15]=r14; \ - st4 [r2]=r0; \ - ;; - -/* First restore vpsr.ic, and then vpsr.i */ -#define XEN_RESTORE_PSR_IC \ - st4 [r2]=r3; \ - st1 [r15]=r16; \ - ;; - GLOBAL_ENTRY(xen_get_ivr) movl r8=running_on_xen;; ld4 r8=[r8];; cmp.eq p7,p0=r8,r0;; (p7) mov r8=cr.ivr;; (p7) br.ret.sptk.many rp - ;; - XEN_CLEAR_PSR_IC ;; XEN_HYPER_GET_IVR ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp ;; END(xen_get_ivr) @@ -52,13 +27,9 @@ GLOBAL_ENTRY(xen_get_tpr) cmp.eq p7,p0=r8,r0;; (p7) mov r8=cr.tpr;; (p7) br.ret.sptk.many rp - ;; - XEN_CLEAR_PSR_IC ;; XEN_HYPER_GET_TPR ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp ;; END(xen_get_tpr) @@ -72,12 +43,8 @@ GLOBAL_ENTRY(xen_set_tpr) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_SET_TPR ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp ;; END(xen_set_tpr) @@ -91,12 +58,8 @@ GLOBAL_ENTRY(xen_eoi) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_EOI ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp ;; END(xen_eoi) @@ -110,12 +73,8 @@ GLOBAL_ENTRY(xen_thash) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_THASH ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp ;; END(xen_thash) @@ -129,12 +88,8 @@ GLOBAL_ENTRY(xen_set_itm) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_SET_ITM ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp ;; END(xen_set_itm) @@ -149,12 +104,8 @@ GLOBAL_ENTRY(xen_ptcga) mov r8=r32 mov r9=r33 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_PTC_GA ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp ;; END(xen_ptcga) @@ -168,12 +119,8 @@ GLOBAL_ENTRY(xen_get_rr) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_GET_RR ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp ;; END(xen_get_rr) @@ -188,12 +135,8 @@ GLOBAL_ENTRY(xen_set_rr) mov r8=r32 mov r9=r33 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_SET_RR ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp ;; END(xen_set_rr) @@ -240,12 +183,8 @@ GLOBAL_ENTRY(xen_set_kr) 1: mov r8=r32 mov r9=r33 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_SET_KR ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp END(xen_set_kr) @@ -258,12 +197,8 @@ GLOBAL_ENTRY(xen_fc) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_FC ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp END(xen_fc) @@ -276,12 +211,8 @@ GLOBAL_ENTRY(xen_get_cpuid) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_GET_CPUID ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp END(xen_get_cpuid) @@ -294,12 +225,8 @@ GLOBAL_ENTRY(xen_get_pmd) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_GET_PMD ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp END(xen_get_pmd) @@ -313,12 +240,8 @@ GLOBAL_ENTRY(xen_get_eflag) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_GET_EFLAG ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp END(xen_get_eflag) @@ -332,12 +255,8 @@ GLOBAL_ENTRY(xen_set_eflag) ;; mov r8=r32 ;; - XEN_CLEAR_PSR_IC - ;; XEN_HYPER_SET_EFLAG ;; - XEN_RESTORE_PSR_IC - ;; br.ret.sptk.many rp END(xen_set_eflag) #endif @@ -355,27 +274,6 @@ END(xen_send_ipi) #ifdef CONFIG_XEN_IA64_VDSO_PARAVIRT // Those are vdso specialized. // In fsys mode, call, ret can't be used. -GLOBAL_ENTRY(xen_rsm_be_i) - st1 [r22]=r20 - st4 [r23]=r0 - XEN_HYPER_RSM_BE - st4 [r23]=r20 - brl.cond.sptk .vdso_rsm_be_i_ret - ;; -END(xen_rsm_be_i) - -GLOBAL_ENTRY(xen_get_psr) - mov r31=r8 - mov r25=IA64_PSR_IC - st4 [r23]=r0 - XEN_HYPER_GET_PSR - ;; - st4 [r23]=r20 - or r29=r8,r25 // vpsr.ic was cleared for hyperprivop - mov r8=r31 - brl.cond.sptk .vdso_get_psr_ret - ;; -END(xen_get_psr) // see xen_ssm_i() in privop.h // r22 = &vcpu->vcpu_info->evtchn_upcall_mask @@ -395,7 +293,6 @@ END(xen_get_psr) (p14) cmp.ne.unc p11,p0=r0,r25; \ ;; \ (p11) st1 [r22]=r20; \ -(p11) st4 [r23]=r0; \ (p11) XEN_HYPER_SSM_I; GLOBAL_ENTRY(xen_ssm_i_0) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S index aad0aac631..4d468c70f9 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenentry.S @@ -59,12 +59,6 @@ GLOBAL_ENTRY(ia64_switch_to) shr.u r26=r20,IA64_GRANULE_SHIFT cmp.eq p7,p6=r25,in0 ;; -#ifdef CONFIG_XEN - movl r8=XSI_PSR_IC - ;; - st4 [r8]=r0 // force psr.ic off for hyperprivop(s) - ;; -#endif /* * If we've already mapped this task's page, we can skip doing it again. */ @@ -72,19 +66,13 @@ GLOBAL_ENTRY(ia64_switch_to) (p6) br.cond.dpnt .map ;; .done: + ld8 sp=[r21] // load kernel stack pointer of new task #ifdef CONFIG_XEN - // psr.ic already off // update "current" application register mov r8=IA64_KR_CURRENT mov r9=in0;; XEN_HYPER_SET_KR - ld8 sp=[r21] // load kernel stack pointer of new task - movl r27=XSI_PSR_IC - mov r8=1 - ;; - st4 [r27]=r8 // psr.ic back on #else - ld8 sp=[r21] // load kernel stack pointer of new task mov IA64_KR(CURRENT)=in0 // update "current" application register #endif mov r8=r13 // return pointer to previously running task @@ -99,7 +87,10 @@ GLOBAL_ENTRY(ia64_switch_to) .map: #ifdef CONFIG_XEN - // psr.ic already off + movl r25=XSI_PSR_IC // clear psr.ic + ;; + st4 [r25]=r0 + ;; #else rsm psr.ic // interrupts (psr.i) are already disabled here #endif @@ -132,7 +123,13 @@ GLOBAL_ENTRY(ia64_switch_to) #endif ;; itr.d dtr[r25]=r23 // wire in new mapping... -#ifndef CONFIG_XEN +#ifdef CONFIG_XEN + mov r9=1 + movl r8=XSI_PSR_IC + ;; + st4 [r8]=r9 + ;; +#else ssm psr.ic // reenable the psr.ic bit ;; srlz.d diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S b/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S index 6217a395ff..c7648e0bcd 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenivt.S @@ -709,11 +709,23 @@ ENTRY(page_fault) ;; #endif #ifdef CONFIG_XEN - br.cond.sptk.many xen_page_fault + +#define MASK_TO_PEND_OFS (-1) + +(p15) movl r14=XSI_PSR_I_ADDR ;; -done_xen_page_fault: -#endif +(p15) ld8 r14=[r14] + ;; +(p15) st1 [r14]=r0,MASK_TO_PEND_OFS // if (p15) vpsr.i = 1 + ;; // if (p15) (vcpu->vcpu_info->evtchn_upcall_mask)=0 +(p15) ld1 r14=[r14] // if (vcpu->vcpu_info->evtchn_upcall_pending) + ;; +(p15) cmp.ne p15,p0=r14,r0 + ;; +(p15) XEN_HYPER_SSM_I +#else (p15) ssm psr.i // restore psr.i +#endif movl r14=ia64_leave_kernel ;; SAVE_REST @@ -729,25 +741,6 @@ END(page_fault) ENTRY(dkey_miss) DBG_FAULT(7) FAULT(7) -#ifdef CONFIG_XEN - // Leaving this code inline above results in an IVT section overflow - // There is no particular reason for this code to be here... -xen_page_fault: -(p15) movl r3=XSI_PSR_I_ADDR - ;; -(p15) ld8 r3=[r3] - ;; -(p15) st1 [r3]=r0,-1 // if (p15) vpsr.i = 1 - mov r14=r0 - ;; -(p15) ld1 r14=[r3] // if (pending_events) - adds r3=8,r2 // re-set up second base pointer - ;; -(p15) cmp.ne p15,p0=r14,r0 - ;; - br.cond.sptk.many done_xen_page_fault - ;; -#endif END(dkey_miss) .org ia64_ivt+0x2000 @@ -1170,14 +1163,13 @@ ENTRY(break_fault) #ifdef CONFIG_XEN (p15) ld8 r16=[r16] // vpsr.i ;; -(p15) st1 [r16]=r0,-1 // if (p15) vpsr.i = 1 - mov r2=r0 +(p15) st1 [r16]=r0,MASK_TO_PEND_OFS // if (p15) vpsr.i = 1 + ;; // if (p15) (vcpu->vcpu_info->evtchn_upcall_mask)=0 +(p15) ld1 r2=[r16] // if (vcpu->vcpu_info->evtchn_upcall_pending) ;; -(p15) ld1 r2=[r16] // if (pending_events) +(p15) cmp.ne.unc p6,p0=r2,r0 ;; - cmp.ne p6,p0=r2,r0 - ;; -(p6) ssm psr.i // do a real ssm psr.i +(p6) XEN_HYPER_SSM_I // do a real ssm psr.i #else (p15) ssm psr.i // M2 restore psr.i #endif diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/xenpal.S b/linux-2.6-xen-sparse/arch/ia64/xen/xenpal.S index 5f9681e49a..5208a3d9d0 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/xenpal.S +++ b/linux-2.6-xen-sparse/arch/ia64/xen/xenpal.S @@ -41,16 +41,16 @@ GLOBAL_ENTRY(xen_pal_call_static) #ifdef CONFIG_XEN // this is low priority for paravirtualization, but is called // from the idle loop so confuses privop counting - movl r31=XSI_PSR_IC + movl r31=XSI_PSR_I_ADDR ;; -(p6) st4 [r31]=r0 + ld8 r31=[r31] + mov r22=1 ;; -(p7) adds r31=XSI_PSR_I_ADDR_OFS-XSI_PSR_IC_OFS,r31 -(p7) mov r22=1 + st1 [r31]=r22 + ;; +(p6) movl r31=XSI_PSR_IC ;; -(p7) ld8 r31=[r31] - ;; -(p7) st1 [r31]=r22 +(p6) st4.rel [r31]=r0 ;; mov r31 = in3 mov b7 = loc2 diff --git a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h index b3bd8fb7dc..2bd0c1fb71 100644 --- a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h +++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h @@ -123,8 +123,6 @@ extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */ * that we inline it */ #define xen_hyper_ssm_i() \ ({ \ - xen_set_virtual_psr_i(0); \ - xen_set_virtual_psr_ic(0); \ XEN_HYPER_SSM_I; \ }) @@ -139,8 +137,12 @@ extern void xen_set_eflag(unsigned long); /* see xen_ia64_setreg */ #define xen_ssm_i() \ ({ \ int old = xen_get_virtual_psr_i(); \ - xen_set_virtual_psr_i(1); \ - if (!old && xen_get_virtual_pend()) xen_hyper_ssm_i(); \ + if (!old) { \ + if (xen_get_virtual_pend()) \ + xen_hyper_ssm_i(); \ + else \ + xen_set_virtual_psr_i(1); \ + } \ }) #define xen_ia64_intrin_local_irq_restore(x) \ diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c index 3c8741a1e6..e2ffb9d72d 100644 --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -545,7 +545,8 @@ ia64_handle_break(unsigned long ifa, struct pt_regs *regs, unsigned long isr, vcpu_increment_iip(current); } else reflect_interruption(isr, regs, vector); - } else if (!PSCB(v, interrupt_collection_enabled)) { + } else if ((iim - HYPERPRIVOP_START) < HYPERPRIVOP_MAX + && ia64_get_cpl(regs->cr_ipsr) == 2) { if (ia64_hyperprivop(iim, regs)) vcpu_increment_iip(current); } else { diff --git a/xen/arch/ia64/xen/ivt.S b/xen/arch/ia64/xen/ivt.S index 4eec37f89a..5ceda96599 100644 --- a/xen/arch/ia64/xen/ivt.S +++ b/xen/arch/ia64/xen/ivt.S @@ -1,6 +1,7 @@ #ifdef XEN #include #include +#include #endif /* * arch/ia64/kernel/ivt.S @@ -1074,18 +1075,26 @@ ENTRY(break_fault) #endif movl r18=THIS_CPU(current_psr_ic_addr) ;; - ld8 r18=[r18] - ;; - ld4 r19=[r18] + ld8 r18=[r18] ;; cmp.eq p7,p0=r0,r17 // is this a psuedo-cover? (p7) br.spnt.many dispatch_privop_fault ;; - // If vpsr.ic is off, we have a hyperprivop. A hyperprivop is - // hand-coded assembly with psr.ic off which means it can make - // no calls, cannot use r1-r15, and it can have no memory accesses - // unless they are to pinned addresses! - cmp4.eq p7,p0=r0,r19 + // if (ipsr.cpl == 2 && (iim - HYPERPRIVOP_START) < HYPERPRIVOP_MAX) + // this is a hyperprivop. A hyperprivop is hand-coded assembly with + // psr.ic off which means it can make no calls, cannot use r1-r15, + // and it can have no memory accesses unless they are to pinned + // addresses! + mov r19= cr.ipsr + movl r20=HYPERPRIVOP_START + mov r21=HYPERPRIVOP_MAX + ;; + sub r20=r17,r20 + extr.u r19=r19,IA64_PSR_CPL0_BIT,2 // extract cpl field from cr.ipsr + ;; + cmp.gtu p7,p0=r21,r20 + ;; + cmp.eq.and p7,p0=2,r19 // ipsr.cpl==2 (p7) br.sptk.many fast_hyperprivop ;; movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index b2830f6c66..8b74ba39cc 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -434,32 +434,33 @@ struct xen_ia64_boot_param { #define XMAPPEDREGS_OFS XSI_SIZE /* Hyperprivops. */ -#define HYPERPRIVOP_RFI 0x1 -#define HYPERPRIVOP_RSM_DT 0x2 -#define HYPERPRIVOP_SSM_DT 0x3 -#define HYPERPRIVOP_COVER 0x4 -#define HYPERPRIVOP_ITC_D 0x5 -#define HYPERPRIVOP_ITC_I 0x6 -#define HYPERPRIVOP_SSM_I 0x7 -#define HYPERPRIVOP_GET_IVR 0x8 -#define HYPERPRIVOP_GET_TPR 0x9 -#define HYPERPRIVOP_SET_TPR 0xa -#define HYPERPRIVOP_EOI 0xb -#define HYPERPRIVOP_SET_ITM 0xc -#define HYPERPRIVOP_THASH 0xd -#define HYPERPRIVOP_PTC_GA 0xe -#define HYPERPRIVOP_ITR_D 0xf -#define HYPERPRIVOP_GET_RR 0x10 -#define HYPERPRIVOP_SET_RR 0x11 -#define HYPERPRIVOP_SET_KR 0x12 -#define HYPERPRIVOP_FC 0x13 -#define HYPERPRIVOP_GET_CPUID 0x14 -#define HYPERPRIVOP_GET_PMD 0x15 -#define HYPERPRIVOP_GET_EFLAG 0x16 -#define HYPERPRIVOP_SET_EFLAG 0x17 -#define HYPERPRIVOP_RSM_BE 0x18 -#define HYPERPRIVOP_GET_PSR 0x19 -#define HYPERPRIVOP_MAX 0x19 +#define HYPERPRIVOP_START 0x1 +#define HYPERPRIVOP_RFI (HYPERPRIVOP_START + 0x0) +#define HYPERPRIVOP_RSM_DT (HYPERPRIVOP_START + 0x1) +#define HYPERPRIVOP_SSM_DT (HYPERPRIVOP_START + 0x2) +#define HYPERPRIVOP_COVER (HYPERPRIVOP_START + 0x3) +#define HYPERPRIVOP_ITC_D (HYPERPRIVOP_START + 0x4) +#define HYPERPRIVOP_ITC_I (HYPERPRIVOP_START + 0x5) +#define HYPERPRIVOP_SSM_I (HYPERPRIVOP_START + 0x6) +#define HYPERPRIVOP_GET_IVR (HYPERPRIVOP_START + 0x7) +#define HYPERPRIVOP_GET_TPR (HYPERPRIVOP_START + 0x8) +#define HYPERPRIVOP_SET_TPR (HYPERPRIVOP_START + 0x9) +#define HYPERPRIVOP_EOI (HYPERPRIVOP_START + 0xa) +#define HYPERPRIVOP_SET_ITM (HYPERPRIVOP_START + 0xb) +#define HYPERPRIVOP_THASH (HYPERPRIVOP_START + 0xc) +#define HYPERPRIVOP_PTC_GA (HYPERPRIVOP_START + 0xd) +#define HYPERPRIVOP_ITR_D (HYPERPRIVOP_START + 0xe) +#define HYPERPRIVOP_GET_RR (HYPERPRIVOP_START + 0xf) +#define HYPERPRIVOP_SET_RR (HYPERPRIVOP_START + 0x10) +#define HYPERPRIVOP_SET_KR (HYPERPRIVOP_START + 0x11) +#define HYPERPRIVOP_FC (HYPERPRIVOP_START + 0x12) +#define HYPERPRIVOP_GET_CPUID (HYPERPRIVOP_START + 0x13) +#define HYPERPRIVOP_GET_PMD (HYPERPRIVOP_START + 0x14) +#define HYPERPRIVOP_GET_EFLAG (HYPERPRIVOP_START + 0x15) +#define HYPERPRIVOP_SET_EFLAG (HYPERPRIVOP_START + 0x16) +#define HYPERPRIVOP_RSM_BE (HYPERPRIVOP_START + 0x17) +#define HYPERPRIVOP_GET_PSR (HYPERPRIVOP_START + 0x18) +#define HYPERPRIVOP_MAX (0x19) /* Fast and light hypercalls. */ #define __HYPERVISOR_ia64_fast_eoi 0x0200 From 98ec176ab38e22faf7e0fc374553351100dd295b Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Tue, 2 Jan 2007 16:39:42 -0700 Subject: [PATCH 020/570] [IA64] Rename RID maker HVM_PARAM_CALLBACK_IRQ_RID to IA64_CALLBACK_IRQ_RID Signed-off-by: Tsunehisa Doi --- unmodified_drivers/linux-2.6/platform-pci/platform-pci.c | 2 +- xen/arch/ia64/vmx/vmx_process.c | 2 +- xen/include/public/arch-ia64.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c index b529ce1308..a1b7eafc4e 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c @@ -192,7 +192,7 @@ static int get_callback_irq(struct pci_dev *pdev) rid = ((pdev->bus->number & 0xff) << 8) | pdev->devfn; printk(KERN_INFO DRV_NAME ":use Requester-ID(%04x) as callback irq\n", rid); - return rid | HVM_PARAM_CALLBACK_IRQ_RID; + return rid | IA64_CALLBACK_IRQ_RID; #else /* !__ia64__ */ return pdev->irq; #endif diff --git a/xen/arch/ia64/vmx/vmx_process.c b/xen/arch/ia64/vmx/vmx_process.c index 1fce5524b5..f8ff340a78 100644 --- a/xen/arch/ia64/vmx/vmx_process.c +++ b/xen/arch/ia64/vmx/vmx_process.c @@ -212,7 +212,7 @@ void leave_hypervisor_tail(struct pt_regs *regs) if (callback_irq != 0 && local_events_need_delivery()) { /* change level for para-device callback irq */ /* use level irq to send discrete event */ - if (callback_irq & HVM_PARAM_CALLBACK_IRQ_RID) { + if (callback_irq & IA64_CALLBACK_IRQ_RID) { /* case of using Requester-ID as callback irq */ /* RID: '<#bus(8)><#dev(5)><#func(3)>' */ int dev = (callback_irq >> 3) & 0x1f; diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index 8b74ba39cc..2da8fba00a 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -64,7 +64,7 @@ DEFINE_XEN_GUEST_HANDLE(xen_pfn_t); /* Arch specific callback irq definition */ /* using Requester-ID(RID) as callback irq */ -#define HVM_PARAM_CALLBACK_IRQ_RID (1 << 31) +#define IA64_CALLBACK_IRQ_RID (1 << 31) /* Maximum number of virtual CPUs in multi-processor guests. */ /* WARNING: before changing this, check that shared_info fits on a page */ From 4155aa4c706a25d68bf1424780ddc6e09f947d91 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Tue, 2 Jan 2007 16:42:09 -0700 Subject: [PATCH 021/570] [IA64] tidy up vcpu_set_itc error message This patch enhances the error message in question in two minor ways * typo fix: one -> once * Print the entire message at once, otherwise it seems to end up geting interlaced with other dom0 kernel messages on the console (on my system at least). Signed-Off-By: Simon Horman --- xen/arch/ia64/xen/vcpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index da609c8a8e..4b57f2ddb0 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -1207,8 +1207,8 @@ IA64FAULT vcpu_set_itc(VCPU * vcpu, u64 val) #ifdef DISALLOW_SETTING_ITC_FOR_NOW static int did_print; if (!did_print) { - printk("vcpu_set_itc: Setting ar.itc is currently disabled\n"); - printk("(this message is only displayed one)\n"); + printk("vcpu_set_itc: Setting ar.itc is currently disabled " + "(this message is only displayed once)\n"); did_print = 1; } #else From 30bc7b0ff1c01a935705ea8bc7d6230dbc175c10 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 3 Jan 2007 13:46:23 +0000 Subject: [PATCH 022/570] [LINUX] Build blktap as module named xenblktap. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/drivers/xen/blktap/Makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/Makefile b/linux-2.6-xen-sparse/drivers/xen/blktap/Makefile index 409b07896f..f10cc4fe12 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/Makefile +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/Makefile @@ -1,3 +1,5 @@ LINUXINCLUDE += -I../xen/include/public/io -obj-y := xenbus.o interface.o blktap.o +obj-$(CONFIG_XEN_BLKDEV_TAP) := xenblktap.o + +xenblktap-y := xenbus.o interface.o blktap.o From 49f1cd42a181a4123c28e8262bc3c219e2dc74d4 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 3 Jan 2007 13:55:53 +0000 Subject: [PATCH 023/570] [IOEMU] Process reset requests before returning control to the guest. Since 12899:4ae4bdee00e Xen only pays attention the first shutdown or reboot request for a domain. When a reset if requested we need to make the SCHEDOP_remote_shutdown hypercall before we return control to the guest so that it wins the "race" with the heuristic in xen/arch/x86/hvm/hvm.c:hvm_vcpu_down() which causes a powerdown. Signed-off-by: Ian Campbell --- tools/ioemu/target-i386-dm/helper2.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tools/ioemu/target-i386-dm/helper2.c b/tools/ioemu/target-i386-dm/helper2.c index aa7b042561..ae84b9ed23 100644 --- a/tools/ioemu/target-i386-dm/helper2.c +++ b/tools/ioemu/target-i386-dm/helper2.c @@ -498,6 +498,8 @@ void handle_buffered_io(void *opaque) void cpu_handle_ioreq(void *opaque) { + extern int vm_running; + extern int shutdown_requested; CPUState *env = opaque; ioreq_t *req = cpu_get_ioreq(); @@ -516,6 +518,25 @@ void cpu_handle_ioreq(void *opaque) } wmb(); /* Update ioreq contents /then/ update state. */ + + /* + * We do this before we send the response so that the tools + * have the opportunity to pick up on the reset before the + * guest resumes and does a hlt with interrupts disabled which + * causes Xen to powerdown the domain. + */ + if (vm_running) { + if (shutdown_requested) { + fprintf(logfile, "shutdown requested in cpu_handle_ioreq\n"); + destroy_hvm_domain(); + } + if (reset_requested) { + fprintf(logfile, "reset requested in cpu_handle_ioreq.\n"); + qemu_system_reset(); + reset_requested = 0; + } + } + req->state = STATE_IORESP_READY; xc_evtchn_notify(xce_handle, ioreq_local_port[send_vcpu]); } From 0550678b74b1afac96ff8e823bf50b436f66dc57 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 3 Jan 2007 14:08:42 +0000 Subject: [PATCH 024/570] [LINUX] Implement the idle=poll option in the kernel when running on Xen. This causes the kernel to use a polling loop rather than hypercall down to block. I have found this useful to profile the amount of sleep cycles when using xenoprof, there may be other uses. Signed-off-by: Amitabha Roy --- .../arch/i386/kernel/process-xen.c | 43 +++++++++++++++--- .../arch/x86_64/kernel/process-xen.c | 45 ++++++++++++++++--- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c index e6724a00b1..00a8d8a8eb 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c @@ -101,8 +101,24 @@ void enable_hlt(void) EXPORT_SYMBOL(enable_hlt); -/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */ -void xen_idle(void) +/* + * On SMP it's slightly faster (but much more power-consuming!) + * to poll the ->work.need_resched flag instead of waiting for the + * cross-CPU IPI to arrive. Use this option with caution. + */ +static void poll_idle(void) +{ + local_irq_enable(); + + asm volatile( + "2:" + "testl %0, %1;" + "rep; nop;" + "je 2b;" + : : "i"(_TIF_NEED_RESCHED), "m" (current_thread_info()->flags)); +} + +static void xen_idle(void) { local_irq_disable(); @@ -162,7 +178,7 @@ void cpu_idle(void) play_dead(); __get_cpu_var(irq_stat).idle_timestamp = jiffies; - xen_idle(); + pm_idle(); } preempt_enable_no_resched(); schedule(); @@ -198,9 +214,24 @@ void cpu_idle_wait(void) } EXPORT_SYMBOL_GPL(cpu_idle_wait); -/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */ -/* Always use xen_idle() instead. */ -void __devinit select_idle_routine(const struct cpuinfo_x86 *c) {} +void __devinit select_idle_routine(const struct cpuinfo_x86 *c) +{ + if (!pm_idle) + pm_idle = xen_idle; +} + +static int __init idle_setup (char *str) +{ + if (!strncmp(str, "poll", 4)) { + printk("using polling idle threads.\n"); + pm_idle = poll_idle; + } + + boot_option_idle_override = 1; + return 1; +} + +__setup("idle=", idle_setup); void show_regs(struct pt_regs * regs) { diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c index 65ba83c625..c12ebe0e01 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c @@ -119,8 +119,26 @@ void exit_idle(void) __exit_idle(); } -/* XXX XEN doesn't use default_idle(), poll_idle(). Use xen_idle() instead. */ -void xen_idle(void) +/* + * On SMP it's slightly faster (but much more power-consuming!) + * to poll the ->need_resched flag instead of waiting for the + * cross-CPU IPI to arrive. Use this option with caution. + */ +static void poll_idle(void) +{ + local_irq_enable(); + + asm volatile( + "2:" + "testl %0,%1;" + "rep; nop;" + "je 2b;" + : : + "i" (_TIF_NEED_RESCHED), + "m" (current_thread_info()->flags)); +} + +static void xen_idle(void) { local_irq_disable(); @@ -171,7 +189,7 @@ void cpu_idle (void) if (cpu_is_offline(smp_processor_id())) play_dead(); enter_idle(); - xen_idle(); + pm_idle(); __exit_idle(); } @@ -210,9 +228,24 @@ void cpu_idle_wait(void) } EXPORT_SYMBOL_GPL(cpu_idle_wait); -/* XXX XEN doesn't use mwait_idle(), select_idle_routine(), idle_setup(). */ -/* Always use xen_idle() instead. */ -void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) {} +void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) +{ + if (!pm_idle) + pm_idle = xen_idle; +} + +static int __init idle_setup (char *str) +{ + if (!strncmp(str, "poll", 4)) { + printk("using polling idle threads.\n"); + pm_idle = poll_idle; + } + + boot_option_idle_override = 1; + return 1; +} + +__setup("idle=", idle_setup); /* Prints also some state that isn't saved in the pt_regs */ void __show_regs(struct pt_regs * regs) From 72c07f413879d47a5bd472ff8971a0c5bb4b205d Mon Sep 17 00:00:00 2001 From: "kaf24@localhost.localdomain" Date: Wed, 3 Jan 2007 23:53:27 +0000 Subject: [PATCH 025/570] [XEN] Make labels _start,_end,_stext,_etext,_sinittext,_einittext generic. Also sync the tools/symbol.c symbol table generator with Linux. Make section names generic (e.e.g, .init.text, .init.data, ...). Signed-off-by: Keir Fraser --- xen/arch/ia64/xen/xenmisc.c | 20 -- xen/arch/powerpc/setup.c | 13 - xen/arch/powerpc/xen.lds.S | 4 +- xen/arch/x86/boot/x86_32.S | 2 - xen/arch/x86/boot/x86_64.S | 2 - xen/arch/x86/traps.c | 20 +- xen/arch/x86/x86_32/xen.lds.S | 17 +- xen/arch/x86/x86_64/xen.lds.S | 17 +- xen/common/kexec.c | 6 +- xen/common/symbols.c | 6 +- xen/include/asm-ia64/init.h | 25 -- xen/include/asm-powerpc/init.h | 19 -- xen/include/asm-x86/config.h | 4 - xen/include/asm-x86/init.h | 25 -- xen/include/xen/init.h | 19 ++ xen/include/xen/kernel.h | 17 ++ xen/include/xen/symbols.h | 5 +- xen/tools/symbols.c | 441 +++++++++------------------------ 18 files changed, 178 insertions(+), 484 deletions(-) diff --git a/xen/arch/ia64/xen/xenmisc.c b/xen/arch/ia64/xen/xenmisc.c index 051f78ee30..532d812910 100644 --- a/xen/arch/ia64/xen/xenmisc.c +++ b/xen/arch/ia64/xen/xenmisc.c @@ -56,26 +56,6 @@ is_platform_hp_ski(void) struct pt_regs *guest_cpu_user_regs(void) { return vcpu_regs(current); } -/////////////////////////////// -// from arch/ia64/traps.c -/////////////////////////////// - -int is_kernel_text(unsigned long addr) -{ - extern char _stext[], _etext[]; - if (addr >= (unsigned long) _stext && - addr <= (unsigned long) _etext) - return 1; - - return 0; -} - -unsigned long kernel_text_end(void) -{ - extern char _etext[]; - return (unsigned long) _etext; -} - /////////////////////////////// // from common/keyhandler.c /////////////////////////////// diff --git a/xen/arch/powerpc/setup.c b/xen/arch/powerpc/setup.c index c22e6712bb..440acbbb1e 100644 --- a/xen/arch/powerpc/setup.c +++ b/xen/arch/powerpc/setup.c @@ -91,19 +91,6 @@ static struct domain *idle_domain; volatile struct processor_area * volatile global_cpu_table[NR_CPUS]; -int is_kernel_text(unsigned long addr) -{ - if (addr >= (unsigned long) &_start && - addr <= (unsigned long) &_etext) - return 1; - return 0; -} - -unsigned long kernel_text_end(void) -{ - return (unsigned long) &_etext; -} - static void __init do_initcalls(void) { initcall_t *call; diff --git a/xen/arch/powerpc/xen.lds.S b/xen/arch/powerpc/xen.lds.S index 2fe00d7b60..07bb7a6dae 100644 --- a/xen/arch/powerpc/xen.lds.S +++ b/xen/arch/powerpc/xen.lds.S @@ -113,10 +113,10 @@ SECTIONS . = ALIGN(32); __setup_start = .; - .setup.init : { *(.setup.init) } + .init.setup : { *(.init.setup) } __setup_end = .; __initcall_start = .; - .initcall.init : { *(.initcall.init) } + .initcall.init : { *(.initcall1.init) } __initcall_end = .; __inithcall_start = .; .inithcall.text : { *(.inithcall.text) } diff --git a/xen/arch/x86/boot/x86_32.S b/xen/arch/x86/boot/x86_32.S index c3466dee5f..c0f9d82c88 100644 --- a/xen/arch/x86/boot/x86_32.S +++ b/xen/arch/x86/boot/x86_32.S @@ -11,8 +11,6 @@ .text ENTRY(start) -ENTRY(stext) -ENTRY(_stext) jmp __start .align 4 diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index ce0e42987c..661f39a38a 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -14,8 +14,6 @@ #define SYM_PHYS(sym) (sym - __PAGE_OFFSET) ENTRY(start) -ENTRY(stext) -ENTRY(_stext) jmp __start .org 0x004 diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 606bc003c1..95d96b03cd 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -115,22 +115,6 @@ integer_param("debug_stack_lines", debug_stack_lines); #define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->rsp) #endif -int is_kernel_text(unsigned long addr) -{ - extern char _stext, _etext; - if (addr >= (unsigned long) &_stext && - addr <= (unsigned long) &_etext) - return 1; - return 0; - -} - -unsigned long kernel_text_end(void) -{ - extern char _etext; - return (unsigned long) &_etext; -} - static void show_guest_stack(struct cpu_user_regs *regs) { int i; @@ -187,7 +171,7 @@ static void show_trace(struct cpu_user_regs *regs) while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 ) { addr = *stack++; - if ( is_kernel_text(addr) ) + if ( is_kernel_text(addr) || is_kernel_inittext(addr) ) { printk("[<%p>]", _p(addr)); print_symbol(" %s\n ", addr); @@ -316,7 +300,7 @@ void show_stack_overflow(unsigned long esp) while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 ) { addr = *stack++; - if ( is_kernel_text(addr) ) + if ( is_kernel_text(addr) || is_kernel_inittext(addr) ) { printk("%p: [<%p>]", stack, _p(addr)); print_symbol(" %s\n ", addr); diff --git a/xen/arch/x86/x86_32/xen.lds.S b/xen/arch/x86/x86_32/xen.lds.S index a44bf8701b..16fa9c895e 100644 --- a/xen/arch/x86/x86_32/xen.lds.S +++ b/xen/arch/x86/x86_32/xen.lds.S @@ -19,7 +19,8 @@ PHDRS SECTIONS { . = 0xFF000000 + 0x100000; - _text = .; /* Text and read-only data */ + _start = .; + _stext = .; /* Text and read-only data */ .text : { *(.text) *(.fixup) @@ -51,14 +52,16 @@ SECTIONS . = ALIGN(4096); /* Init code and data */ __init_begin = .; - .text.init : { *(.text.init) } :text - .data.init : { *(.data.init) } :text + _sinittext = .; + .init.text : { *(.init.text) } :text + _einittext = .; + .init.data : { *(.init.data) } :text . = ALIGN(32); __setup_start = .; - .setup.init : { *(.setup.init) } :text + .init.setup : { *(.init.setup) } :text __setup_end = .; __initcall_start = .; - .initcall.init : { *(.initcall.init) } :text + .initcall.init : { *(.initcall1.init) } :text __initcall_end = .; . = ALIGN(PAGE_SIZE); __init_end = .; @@ -80,8 +83,8 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { - *(.text.exit) - *(.data.exit) + *(.exit.text) + *(.exit.data) *(.exitcall.exit) } diff --git a/xen/arch/x86/x86_64/xen.lds.S b/xen/arch/x86/x86_64/xen.lds.S index f2ab8f8aa5..9841882c94 100644 --- a/xen/arch/x86/x86_64/xen.lds.S +++ b/xen/arch/x86/x86_64/xen.lds.S @@ -17,7 +17,8 @@ PHDRS SECTIONS { . = 0xFFFF830000100000; - _text = .; /* Text and read-only data */ + _start = .; + _stext = .; /* Text and read-only data */ .text : { *(.text) *(.fixup) @@ -49,14 +50,16 @@ SECTIONS . = ALIGN(4096); /* Init code and data */ __init_begin = .; - .text.init : { *(.text.init) } :text - .data.init : { *(.data.init) } :text + _sinittext = .; + .init.text : { *(.init.text) } :text + _einittext = .; + .init.data : { *(.init.data) } :text . = ALIGN(32); __setup_start = .; - .setup.init : { *(.setup.init) } :text + .init.setup : { *(.init.setup) } :text __setup_end = .; __initcall_start = .; - .initcall.init : { *(.initcall.init) } :text + .initcall.init : { *(.initcall1.init) } :text __initcall_end = .; . = ALIGN(PAGE_SIZE); __init_end = .; @@ -78,8 +81,8 @@ SECTIONS /* Sections to be discarded */ /DISCARD/ : { - *(.text.exit) - *(.data.exit) + *(.exit.text) + *(.exit.data) *(.exitcall.exit) } diff --git a/xen/common/kexec.c b/xen/common/kexec.c index 9403492346..8f511608f5 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -150,12 +150,10 @@ static int kexec_get_reserve(xen_kexec_range_t *range) return 0; } -extern unsigned long _text; - static int kexec_get_xen(xen_kexec_range_t *range) { - range->start = virt_to_maddr(&_text); - range->size = (unsigned long)&_end - (unsigned long)&_text; + range->start = virt_to_maddr(_start); + range->size = (unsigned long)_end - (unsigned long)_start; return 0; } diff --git a/xen/common/symbols.c b/xen/common/symbols.c index 6bc3956a13..496f231f8b 100644 --- a/xen/common/symbols.c +++ b/xen/common/symbols.c @@ -12,6 +12,7 @@ #include #include +#include #include #include #include @@ -99,7 +100,7 @@ const char *symbols_lookup(unsigned long addr, namebuf[KSYM_NAME_LEN] = 0; namebuf[0] = 0; - if (!is_kernel_text(addr)) + if (!is_kernel_text(addr) && !is_kernel_inittext(addr)) return NULL; /* do a binary search on the sorted symbols_addresses array */ @@ -130,7 +131,8 @@ const char *symbols_lookup(unsigned long addr, /* if we found no next symbol, we use the end of the section */ if (!symbol_end) - symbol_end = kernel_text_end(); + symbol_end = is_kernel_inittext(addr) ? + (unsigned long)_einittext : (unsigned long)_etext; *symbolsize = symbol_end - symbols_addresses[low]; *offset = addr - symbols_addresses[low]; diff --git a/xen/include/asm-ia64/init.h b/xen/include/asm-ia64/init.h index 7e5df20da6..5295b35e63 100644 --- a/xen/include/asm-ia64/init.h +++ b/xen/include/asm-ia64/init.h @@ -1,29 +1,4 @@ #ifndef _XEN_ASM_INIT_H #define _XEN_ASM_INIT_H -/* - * Mark functions and data as being only used at initialization - * or exit time. - */ -#define __init \ - __attribute__ ((__section__ (".init.text"))) -#define __exit \ - __attribute_used__ __attribute__ ((__section__(".text.exit"))) -#define __initdata \ - __attribute__ ((__section__ (".init.data"))) -#define __exitdata \ - __attribute_used__ __attribute__ ((__section__ (".data.exit"))) -#define __initsetup \ - __attribute_used__ __attribute__ ((__section__ (".init.setup"))) -#define __init_call \ - __attribute_used__ __attribute__ ((__section__ (".initcall1.init"))) -#define __exit_call \ - __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) - -/* For assembly routines -#define __INIT .section ".text.init","ax" -#define __FINIT .previous -#define __INITDATA .section ".data.init","aw" -*/ - #endif /* _XEN_ASM_INIT_H */ diff --git a/xen/include/asm-powerpc/init.h b/xen/include/asm-powerpc/init.h index 7ac4f0cbf7..11f9d6e104 100644 --- a/xen/include/asm-powerpc/init.h +++ b/xen/include/asm-powerpc/init.h @@ -21,25 +21,6 @@ #ifndef _XEN_ASM_INIT_H #define _XEN_ASM_INIT_H -/* - * Mark functions and data as being only used at initialization - * or exit time. - */ -#define __init \ - __attribute__ ((__section__ (".init.text"))) -#define __exit \ - __attribute_used__ __attribute__ ((__section__(".text.exit"))) -#define __initdata \ - __attribute__ ((__section__ (".init.data"))) -#define __exitdata \ - __attribute_used__ __attribute__ ((__section__ (".data.exit"))) -#define __initsetup \ - __attribute_used__ __attribute__ ((__section__ (".setup.init"))) -#define __init_call \ - __attribute_used__ __attribute__ ((__section__ (".initcall.init"))) -#define __exit_call \ - __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) - struct cpu_user_regs; typedef void (*hcall_handler_t)(struct cpu_user_regs *regs); diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 1ccb34edd2..562bb786d4 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -84,10 +84,6 @@ #define CONFIG_DMA_BITSIZE 30 -#ifndef __ASSEMBLY__ -extern unsigned long _end; /* standard ELF symbol */ -#endif /* __ASSEMBLY__ */ - #if defined(__x86_64__) #define CONFIG_X86_64 1 diff --git a/xen/include/asm-x86/init.h b/xen/include/asm-x86/init.h index 8f1e764080..5295b35e63 100644 --- a/xen/include/asm-x86/init.h +++ b/xen/include/asm-x86/init.h @@ -1,29 +1,4 @@ #ifndef _XEN_ASM_INIT_H #define _XEN_ASM_INIT_H -/* - * Mark functions and data as being only used at initialization - * or exit time. - */ -#define __init \ - __attribute__ ((__section__ (".init.text"))) -#define __exit \ - __attribute_used__ __attribute__ ((__section__(".text.exit"))) -#define __initdata \ - __attribute__ ((__section__ (".init.data"))) -#define __exitdata \ - __attribute_used__ __attribute__ ((__section__ (".data.exit"))) -#define __initsetup \ - __attribute_used__ __attribute__ ((__section__ (".setup.init"))) -#define __init_call \ - __attribute_used__ __attribute__ ((__section__ (".initcall.init"))) -#define __exit_call \ - __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) - -/* For assembly routines -#define __INIT .section ".text.init","ax" -#define __FINIT .previous -#define __INITDATA .section ".data.init","aw" -*/ - #endif /* _XEN_ASM_INIT_H */ diff --git a/xen/include/xen/init.h b/xen/include/xen/init.h index 0709c9abd8..3ff3ff0e37 100644 --- a/xen/include/xen/init.h +++ b/xen/include/xen/init.h @@ -4,6 +4,25 @@ #include #include +/* + * Mark functions and data as being only used at initialization + * or exit time. + */ +#define __init \ + __attribute__ ((__section__ (".init.text"))) +#define __exit \ + __attribute_used__ __attribute__ ((__section__(".exit.text"))) +#define __initdata \ + __attribute__ ((__section__ (".init.data"))) +#define __exitdata \ + __attribute_used__ __attribute__ ((__section__ (".exit.data"))) +#define __initsetup \ + __attribute_used__ __attribute__ ((__section__ (".init.setup"))) +#define __init_call \ + __attribute_used__ __attribute__ ((__section__ (".initcall1.init"))) +#define __exit_call \ + __attribute_used__ __attribute__ ((__section__ (".exitcall.exit"))) + /* These macros are used to mark some functions or * initialized data (doesn't apply to uninitialized data) * as `initialization' functions. The kernel can take this diff --git a/xen/include/xen/kernel.h b/xen/include/xen/kernel.h index a58d4269e6..34e831a39a 100644 --- a/xen/include/xen/kernel.h +++ b/xen/include/xen/kernel.h @@ -56,6 +56,23 @@ 1; \ }) +extern char _start[], _end[]; +#define is_kernel(p) ({ \ + char *__p = (char *)(unsigned long)(p); \ + (__p >= _start) && (__p <= _end); \ +}) + +extern char _stext[], _etext[]; +#define is_kernel_text(p) ({ \ + char *__p = (char *)(unsigned long)(p); \ + (__p >= _stext) && (__p <= _etext); \ +}) + +extern char _sinittext[], _einittext[]; +#define is_kernel_inittext(p) ({ \ + char *__p = (char *)(unsigned long)(p); \ + (__p >= _sinittext) && (__p <= _einittext); \ +}) #endif /* _LINUX_KERNEL_H */ diff --git a/xen/include/xen/symbols.h b/xen/include/xen/symbols.h index a30b82c002..082d707469 100644 --- a/xen/include/xen/symbols.h +++ b/xen/include/xen/symbols.h @@ -6,9 +6,6 @@ #define KSYM_NAME_LEN 127 -extern int is_kernel_text(unsigned long addr); -extern unsigned long kernel_text_end(void); - /* Lookup an address. */ const char *symbols_lookup(unsigned long addr, unsigned long *symbolsize, @@ -16,7 +13,7 @@ const char *symbols_lookup(unsigned long addr, char *namebuf); /* Replace "%s" in format with address, if found */ -extern void __print_symbol(const char *fmt, unsigned long address); +void __print_symbol(const char *fmt, unsigned long address); /* This macro allows us to keep printk typechecking */ static void __check_printsym_format(const char *fmt, ...) diff --git a/xen/tools/symbols.c b/xen/tools/symbols.c index 3eca4cae1b..ed126a2d06 100644 --- a/xen/tools/symbols.c +++ b/xen/tools/symbols.c @@ -5,7 +5,7 @@ * This software may be used and distributed according to the terms * of the GNU General Public License, incorporated herein by reference. * - * Usage: nm -n | scripts/symbols [--all-symbols] > symbols.S + * Usage: nm -n vmlinux | scripts/symbols [--all-symbols] > symbols.S * * ChangeLog: * @@ -24,75 +24,37 @@ * */ +#define _GNU_SOURCE + #include #include #include #include -/* maximum token length used. It doesn't pay to increase it a lot, because - * very long substrings probably don't repeat themselves too often. */ -#define MAX_TOK_SIZE 11 #define KSYM_NAME_LEN 127 -/* we use only a subset of the complete symbol table to gather the token count, - * to speed up compression, at the expense of a little compression ratio */ -#define WORKING_SET 1024 - -/* first find the best token only on the list of tokens that would profit more - * than GOOD_BAD_THRESHOLD. Only if this list is empty go to the "bad" list. - * Increasing this value will put less tokens on the "good" list, so the search - * is faster. However, if the good list runs out of tokens, we must painfully - * search the bad list. */ -#define GOOD_BAD_THRESHOLD 10 - -/* token hash parameters */ -#define HASH_BITS 18 -#define HASH_TABLE_SIZE (1 << HASH_BITS) -#define HASH_MASK (HASH_TABLE_SIZE - 1) -#define HASH_BASE_OFFSET 2166136261U -#define HASH_FOLD(a) ((a)&(HASH_MASK)) - -/* flags to mark symbols */ -#define SYM_FLAG_VALID 1 -#define SYM_FLAG_SAMPLED 2 struct sym_entry { unsigned long long addr; - char type; - unsigned char flags; - unsigned char len; + unsigned int len; unsigned char *sym; }; static struct sym_entry *table; -static int size, cnt; -static unsigned long long _stext, _etext; +static unsigned int table_size, table_cnt; +static unsigned long long _stext, _etext, _sinittext, _einittext, _sextratext, _eextratext; static int all_symbols = 0; static char symbol_prefix_char = '\0'; -struct token { - unsigned char data[MAX_TOK_SIZE]; - unsigned char len; - /* profit: the number of bytes that could be saved by inserting this - * token into the table */ - int profit; - struct token *next; /* next token on the hash list */ - struct token *right; /* next token on the good/bad list */ - struct token *left; /* previous token on the good/bad list */ - struct token *smaller; /* token that is less one letter than this one */ - }; - -struct token bad_head, good_head; -struct token *hash_table[HASH_TABLE_SIZE]; +int token_profit[0x10000]; /* the table that holds the result of the compression */ -unsigned char best_table[256][MAX_TOK_SIZE+1]; +unsigned char best_table[256][2]; unsigned char best_table_len[256]; -static void -usage(void) +static void usage(void) { fprintf(stderr, "Usage: symbols [--all-symbols] [--symbol-prefix=] < in.map > out.S\n"); exit(1); @@ -102,21 +64,19 @@ usage(void) * This ignores the intensely annoying "mapping symbols" found * in ARM ELF files: $a, $t and $d. */ -static inline int -is_arm_mapping_symbol(const char *str) +static inline int is_arm_mapping_symbol(const char *str) { return str[0] == '$' && strchr("atd", str[1]) && (str[2] == '\0' || str[2] == '.'); } -static int -read_symbol(FILE *in, struct sym_entry *s) +static int read_symbol(FILE *in, struct sym_entry *s) { char str[500]; - char *sym; + char *sym, stype; int rc; - rc = fscanf(in, "%llx %c %499s\n", &s->addr, &s->type, str); + rc = fscanf(in, "%llx %c %499s\n", &s->addr, &stype, str); if (rc != 3) { if (rc != EOF) { /* skip line */ @@ -135,7 +95,15 @@ read_symbol(FILE *in, struct sym_entry *s) _stext = s->addr; else if (strcmp(sym, "_etext") == 0) _etext = s->addr; - else if (toupper(s->type) == 'A') + else if (strcmp(sym, "_sinittext") == 0) + _sinittext = s->addr; + else if (strcmp(sym, "_einittext") == 0) + _einittext = s->addr; + else if (strcmp(sym, "_sextratext") == 0) + _sextratext = s->addr; + else if (strcmp(sym, "_eextratext") == 0) + _eextratext = s->addr; + else if (toupper(stype) == 'A') { /* Keep these useful absolute symbols */ if (strcmp(sym, "__kernel_syscall_via_break") && @@ -145,22 +113,24 @@ read_symbol(FILE *in, struct sym_entry *s) return -1; } - else if (toupper(s->type) == 'U' || + else if (toupper(stype) == 'U' || is_arm_mapping_symbol(sym)) return -1; + /* exclude also MIPS ELF local symbols ($L123 instead of .L123) */ + else if (str[0] == '$') + return -1; /* include the type field in the symbol name, so that it gets * compressed together */ s->len = strlen(str) + 1; - s->sym = (unsigned char *) malloc(s->len + 1); + s->sym = malloc(s->len + 1); strcpy((char *)s->sym + 1, str); - s->sym[0] = s->type; + s->sym[0] = stype; return 0; } -static int -symbol_valid(struct sym_entry *s) +static int symbol_valid(struct sym_entry *s) { /* Symbols which vary between passes. Passes 1 and 2 must have * identical symbol lists. The symbols_* symbols below are only added @@ -189,7 +159,9 @@ symbol_valid(struct sym_entry *s) /* if --all-symbols is not specified, then symbols outside the text * and inittext sections are discarded */ if (!all_symbols) { - if (s->addr < _stext || s->addr > _etext) + if ((s->addr < _stext || s->addr > _etext) + && (s->addr < _sinittext || s->addr > _einittext) + && (s->addr < _sextratext || s->addr > _eextratext)) return 0; /* Corner case. Discard any symbols with the same value as * _etext _einittext or _eextratext; they can move between pass @@ -197,7 +169,9 @@ symbol_valid(struct sym_entry *s) * move then they may get dropped in pass 2, which breaks the * symbols rules. */ - if (s->addr == _etext && strcmp((char *)s->sym + offset, "_etext")) + if ((s->addr == _etext && strcmp((char*)s->sym + offset, "_etext")) || + (s->addr == _einittext && strcmp((char*)s->sym + offset, "_einittext")) || + (s->addr == _eextratext && strcmp((char*)s->sym + offset, "_eextratext"))) return 0; } @@ -212,20 +186,19 @@ symbol_valid(struct sym_entry *s) return 1; } -static void -read_map(FILE *in) +static void read_map(FILE *in) { while (!feof(in)) { - if (cnt >= size) { - size += 10000; - table = realloc(table, sizeof(*table) * size); + if (table_cnt >= table_size) { + table_size += 10000; + table = realloc(table, sizeof(*table) * table_size); if (!table) { fprintf(stderr, "out of memory\n"); exit (1); } } - if (read_symbol(in, &table[cnt]) == 0) - cnt++; + if (read_symbol(in, &table[table_cnt]) == 0) + table_cnt++; } } @@ -269,10 +242,9 @@ static int expand_symbol(unsigned char *data, int len, char *result) return total; } -static void -write_src(void) +static void write_src(void) { - int i, k, off, valid; + unsigned int i, k, off; unsigned int best_idx[256]; unsigned int *markers; char buf[KSYM_NAME_LEN+1]; @@ -289,33 +261,24 @@ write_src(void) printf(".data\n"); output_label("symbols_addresses"); - valid = 0; - for (i = 0; i < cnt; i++) { - if (table[i].flags & SYM_FLAG_VALID) { - printf("\tPTR\t%#llx\n", table[i].addr); - valid++; - } + for (i = 0; i < table_cnt; i++) { + printf("\tPTR\t%#llx\n", table[i].addr); } printf("\n"); output_label("symbols_num_syms"); - printf("\tPTR\t%d\n", valid); + printf("\tPTR\t%d\n", table_cnt); printf("\n"); /* table of offset markers, that give the offset in the compressed stream * every 256 symbols */ - markers = (unsigned int *) malloc(sizeof(unsigned int)*((valid + 255) / 256)); + markers = (unsigned int *) malloc(sizeof(unsigned int) * ((table_cnt + 255) / 256)); output_label("symbols_names"); - valid = 0; off = 0; - for (i = 0; i < cnt; i++) { - - if (!(table[i].flags & SYM_FLAG_VALID)) - continue; - - if ((valid & 0xFF) == 0) - markers[valid >> 8] = off; + for (i = 0; i < table_cnt; i++) { + if ((i & 0xFF) == 0) + markers[i >> 8] = off; printf("\t.byte 0x%02x", table[i].len); for (k = 0; k < table[i].len; k++) @@ -323,12 +286,11 @@ write_src(void) printf("\n"); off += table[i].len + 1; - valid++; } printf("\n"); output_label("symbols_markers"); - for (i = 0; i < ((valid + 255) >> 8); i++) + for (i = 0; i < ((table_cnt + 255) >> 8); i++) printf("\tPTR\t%d\n", markers[i]); printf("\n"); @@ -338,7 +300,7 @@ write_src(void) off = 0; for (i = 0; i < 256; i++) { best_idx[i] = off; - expand_symbol(best_table[i],best_table_len[i],buf); + expand_symbol(best_table[i], best_table_len[i], buf); printf("\t.asciz\t\"%s\"\n", buf); off += strlen(buf) + 1; } @@ -353,153 +315,13 @@ write_src(void) /* table lookup compression functions */ -static inline unsigned int rehash_token(unsigned int hash, unsigned char data) -{ - return ((hash * 16777619) ^ data); -} - -static unsigned int hash_token(unsigned char *data, int len) -{ - unsigned int hash=HASH_BASE_OFFSET; - int i; - - for (i = 0; i < len; i++) - hash = rehash_token(hash, data[i]); - - return HASH_FOLD(hash); -} - -/* find a token given its data and hash value */ -static struct token *find_token_hash(unsigned char *data, int len, unsigned int hash) -{ - struct token *ptr; - - ptr = hash_table[hash]; - - while (ptr) { - if ((ptr->len == len) && (memcmp(ptr->data, data, len) == 0)) - return ptr; - ptr=ptr->next; - } - - return NULL; -} - -static inline void insert_token_in_group(struct token *head, struct token *ptr) -{ - ptr->right = head->right; - ptr->right->left = ptr; - head->right = ptr; - ptr->left = head; -} - -static inline void remove_token_from_group(struct token *ptr) -{ - ptr->left->right = ptr->right; - ptr->right->left = ptr->left; -} - - -/* build the counts for all the tokens that start with "data", and have lenghts - * from 2 to "len" */ -static void learn_token(unsigned char *data, int len) -{ - struct token *ptr,*last_ptr; - int i, newprofit; - unsigned int hash = HASH_BASE_OFFSET; - unsigned int hashes[MAX_TOK_SIZE + 1]; - - if (len > MAX_TOK_SIZE) - len = MAX_TOK_SIZE; - - /* calculate and store the hash values for all the sub-tokens */ - hash = rehash_token(hash, data[0]); - for (i = 2; i <= len; i++) { - hash = rehash_token(hash, data[i-1]); - hashes[i] = HASH_FOLD(hash); - } - - last_ptr = NULL; - ptr = NULL; - - for (i = len; i >= 2; i--) { - hash = hashes[i]; - - if (!ptr) ptr = find_token_hash(data, i, hash); - - if (!ptr) { - /* create a new token entry */ - ptr = (struct token *) malloc(sizeof(*ptr)); - - memcpy(ptr->data, data, i); - ptr->len = i; - - /* when we create an entry, it's profit is 0 because - * we also take into account the size of the token on - * the compressed table. We then subtract GOOD_BAD_THRESHOLD - * so that the test to see if this token belongs to - * the good or bad list, is a comparison to zero */ - ptr->profit = -GOOD_BAD_THRESHOLD; - - ptr->next = hash_table[hash]; - hash_table[hash] = ptr; - - insert_token_in_group(&bad_head, ptr); - - ptr->smaller = NULL; - } else { - newprofit = ptr->profit + (ptr->len - 1); - /* check to see if this token needs to be moved to a - * different list */ - if((ptr->profit < 0) && (newprofit >= 0)) { - remove_token_from_group(ptr); - insert_token_in_group(&good_head,ptr); - } - ptr->profit = newprofit; - } - - if (last_ptr) last_ptr->smaller = ptr; - last_ptr = ptr; - - ptr = ptr->smaller; - } -} - -/* decrease the counts for all the tokens that start with "data", and have lenghts - * from 2 to "len". This function is much simpler than learn_token because we have - * more guarantees (tho tokens exist, the ->smaller pointer is set, etc.) - * The two separate functions exist only because of compression performance */ -static void forget_token(unsigned char *data, int len) -{ - struct token *ptr; - int i, newprofit; - unsigned int hash=0; - - if (len > MAX_TOK_SIZE) len = MAX_TOK_SIZE; - - hash = hash_token(data, len); - ptr = find_token_hash(data, len, hash); - - for (i = len; i >= 2; i--) { - - newprofit = ptr->profit - (ptr->len - 1); - if ((ptr->profit >= 0) && (newprofit < 0)) { - remove_token_from_group(ptr); - insert_token_in_group(&bad_head, ptr); - } - ptr->profit=newprofit; - - ptr=ptr->smaller; - } -} - /* count all the possible tokens in a symbol */ static void learn_symbol(unsigned char *symbol, int len) { int i; for (i = 0; i < len - 1; i++) - learn_token(symbol + i, len - i); + token_profit[ symbol[i] + (symbol[i + 1] << 8) ]++; } /* decrease the count for all the possible tokens in a symbol */ @@ -508,117 +330,90 @@ static void forget_symbol(unsigned char *symbol, int len) int i; for (i = 0; i < len - 1; i++) - forget_token(symbol + i, len - i); + token_profit[ symbol[i] + (symbol[i + 1] << 8) ]--; } -/* set all the symbol flags and do the initial token count */ +/* remove all the invalid symbols from the table and do the initial token count */ static void build_initial_tok_table(void) { - int i, use_it, valid; + unsigned int i, pos; - valid = 0; - for (i = 0; i < cnt; i++) { - table[i].flags = 0; + pos = 0; + for (i = 0; i < table_cnt; i++) { if ( symbol_valid(&table[i]) ) { - table[i].flags |= SYM_FLAG_VALID; - valid++; + if (pos != i) + table[pos] = table[i]; + learn_symbol(table[pos].sym, table[pos].len); + pos++; } } - - use_it = 0; - for (i = 0; i < cnt; i++) { - - /* subsample the available symbols. This method is almost like - * a Bresenham's algorithm to get uniformly distributed samples - * across the symbol table */ - if (table[i].flags & SYM_FLAG_VALID) { - - use_it += WORKING_SET; - - if (use_it >= valid) { - table[i].flags |= SYM_FLAG_SAMPLED; - use_it -= valid; - } - } - if (table[i].flags & SYM_FLAG_SAMPLED) - learn_symbol(table[i].sym, table[i].len); - } + table_cnt = pos; } /* replace a given token in all the valid symbols. Use the sampled symbols * to update the counts */ -static void compress_symbols(unsigned char *str, int tlen, int idx) +static void compress_symbols(unsigned char *str, int idx) { - int i, len, learn, size; - unsigned char *p; + unsigned int i, len, size; + unsigned char *p1, *p2; - for (i = 0; i < cnt; i++) { - - if (!(table[i].flags & SYM_FLAG_VALID)) continue; + for (i = 0; i < table_cnt; i++) { len = table[i].len; - learn = 0; - p = table[i].sym; + p1 = table[i].sym; + + /* find the token on the symbol */ + p2 = memmem(p1, len, str, 2); + if (!p2) continue; + + /* decrease the counts for this symbol's tokens */ + forget_symbol(table[i].sym, len); + + size = len; do { + *p2 = idx; + p2++; + size -= (p2 - p1); + memmove(p2, p2 + 1, size); + p1 = p2; + len--; + + if (size < 2) break; + /* find the token on the symbol */ - p = (unsigned char *) strstr((char *) p, (char *) str); - if (!p) break; + p2 = memmem(p1, size, str, 2); - if (!learn) { - /* if this symbol was used to count, decrease it */ - if (table[i].flags & SYM_FLAG_SAMPLED) - forget_symbol(table[i].sym, len); - learn = 1; - } + } while (p2); - *p = idx; - size = (len - (p - table[i].sym)) - tlen + 1; - memmove(p + 1, p + tlen, size); - p++; - len -= tlen - 1; + table[i].len = len; - } while (size >= tlen); - - if(learn) { - table[i].len = len; - /* if this symbol was used to count, learn it again */ - if(table[i].flags & SYM_FLAG_SAMPLED) - learn_symbol(table[i].sym, len); - } + /* increase the counts for this symbol's new tokens */ + learn_symbol(table[i].sym, len); } } /* search the token with the maximum profit */ -static struct token *find_best_token(void) +static int find_best_token(void) { - struct token *ptr,*best,*head; - int bestprofit; + int i, best, bestprofit; bestprofit=-10000; + best = 0; - /* failsafe: if the "good" list is empty search from the "bad" list */ - if(good_head.right == &good_head) head = &bad_head; - else head = &good_head; - - ptr = head->right; - best = NULL; - while (ptr != head) { - if (ptr->profit > bestprofit) { - bestprofit = ptr->profit; - best = ptr; + for (i = 0; i < 0x10000; i++) { + if (token_profit[i] > bestprofit) { + best = i; + bestprofit = token_profit[i]; } - ptr = ptr->right; } - return best; } /* this is the core of the algorithm: calculate the "best" table */ static void optimize_result(void) { - struct token *best; - int i; + int i, best; /* using the '\0' symbol last allows compress_symbols to use standard * fast string functions */ @@ -632,14 +427,12 @@ static void optimize_result(void) best = find_best_token(); /* place it in the "best" table */ - best_table_len[i] = best->len; - memcpy(best_table[i], best->data, best_table_len[i]); - /* zero terminate the token so that we can use strstr - in compress_symbols */ - best_table[i][best_table_len[i]]='\0'; + best_table_len[i] = 2; + best_table[i][0] = best & 0xFF; + best_table[i][1] = (best >> 8) & 0xFF; /* replace this token in all the valid symbols */ - compress_symbols(best_table[i], best_table_len[i], i); + compress_symbols(best_table[i], i); } } } @@ -647,39 +440,28 @@ static void optimize_result(void) /* start by placing the symbols that are actually used on the table */ static void insert_real_symbols_in_table(void) { - int i, j, c; + unsigned int i, j, c; memset(best_table, 0, sizeof(best_table)); memset(best_table_len, 0, sizeof(best_table_len)); - for (i = 0; i < cnt; i++) { - if (table[i].flags & SYM_FLAG_VALID) { - for (j = 0; j < table[i].len; j++) { - c = table[i].sym[j]; - best_table[c][0]=c; - best_table_len[c]=1; - } + for (i = 0; i < table_cnt; i++) { + for (j = 0; j < table[i].len; j++) { + c = table[i].sym[j]; + best_table[c][0]=c; + best_table_len[c]=1; } } } static void optimize_token_table(void) { - memset(hash_table, 0, sizeof(hash_table)); - - good_head.left = &good_head; - good_head.right = &good_head; - - bad_head.left = &bad_head; - bad_head.right = &bad_head; - build_initial_tok_table(); insert_real_symbols_in_table(); /* When valid symbol is not registered, exit to error */ - if (good_head.left == good_head.right && - bad_head.left == bad_head.right) { + if (!table_cnt) { fprintf(stderr, "No valid symbol.\n"); exit(1); } @@ -688,8 +470,7 @@ static void optimize_token_table(void) } -int -main(int argc, char **argv) +int main(int argc, char **argv) { if (argc >= 2) { int i; From 5719e608b404c5f566ab2410047ba07ebe02d588 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 4 Jan 2007 10:17:34 +0000 Subject: [PATCH 026/570] [XEN] Avoid use of GNU-specific memmem(). Signed-off-by: Keir Fraser --- xen/tools/symbols.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/xen/tools/symbols.c b/xen/tools/symbols.c index ed126a2d06..00f1a43037 100644 --- a/xen/tools/symbols.c +++ b/xen/tools/symbols.c @@ -350,6 +350,14 @@ static void build_initial_tok_table(void) table_cnt = pos; } +static void *memmem_pvt(void *h, size_t hlen, void *n, size_t nlen) +{ + char *p; + for (p = h; (p - (char *)h) <= (hlen - nlen); p++) + if (!memcmp(p, n, nlen)) return p; + return NULL; +} + /* replace a given token in all the valid symbols. Use the sampled symbols * to update the counts */ static void compress_symbols(unsigned char *str, int idx) @@ -363,7 +371,7 @@ static void compress_symbols(unsigned char *str, int idx) p1 = table[i].sym; /* find the token on the symbol */ - p2 = memmem(p1, len, str, 2); + p2 = memmem_pvt(p1, len, str, 2); if (!p2) continue; /* decrease the counts for this symbol's tokens */ @@ -382,7 +390,7 @@ static void compress_symbols(unsigned char *str, int idx) if (size < 2) break; /* find the token on the symbol */ - p2 = memmem(p1, size, str, 2); + p2 = memmem_pvt(p1, size, str, 2); } while (p2); From b7e67b038fe0d1ffbf5227024c06fe90b86a6d51 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 4 Jan 2007 10:20:45 +0000 Subject: [PATCH 027/570] [XEND] Fix allocation of fixed VNC ports. From: MArk Williamson Signed-off-by: Keir Fraser --- tools/python/xen/xend/server/vfbif.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/vfbif.py b/tools/python/xen/xend/server/vfbif.py index d07cd2f9e8..816dcd5a6f 100644 --- a/tools/python/xen/xend/server/vfbif.py +++ b/tools/python/xen/xend/server/vfbif.py @@ -64,7 +64,7 @@ class VfbifController(DevController): if config.has_key("vncunused"): args += ["--unused"] elif config.has_key("vncdisplay"): - args += ["--vncport", "%d" % (5900 + config["vncdisplay"])] + args += ["--vncport", "%d" % (5900 + int(config["vncdisplay"]))] vnclisten = config.get("vnclisten", xen.xend.XendRoot.instance().get_vnclisten_address()) args += [ "--listen", vnclisten ] From 1033df914402ac2cdf6db55cc9f79c9888adabe4 Mon Sep 17 00:00:00 2001 From: Steven Hand Date: Thu, 4 Jan 2007 10:58:01 +0000 Subject: [PATCH 028/570] Make sure we always have a sensible idle function; this fixes problems booting dom0 on AMD introduced by -unstable cset 13213:bf25488db8eb. Signed-off-by: Steven Hand --- linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c | 9 ++++++--- linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c | 10 ++++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c index 00a8d8a8eb..0dbc6a412e 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c @@ -168,17 +168,22 @@ void cpu_idle(void) /* endless idle loop with no priority at all */ while (1) { while (!need_resched()) { + void (*idle)(void); if (__get_cpu_var(cpu_idle_state)) __get_cpu_var(cpu_idle_state) = 0; rmb(); + idle = pm_idle; + + if (!idle) + idle = xen_idle; if (cpu_is_offline(cpu)) play_dead(); __get_cpu_var(irq_stat).idle_timestamp = jiffies; - pm_idle(); + idle(); } preempt_enable_no_resched(); schedule(); @@ -216,8 +221,6 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); void __devinit select_idle_routine(const struct cpuinfo_x86 *c) { - if (!pm_idle) - pm_idle = xen_idle; } static int __init idle_setup (char *str) diff --git a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c index c12ebe0e01..8267a772b7 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/kernel/process-xen.c @@ -182,14 +182,18 @@ void cpu_idle (void) /* endless idle loop with no priority at all */ while (1) { while (!need_resched()) { + void (*idle)(void); + if (__get_cpu_var(cpu_idle_state)) __get_cpu_var(cpu_idle_state) = 0; rmb(); - + idle = pm_idle; + if (!idle) + idle = xen_idle; if (cpu_is_offline(smp_processor_id())) play_dead(); enter_idle(); - pm_idle(); + idle(); __exit_idle(); } @@ -230,8 +234,6 @@ EXPORT_SYMBOL_GPL(cpu_idle_wait); void __cpuinit select_idle_routine(const struct cpuinfo_x86 *c) { - if (!pm_idle) - pm_idle = xen_idle; } static int __init idle_setup (char *str) From 7c6b36118d37cfe5d50bcabc32b6d28d99aadc11 Mon Sep 17 00:00:00 2001 From: Christian Limpach Date: Thu, 4 Jan 2007 13:05:09 +0000 Subject: [PATCH 029/570] [linux] Remove some gratuitous differences with plain 2.6.16.33. Signed-off-by: Christian Limpach --- linux-2.6-xen-sparse/arch/i386/pci/irq-xen.c | 5 ++--- linux-2.6-xen-sparse/net/core/dev.c | 3 +-- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/i386/pci/irq-xen.c b/linux-2.6-xen-sparse/arch/i386/pci/irq-xen.c index f491038674..ee2f87191f 100644 --- a/linux-2.6-xen-sparse/arch/i386/pci/irq-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/pci/irq-xen.c @@ -110,7 +110,6 @@ static struct irq_routing_table * __init pirq_find_routing_table(void) if (rt) return rt; } - return NULL; } @@ -261,13 +260,13 @@ static int pirq_via_set(struct pci_dev *router, struct pci_dev *dev, int pirq, i */ static int pirq_via586_get(struct pci_dev *router, struct pci_dev *dev, int pirq) { - static unsigned int pirqmap[4] = { 3, 2, 5, 1 }; + static unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; return read_config_nybble(router, 0x55, pirqmap[pirq-1]); } static int pirq_via586_set(struct pci_dev *router, struct pci_dev *dev, int pirq, int irq) { - static unsigned int pirqmap[4] = { 3, 2, 5, 1 }; + static unsigned int pirqmap[5] = { 3, 2, 5, 1, 1 }; write_config_nybble(router, 0x55, pirqmap[pirq-1], irq); return 1; } diff --git a/linux-2.6-xen-sparse/net/core/dev.c b/linux-2.6-xen-sparse/net/core/dev.c index ef92b788f0..3065f9242d 100644 --- a/linux-2.6-xen-sparse/net/core/dev.c +++ b/linux-2.6-xen-sparse/net/core/dev.c @@ -1248,14 +1248,13 @@ static int dev_gso_segment(struct sk_buff *skb) /* Verifying header integrity only. */ if (!segs) return 0; - + if (unlikely(IS_ERR(segs))) return PTR_ERR(segs); skb->next = segs; DEV_GSO_CB(skb)->destructor = skb->destructor; skb->destructor = dev_gso_skb_destructor; - return 0; } From b2bfd9596fee74d3d3e5f97134c17119aa61a9d4 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 4 Jan 2007 14:25:58 +0000 Subject: [PATCH 030/570] Switch hotplug scripts to use /bin/bash rather than /bin/sh. Hotplug scripts include certain bash-isms that are not supported under some distros' default shell (eg. Ubuntu 6.10's use of dash) Signed-off-by: Alastair Tse --- tools/examples/blktap | 2 +- tools/examples/block | 2 +- tools/examples/block-enbd | 2 +- tools/examples/block-nbd | 2 +- tools/examples/external-device-migrate | 2 +- tools/examples/network-bridge | 2 +- tools/examples/network-nat | 2 +- tools/examples/network-route | 2 +- tools/examples/vif-bridge | 2 +- tools/examples/vif-common.sh | 8 ++++---- tools/examples/vif-nat | 2 +- tools/examples/vif-route | 2 +- tools/examples/vtpm | 2 +- tools/examples/vtpm-delete | 2 +- tools/examples/xen-backend.agent | 2 +- tools/examples/xen-hotplug-cleanup | 2 +- 16 files changed, 19 insertions(+), 19 deletions(-) diff --git a/tools/examples/blktap b/tools/examples/blktap index bc25b48be2..5a7ee3236b 100644 --- a/tools/examples/blktap +++ b/tools/examples/blktap @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Copyright (c) 2005, XenSource Ltd. diff --git a/tools/examples/block b/tools/examples/block index 8ec73231bf..2b6b991125 100644 --- a/tools/examples/block +++ b/tools/examples/block @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash dir=$(dirname "$0") . "$dir/block-common.sh" diff --git a/tools/examples/block-enbd b/tools/examples/block-enbd index 75c6f257aa..67faa84268 100755 --- a/tools/examples/block-enbd +++ b/tools/examples/block-enbd @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Usage: block-enbd [bind server ctl_port |unbind node] # diff --git a/tools/examples/block-nbd b/tools/examples/block-nbd index 8c5cb17b79..b29b31564a 100644 --- a/tools/examples/block-nbd +++ b/tools/examples/block-nbd @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Usage: block-nbd [bind server ctl_port |unbind node] # diff --git a/tools/examples/external-device-migrate b/tools/examples/external-device-migrate index fa52334231..c7c99afec3 100644 --- a/tools/examples/external-device-migrate +++ b/tools/examples/external-device-migrate @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Copyright (c) 2005 IBM Corporation # diff --git a/tools/examples/network-bridge b/tools/examples/network-bridge index 49b79db95b..b616a72275 100755 --- a/tools/examples/network-bridge +++ b/tools/examples/network-bridge @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash #============================================================================ # Default Xen network start/stop script. # Xend calls a network script when it starts. diff --git a/tools/examples/network-nat b/tools/examples/network-nat index 94b84307c0..62d2b0c259 100644 --- a/tools/examples/network-nat +++ b/tools/examples/network-nat @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash #============================================================================ # Default Xen network start/stop script when using NAT. # Xend calls a network script when it starts. diff --git a/tools/examples/network-route b/tools/examples/network-route index de535c3280..574441e334 100755 --- a/tools/examples/network-route +++ b/tools/examples/network-route @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash #============================================================================ # Default Xen network start/stop script. # Xend calls a network script when it starts. diff --git a/tools/examples/vif-bridge b/tools/examples/vif-bridge index 7008210579..0935ad2fae 100755 --- a/tools/examples/vif-bridge +++ b/tools/examples/vif-bridge @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash #============================================================================ # /etc/xen/vif-bridge # diff --git a/tools/examples/vif-common.sh b/tools/examples/vif-common.sh index 50da9a4494..ee67ee2aaa 100644 --- a/tools/examples/vif-common.sh +++ b/tools/examples/vif-common.sh @@ -64,7 +64,7 @@ then fi -function frob_iptable() +frob_iptable() { if [ "$command" == "online" ] then @@ -89,7 +89,7 @@ If you are using iptables, this may affect networking for guest domains." # to those coming from the specified networks, though we allow DHCP requests # as well. # -function handle_iptable() +handle_iptable() { # Check for a working iptables installation. Checking for the iptables # binary is not sufficient, because the user may not have the appropriate @@ -123,7 +123,7 @@ function handle_iptable() # Print the IP address currently in use at the given interface, or nothing if # the interface is not up. # -function ip_of() +ip_of() { ip addr show "$1" | awk "/^.*inet.*$1\$/{print \$2}" | sed -n '1 s,/.*,,p' } @@ -137,7 +137,7 @@ function ip_of() # to these scripts, or eth0 by default. This function will call fatal if no # such interface could be found. # -function dom0_ip() +dom0_ip() { local nd=${netdev:-eth0} local result=$(ip_of "$nd") diff --git a/tools/examples/vif-nat b/tools/examples/vif-nat index 29611654eb..579d7eba35 100644 --- a/tools/examples/vif-nat +++ b/tools/examples/vif-nat @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash #============================================================================ # /etc/xen/vif-nat # diff --git a/tools/examples/vif-route b/tools/examples/vif-route index 8d0fb8d76c..f5fd88ed5a 100755 --- a/tools/examples/vif-route +++ b/tools/examples/vif-route @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash #============================================================================ # /etc/xen/vif-route # diff --git a/tools/examples/vtpm b/tools/examples/vtpm index cf8b50ff50..38a4532fc2 100644 --- a/tools/examples/vtpm +++ b/tools/examples/vtpm @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash dir=$(dirname "$0") . "$dir/vtpm-hotplug-common.sh" diff --git a/tools/examples/vtpm-delete b/tools/examples/vtpm-delete index 14bfddcd94..b54a093f02 100644 --- a/tools/examples/vtpm-delete +++ b/tools/examples/vtpm-delete @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # This scripts must be called the following way: # vtpm-delete diff --git a/tools/examples/xen-backend.agent b/tools/examples/xen-backend.agent index 3a01a2c7ea..f043854ad0 100755 --- a/tools/examples/xen-backend.agent +++ b/tools/examples/xen-backend.agent @@ -1,4 +1,4 @@ -#! /bin/sh +#! /bin/bash PATH=/etc/xen/scripts:$PATH diff --git a/tools/examples/xen-hotplug-cleanup b/tools/examples/xen-hotplug-cleanup index 6356a91892..f7337e45bf 100644 --- a/tools/examples/xen-hotplug-cleanup +++ b/tools/examples/xen-hotplug-cleanup @@ -1,4 +1,4 @@ -#! /bin/sh +#! /bin/bash dir=$(dirname "$0") . "$dir/xen-hotplug-common.sh" From 2ea27d8c999619064bd773ebed712211fd0ea9e3 Mon Sep 17 00:00:00 2001 From: Steven Hand Date: Thu, 4 Jan 2007 15:08:40 +0000 Subject: [PATCH 031/570] [XM-TEST] Tweak 06_block-destroy_check_list_pos to allow more time to check block device has gone away from point of view of domain sxp. Signed-off-by: Steven Hand --- .../block-destroy/06_block-destroy_check_list_pos.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py b/tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py index 292db063d6..b9fdc0691b 100644 --- a/tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py +++ b/tools/xm-test/tests/block-destroy/06_block-destroy_check_list_pos.py @@ -6,7 +6,7 @@ from XmTestLib import * from XmTestLib.block_utils import * -import re +import re, time def checkXmLongList(domain): s, o = traceCommand("xm list --long %s" % domain.getName()) @@ -35,4 +35,8 @@ if not checkXmLongList(domain): block_detach(domain, "xvda1") if checkXmLongList(domain): - FAIL("xm long list does not show that xvda1 was removed") + # device info is removed by hotplug scripts - give them a chance + # to fire (they run asynchronously with us). + time.sleep(1) + if checkXmLongList(domain): + FAIL("xm long list does not show that xvda1 was removed") From df7005672dcf38de4a0d820c90f1421a39ce66ff Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 4 Jan 2007 15:32:26 +0000 Subject: [PATCH 032/570] [XEND] Parse as much device SXP as possible. Fix vtpm device check and xm list --long listing detached block devices. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendConfig.py | 36 +++++++++++++++++------------ 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 08ccf9e54f..d8bb63494c 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -508,8 +508,12 @@ class XendConfig(dict): pci_devs = [] for pci_dev in sxp.children(config, 'dev'): pci_dev_info = {} - for opt, val in pci_dev[1:]: - pci_dev_info[opt] = val + for opt_val in pci_dev[1:]: + try: + opt, val = opt_val + pci_dev_info[opt] = val + except TypeError: + pass pci_devs.append(pci_dev_info) cfg['devices'][pci_devs_uuid] = (dev_type, @@ -572,7 +576,6 @@ class XendConfig(dict): if 'security' in cfg and isinstance(cfg['security'], str): cfg['security'] = sxp.from_string(cfg['security']) - # TODO: get states old_state = sxp.child_value(sxp_cfg, 'state') if old_state: for i in range(len(CONFIG_OLD_DOM_STATES)): @@ -855,14 +858,15 @@ class XendConfig(dict): for cls in XendDevices.valid_devices(): found = False - # figure if there is a device that is running + # figure if there is a dev controller is valid and running if domain: try: controller = domain.getDeviceController(cls) configs = controller.configurations() for config in configs: sxpr.append(['device', config]) - found = True + + found = True except: log.exception("dumping sxp from device controllers") pass @@ -923,11 +927,12 @@ class XendConfig(dict): dev_type = sxp.name(config) dev_info = {} - try: - for opt, val in config[1:]: + for opt_val in config[1:]: + try: + opt, val = opt_val dev_info[opt] = val - except ValueError: - pass # SXP has no options for this device + except (TypeError, ValueError): # unpack error + pass if dev_type == 'vbd': if dev_info.get('dev', '').startswith('ioemu:'): @@ -996,7 +1001,7 @@ class XendConfig(dict): self['vbd_refs'].append(dev_uuid) return dev_uuid - elif dev_type in ('vtpm'): + elif dev_type == 'vtpm': if cfg_xenapi.get('type'): dev_info['type'] = cfg_xenapi.get('type') @@ -1019,11 +1024,12 @@ class XendConfig(dict): dev_type = sxp.name(config) dev_info = {} - try: - for opt, val in config[1:]: - self['devices'][opt] = val - except ValueError: - pass # SXP has no options for this device + for opt_val in config[1:]: + try: + opt, val = opt_val + self['devices'][dev_uuid][opt] = val + except (TypeError, ValueError): + pass # no value for this config option return True From a9aa1a0d2904e322276d5c3cefdef465128f5516 Mon Sep 17 00:00:00 2001 From: Christian Limpach Date: Thu, 4 Jan 2007 15:50:08 +0000 Subject: [PATCH 033/570] [linux] Fix vsnprintf patch not to write null byte past the end of the buffer. Signed-off-by: Christian Limpach --- patches/linux-2.6.16.33/vsnprintf.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/patches/linux-2.6.16.33/vsnprintf.patch b/patches/linux-2.6.16.33/vsnprintf.patch index 69a93fa5c5..3e32773986 100644 --- a/patches/linux-2.6.16.33/vsnprintf.patch +++ b/patches/linux-2.6.16.33/vsnprintf.patch @@ -203,7 +203,7 @@ index b07db5c..f595947 100644 + if (str < end) + *str = '\0'; + else -+ *end = '\0'; ++ end[-1] = '\0'; + } + /* the trailing null byte doesn't count towards the total */ return str-buf; From 3a1c98ecfb44acb9c86adb56749e8d136ccd11bf Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 4 Jan 2007 15:58:20 +0000 Subject: [PATCH 034/570] [XEND] Allow arbitrary values for the vif 'type'. Signed-off-by: David Edmondson --- tools/python/xen/xend/server/netif.py | 8 ++++++-- tools/python/xen/xm/create.py | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/server/netif.py b/tools/python/xen/xend/server/netif.py index 92e5626ade..c229ed7b20 100644 --- a/tools/python/xen/xend/server/netif.py +++ b/tools/python/xen/xend/server/netif.py @@ -150,16 +150,20 @@ class NetifController(DevController): devid = self.allocateDeviceID() + # The default type is 'netfront'. + if not typ: + typ = 'netfront' + if not mac: mac = randomMAC() back = { 'script' : script, 'mac' : mac, - 'handle' : "%i" % devid } + 'handle' : "%i" % devid, + 'type' : typ } if typ == 'ioemu': front = {} - back['type'] = 'ioemu' else: front = { 'handle' : "%i" % devid, 'mac' : mac } diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index b603b922d6..140b6f7749 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -300,7 +300,7 @@ gopts.var('vif', val="type=TYPE,mac=MAC,bridge=BRIDGE,ip=IPADDR,script=SCRIPT,ba fn=append_value, default=[], use="""Add a network interface with the given MAC address and bridge. The vif is configured by calling the given configuration script. - If type is not specified, default is netfront not ioemu device. + If type is not specified, default is netfront. If mac is not specified a random MAC address is used. If not specified then the network backend chooses it's own MAC address. If bridge is not specified the first bridge found is used. From a089f6e2cd69091bb158d7c46df32c9984ed88d7 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 4 Jan 2007 16:21:12 +0000 Subject: [PATCH 035/570] [XEND] Only use DevController to generate SXP for running domains. Otherwise the previous patch breaks managed domains in xm list. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index d8bb63494c..92af7b4239 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -859,7 +859,7 @@ class XendConfig(dict): found = False # figure if there is a dev controller is valid and running - if domain: + if domain and domain.getDomid(): try: controller = domain.getDeviceController(cls) configs = controller.configurations() From 019793657beaf52a0979be3c2407cf3dd2ce4aff Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 4 Jan 2007 16:30:20 +0000 Subject: [PATCH 036/570] [XEND] Default values for VBD mode and cpu_weight. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendDomainInfo.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 2df5316fcf..46386871fa 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -914,7 +914,7 @@ class XendDomainInfo: return self.info.get('cpu_cap', 0) def getWeight(self): - return self.info['cpu_weight'] + return self.info.get('cpu_weight', 256) def setResume(self, state): self._resume = state @@ -1991,7 +1991,7 @@ class XendDomainInfo: config['image'] = config.get('uname', '') config['io_read_kbs'] = 0.0 config['io_write_kbs'] = 0.0 - if config['mode'] == 'r': + if config.get('mode', 'r') == 'r': config['mode'] = 'RO' else: config['mode'] = 'RW' From eddd713445f04941b107d01278f761ac8ccc91fb Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 4 Jan 2007 16:31:29 +0000 Subject: [PATCH 037/570] [XEND] Add VBD_MODE enum from XenAPI. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendAPIConstants.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/python/xen/xend/XendAPIConstants.py b/tools/python/xen/xend/XendAPIConstants.py index 875f948bcf..6d260d5939 100644 --- a/tools/python/xen/xend/XendAPIConstants.py +++ b/tools/python/xen/xend/XendAPIConstants.py @@ -73,3 +73,4 @@ XEN_API_BOOT_TYPE = [ XEN_API_VBD_MODE = ['RO', 'RW'] XEN_API_VDI_TYPE = ['system', 'user', 'ephemeral'] XEN_API_DRIVER_TYPE = ['ioemu', 'paravirtualised'] +XEN_API_VBD_TYPE = ['CD', 'Disk'] From 4b166e2a1717101567cbb9658ced8b64495e1b65 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 4 Jan 2007 16:34:19 +0000 Subject: [PATCH 038/570] [XEND] Prevent exception if PIF does not have a network. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendNode.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendNode.py b/tools/python/xen/xend/XendNode.py index f0037e984a..117ca3d25d 100644 --- a/tools/python/xen/xend/XendNode.py +++ b/tools/python/xen/xend/XendNode.py @@ -103,7 +103,7 @@ class XendNode: saved_pifs = self.state_store.load_state('pif') if saved_pifs: for pif_uuid, pif in saved_pifs.items(): - if pif['network'] in self.networks: + if pif.get('network') in self.networks: network = self.networks[pif['network']] try: self.PIF_create(pif['name'], pif['MTU'], pif['VLAN'], From ab452d0667ad37d36d58f69c539d8250bc512248 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 4 Jan 2007 16:42:44 +0000 Subject: [PATCH 039/570] [XEND] Fix block-list for dom0 in xm. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendConfig.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index 92af7b4239..f003c6e9eb 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -859,7 +859,7 @@ class XendConfig(dict): found = False # figure if there is a dev controller is valid and running - if domain and domain.getDomid(): + if domain and domain.getDomid() != None: try: controller = domain.getDeviceController(cls) configs = controller.configurations() From 34a19935542b96e43776d7499b97d7d183f6d44d Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 14:50:26 -0700 Subject: [PATCH 040/570] [IA64] Change dom0's initrd image load area so that it follows start info. It becomes non-sense to use dom0_size if dom0 memoy is assigned sparsely. Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/domain.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 8406c12708..58b8200b9c 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -1051,10 +1051,11 @@ int construct_dom0(struct domain *d, if(initrd_start && initrd_len){ unsigned long offset; - pinitrd_start= dom0_size - (PAGE_ALIGN(initrd_len) + 4*1024*1024); - if (pinitrd_start <= pstart_info) - panic("%s:enough memory is not assigned to dom0", __func__); - + /* The next page aligned boundary after the start info. + Note: EFI_PAGE_SHIFT = 12 <= PAGE_SHIFT */ + pinitrd_start = pstart_info + PAGE_SIZE; + if (pinitrd_start + initrd_len >= dom0_size) + panic("%s: not enough memory assigned to dom0", __func__); for (offset = 0; offset < initrd_len; offset += PAGE_SIZE) { struct page_info *p; p = assign_new_domain_page(d, pinitrd_start + offset); @@ -1109,10 +1110,6 @@ int construct_dom0(struct domain *d, /* Copy the OS image. */ loaddomainelfimage(d,image_start); - /* Copy the initial ramdisk. */ - //if ( initrd_len != 0 ) - // memcpy((void *)vinitrd_start, initrd_start, initrd_len); - BUILD_BUG_ON(sizeof(start_info_t) + sizeof(dom0_vga_console_info_t) + sizeof(struct ia64_boot_param) > PAGE_SIZE); @@ -1161,8 +1158,7 @@ int construct_dom0(struct domain *d, bp->console_info.orig_y = bp->console_info.num_rows == 0 ? 0 : bp->console_info.num_rows - 1; - bp->initrd_start = dom0_size - - (PAGE_ALIGN(ia64_boot_param->initrd_size) + 4*1024*1024); + bp->initrd_start = pinitrd_start; bp->initrd_size = ia64_boot_param->initrd_size; ci = (dom0_vga_console_info_t *)((unsigned char *)si + From c4dfc18b79013527a854bb7437b5f0c5e1b6b1c9 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 15:12:05 -0700 Subject: [PATCH 041/570] [IA64] Fix dom0 builder so that xen doesn't assign memory on I/O area. Signed-off-by: Alex Williamson Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/dom_fw.c | 83 ++++++-------------------------------- 1 file changed, 12 insertions(+), 71 deletions(-) diff --git a/xen/arch/ia64/xen/dom_fw.c b/xen/arch/ia64/xen/dom_fw.c index cfb1cb13ce..2ad12048ce 100644 --- a/xen/arch/ia64/xen/dom_fw.c +++ b/xen/arch/ia64/xen/dom_fw.c @@ -516,10 +516,10 @@ complete_dom0_memmap(struct domain *d, { efi_memory_desc_t *md; u64 addr; - int j; void *efi_map_start, *efi_map_end, *p; u64 efi_desc_size; int i; + unsigned long dom_mem = maxmem - (d->tot_pages << PAGE_SHIFT); /* Walk through all MDT entries. Copy all interesting entries. */ @@ -566,26 +566,22 @@ complete_dom0_memmap(struct domain *d, case EFI_LOADER_DATA: case EFI_BOOT_SERVICES_CODE: case EFI_BOOT_SERVICES_DATA: - /* Create dom0 MDT entries for conventional memory - below 1MB. Without this Linux will assume VGA is - present because 0xA0000 will always be either a hole - in the MDT or an I/O region via the passthrough. */ - - end = min(ONE_MB, end); - - /* Avoid firmware and hypercall area. - We know they are 0-based. */ - if (end < FW_END_PADDR || start >= ONE_MB) + if (!(md->attribute & EFI_MEMORY_WB)) break; - if (start < FW_END_PADDR) - start = FW_END_PADDR; - + + start = max(FW_END_PADDR, start); + end = min(start + dom_mem, end); + if (end <= start) + break; + dom_md->type = EFI_CONVENTIONAL_MEMORY; dom_md->phys_addr = start; dom_md->virt_addr = 0; dom_md->num_pages = (end - start) >> EFI_PAGE_SHIFT; - dom_md->attribute = md->attribute; + dom_md->attribute = EFI_MEMORY_WB; num_mds++; + + dom_mem -= dom_md->num_pages << EFI_PAGE_SHIFT; break; case EFI_UNUSABLE_MEMORY: @@ -601,57 +597,6 @@ complete_dom0_memmap(struct domain *d, } BUG_ON(num_mds > NUM_MEM_DESCS); - sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t), - efi_mdt_cmp, NULL); - - /* find gaps and fill them with conventional memory */ - i = num_mds; - for (j = 0; j < num_mds; j++) { - unsigned long end; - unsigned long next_start; - - md = &tables->efi_memmap[j]; - end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); - - if (j + 1 < num_mds) { - efi_memory_desc_t* next_md; - next_md = &tables->efi_memmap[j + 1]; - next_start = next_md->phys_addr; - - /* Have just been sorted. */ - BUG_ON(end > next_start); - - /* No room for memory! */ - if (end == next_start) - continue; - - if (next_start > maxmem) - next_start = maxmem; - } - else - next_start = maxmem; - - /* Avoid "legacy" low memory addresses - and the HYPERCALL area. */ - if (end < ONE_MB) - end = ONE_MB; - - // clip the range and align to PAGE_SIZE - next_start = next_start & PAGE_MASK; - end = PAGE_ALIGN(end); - - /* No room for memory. */ - if (end >= next_start) - continue; - - MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, - end, next_start); - - if (next_start >= maxmem) - break; - } - num_mds = i; - BUG_ON(num_mds > NUM_MEM_DESCS); sort(tables->efi_memmap, num_mds, sizeof(efi_memory_desc_t), efi_mdt_cmp, NULL); @@ -661,9 +606,7 @@ complete_dom0_memmap(struct domain *d, */ for (i = 0; i < num_mds; i++) { md = &tables->efi_memmap[i]; - if (md->phys_addr > maxmem) - break; - + if (md->type == EFI_LOADER_DATA || md->type == EFI_PAL_CODE || md->type == EFI_CONVENTIONAL_MEMORY) { @@ -675,8 +618,6 @@ complete_dom0_memmap(struct domain *d, /* md->num_pages = 0 is allowed. */ continue; } - if (end > (max_page << PAGE_SHIFT)) - end = (max_page << PAGE_SHIFT); for (addr = start; addr < end; addr += PAGE_SIZE) assign_new_domain0_page(d, addr); From 4038833e79191e1618bdf13aa753db525f634765 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 15:25:47 -0700 Subject: [PATCH 042/570] [IA64] Add convmem_end Split the meaning of struct domain::maxmem into struct arch_domain::convmem_end so that maxmem means the number of pages which domain has and convmem_end means the highest address of conventional memory (i.e. RAM). Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/dom_fw.c | 2 ++ xen/arch/ia64/xen/domain.c | 5 +++-- xen/arch/ia64/xen/mm.c | 6 +++--- xen/include/asm-ia64/domain.h | 3 +++ 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/xen/arch/ia64/xen/dom_fw.c b/xen/arch/ia64/xen/dom_fw.c index 2ad12048ce..97a687e08c 100644 --- a/xen/arch/ia64/xen/dom_fw.c +++ b/xen/arch/ia64/xen/dom_fw.c @@ -582,6 +582,7 @@ complete_dom0_memmap(struct domain *d, num_mds++; dom_mem -= dom_md->num_pages << EFI_PAGE_SHIFT; + d->arch.convmem_end = end; break; case EFI_UNUSABLE_MEMORY: @@ -804,6 +805,7 @@ dom_fw_init(struct domain *d, /* Memory. */ MAKE_MD(EFI_CONVENTIONAL_MEMORY, EFI_MEMORY_WB, FW_END_PADDR, maxmem); + d->arch.convmem_end = maxmem; /* Create an entry for IO ports. */ MAKE_MD(EFI_MEMORY_MAPPED_IO_PORT_SPACE, EFI_MEMORY_UC, diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index 58b8200b9c..aafb0c2515 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -760,8 +760,9 @@ int shadow_mode_control(struct domain *d, xen_domctl_shadow_op_t *sc) atomic64_set(&d->arch.shadow_fault_count, 0); atomic64_set(&d->arch.shadow_dirty_count, 0); - d->arch.shadow_bitmap_size = (d->max_pages + BITS_PER_LONG-1) & - ~(BITS_PER_LONG-1); + d->arch.shadow_bitmap_size = + ((d->arch.convmem_end >> PAGE_SHIFT) + + BITS_PER_LONG - 1) & ~(BITS_PER_LONG - 1); d->arch.shadow_bitmap = xmalloc_array(unsigned long, d->arch.shadow_bitmap_size / BITS_PER_LONG); if (d->arch.shadow_bitmap == NULL) { diff --git a/xen/arch/ia64/xen/mm.c b/xen/arch/ia64/xen/mm.c index 0a5acc0636..1effbf9160 100644 --- a/xen/arch/ia64/xen/mm.c +++ b/xen/arch/ia64/xen/mm.c @@ -700,12 +700,12 @@ unsigned long lookup_domain_mpa(struct domain *d, unsigned long mpaddr, printk("%s: d 0x%p id %d current 0x%p id %d\n", __func__, d, d->domain_id, current, current->vcpu_id); - if ((mpaddr >> PAGE_SHIFT) < d->max_pages) + if (mpaddr < d->arch.convmem_end) printk("%s: non-allocated mpa 0x%lx (< 0x%lx)\n", __func__, - mpaddr, (unsigned long)d->max_pages << PAGE_SHIFT); + mpaddr, d->arch.convmem_end); else printk("%s: bad mpa 0x%lx (=> 0x%lx)\n", __func__, - mpaddr, (unsigned long)d->max_pages << PAGE_SHIFT); + mpaddr, d->arch.convmem_end); if (entry != NULL) p2m_entry_set(entry, NULL, __pte(0)); diff --git a/xen/include/asm-ia64/domain.h b/xen/include/asm-ia64/domain.h index b327bcb27b..a09446d6b1 100644 --- a/xen/include/asm-ia64/domain.h +++ b/xen/include/asm-ia64/domain.h @@ -78,6 +78,9 @@ struct arch_domain { }; }; + /* maximum metaphysical address of conventional memory */ + u64 convmem_end; + /* Allowed accesses to io ports. */ struct rangeset *ioport_caps; From a0fab920c59bcbd138b309b85790c6435628db9b Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 15:28:16 -0700 Subject: [PATCH 043/570] [IA64] Fix warning when building with CONFIG_FLATMEM unset Signed-off-by: Isaku Yamahata --- linux-2.6-xen-sparse/include/asm-ia64/maddr.h | 1 - linux-2.6-xen-sparse/include/asm-ia64/page.h | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/include/asm-ia64/maddr.h b/linux-2.6-xen-sparse/include/asm-ia64/maddr.h index cbdef5a96e..cacad452d8 100644 --- a/linux-2.6-xen-sparse/include/asm-ia64/maddr.h +++ b/linux-2.6-xen-sparse/include/asm-ia64/maddr.h @@ -68,7 +68,6 @@ machine_to_phys_for_dma(unsigned long machine) static inline unsigned long mfn_to_local_pfn(unsigned long mfn) { - extern unsigned long max_mapnr; unsigned long pfn = mfn_to_pfn_for_dma(mfn); if (!pfn_valid(pfn)) return INVALID_P2M_ENTRY; diff --git a/linux-2.6-xen-sparse/include/asm-ia64/page.h b/linux-2.6-xen-sparse/include/asm-ia64/page.h index fca73f00ef..c161dc3aeb 100644 --- a/linux-2.6-xen-sparse/include/asm-ia64/page.h +++ b/linux-2.6-xen-sparse/include/asm-ia64/page.h @@ -105,6 +105,7 @@ extern int ia64_pfn_valid (unsigned long pfn); #endif #ifdef CONFIG_FLATMEM +extern unsigned long max_mapnr; # define pfn_valid(pfn) (((pfn) < max_mapnr) && ia64_pfn_valid(pfn)) # define page_to_pfn(page) ((unsigned long) (page - mem_map)) # define pfn_to_page(pfn) (mem_map + (pfn)) From 003fd895c4d87ef54bfdf588986d55fec3569ea5 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 15:45:10 -0700 Subject: [PATCH 044/570] [IA64] allocate contiguous_bitmap sparsely like virtual memmap. With dom0 memory assignment changed, memory might be sparse, so simple bitmap may waste too much memory. Signed-off-by: Isaku Yamahata --- .../arch/ia64/xen/hypervisor.c | 86 ++++++++++++++++++- 1 file changed, 83 insertions(+), 3 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c index 173a4f613a..d0bc3f92ec 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c @@ -25,7 +25,10 @@ #include #include #include +#include #include +#include +#include #include #include #include @@ -56,13 +59,90 @@ static int p2m_expose_init(void); */ unsigned long *contiguous_bitmap; +#ifdef CONFIG_VIRTUAL_MEM_MAP +/* Following logic is stolen from create_mem_map_table() for virtual memmap */ +static int +create_contiguous_bitmap(u64 start, u64 end, void *arg) +{ + unsigned long address, start_page, end_page; + unsigned long bitmap_start, bitmap_end; + unsigned char *bitmap; + int node; + pgd_t *pgd; + pud_t *pud; + pmd_t *pmd; + pte_t *pte; + + bitmap_start = (unsigned long)contiguous_bitmap + + ((__pa(start) >> PAGE_SHIFT) >> 3); + bitmap_end = (unsigned long)contiguous_bitmap + + (((__pa(end) >> PAGE_SHIFT) + 2 * BITS_PER_LONG) >> 3); + + start_page = bitmap_start & PAGE_MASK; + end_page = PAGE_ALIGN(bitmap_end); + node = paddr_to_nid(__pa(start)); + + bitmap = alloc_bootmem_pages_node(NODE_DATA(node), + end_page - start_page); + BUG_ON(!bitmap); + memset(bitmap, 0, end_page - start_page); + + for (address = start_page; address < end_page; address += PAGE_SIZE) { + pgd = pgd_offset_k(address); + if (pgd_none(*pgd)) + pgd_populate(&init_mm, pgd, + alloc_bootmem_pages_node(NODE_DATA(node), + PAGE_SIZE)); + pud = pud_offset(pgd, address); + + if (pud_none(*pud)) + pud_populate(&init_mm, pud, + alloc_bootmem_pages_node(NODE_DATA(node), + PAGE_SIZE)); + pmd = pmd_offset(pud, address); + + if (pmd_none(*pmd)) + pmd_populate_kernel(&init_mm, pmd, + alloc_bootmem_pages_node + (NODE_DATA(node), PAGE_SIZE)); + pte = pte_offset_kernel(pmd, address); + + if (pte_none(*pte)) + set_pte(pte, + pfn_pte(__pa(bitmap + (address - start_page)) + >> PAGE_SHIFT, PAGE_KERNEL)); + } + return 0; +} +#endif + +static void +__contiguous_bitmap_init(unsigned long size) +{ + contiguous_bitmap = alloc_bootmem_pages(size); + BUG_ON(!contiguous_bitmap); + memset(contiguous_bitmap, 0, size); +} + void contiguous_bitmap_init(unsigned long end_pfn) { unsigned long size = (end_pfn + 2 * BITS_PER_LONG) >> 3; - contiguous_bitmap = alloc_bootmem_pages(size); - BUG_ON(!contiguous_bitmap); - memset(contiguous_bitmap, 0, size); +#ifndef CONFIG_VIRTUAL_MEM_MAP + __contiguous_bitmap_init(size); +#else + unsigned long max_gap = 0; + + efi_memmap_walk(find_largest_hole, (u64*)&max_gap); + if (max_gap < LARGE_GAP) { + __contiguous_bitmap_init(size); + } else { + unsigned long map_size = PAGE_ALIGN(size); + vmalloc_end -= map_size; + contiguous_bitmap = (unsigned long*)vmalloc_end; + efi_memmap_walk(create_contiguous_bitmap, NULL); + } +#endif } #if 0 From f582880f6b392007a29ed9e652511688d708e068 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 16:00:56 -0700 Subject: [PATCH 045/570] [IA64] Respect memory attributes for EFI_RUNTIME memory Respect memory attributes when mapping EFI_RUNTIME and reserved pages. Not all of these pages are writable and/or cachable! Signed-off-by: Jes Sorensen --- xen/arch/ia64/xen/dom_fw.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/xen/arch/ia64/xen/dom_fw.c b/xen/arch/ia64/xen/dom_fw.c index 97a687e08c..3f9dd9cf2a 100644 --- a/xen/arch/ia64/xen/dom_fw.c +++ b/xen/arch/ia64/xen/dom_fw.c @@ -533,6 +533,7 @@ complete_dom0_memmap(struct domain *d, u64 start = md->phys_addr; u64 size = md->num_pages << EFI_PAGE_SHIFT; u64 end = start + size; + unsigned long flags; switch (md->type) { case EFI_RUNTIME_SERVICES_CODE: @@ -540,9 +541,19 @@ complete_dom0_memmap(struct domain *d, case EFI_ACPI_RECLAIM_MEMORY: case EFI_ACPI_MEMORY_NVS: case EFI_RESERVED_TYPE: - /* Map into dom0 - All these are writable. */ - assign_domain_mach_page(d, start, size, - ASSIGN_writable); + /* + * Map into dom0 - We must respect protection + * and cache attributes. Not all of these pages + * are writable!!! + */ + flags = ASSIGN_writable; /* dummy - zero */ + if (md->attribute & EFI_MEMORY_WP) + flags |= ASSIGN_readonly; + if (md->attribute & EFI_MEMORY_UC) + flags |= ASSIGN_nocache; + + assign_domain_mach_page(d, start, size, flags); + /* Fall-through. */ case EFI_MEMORY_MAPPED_IO: /* Will be mapped with ioremap. */ From eacdd4f1287a43286850c05613de2f049eccc488 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 16:10:25 -0700 Subject: [PATCH 046/570] [IA64] Fix calling xencomm_copy_chunk_{to, from} with len = 0 Originally debugged by Kazuhiro Suzuki Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/xencomm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/ia64/xen/xencomm.c b/xen/arch/ia64/xen/xencomm.c index 3b8e40b5b3..21eef3a51a 100644 --- a/xen/arch/ia64/xen/xencomm.c +++ b/xen/arch/ia64/xen/xencomm.c @@ -153,7 +153,7 @@ xencomm_copy_from_guest( chunksz -= chunk_skip; skip -= chunk_skip; - if (skip == 0) { + if (skip == 0 && chunksz > 0) { unsigned int bytes = min(chunksz, n - to_pos); int res; @@ -295,7 +295,7 @@ xencomm_copy_to_guest( skip -= chunk_skip; dest_paddr += chunk_skip; - if (skip == 0) { + if (skip == 0 && chunksz > 0) { unsigned int bytes = min(chunksz, n - from_pos); int res; From e207cc255580652487cbfad7597b69b248f6efb9 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 16:14:22 -0700 Subject: [PATCH 047/570] [IA64] Enable fast hyperprivop for ssm.i and rfi Signed-off-by: Anthony Xu --- xen/arch/ia64/asm-offsets.c | 1 + xen/arch/ia64/xen/hyperprivop.S | 22 ++++++++++------------ 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/xen/arch/ia64/asm-offsets.c b/xen/arch/ia64/asm-offsets.c index e0f502f662..efd68306d0 100644 --- a/xen/arch/ia64/asm-offsets.c +++ b/xen/arch/ia64/asm-offsets.c @@ -60,6 +60,7 @@ void foo(void) DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_saved_rr0)); DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct vcpu, arch.breakimm)); DEFINE(IA64_VCPU_IVA_OFFSET, offsetof (struct vcpu, arch.iva)); + DEFINE(IA64_VCPU_EVENT_CALLBACK_IP_OFFSET, offsetof (struct vcpu, arch.event_callback_ip)); DEFINE(IA64_VCPU_IRR0_OFFSET, offsetof (struct vcpu, arch.irr[0])); DEFINE(IA64_VCPU_IRR3_OFFSET, offsetof (struct vcpu, arch.irr[3])); DEFINE(IA64_VCPU_INSVC3_OFFSET, offsetof (struct vcpu, arch.insvc[3])); diff --git a/xen/arch/ia64/xen/hyperprivop.S b/xen/arch/ia64/xen/hyperprivop.S index 763f66b072..9d6d418784 100644 --- a/xen/arch/ia64/xen/hyperprivop.S +++ b/xen/arch/ia64/xen/hyperprivop.S @@ -37,10 +37,10 @@ # define FAST_BREAK # undef FAST_ACCESS_REFLECT //XXX TODO fast_access_reflect // doesn't support dom0 vp yet. -//# define FAST_RFI +# define FAST_RFI // TODO: Since we use callback to deliver interrupt, // FAST_SSM_I needs to be rewritten. -//# define FAST_SSM_I +# define FAST_SSM_I # define FAST_PTC_GA # undef RFI_TO_INTERRUPT // not working yet #endif @@ -282,13 +282,11 @@ ENTRY(hyper_ssm_i) adds r21=XSI_PRECOVER_IFS_OFS-XSI_PSR_IC_OFS,r18 ;; st8 [r21]=r20 ;; // leave cr.ifs alone for later rfi - // set iip to go to domain IVA break instruction vector + // set iip to go to event callback handler movl r22=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; ld8 r22=[r22];; - adds r22=IA64_VCPU_IVA_OFFSET,r22;; - ld8 r23=[r22];; - movl r24=0x3000;; - add r24=r24,r23;; + adds r22=IA64_VCPU_EVENT_CALLBACK_IP_OFFSET,r22;; + ld8 r24=[r22];; mov cr.iip=r24;; // OK, now all set to go except for switch to virtual bank0 mov r30=r2 @@ -1027,8 +1025,12 @@ ENTRY(hyper_rfi) adds r20=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;; ld8 r21=[r20];; // r21 = vcr.ipsr extr.u r22=r21,IA64_PSR_I_BIT,1 ;; - mov r30=r22 + mov r30=r22;; // r30 determines whether we might deliver an immediate extint +#ifndef RFI_TO_INTERRUPT // see beginning of file + cmp.ne p6,p0=r30,r0 +(p6) br.cond.spnt.few dispatch_break_fault ;; +#endif 1: adds r20=XSI_IPSR_OFS-XSI_PSR_IC_OFS,r18 ;; ld8 r21=[r20];; // r21 = vcr.ipsr @@ -1063,10 +1065,6 @@ ENTRY(hyper_rfi) cmp.ltu p0,p7=r22,r23 ;; // if !(iip=high) (p7) br.spnt.few dispatch_break_fault ;; -#ifndef RFI_TO_INTERRUPT // see beginning of file - cmp.ne p6,p0=r30,r0 -(p6) br.cond.spnt.few dispatch_break_fault ;; -#endif 1: // OK now, let's do an rfi. #ifdef FAST_HYPERPRIVOP_CNT From 03cc744bdbfcb402d13d0e58316ea24036f232ba Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 16:17:37 -0700 Subject: [PATCH 048/570] [IA64] Use rum psr.be instead of XEN_HYPER_RSM_BE Good for guest syscall performance Signed-off-by: Anthony Xu --- linux-2.6-xen-sparse/arch/ia64/kernel/gate.S | 2 +- linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S b/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S index 6a13812893..9c19a5dda8 100644 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/gate.S @@ -145,7 +145,7 @@ GLOBAL_ENTRY(__kernel_syscall_via_epc) ;; (isRaw) rsm psr.be | psr.i (isXen) st1 [r22]=r20 -(isXen) XEN_HYPER_RSM_BE +(isXen) rum psr.be ;; #else rsm psr.be | psr.i // M2 (5 cyc to srlz.d) diff --git a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h index 2bd0c1fb71..a0c2828b63 100644 --- a/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h +++ b/linux-2.6-xen-sparse/include/asm-ia64/xen/privop.h @@ -45,7 +45,6 @@ #define XEN_HYPER_GET_PMD break HYPERPRIVOP_GET_PMD #define XEN_HYPER_GET_EFLAG break HYPERPRIVOP_GET_EFLAG #define XEN_HYPER_SET_EFLAG break HYPERPRIVOP_SET_EFLAG -#define XEN_HYPER_RSM_BE break HYPERPRIVOP_RSM_BE #define XEN_HYPER_GET_PSR break HYPERPRIVOP_GET_PSR #define XSI_IFS (XSI_BASE + XSI_IFS_OFS) From fe29ad0cc51d5c16199423db5ac7a653cfd3fa46 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 16:22:31 -0700 Subject: [PATCH 049/570] [IA64] Fix dom0vp_expose_p2m dom0vp_expose_p2m() assumes that memory is populated non-sparsely. However with dom0 builder modification this assumption is not always true. Make dom0vp_expose_p2m() allow sparsely populated memory. Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/mm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xen/arch/ia64/xen/mm.c b/xen/arch/ia64/xen/mm.c index 1effbf9160..b560abf5f8 100644 --- a/xen/arch/ia64/xen/mm.c +++ b/xen/arch/ia64/xen/mm.c @@ -1439,10 +1439,9 @@ dom0vp_expose_p2m(struct domain* d, for (i = 0; i < expose_num_pfn / PTRS_PER_PTE + 1; i++) { assign_pte = lookup_noalloc_domain_pte(d, (assign_start_gpfn + i) << PAGE_SHIFT); - BUG_ON(assign_pte == NULL); - if (pte_present(*assign_pte)) { + if (assign_pte == NULL || pte_present(*assign_pte)) continue; - } + if (expose_p2m_page(d, (assign_start_gpfn + i) << PAGE_SHIFT, p2m_pte_zero_page) < 0) { gdprintk(XENLOG_INFO, "%s failed to assign zero-pte page\n", __func__); From 926136b29a9fbc09ff00b088ac0da37b7c371ab1 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 16:25:14 -0700 Subject: [PATCH 050/570] [IA64] setup scrub_pages Signed-off-by: Akio Takebe --- xen/arch/ia64/xen/dom0_ops.c | 1 + 1 file changed, 1 insertion(+) diff --git a/xen/arch/ia64/xen/dom0_ops.c b/xen/arch/ia64/xen/dom0_ops.c index e21c96f827..2ee0a935a9 100644 --- a/xen/arch/ia64/xen/dom0_ops.c +++ b/xen/arch/ia64/xen/dom0_ops.c @@ -226,6 +226,7 @@ long arch_do_sysctl(xen_sysctl_t *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) #endif pi->total_pages = total_pages; pi->free_pages = avail_domheap_pages(); + pi->scrub_pages = avail_scrub_pages(); pi->cpu_khz = local_cpu_data->proc_freq / 1000; memset(pi->hw_cap, 0, sizeof(pi->hw_cap)); //memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4); From defc7a67a1b3a84411a0b145191cf7f3b83ad68d Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 4 Jan 2007 23:21:30 -0700 Subject: [PATCH 051/570] [IA64] Only set nocache flag on dom0 ranges that do not support WB Signed-off-by: Alex Williamson --- xen/arch/ia64/xen/dom_fw.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/xen/arch/ia64/xen/dom_fw.c b/xen/arch/ia64/xen/dom_fw.c index 3f9dd9cf2a..b122a793ca 100644 --- a/xen/arch/ia64/xen/dom_fw.c +++ b/xen/arch/ia64/xen/dom_fw.c @@ -549,7 +549,8 @@ complete_dom0_memmap(struct domain *d, flags = ASSIGN_writable; /* dummy - zero */ if (md->attribute & EFI_MEMORY_WP) flags |= ASSIGN_readonly; - if (md->attribute & EFI_MEMORY_UC) + if ((md->attribute & EFI_MEMORY_UC) && + !(md->attribute & EFI_MEMORY_WB)) flags |= ASSIGN_nocache; assign_domain_mach_page(d, start, size, flags); From 2c67d503cb1c507a78d00b69689db96a2869f86b Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 5 Jan 2007 10:38:48 +0000 Subject: [PATCH 052/570] [XEN] Add extra opcodes to emulator. Fix operand-size computation for 64-bit PUSH/POP. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 49 +++++++++++++++++++++++++++++++++----- 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 7d6b809bfa..24ae7dae44 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -85,9 +85,15 @@ static uint8_t opcode_table[256] = { ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, 0, 0, 0, 0, /* 0x40 - 0x4F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0x50 - 0x5F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, + ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, + ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, + ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, /* 0x60 - 0x6F */ 0, 0, 0, DstReg|SrcMem32|ModRM|Mov /* movsxd (x86/64) */, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -864,8 +870,8 @@ x86_emulate_memop( dst.val = src.val; break; case 0x8f: /* pop (sole member of Grp1a) */ - /* 64-bit mode: POP always pops a 64-bit operand. */ - if ( mode == X86EMUL_MODE_PROT64 ) + /* 64-bit mode: POP defaults to a 64-bit operand. */ + if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) dst.bytes = 8; if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp), &dst.val, dst.bytes, ctxt)) != 0 ) @@ -940,8 +946,8 @@ x86_emulate_memop( emulate_1op("dec", dst, _regs.eflags); break; case 6: /* push */ - /* 64-bit mode: PUSH always pushes a 64-bit operand. */ - if ( mode == X86EMUL_MODE_PROT64 ) + /* 64-bit mode: PUSH defaults to a 64-bit operand. */ + if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) { dst.bytes = 8; if ( (rc = ops->read(dst.mem.seg, dst.mem.off, @@ -1011,6 +1017,37 @@ x86_emulate_memop( } switch ( b ) { + case 0x40 ... 0x4f: /* inc/dec reg */ + dst.type = OP_REG; + dst.reg = decode_register(b&7, &_regs, 0); + dst.bytes = op_bytes; + dst.orig_val = dst.val = *dst.reg; + if ( b & 8 ) + emulate_1op("dec", dst, _regs.eflags); + else + emulate_1op("inc", dst, _regs.eflags); + break; + case 0x50 ... 0x57: /* push reg */ + dst.type = OP_MEM; + dst.bytes = op_bytes; + if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) + dst.bytes = 8; + dst.val = *(unsigned long *)decode_register(b&7, &_regs, 0); + register_address_increment(_regs.esp, -dst.bytes); + dst.mem.seg = x86_seg_ss; + dst.mem.off = truncate_ea(_regs.esp); + break; + case 0x58 ... 0x5f: /* pop reg */ + dst.type = OP_REG; + dst.reg = decode_register(b&7, &_regs, 0); + dst.bytes = op_bytes; + if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) + dst.bytes = 8; + if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp), + &dst.val, dst.bytes, ctxt)) != 0 ) + goto done; + register_address_increment(_regs.esp, dst.bytes); + break; case 0xa0 ... 0xa1: /* mov mem.offs,{%al,%ax,%eax,%rax} */ /* Source EA is not encoded via ModRM. */ dst.type = OP_REG; From 47fde3df04f0956d11adbe0db9f82936e57abba2 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 5 Jan 2007 10:39:45 +0000 Subject: [PATCH 053/570] [TOOLS] Fix typo in XenDomainInfo:device_configure. Signed-off-by: Ian Campbell --- tools/python/xen/xend/XendDomainInfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 46386871fa..8185d93576 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -511,7 +511,7 @@ class XendDomainInfo: # look up uuid of the device dev_control = self.getDeviceController(deviceClass) dev_sxpr = dev_control.sxpr(devid) - dev_uuid = sxp.child_value(sxpr, 'uuid') + dev_uuid = sxp.child_value(dev_sxpr, 'uuid') if not dev_uuid: return False From 7a0e89cd5b7abbe1aa1b700cf9a46d468b46896e Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 5 Jan 2007 10:55:55 +0000 Subject: [PATCH 054/570] [XEN] Add LEA to the Xen x86 emulator. Rename x86_emulate_memop() to x86_emulate(), as the emulator now does more than emulation of 'special' memory accesses. Signed-off-by: Keir Fraser --- tools/tests/test_x86_emulator.c | 59 ++++++++++++++++++++++--------- xen/arch/x86/mm.c | 2 +- xen/arch/x86/mm/shadow/multi.c | 2 +- xen/arch/x86/x86_emulate.c | 7 ++-- xen/include/asm-x86/x86_emulate.h | 5 ++- 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/tools/tests/test_x86_emulator.c b/tools/tests/test_x86_emulator.c index bd7f1411ad..ea8cf54f63 100644 --- a/tools/tests/test_x86_emulator.c +++ b/tools/tests/test_x86_emulator.c @@ -119,7 +119,7 @@ int main(int argc, char **argv) regs.ecx = 0x12345678; regs.eax = (unsigned long)res; *res = 0x7FFFFFFF; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x92345677) || (regs.eflags != 0xa94) || @@ -133,7 +133,7 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; regs.eax = 0x7FFFFFFF; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (regs.ecx != 0x12345678) || (regs.eax != 0x92345677) || @@ -152,7 +152,7 @@ int main(int argc, char **argv) regs.ecx = 0x12345678UL; #endif regs.eax = (unsigned long)res; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x92345677) || (regs.ecx != 0x8000000FUL) || @@ -166,7 +166,7 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.ecx = ~0UL; regs.eax = (unsigned long)res; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x92345677) || (regs.ecx != 0x92345677UL) || @@ -181,7 +181,7 @@ int main(int argc, char **argv) regs.eax = 0x92345677UL; regs.ecx = 0xAA; regs.ebx = (unsigned long)res; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x923456AA) || (regs.eflags != 0x244) || @@ -197,7 +197,7 @@ int main(int argc, char **argv) regs.eax = 0xAABBCC77UL; regs.ecx = 0xFF; regs.ebx = (unsigned long)res; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x923456AA) || ((regs.eflags&0x240) != 0x200) || @@ -213,7 +213,7 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.ecx = 0x12345678; regs.eax = (unsigned long)res; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x12345678) || (regs.eflags != 0x200) || @@ -230,7 +230,7 @@ int main(int argc, char **argv) regs.eax = 0x923456AAUL; regs.ecx = 0xDDEEFF00L; regs.ebx = (unsigned long)res; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0xDDEEFF00) || (regs.eflags != 0x244) || @@ -247,7 +247,7 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.esi = (unsigned long)res + 0; regs.edi = (unsigned long)res + 2; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x44554455) || (regs.eflags != 0x200) || @@ -264,7 +264,7 @@ int main(int argc, char **argv) regs.eflags = 0x200; regs.eip = (unsigned long)&instr[0]; regs.edi = (unsigned long)res; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x2233445D) || ((regs.eflags&0x201) != 0x201) || @@ -279,7 +279,7 @@ int main(int argc, char **argv) regs.eip = (unsigned long)&instr[0]; regs.eax = -32; regs.edi = (unsigned long)(res+1); - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x2233445E) || ((regs.eflags&0x201) != 0x201) || @@ -299,7 +299,7 @@ int main(int argc, char **argv) regs.ecx = 0xCCCCFFFF; regs.eip = (unsigned long)&instr[0]; regs.edi = (unsigned long)res; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (res[0] != 0x9999AAAA) || (res[1] != 0xCCCCFFFF) || @@ -313,7 +313,7 @@ int main(int argc, char **argv) regs.eflags = 0x200; regs.eip = (unsigned long)&instr[0]; regs.edi = (unsigned long)res; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (res[0] != 0x9999AAAA) || (res[1] != 0xCCCCFFFF) || @@ -331,7 +331,7 @@ int main(int argc, char **argv) regs.ecx = 0x12345678; regs.eax = (unsigned long)res; *res = 0x82; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x82) || (regs.ecx != 0xFFFFFF82) || @@ -347,7 +347,7 @@ int main(int argc, char **argv) regs.ecx = 0x12345678; regs.eax = (unsigned long)res; *res = 0x1234aa82; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x1234aa82) || (regs.ecx != 0xaa82) || @@ -363,7 +363,7 @@ int main(int argc, char **argv) regs.ecx = (unsigned long)res; regs.eax = 0x12345678; *res = 0x11111111; - rc = x86_emulate_memop(&ctxt, &emulops); + rc = x86_emulate(&ctxt, &emulops); if ( (rc != 0) || (*res != 0x11116789) || (regs.eax != 0x12341111) || @@ -372,6 +372,33 @@ int main(int argc, char **argv) goto fail; printf("okay\n"); + printf("%-40s", "Testing dec %%ax..."); + instr[0] = 0x66; instr[1] = 0x48; + regs.eflags = 0x200; + regs.eip = (unsigned long)&instr[0]; + regs.eax = 0x00000000; + rc = x86_emulate(&ctxt, &emulops); + if ( (rc != 0) || + (regs.eax != 0x0000ffff) || + ((regs.eflags&0x240) != 0x200) || + (regs.eip != (unsigned long)&instr[2]) ) + goto fail; + printf("okay\n"); + + printf("%-40s", "Testing lea 8(%%ebp),%%eax..."); + instr[0] = 0x8d; instr[1] = 0x45; instr[2] = 0x08; + regs.eflags = 0x200; + regs.eip = (unsigned long)&instr[0]; + regs.eax = 0x12345678; + regs.ebp = 0xaaaaaaaa; + rc = x86_emulate(&ctxt, &emulops); + if ( (rc != 0) || + (regs.eax != 0xaaaaaab2) || + ((regs.eflags&0x240) != 0x200) || + (regs.eip != (unsigned long)&instr[3]) ) + goto fail; + printf("okay\n"); + return 0; fail: diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 6ed7d84490..c6615139cf 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3297,7 +3297,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, ptwr_ctxt.ctxt.mode = X86EMUL_MODE_HOST; ptwr_ctxt.cr2 = addr; ptwr_ctxt.pte = pte; - if ( x86_emulate_memop(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) ) + if ( x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) ) goto bail; UNLOCK_BIGLOCK(d); diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 7d30dc2f6d..72b1b847ed 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -2836,7 +2836,7 @@ static int sh_page_fault(struct vcpu *v, * it seems very unlikely that any OS grants user access to page tables. */ if ( (regs->error_code & PFEC_user_mode) || - x86_emulate_memop(&emul_ctxt.ctxt, emul_ops) ) + x86_emulate(&emul_ctxt.ctxt, emul_ops) ) { SHADOW_PRINTK("emulator failure, unshadowing mfn %#lx\n", mfn_x(gmfn)); diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 24ae7dae44..323626ce0f 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -107,7 +107,7 @@ static uint8_t opcode_table[256] = { /* 0x88 - 0x8F */ ByteOp|DstMem|SrcReg|ModRM|Mov, DstMem|SrcReg|ModRM|Mov, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, - 0, 0, 0, DstMem|SrcNone|ModRM|Mov, + 0, DstReg|SrcNone|ModRM, 0, DstMem|SrcNone|ModRM|Mov, /* 0x90 - 0x9F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xA7 */ @@ -447,7 +447,7 @@ decode_register( } int -x86_emulate_memop( +x86_emulate( struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) { @@ -869,6 +869,9 @@ x86_emulate_memop( case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ dst.val = src.val; break; + case 0x8d: /* lea */ + dst.val = ea.mem.off; + break; case 0x8f: /* pop (sole member of Grp1a) */ /* 64-bit mode: POP defaults to a 64-bit operand. */ if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) diff --git a/xen/include/asm-x86/x86_emulate.h b/xen/include/asm-x86/x86_emulate.h index 89a42da7b0..6e234cb22b 100644 --- a/xen/include/asm-x86/x86_emulate.h +++ b/xen/include/asm-x86/x86_emulate.h @@ -154,12 +154,11 @@ struct x86_emulate_ctxt #endif /* - * x86_emulate_memop: Emulate an instruction that faulted attempting to - * read/write a 'special' memory area. + * x86_emulate: Emulate an instruction. * Returns -1 on failure, 0 on success. */ int -x86_emulate_memop( +x86_emulate( struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops); From 71314211e9773d0d1710f943801c1c725f8e4b66 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 5 Jan 2007 10:58:48 +0000 Subject: [PATCH 055/570] Fix xend stop if we're run directly instead of via the caretaker parent. Signed-off-by: John Levon --- tools/python/xen/xend/server/SrvDaemon.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/python/xen/xend/server/SrvDaemon.py b/tools/python/xen/xend/server/SrvDaemon.py index bd93e6fc56..04f7a789a6 100644 --- a/tools/python/xen/xend/server/SrvDaemon.py +++ b/tools/python/xen/xend/server/SrvDaemon.py @@ -203,7 +203,7 @@ class Daemon: if not osdep.xend_autorestart: self.run(os.fdopen(w, 'w')) - break + os._exit(0) pid = self.fork_pid() if pid: From c082fcbec5b5f09cdff8baed09786b81a40ef14e Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 5 Jan 2007 11:03:16 +0000 Subject: [PATCH 056/570] Xen 3.0.3 pre-pended all configuration prior to the user-specified args in the boot cmdline. Restore this behaviour to fix incompatabilities with fragile parsers in some domU kernels. Signed-off-by: John Levon --- tools/python/xen/xend/XendConfig.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index f003c6e9eb..cfd2c20e6e 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -1113,15 +1113,19 @@ class XendConfig(dict): # configuration log.debug("update_with_image_sxp(%s)" % scrub_password(image_sxp)) - kernel_args = sxp.child_value(image_sxp, 'args', '') + kernel_args = "" # attempt to extract extra arguments from SXP config arg_ip = sxp.child_value(image_sxp, 'ip') if arg_ip and not re.search(r'ip=[^ ]+', kernel_args): - kernel_args += ' ip=%s' % arg_ip + kernel_args += 'ip=%s ' % arg_ip arg_root = sxp.child_value(image_sxp, 'root') if arg_root and not re.search(r'root=', kernel_args): - kernel_args += ' root=%s' % arg_root + kernel_args += 'root=%s ' % arg_root + + # user-specified args must come last: previous releases did this and + # some domU kernels rely upon the ordering. + kernel_args += sxp.child_value(image_sxp, 'args', '') if bootloader: self['_temp_using_bootloader'] = '1' From d913c891b75e91d3394c244cfa99989ea9a797c3 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 12:29:26 +0000 Subject: [PATCH 057/570] Added permissiveness for floats. Signed-off-by: Ewan Mellor --- tools/libxen/src/xen_common.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/libxen/src/xen_common.c b/tools/libxen/src/xen_common.c index ea0909d1a4..c380b85190 100644 --- a/tools/libxen/src/xen_common.c +++ b/tools/libxen/src/xen_common.c @@ -557,8 +557,14 @@ static void parse_into(xen_session *s, xmlNode *value_node, xmlChar *string = string_from_value(value_node, "double"); if (string == NULL) { +#if PERMISSIVE + fprintf(stderr, + "Expected a Float from the server, but didn't get one\n"); + ((double *)value)[slot] = 0.0; +#else server_error( s, "Expected a Float from the server, but didn't get one"); +#endif } else { From 800c66b2642c9101ace90f48cb643f4636d1d545 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 12:30:32 +0000 Subject: [PATCH 058/570] Treat tags with no type tag inside as if they were strings (as required by the XML-RPC spec). Signed-off-by: Ewan Mellor --- tools/libxen/src/xen_common.c | 42 +++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/tools/libxen/src/xen_common.c b/tools/libxen/src/xen_common.c index c380b85190..9834565ff0 100644 --- a/tools/libxen/src/xen_common.c +++ b/tools/libxen/src/xen_common.c @@ -373,11 +373,18 @@ static void server_error_2(xen_session *session, const char *error_string, } -static bool is_container_node(xmlNode *n, char *type) +static bool is_node(xmlNode *n, char *type) { return n->type == XML_ELEMENT_NODE && - 0 == strcmp((char *)n->name, type) && + 0 == strcmp((char *)n->name, type); +} + + +static bool is_container_node(xmlNode *n, char *type) +{ + return + is_node(n, type) && n->children != NULL && n->children == n->last && n->children->type == XML_ELEMENT_NODE; @@ -390,13 +397,30 @@ static bool is_container_node(xmlNode *n, char *type) */ static xmlChar *string_from_value(xmlNode *n, char *type) { - return - is_container_node(n, "value") && - 0 == strcmp((char *)n->children->name, type) ? - (n->children->children == NULL ? - xmlStrdup(BAD_CAST("")) : - xmlNodeGetContent(n->children->children)) : - NULL; + /* + XYZ is normal, but the XML-RPC spec also + allows XYZ where XYZ is to be interpreted as a string. + */ + + if (is_container_node(n, "value") && + 0 == strcmp((char *)n->children->name, type)) + { + return + n->children->children == NULL ? + xmlStrdup(BAD_CAST("")) : + xmlNodeGetContent(n->children->children); + } + else if (0 == strcmp(type, "string") && is_node(n, "value")) + { + return + n->children == NULL ? + xmlStrdup(BAD_CAST("")) : + xmlNodeGetContent(n->children); + } + else + { + return NULL; + } } From 957eed72524f2b144a86570f52b3a487fabb4939 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 12:31:49 +0000 Subject: [PATCH 059/570] Remove broken and unused set_u32. Signed-off-by: Ewan Mellor --- tools/python/xen/xm/opts.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tools/python/xen/xm/opts.py b/tools/python/xen/xm/opts.py index 1eac629aa1..7dd28bfa4e 100644 --- a/tools/python/xen/xm/opts.py +++ b/tools/python/xen/xm/opts.py @@ -559,14 +559,6 @@ def set_bool(opt, k, v): else: opt.opts.err('Invalid value:' +v) -def set_u32(opt, k, v): - """Set an option to an u32 value.""" - try: - v = u32(v) - except: - opt.opts.err('Invalid value: ' + str(v)) - opt.set(v) - def set_value(opt, k, v): """Set an option to a value.""" opt.set(v) From 972656054ca0d899cb5fd81d1a105a9e90954e56 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 12:32:40 +0000 Subject: [PATCH 060/570] Fix missing import, and a small tidyup. Signed-off-by: Ewan Mellor --- tools/python/xen/xm/create.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 140b6f7749..1726979aaa 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -823,7 +823,7 @@ def preprocess_ioports(vals): if len(d) == 1: d.append(d[0]) # Components are in hex: add hex specifier. - hexd = map(lambda v: '0x'+v, d) + hexd = ['0x' + x for x in d] ioports.append(hexd) vals.ioports = ioports @@ -1176,6 +1176,7 @@ def config_security_check(config, verbose): try: domain_label = security.ssidref2label(security.NULL_SSIDREF) except: + import traceback traceback.print_exc(limit=1) return 0 domain_policy = 'NULL' From e821b95d39ac3372f752901a9f62dab16db20f46 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 12:33:23 +0000 Subject: [PATCH 061/570] Fix bindings for PIF_set_MAC and PIF.set_MTU. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendAPI.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index 2496bf8414..2da852c5dd 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -593,10 +593,10 @@ class XendAPI: return xen_api_success(self._get_PIF(ref).set_name(name)) def PIF_set_MAC(self, _, ref, mac): - return xen_api_success(self._get_PIF(ref).set_mac(name)) + return xen_api_success(self._get_PIF(ref).set_mac(mac)) def PIF_set_MTU(self, _, ref, mtu): - return xen_api_success(self._get_PIF(ref).set_mtu(name)) + return xen_api_success(self._get_PIF(ref).set_mtu(mtu)) def PIF_create_VLAN(self, _, ref, network, vlan): try: From 3d24f27402fa2b7d5fd85ee66f3677b076ef3749 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 5 Jan 2007 14:44:58 +0000 Subject: [PATCH 062/570] [XEN] Fix EA calculation for POP when stack pointer is used as base of the EA calculation. It should be used *post* increment. Original patch from Jan Beulich Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 323626ce0f..6ad67874ad 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -616,6 +616,11 @@ x86_emulate( ea.mem.off <<= (sib >> 6) & 3; if ( (modrm_mod == 0) && ((sib_base & 7) == 5) ) ea.mem.off += insn_fetch_type(int32_t); + else if ( (sib_base == 4) && !twobyte && (b == 0x8f) ) + /* POP must have its EA calculated post increment. */ + ea.mem.off += _regs.esp + + (((mode == X86EMUL_MODE_PROT64) && (op_bytes == 4)) + ? 8 : op_bytes); else ea.mem.off += *(long*)decode_register(sib_base, &_regs, 0); } From 79a9f1f4846c161d8bb066e7a99cb2479bad0117 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 15:34:47 +0000 Subject: [PATCH 063/570] Rename the 3DNOW and 3DNOWEXT API constants to THREEDNOW, so that they may be used directly as identifiers in bindings. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 4 ++-- tools/libxen/include/xen_cpu_feature.h | 4 ++-- tools/libxen/src/xen_cpu_feature.c | 4 ++-- tools/python/xen/xend/XendAPIConstants.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index ffc0a61d42..4f44ceaddb 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -184,8 +184,8 @@ The following enumeration types are used: \hspace{0.5cm}{\tt NX} & Execute Disable \\ \hspace{0.5cm}{\tt MMXEXT} & AMD MMX extensions \\ \hspace{0.5cm}{\tt LM} & Long Mode (x86-64) \\ -\hspace{0.5cm}{\tt 3DNOWEXT} & AMD 3DNow! extensions \\ -\hspace{0.5cm}{\tt 3DNOW} & 3DNow! \\ +\hspace{0.5cm}{\tt THREEDNOWEXT} & AMD 3DNow! extensions \\ +\hspace{0.5cm}{\tt THREEDNOW} & 3DNow! \\ \hspace{0.5cm}{\tt RECOVERY} & CPU in recovery mode \\ \hspace{0.5cm}{\tt LONGRUN} & Longrun power control \\ \hspace{0.5cm}{\tt LRTI} & LongRun table interface \\ diff --git a/tools/libxen/include/xen_cpu_feature.h b/tools/libxen/include/xen_cpu_feature.h index 6e0614a8ac..57a34d2773 100644 --- a/tools/libxen/include/xen_cpu_feature.h +++ b/tools/libxen/include/xen_cpu_feature.h @@ -198,12 +198,12 @@ enum xen_cpu_feature /** * AMD 3DNow! extensions */ - XEN_CPU_FEATURE_3DNOWEXT, + XEN_CPU_FEATURE_THREEDNOWEXT, /** * 3DNow! */ - XEN_CPU_FEATURE_3DNOW, + XEN_CPU_FEATURE_THREEDNOW, /** * CPU in recovery mode diff --git a/tools/libxen/src/xen_cpu_feature.c b/tools/libxen/src/xen_cpu_feature.c index 98fb64f9e3..6f19f32704 100644 --- a/tools/libxen/src/xen_cpu_feature.c +++ b/tools/libxen/src/xen_cpu_feature.c @@ -62,8 +62,8 @@ static const char *lookup_table[] = "NX", "MMXEXT", "LM", - "3DNOWEXT", - "3DNOW", + "THREEDNOWEXT", + "THREEDNOW", "RECOVERY", "LONGRUN", "LRTI", diff --git a/tools/python/xen/xend/XendAPIConstants.py b/tools/python/xen/xend/XendAPIConstants.py index 6d260d5939..78c9f1e5af 100644 --- a/tools/python/xen/xend/XendAPIConstants.py +++ b/tools/python/xen/xend/XendAPIConstants.py @@ -41,7 +41,7 @@ XEN_API_CPU_FEATURE = [ 'CMOV', 'PAT', 'PSE36', 'PN', 'CLFLSH', 'DTES', 'ACPI', 'MMX', 'FXCR', 'XMM', 'XMM2', 'SELFSNOOP', 'HT', 'ACC', 'IA64', 'SYSCALL', 'MP', 'NX', 'MMXEXT', - 'LM', '3DNOWEXT', '3DNOW', 'RECOVERY', 'LONGRUN', + 'LM', 'THREEDNOWEXT', 'THREEDNOW', 'RECOVERY', 'LONGRUN', 'LRTI', 'CXMMX', 'K6_MTRR', 'CYRIX_ARR', 'CENTAUR_MCR', 'K8', 'K7', 'P3', 'P4', 'CONSTANT_TSC', 'FXSAVE_LEAK', 'XMM3', 'MWAIT', 'DSCPL', 'EST', 'TM2', 'CID', 'CX16', From 8787be2922d716b5c0edf8e8b970ffafbb439c8e Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 15:38:01 +0000 Subject: [PATCH 064/570] Record the last shutdown reason for each VM in the store. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendConstants.py | 1 + tools/python/xen/xend/XendDomainInfo.py | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tools/python/xen/xend/XendConstants.py b/tools/python/xen/xend/XendConstants.py index e07fa127f1..e42216d06b 100644 --- a/tools/python/xen/xend/XendConstants.py +++ b/tools/python/xen/xend/XendConstants.py @@ -80,6 +80,7 @@ ZOMBIE_PREFIX = 'Zombie-' MINIMUM_RESTART_TIME = 20 RESTART_IN_PROGRESS = 'xend/restart_in_progress' +LAST_SHUTDOWN_REASON = 'xend/last_shutdown_reason' # # Device migration stages (eg. XendDomainInfo, XendCheckpoint, server.tpmif) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 8185d93576..b47083a885 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -969,6 +969,7 @@ class XendDomainInfo: log.warn('Domain has crashed: name=%s id=%d.', self.info['name_label'], self.domid) + self._writeVm(LAST_SHUTDOWN_REASON, 'crash') if xroot.get_enable_dump(): self.dumpCore() @@ -988,6 +989,7 @@ class XendDomainInfo: log.info('Domain has shutdown: name=%s id=%d reason=%s.', self.info['name_label'], self.domid, reason) + self._writeVm(LAST_SHUTDOWN_REASON, reason) self._clearRestart() From a76d47f9b7e093407df2020f96be71d09d8ccc14 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 15:50:20 +0000 Subject: [PATCH 065/570] Added NETWORK_ALREADY_CONNECTED error code to the documentation. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index 4f44ceaddb..950eb049e8 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -10575,6 +10575,16 @@ expected parameters are returned. \begin{verbatim}MESSAGE_PARAMETER_COUNT_MISMATCH(method, expected, received)\end{verbatim} \begin{center}\rule{10em}{0.1pt}\end{center} +\subsubsection{NETWORK\_ALREADY\_CONNECTED} + +You tried to create a PIF, but the network you tried to attach it to is +already attached to some other PIF, and so the creation failed. + +\vspace{0.3cm} +{\bf Signature:} +\begin{verbatim}NETWORK_ALREADY_CONNECTED(network, connected PIF)\end{verbatim} +\begin{center}\rule{10em}{0.1pt}\end{center} + \subsubsection{SESSION\_AUTHENTICATION\_FAILED} The credentials given by the user are incorrect, so access has been denied, From 66e0f08171b210944903d50dd6d05d6994804800 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 15:51:39 +0000 Subject: [PATCH 066/570] Added session.last_active field. Removed the constructors and destructors for session and task classes -- these are implicitly added and removed, so we should not have explicit constructors and destructors for them. Signed-off-by: Ewan Mellor --- docs/xen-api/xenapi-datamodel.tex | 109 ++---------------------------- 1 file changed, 7 insertions(+), 102 deletions(-) diff --git a/docs/xen-api/xenapi-datamodel.tex b/docs/xen-api/xenapi-datamodel.tex index 950eb049e8..3d74a76302 100644 --- a/docs/xen-api/xenapi-datamodel.tex +++ b/docs/xen-api/xenapi-datamodel.tex @@ -286,6 +286,7 @@ Quals & Field & Type & Description \\ $\mathit{RO}_\mathit{run}$ & {\tt uuid} & string & unique identifier/object reference \\ $\mathit{RO}_\mathit{ins}$ & {\tt this\_host} & host ref & Currently connected host \\ $\mathit{RO}_\mathit{ins}$ & {\tt this\_user} & user ref & Currently connected user \\ +$\mathit{RO}_\mathit{run}$ & {\tt last\_active} & int & Timestamp for last time session was active \\ \hline \end{longtable} \subsection{Additional RPCs associated with class: session} @@ -440,45 +441,13 @@ value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} -\subsubsection{RPC name:~create} +\subsubsection{RPC name:~get\_last\_active} {\bf Overview:} -Create a new session instance, and return its handle. +Get the last\_active field of the given session. \noindent {\bf Signature:} -\begin{verbatim} (session ref) create (session_id s, session record args)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt session record } & args & All constructor arguments \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -session ref -} - - -reference to the newly created object -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~destroy} - -{\bf Overview:} -Destroy the specified session instance. - - \noindent {\bf Signature:} -\begin{verbatim} void destroy (session_id s, session ref self)\end{verbatim} +\begin{verbatim} int get_last_active (session_id s, session ref self)\end{verbatim} \noindent{\bf Arguments:} @@ -496,11 +465,11 @@ Destroy the specified session instance. \noindent {\bf Return Type:} {\tt -void +int } - +value of the field \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} @@ -596,7 +565,7 @@ $\mathit{RO}_\mathit{run}$ & {\tt error\_info} & string Set & if the task has f \subsubsection{RPC name:~get\_all} {\bf Overview:} -Return a list of all the tasks known to the system +Return a list of all the tasks known to the system. \noindent {\bf Signature:} \begin{verbatim} ((task ref) Set) get_all (session_id s)\end{verbatim} @@ -999,70 +968,6 @@ string Set value of the field -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~create} - -{\bf Overview:} -Create a new task instance, and return its handle. - - \noindent {\bf Signature:} -\begin{verbatim} (task ref) create (session_id s, task record args)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt task record } & args & All constructor arguments \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -task ref -} - - -reference to the newly created object -\vspace{0.3cm} -\vspace{0.3cm} -\vspace{0.3cm} -\subsubsection{RPC name:~destroy} - -{\bf Overview:} -Destroy the specified task instance. - - \noindent {\bf Signature:} -\begin{verbatim} void destroy (session_id s, task ref self)\end{verbatim} - - -\noindent{\bf Arguments:} - - -\vspace{0.3cm} -\begin{tabular}{|c|c|p{7cm}|} - \hline -{\bf type} & {\bf name} & {\bf description} \\ \hline -{\tt task ref } & self & reference to the object \\ \hline - -\end{tabular} - -\vspace{0.3cm} - - \noindent {\bf Return Type:} -{\tt -void -} - - - \vspace{0.3cm} \vspace{0.3cm} \vspace{0.3cm} From 4faade7465169850ccef5daf7d4cba06b75ec451 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 15:52:58 +0000 Subject: [PATCH 067/570] Fix examples to have correct class names and error handling. Signed-off-by: Ewan Mellor --- docs/xen-api/wire-protocol.tex | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/docs/xen-api/wire-protocol.tex b/docs/xen-api/wire-protocol.tex index 338f093519..bcb228379e 100644 --- a/docs/xen-api/wire-protocol.tex +++ b/docs/xen-api/wire-protocol.tex @@ -149,16 +149,16 @@ We ought to support at least The XML-RPC interface is session-based; before you can make arbitrary RPC calls you must login and initiate a session. For example: \begin{verbatim} - session_id Session.login_with_password(string uname, string pwd) + session_id session.login_with_password(string uname, string pwd) \end{verbatim} Where {\tt uname} and {\tt password} refer to your username and password respectively, as defined by the Xen administrator. -The {\tt session\_id} returned by {\tt Session.Login} is passed to subequent -RPC calls as an authentication token. +The {\tt session\_id} returned by {\tt session.login_with_password} is passed +to subequent RPC calls as an authentication token. -A session can be terminated with the {\tt Session.Logout} function: +A session can be terminated with the {\tt session.logout} function: \begin{verbatim} - void Session.Logout(session_id session) + void session.logout(session_id session) \end{verbatim} \subsection{Synchronous and Asynchronous invocation} @@ -251,14 +251,20 @@ call takes the session token as the only parameter) '2045dbc0-0734-4eea-9cb2-b8218c6b5bf2', '3202ae18-a046-4c32-9fda-e32e9631866e'] \end{verbatim} -Note the VM references are internally UUIDs. Once a reference to a VM has been acquired a lifecycle operation may be invoked: +The VM references here are UUIDs, though they may not be that simple in the +future, and you should treat them as opaque strings. Once a reference to a VM +has been acquired a lifecycle operation may be invoked: \begin{verbatim} >>> xen.VM.start(session, all_vms[3], False) -{'Status': 'Failure', 'ErrorDescription': 'Operation not implemented'} +{'Status': 'Failure', 'ErrorDescription': ['VM_BAD_POWER_STATE', 'Halted', 'Running']} \end{verbatim} -In this case the {\tt start} message has not been implemented and an error response has been returned. Currently these high-level errors are returned as structured data (rather than as XMLRPC faults), allowing for internationalised errors in future. Finally, here are some examples of using accessors for object fields: +In this case the {\tt start} message has been rejected, because the VM is +already running, and so an error response has been returned. These high-level +errors are returned as structured data (rather than as XML-RPC faults), +allowing them to be internationalised. Finally, here are some examples of +using accessors for object fields: \begin{verbatim} >>> xen.VM.get_name_label(session, all_vms[3])['Value'] From 4ab50980283a14fabf574bd06ba0e74e0ba37a70 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 5 Jan 2007 15:54:06 +0000 Subject: [PATCH 068/570] [XEN] Add more instructions to the emulator. Fix prefix handling to ignore misplaced REX bytes and to grok both kinds of REP prefix properly. These fixes are from Jan Beulich . Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 134 ++++++++++++++++++++++++++----------- 1 file changed, 96 insertions(+), 38 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 6ad67874ad..c9de3a577f 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -55,35 +55,35 @@ static uint8_t opcode_table[256] = { /* 0x00 - 0x07 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - 0, 0, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, /* 0x08 - 0x0F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - 0, 0, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, /* 0x10 - 0x17 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - 0, 0, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, /* 0x18 - 0x1F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - 0, 0, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, /* 0x20 - 0x27 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - 0, 0, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, /* 0x28 - 0x2F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - 0, 0, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, /* 0x30 - 0x37 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - 0, 0, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, /* 0x38 - 0x3F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - 0, 0, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, /* 0x40 - 0x4F */ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, @@ -108,8 +108,11 @@ static uint8_t opcode_table[256] = { ByteOp|DstMem|SrcReg|ModRM|Mov, DstMem|SrcReg|ModRM|Mov, ByteOp|DstReg|SrcMem|ModRM|Mov, DstReg|SrcMem|ModRM|Mov, 0, DstReg|SrcNone|ModRM, 0, DstMem|SrcNone|ModRM|Mov, - /* 0x90 - 0x9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x90 - 0x97 */ + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + /* 0x98 - 0x9F */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xA7 */ ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, @@ -134,10 +137,10 @@ static uint8_t opcode_table[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xF0 - 0xF7 */ 0, 0, 0, 0, - 0, 0, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM, + 0, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM, /* 0xF8 - 0xFF */ - 0, 0, 0, 0, - 0, 0, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM + ImplicitOps, ImplicitOps, 0, 0, + ImplicitOps, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM }; static uint8_t twobyte_table[256] = { @@ -488,7 +491,7 @@ x86_emulate( return -1; } - /* Legacy prefixes. */ + /* Prefix bytes. */ for ( i = 0; i < 8; i++ ) { switch ( b = insn_fetch_type(uint8_t) ) @@ -523,25 +526,26 @@ x86_emulate( case 0xf0: /* LOCK */ lock_prefix = 1; break; + case 0xf2: /* REPNE/REPNZ */ case 0xf3: /* REP/REPE/REPZ */ rep_prefix = 1; break; - case 0xf2: /* REPNE/REPNZ */ - break; + case 0x40 ... 0x4f: /* REX */ + if ( mode != X86EMUL_MODE_PROT64 ) + goto done_prefixes; + rex_prefix = b; + continue; default: goto done_prefixes; } + + /* Any legacy prefix after a REX prefix nullifies its effect. */ + rex_prefix = 0; } done_prefixes: - /* REX prefix. */ - if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) ) - { - rex_prefix = b; - if ( b & 8 ) /* REX.W */ - op_bytes = 8; - b = insn_fetch_type(uint8_t); - } + if ( rex_prefix & 8 ) /* REX.W */ + op_bytes = 8; /* Opcode byte(s). */ d = opcode_table[b]; @@ -570,6 +574,7 @@ x86_emulate( if ( modrm_mod == 3 ) { + modrm_rm |= (rex_prefix & 1) << 3; ea.type = OP_REG; ea.reg = decode_register( modrm_rm, &_regs, (d & ByteOp) && (rex_prefix == 0)); @@ -812,28 +817,52 @@ x86_emulate( switch ( b ) { - case 0x00 ... 0x05: add: /* add */ + case 0x04 ... 0x05: /* add imm,%%eax */ + dst.reg = (unsigned long *)&_regs.eax; + dst.val = dst.orig_val = _regs.eax; + case 0x00 ... 0x03: add: /* add */ emulate_2op_SrcV("add", src, dst, _regs.eflags); break; - case 0x08 ... 0x0d: or: /* or */ + case 0x0c ... 0x0d: /* or imm,%%eax */ + dst.reg = (unsigned long *)&_regs.eax; + dst.val = dst.orig_val = _regs.eax; + case 0x08 ... 0x0b: or: /* or */ emulate_2op_SrcV("or", src, dst, _regs.eflags); break; - case 0x10 ... 0x15: adc: /* adc */ + case 0x14 ... 0x15: /* adc imm,%%eax */ + dst.reg = (unsigned long *)&_regs.eax; + dst.val = dst.orig_val = _regs.eax; + case 0x10 ... 0x13: adc: /* adc */ emulate_2op_SrcV("adc", src, dst, _regs.eflags); break; - case 0x18 ... 0x1d: sbb: /* sbb */ + case 0x1c ... 0x1d: /* sbb imm,%%eax */ + dst.reg = (unsigned long *)&_regs.eax; + dst.val = dst.orig_val = _regs.eax; + case 0x18 ... 0x1b: sbb: /* sbb */ emulate_2op_SrcV("sbb", src, dst, _regs.eflags); break; - case 0x20 ... 0x25: and: /* and */ + case 0x24 ... 0x25: /* and imm,%%eax */ + dst.reg = (unsigned long *)&_regs.eax; + dst.val = dst.orig_val = _regs.eax; + case 0x20 ... 0x23: and: /* and */ emulate_2op_SrcV("and", src, dst, _regs.eflags); break; - case 0x28 ... 0x2d: sub: /* sub */ + case 0x2c ... 0x2d: /* sub imm,%%eax */ + dst.reg = (unsigned long *)&_regs.eax; + dst.val = dst.orig_val = _regs.eax; + case 0x28 ... 0x2b: sub: /* sub */ emulate_2op_SrcV("sub", src, dst, _regs.eflags); break; - case 0x30 ... 0x35: xor: /* xor */ + case 0x34 ... 0x35: /* xor imm,%%eax */ + dst.reg = (unsigned long *)&_regs.eax; + dst.val = dst.orig_val = _regs.eax; + case 0x30 ... 0x33: xor: /* xor */ emulate_2op_SrcV("xor", src, dst, _regs.eflags); break; - case 0x38 ... 0x3d: cmp: /* cmp */ + case 0x3c ... 0x3d: /* cmp imm,%%eax */ + dst.reg = (unsigned long *)&_regs.eax; + dst.val = dst.orig_val = _regs.eax; + case 0x38 ... 0x3b: cmp: /* cmp */ emulate_2op_SrcV("cmp", src, dst, _regs.eflags); break; case 0x63: /* movsxd */ @@ -857,7 +886,7 @@ x86_emulate( case 0x84 ... 0x85: test: /* test */ emulate_2op_SrcV("test", src, dst, _regs.eflags); break; - case 0x86 ... 0x87: /* xchg */ + case 0x86 ... 0x87: xchg: /* xchg */ /* Write back the register source. */ switch ( dst.bytes ) { @@ -1011,6 +1040,8 @@ x86_emulate( return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; special_insn: + /* Default action: disable writeback. There may be no dest operand. */ + dst.orig_val = dst.val; if ( twobyte ) goto twobyte_special_insn; if ( rep_prefix ) @@ -1027,7 +1058,7 @@ x86_emulate( { case 0x40 ... 0x4f: /* inc/dec reg */ dst.type = OP_REG; - dst.reg = decode_register(b&7, &_regs, 0); + dst.reg = decode_register(b & 7, &_regs, 0); dst.bytes = op_bytes; dst.orig_val = dst.val = *dst.reg; if ( b & 8 ) @@ -1040,14 +1071,16 @@ x86_emulate( dst.bytes = op_bytes; if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) dst.bytes = 8; - dst.val = *(unsigned long *)decode_register(b&7, &_regs, 0); + dst.val = *(unsigned long *)decode_register( + (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); register_address_increment(_regs.esp, -dst.bytes); dst.mem.seg = x86_seg_ss; dst.mem.off = truncate_ea(_regs.esp); break; case 0x58 ... 0x5f: /* pop reg */ dst.type = OP_REG; - dst.reg = decode_register(b&7, &_regs, 0); + dst.reg = decode_register( + (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); dst.bytes = op_bytes; if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) dst.bytes = 8; @@ -1056,6 +1089,18 @@ x86_emulate( goto done; register_address_increment(_regs.esp, dst.bytes); break; + case 0x90: /* nop / xchg %%r8,%%rax */ + if ( !(rex_prefix & 1) ) + break; /* nop */ + case 0x91 ... 0x97: /* xchg reg,%%rax */ + src.type = OP_REG; + src.reg = (unsigned long *)&_regs.eax; + src.val = *src.reg; + dst.type = OP_REG; + dst.reg = decode_register( + (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); + dst.val = dst.orig_val = *dst.reg; + goto xchg; case 0xa0 ... 0xa1: /* mov mem.offs,{%al,%ax,%eax,%rax} */ /* Source EA is not encoded via ModRM. */ dst.type = OP_REG; @@ -1105,6 +1150,21 @@ x86_emulate( register_address_increment( _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); break; + case 0xf5: /* cmc */ + _regs.eflags ^= EFLG_CF; + break; + case 0xf8: /* clc */ + _regs.eflags &= ~EFLG_CF; + break; + case 0xf9: /* stc */ + _regs.eflags |= EFLG_CF; + break; + case 0xfc: /* cld */ + _regs.eflags &= ~EFLG_DF; + break; + case 0xfd: /* std */ + _regs.eflags |= EFLG_DF; + break; } goto writeback; @@ -1218,8 +1278,6 @@ x86_emulate( goto writeback; twobyte_special_insn: - /* Disable writeback. */ - dst.orig_val = dst.val; switch ( b ) { case 0x0d: /* GrpP (prefetch) */ From 415630a22d0fb2121887473f440db95b34b6a26e Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 5 Jan 2007 15:57:23 +0000 Subject: [PATCH 069/570] [XEN] Remove an out-of-date comment. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 9 --------- 1 file changed, 9 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index c9de3a577f..0df20bd961 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -19,15 +19,6 @@ #endif #include -/* - * Opcode effective-address decode tables. - * Note that we only emulate instructions that have at least one memory - * operand (excluding implicit stack references). We assume that stack - * references and instruction fetches will never occur in special memory - * areas that require emulation. So, for example, 'mov ,' need - * not be handled. - */ - /* Operand sizes: 8-bit operands or specified/overridden size. */ #define ByteOp (1<<0) /* 8-bit operands. */ /* Destination operand type. */ From 9bff7e28c68ba25c7103a2f9f3646fb55c4206bd Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Fri, 5 Jan 2007 16:11:49 +0000 Subject: [PATCH 070/570] Catch exception from dumpCore when inside refreshShutdown. Thanks to John Levon for diagnosis and suggesting the fix. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomainInfo.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index b47083a885..3a2fa3ef4f 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -972,7 +972,12 @@ class XendDomainInfo: self._writeVm(LAST_SHUTDOWN_REASON, 'crash') if xroot.get_enable_dump(): - self.dumpCore() + try: + self.dumpCore() + except XendError: + # This error has been logged -- there's nothing more + # we can do in this context. + pass restart_reason = 'crash' self._stateSet(DOM_STATE_HALTED) @@ -1164,7 +1169,10 @@ class XendDomainInfo: # def dumpCore(self, corefile = None): - """Create a core dump for this domain. Nothrow guarantee.""" + """Create a core dump for this domain. + + @raise: XendError if core dumping failed. + """ try: if not corefile: From 5c6059a43d2b65f653d18c9ffc795c1ee281e05e Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Fri, 5 Jan 2007 16:28:42 +0000 Subject: [PATCH 071/570] [HVM] Sync the base memory reported by ROMBIOS with the e820 map. This stops Etherboot relocating itself onto the SMBIOS tables. Signed-off-by: Tim Deegan --- tools/firmware/rombios/rombios.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tools/firmware/rombios/rombios.c b/tools/firmware/rombios/rombios.c index 7a14b46ac4..edbc0cc528 100644 --- a/tools/firmware/rombios/rombios.c +++ b/tools/firmware/rombios/rombios.c @@ -1435,10 +1435,17 @@ void copy_e820_table() { Bit8u nr_entries = read_byte(0x9000, 0x1e8); + Bit32u base_mem; if (nr_entries > 32) nr_entries = 32; write_word(0xe000, 0x8, nr_entries); memcpyb(0xe000, 0x10, 0x9000, 0x2d0, nr_entries * 0x14); + /* Report the proper base memory size at address 0x0413: otherwise + * non-e820 code will clobber things if BASE_MEM_IN_K is bigger than + * the first e820 entry. Get the size by reading the second 64bit + * field of the first e820 slot. */ + base_mem = read_dword(0x9000, 0x2d0 + 8); + write_word(0x40, 0x13, base_mem >> 10); } #endif /* HVMASSIST */ From 1f2d77695e961365537c7ef9809c5f494991bc79 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Fri, 5 Jan 2007 17:24:55 +0000 Subject: [PATCH 072/570] [XEND] Fix some Xen API error declarations. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendAPI.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/python/xen/xend/XendAPI.py b/tools/python/xen/xend/XendAPI.py index 2da852c5dd..96b81c32be 100644 --- a/tools/python/xen/xend/XendAPI.py +++ b/tools/python/xen/xend/XendAPI.py @@ -543,14 +543,14 @@ class XendAPI: try: node = XendNode.instance() if host_uuid != node.uuid: - return xen_api_error([HOST_HANDLE_INVALID, host_uuid]) + return xen_api_error(['HOST_HANDLE_INVALID', host_uuid]) elif _is_valid_ref(network_uuid, node.is_valid_network): network = node.get_network(network_uuid) return xen_api_success(node.PIF_create(name, mtu, vlan, mac, network)) else: - return xen_api_error([NETWORK_HANDLE_INVALID, network_uuid]) + return xen_api_error(['NETWORK_HANDLE_INVALID', network_uuid]) except NetworkAlreadyConnected, exn: return xen_api_error(['NETWORK_ALREADY_CONNECTED', network_uuid, exn.pif_uuid]) @@ -604,7 +604,7 @@ class XendAPI: return xen_api_success(XendNode.instance().PIF_create_VLAN( ref, network, vlan)) else: - return xen_api_error([NETWORK_HANDLE_INVALID, network]) + return xen_api_error(['NETWORK_HANDLE_INVALID', network]) except NetworkAlreadyConnected, exn: return xen_api_error(['NETWORK_ALREADY_CONNECTED', network, exn.pif_uuid]) From 8843b4291cc8ed99841c7c17b5ae7fe084270c70 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Fri, 5 Jan 2007 17:27:30 +0000 Subject: [PATCH 073/570] Add support to list VDIs and SRs in xapi.py Signed-off-by: Alastair Tse --- tools/python/scripts/xapi.py | 95 ++++++++++++++++++++++++++---------- 1 file changed, 70 insertions(+), 25 deletions(-) diff --git a/tools/python/scripts/xapi.py b/tools/python/scripts/xapi.py index 06baeefe4c..9bc3b507b8 100644 --- a/tools/python/scripts/xapi.py +++ b/tools/python/scripts/xapi.py @@ -41,6 +41,7 @@ VBD_LIST_FORMAT = '%(name_label)-18s %(uuid)-36s %(VDI)-8s '\ COMMANDS = { 'host-info': ('', 'Get Xen Host Info'), 'host-set-name': ('', 'Set host name'), + 'pif-list': ('', 'List all PIFs'), 'sr-list': ('', 'List all SRs'), 'vbd-list': ('', 'List all VBDs'), 'vbd-create': (' [opts]', @@ -63,6 +64,15 @@ COMMANDS = { } OPTIONS = { + 'sr-list': [(('-l', '--long'), + {'action':'store_true', + 'help':'List all properties of SR'}) + ], + + 'vdi-list': [(('-l', '--long'), + {'action':'store_true', + 'help':'List all properties of VDI'}) + ], 'vm-list': [(('-l', '--long'), {'action':'store_true', 'help':'List all properties of VMs'}) @@ -145,7 +155,7 @@ _session = None def _connect(*args): global _server, _session, _initialised if not _initialised: - _server = ServerProxy('httpu:///var/run/xend/xmlrpc.sock') + _server = ServerProxy('httpu:///var/run/xend/xen-api.sock') login = raw_input("Login: ") password = getpass() creds = (login, password) @@ -361,29 +371,53 @@ def xapi_vbd_list(*args): print VBD_LIST_FORMAT % vbd_struct def xapi_vdi_list(*args): + opts, args = parse_args('vdi-list', args, set_defaults = True) + is_long = opts and opts.long + server, session = _connect() vdis = execute(server.VDI.get_all, session) - print VDI_LIST_FORMAT % {'name_label': 'VDI Label', - 'uuid' : 'UUID', - 'virtual_size': 'Sectors', - 'sector_size': 'Sector Size'} - - for vdi in vdis: - vdi_struct = execute(server.VDI.get_record, session, vdi) - print VDI_LIST_FORMAT % vdi_struct + if not is_long: + print VDI_LIST_FORMAT % {'name_label': 'VDI Label', + 'uuid' : 'UUID', + 'virtual_size': 'Sectors', + 'sector_size': 'Sector Size'} + + for vdi in vdis: + vdi_struct = execute(server.VDI.get_record, session, vdi) + print VDI_LIST_FORMAT % vdi_struct + + else: + + for vdi in vdis: + vdi_struct = execute(server.VDI.get_record, session, vdi) + pprint(vdi_struct) def xapi_sr_list(*args): + opts, args = parse_args('sr-list', args, set_defaults = True) + is_long = opts and opts.long + server, session = _connect() srs = execute(server.SR.get_all, session) - print SR_LIST_FORMAT % {'name_label': 'SR Label', - 'uuid' : 'UUID', - 'physical_size': 'Size', - 'type': 'Type'} - for sr in srs: - sr_struct = execute(server.SR.get_record, session, sr) - sr_struct['physical_size'] = int(sr_struct['physical_size'])/MB - print SR_LIST_FORMAT % sr_struct + if not is_long: + print SR_LIST_FORMAT % {'name_label': 'SR Label', + 'uuid' : 'UUID', + 'physical_size': 'Size (MB)', + 'type': 'Type'} + + for sr in srs: + sr_struct = execute(server.SR.get_record, session, sr) + sr_struct['physical_size'] = int(sr_struct['physical_size'])/MB + print SR_LIST_FORMAT % sr_struct + else: + for sr in srs: + sr_struct = execute(server.SR.get_record, session, sr) + pprint(sr_struct) + +def xapi_sr_rename(*args): + server, session = _connect() + sr = execute(server.SR.get_by_name_label, session, args[0]) + execute(server.SR.set_name_label, session, sr[0], args[1]) def xapi_vdi_create(*args): opts, args = parse_args('vdi-create', args) @@ -421,10 +455,11 @@ def xapi_vdi_rename(*args): if len(args) < 2: raise OptionError('Not enough arguments') - vdi_uuid = args[0] + vdi_uuid = execute(server.VDI.get_by_name_label, session, args[0]) vdi_name = args[1] - print 'Renaming VDI %s to %s' % (vdi_uuid, vdi_name) - result = execute(server.VDI.set_name_label, session, vdi_uuid, vdi_name) + + print 'Renaming VDI %s to %s' % (vdi_uuid[0], vdi_name) + result = execute(server.VDI.set_name_label, session, vdi_uuid[0], vdi_name) print 'Done.' @@ -448,6 +483,14 @@ def xapi_vtpm_create(*args): print "Has vtpm record '%s'" % vtpm_rec +def xapi_pif_list(*args): + server, session = _connect() + pif_uuids = execute(server.PIF.get_all, session) + for pif_uuid in pif_uuids: + pif = execute(server.PIF.get_record, session, pif_uuid) + print pif + + # # Command Line Utils # @@ -517,10 +560,12 @@ def usage(command = None, print_usage = True): print print 'Subcommands:' print - sorted_commands = sorted(COMMANDS.keys()) - for command in sorted_commands: - args, description = COMMANDS[command] - print '%-16s %-40s' % (command, description) + + for func in sorted(globals().keys()): + if func.startswith('xapi_'): + command = func[5:].replace('_', '-') + args, description = COMMANDS.get(command, ('', '')) + print '%-16s %-40s' % (command, description) print else: parse_args(command, ['-h']) @@ -549,7 +594,7 @@ def main(args): try: subcmd_func(*args[1:]) except XenAPIError, e: - print 'Error: %s' % str(e.args[1]) + print 'Error: %s' % str(e.args[0]) sys.exit(2) except OptionError, e: print 'Error: %s' % e From 8f2348c03c7ac1a1f6baa91590eb0b5938bf727b Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:32:00 +0000 Subject: [PATCH 074/570] Introduce _DOMF_compat and infrastructure as well as several conditionals dealing with operations that need to distinguish between native and compatibility mode guests. Signed-off-by: Jan Beulich --- config/x86_64.mk | 1 + tools/libxc/xc_linux_build.c | 2 + xen/arch/x86/boot/x86_64.S | 27 ++++- xen/arch/x86/domain.c | 130 ++++++++++++++++++----- xen/arch/x86/domain_build.c | 95 ++++++++++++++--- xen/arch/x86/mm.c | 4 +- xen/arch/x86/setup.c | 3 + xen/arch/x86/traps.c | 13 ++- xen/arch/x86/x86_32/mm.c | 12 +-- xen/arch/x86/x86_32/traps.c | 4 +- xen/arch/x86/x86_64/asm-offsets.c | 8 +- xen/arch/x86/x86_64/mm.c | 12 +-- xen/arch/x86/x86_64/traps.c | 2 + xen/common/Makefile | 1 + xen/common/elf.c | 2 +- xen/common/elf32.c | 19 ++++ xen/include/asm-x86/config.h | 15 ++- xen/include/asm-x86/desc.h | 88 ++++++++++----- xen/include/asm-x86/ldt.h | 3 +- xen/include/asm-x86/mm.h | 2 +- xen/include/asm-x86/regs.h | 3 +- xen/include/asm-x86/x86_32/regs.h | 2 +- xen/include/asm-x86/x86_64/regs.h | 7 +- xen/include/public/arch-x86/xen-x86_64.h | 5 +- xen/include/public/arch-x86/xen.h | 10 ++ xen/include/xen/elf.h | 9 ++ xen/include/xen/sched.h | 10 ++ 27 files changed, 388 insertions(+), 101 deletions(-) create mode 100644 xen/common/elf32.c diff --git a/config/x86_64.mk b/config/x86_64.mk index 99b25d8059..288878638c 100644 --- a/config/x86_64.mk +++ b/config/x86_64.mk @@ -2,6 +2,7 @@ CONFIG_X86 := y CONFIG_X86_64 := y CONFIG_X86_$(XEN_OS) := y +CONFIG_COMPAT := y CONFIG_HVM := y CONFIG_MIGRATE := y CONFIG_XCUTILS := y diff --git a/tools/libxc/xc_linux_build.c b/tools/libxc/xc_linux_build.c index c6cdd156da..8066d5a047 100644 --- a/tools/libxc/xc_linux_build.c +++ b/tools/libxc/xc_linux_build.c @@ -595,6 +595,7 @@ static int compat_check(int xc_handle, struct domain_setup_info *dsi) return 0; } +#ifndef __x86_64__//temp if (strstr(xen_caps, "xen-3.0-x86_32p")) { if (dsi->pae_kernel == PAEKERN_bimodal) { dsi->pae_kernel = PAEKERN_extended_cr3; @@ -612,6 +613,7 @@ static int compat_check(int xc_handle, struct domain_setup_info *dsi) return 0; } } +#endif return 1; } diff --git a/xen/arch/x86/boot/x86_64.S b/xen/arch/x86/boot/x86_64.S index 661f39a38a..fe07e36471 100644 --- a/xen/arch/x86/boot/x86_64.S +++ b/xen/arch/x86/boot/x86_64.S @@ -224,15 +224,34 @@ high_start: .align PAGE_SIZE, 0 ENTRY(gdt_table) .quad 0x0000000000000000 /* unused */ - .quad 0x00cf9a000000ffff /* 0xe008 ring 0 code, compatibility */ - .quad 0x00af9a000000ffff /* 0xe010 ring 0 code, 64-bit mode */ - .quad 0x00cf92000000ffff /* 0xe018 ring 0 data */ + .quad 0x00af9a000000ffff /* 0xe008 ring 0 code, 64-bit mode */ + .quad 0x00cf92000000ffff /* 0xe010 ring 0 data */ + .quad 0x0000000000000000 /* reserved */ .quad 0x00cffa000000ffff /* 0xe023 ring 3 code, compatibility */ .quad 0x00cff2000000ffff /* 0xe02b ring 3 data */ .quad 0x00affa000000ffff /* 0xe033 ring 3 code, 64-bit mode */ - .quad 0x0000000000000000 /* unused */ + .quad 0x00cf9a000000ffff /* 0xe038 ring 0 code, compatibility */ + .org gdt_table - FIRST_RESERVED_GDT_BYTE + __TSS(0) * 8 .fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */ +#ifdef CONFIG_COMPAT + .align PAGE_SIZE, 0 +/* NB. Even rings != 0 get access to the full 4Gb, as only the */ +/* (compatibility) machine->physical mapping table lives there. */ +ENTRY(compat_gdt_table) + .quad 0x0000000000000000 /* unused */ + .quad 0x00af9a000000ffff /* 0xe008 ring 0 code, 64-bit mode */ + .quad 0x00cf92000000ffff /* 0xe010 ring 0 data */ + .quad 0x00cfba000000ffff /* 0xe019 ring 1 code, compatibility */ + .quad 0x00cfb2000000ffff /* 0xe021 ring 1 data */ + .quad 0x00cffa000000ffff /* 0xe02b ring 3 code, compatibility */ + .quad 0x00cff2000000ffff /* 0xe033 ring 3 data */ + .quad 0x00cf9a000000ffff /* 0xe038 ring 0 code, compatibility */ + .org compat_gdt_table - FIRST_RESERVED_GDT_BYTE + __TSS(0) * 8 + .fill 4*NR_CPUS,8,0 /* space for TSS and LDT per CPU */ +# undef LIMIT +#endif + /* Initial PML4 -- level-4 page table. */ .align PAGE_SIZE, 0 ENTRY(idle_pg_table) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index afa2f60f08..ec8fc20a1c 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -283,17 +283,18 @@ int arch_set_info_guest( if ( !is_hvm_vcpu(v) ) { - fixup_guest_stack_selector(c->user_regs.ss); - fixup_guest_stack_selector(c->kernel_ss); - fixup_guest_code_selector(c->user_regs.cs); + fixup_guest_stack_selector(d, c->user_regs.ss); + fixup_guest_stack_selector(d, c->kernel_ss); + fixup_guest_code_selector(d, c->user_regs.cs); -#ifdef __i386__ - fixup_guest_code_selector(c->event_callback_cs); - fixup_guest_code_selector(c->failsafe_callback_cs); -#endif + if ( CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d) ) + { + fixup_guest_code_selector(d, c->event_callback_cs); + fixup_guest_code_selector(d, c->failsafe_callback_cs); + } for ( i = 0; i < 256; i++ ) - fixup_guest_code_selector(c->trap_ctxt[i].cs); + fixup_guest_code_selector(d, c->trap_ctxt[i].cs); /* LDT safety checks. */ if ( ((c->ldt_base & (PAGE_SIZE-1)) != 0) || @@ -489,27 +490,30 @@ static void load_segments(struct vcpu *n) all_segs_okay &= loadsegment(gs, nctxt->user_regs.gs); } - /* This can only be non-zero if selector is NULL. */ - if ( nctxt->fs_base ) - wrmsr(MSR_FS_BASE, - nctxt->fs_base, - nctxt->fs_base>>32); + if ( !IS_COMPAT(n->domain) ) + { + /* This can only be non-zero if selector is NULL. */ + if ( nctxt->fs_base ) + wrmsr(MSR_FS_BASE, + nctxt->fs_base, + nctxt->fs_base>>32); - /* Most kernels have non-zero GS base, so don't bother testing. */ - /* (This is also a serialising instruction, avoiding AMD erratum #88.) */ - wrmsr(MSR_SHADOW_GS_BASE, - nctxt->gs_base_kernel, - nctxt->gs_base_kernel>>32); + /* Most kernels have non-zero GS base, so don't bother testing. */ + /* (This is also a serialising instruction, avoiding AMD erratum #88.) */ + wrmsr(MSR_SHADOW_GS_BASE, + nctxt->gs_base_kernel, + nctxt->gs_base_kernel>>32); - /* This can only be non-zero if selector is NULL. */ - if ( nctxt->gs_base_user ) - wrmsr(MSR_GS_BASE, - nctxt->gs_base_user, - nctxt->gs_base_user>>32); + /* This can only be non-zero if selector is NULL. */ + if ( nctxt->gs_base_user ) + wrmsr(MSR_GS_BASE, + nctxt->gs_base_user, + nctxt->gs_base_user>>32); - /* If in kernel mode then switch the GS bases around. */ - if ( n->arch.flags & TF_kernel_mode ) - __asm__ __volatile__ ( "swapgs" ); + /* If in kernel mode then switch the GS bases around. */ + if ( (n->arch.flags & TF_kernel_mode) ) + __asm__ __volatile__ ( "swapgs" ); + } if ( unlikely(!all_segs_okay) ) { @@ -520,6 +524,55 @@ static void load_segments(struct vcpu *n) (unsigned long *)nctxt->kernel_sp; unsigned long cs_and_mask, rflags; + if ( IS_COMPAT(n->domain) ) + { + unsigned int *esp = ring_1(regs) ? + (unsigned int *)regs->rsp : + (unsigned int *)nctxt->kernel_sp; + unsigned int cs_and_mask, eflags; + int ret = 0; + + /* CS longword also contains full evtchn_upcall_mask. */ + cs_and_mask = (unsigned short)regs->cs | + ((unsigned int)n->vcpu_info->evtchn_upcall_mask << 16); + /* Fold upcall mask into RFLAGS.IF. */ + eflags = regs->_eflags & ~X86_EFLAGS_IF; + eflags |= !n->vcpu_info->evtchn_upcall_mask << 9; + + if ( !ring_1(regs) ) + { + ret = put_user(regs->ss, esp-1); + ret |= put_user(regs->_esp, esp-2); + esp -= 2; + } + + if ( ret | + put_user(eflags, esp-1) | + put_user(cs_and_mask, esp-2) | + put_user(regs->_eip, esp-3) | + put_user(nctxt->user_regs.gs, esp-4) | + put_user(nctxt->user_regs.fs, esp-5) | + put_user(nctxt->user_regs.es, esp-6) | + put_user(nctxt->user_regs.ds, esp-7) ) + { + gdprintk(XENLOG_ERR, "Error while creating compat " + "failsafe callback frame.\n"); + domain_crash(n->domain); + } + + if ( test_bit(_VGCF_failsafe_disables_events, + &n->arch.guest_context.flags) ) + n->vcpu_info->evtchn_upcall_mask = 1; + + regs->entry_vector = TRAP_syscall; + regs->_eflags &= 0xFFFCBEFFUL; + regs->ss = FLAT_COMPAT_KERNEL_SS; + regs->_esp = (unsigned long)(esp-7); + regs->cs = FLAT_COMPAT_KERNEL_CS; + regs->_eip = nctxt->failsafe_callback_eip; + return; + } + if ( !(n->arch.flags & TF_kernel_mode) ) toggle_guest_mode(n); else @@ -581,7 +634,7 @@ static void save_segments(struct vcpu *v) if ( regs->es ) dirty_segment_mask |= DIRTY_ES; - if ( regs->fs ) + if ( regs->fs || IS_COMPAT(v->domain) ) { dirty_segment_mask |= DIRTY_FS; ctxt->fs_base = 0; /* != 0 selector kills fs_base */ @@ -591,7 +644,7 @@ static void save_segments(struct vcpu *v) dirty_segment_mask |= DIRTY_FS_BASE; } - if ( regs->gs ) + if ( regs->gs || IS_COMPAT(v->domain) ) { dirty_segment_mask |= DIRTY_GS; ctxt->gs_base_user = 0; /* != 0 selector kills gs_base_user */ @@ -726,6 +779,23 @@ void context_switch(struct vcpu *prev, struct vcpu *next) { __context_switch(); +#ifdef CONFIG_COMPAT + if ( is_idle_vcpu(prev) + || IS_COMPAT(prev->domain) != IS_COMPAT(next->domain) ) + { + uint32_t efer_lo, efer_hi; + + local_flush_tlb_one(GDT_VIRT_START(next) + FIRST_RESERVED_GDT_BYTE); + + rdmsr(MSR_EFER, efer_lo, efer_hi); + if ( !IS_COMPAT(next->domain) == !(efer_lo & EFER_SCE) ) + { + efer_lo ^= EFER_SCE; + wrmsr(MSR_EFER, efer_lo, efer_hi); + } + } +#endif + /* Re-enable interrupts before restoring state which may fault. */ local_irq_enable(); @@ -938,6 +1008,10 @@ void domain_relinquish_resources(struct domain *d) put_page(mfn_to_page(pfn)); else put_page_and_type(mfn_to_page(pfn)); +#ifdef __x86_64__ + if ( pfn == pagetable_get_pfn(v->arch.guest_table_user) ) + v->arch.guest_table_user = pagetable_null(); +#endif v->arch.guest_table = pagetable_null(); } diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 1c03039c6e..0e15b153e1 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -319,10 +319,38 @@ int construct_dom0(struct domain *d, nr_pages = compute_dom0_nr_pages(); - if ( (rc = parseelfimage(&dsi)) != 0 ) - return rc; + rc = parseelfimage(&dsi); +#ifdef CONFIG_COMPAT + if ( rc == -ENOSYS + && (rc = parseelf32image(&dsi)) == 0 ) + { + l1_pgentry_t gdt_l1e; - xen_pae = (CONFIG_PAGING_LEVELS == 3); + set_bit(_DOMF_compat, &d->domain_flags); + + if ( nr_pages != (unsigned int)nr_pages ) + nr_pages = UINT_MAX; + + /* + * Map compatibility Xen segments into every VCPU's GDT. See + * arch_domain_create() for further comments. + */ + gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), + PAGE_HYPERVISOR); + for ( i = 0; i < MAX_VIRT_CPUS; i++ ) + d->arch.mm_perdomain_pt[((i << GDT_LDT_VCPU_SHIFT) + + FIRST_RESERVED_GDT_PAGE)] = gdt_l1e; + local_flush_tlb_one(GDT_LDT_VIRT_START + FIRST_RESERVED_GDT_BYTE); + } +#endif + if ( rc != 0) + { + if ( rc == -ENOSYS ) + printk("DOM0 image is not a Xen-compatible Elf image.\n"); + return rc; + } + + xen_pae = (CONFIG_PAGING_LEVELS == 3) || IS_COMPAT(d); if (dsi.pae_kernel == PAEKERN_bimodal) dom0_pae = xen_pae; else @@ -338,7 +366,13 @@ int construct_dom0(struct domain *d, dsi.pae_kernel == PAEKERN_bimodal) ) set_bit(VMASST_TYPE_pae_extended_cr3, &d->vm_assist); - if ( (p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES)) != NULL ) +#ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) + p = xen_elf32note_string(&dsi, XEN_ELFNOTE_FEATURES); + else +#endif + p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES); + if ( p != NULL ) { parse_features(p, dom0_features_supported, @@ -590,6 +624,12 @@ int construct_dom0(struct domain *d, return -EINVAL; } + if ( IS_COMPAT(d) ) + { + v->arch.guest_context.failsafe_callback_cs = FLAT_COMPAT_KERNEL_CS; + v->arch.guest_context.event_callback_cs = FLAT_COMPAT_KERNEL_CS; + } + /* WARNING: The new domain must have its 'processor' field filled in! */ maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table; l4start = l4tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; @@ -599,6 +639,8 @@ int construct_dom0(struct domain *d, l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); v->arch.guest_table = pagetable_from_paddr(__pa(l4start)); + if ( IS_COMPAT(d) ) + v->arch.guest_table_user = v->arch.guest_table; l4tab += l4_table_offset(dsi.v_start); mfn = alloc_spfn; @@ -711,10 +753,20 @@ int construct_dom0(struct domain *d, write_ptbase(v); /* Copy the OS image and free temporary buffer. */ - (void)loadelfimage(&dsi); - - hypercall_page = - xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); +#ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) + { + (void)loadelf32image(&dsi); + hypercall_page = + xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); + } + else +#endif + { + (void)loadelfimage(&dsi); + hypercall_page = + xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); + } if ( hypercall_page_defined ) { if ( (hypercall_page < dsi.v_start) || (hypercall_page >= v_end) ) @@ -747,7 +799,7 @@ int construct_dom0(struct domain *d, si->mfn_list = vphysmap_start; sprintf(si->magic, "xen-%i.%i-x86_%d%s", xen_major_version(), xen_minor_version(), - BITS_PER_LONG, xen_pae ? "p" : ""); + !IS_COMPAT(d) ? BITS_PER_LONG : 32, xen_pae ? "p" : ""); /* Write the phys->machine and machine->phys table entries. */ for ( pfn = 0; pfn < d->tot_pages; pfn++ ) @@ -819,9 +871,11 @@ int construct_dom0(struct domain *d, * [EAX,EBX,ECX,EDX,EDI,EBP are zero] */ regs = &v->arch.guest_context.user_regs; - regs->ds = regs->es = regs->fs = regs->gs = FLAT_KERNEL_DS; - regs->ss = FLAT_KERNEL_SS; - regs->cs = FLAT_KERNEL_CS; + regs->ds = regs->es = regs->fs = regs->gs = !IS_COMPAT(d) + ? FLAT_KERNEL_DS + : FLAT_COMPAT_KERNEL_DS; + regs->ss = !IS_COMPAT(d) ? FLAT_KERNEL_SS : FLAT_COMPAT_KERNEL_SS; + regs->cs = !IS_COMPAT(d) ? FLAT_KERNEL_CS : FLAT_COMPAT_KERNEL_CS; regs->eip = dsi.v_kernentry; regs->esp = vstack_end; regs->esi = vstartinfo_start; @@ -906,13 +960,28 @@ int elf_sanity_check(const Elf_Ehdr *ehdr) (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) || (ehdr->e_type != ET_EXEC) ) { - printk("DOM0 image is not a Xen-compatible Elf image.\n"); return 0; } return 1; } +#ifdef CONFIG_COMPAT +int elf32_sanity_check(const Elf32_Ehdr *ehdr) +{ + if ( !IS_ELF(*ehdr) || + (ehdr->e_ident[EI_CLASS] != ELFCLASS32) || + (ehdr->e_machine != EM_386) || + (ehdr->e_ident[EI_DATA] != ELFDATA2LSB) || + (ehdr->e_type != ET_EXEC) ) + { + return 0; + } + + return 1; +} +#endif + /* * Local variables: * mode: C diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index c6615139cf..c8a3834e65 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -433,7 +433,7 @@ static int alloc_segdesc_page(struct page_info *page) descs = map_domain_page(page_to_mfn(page)); for ( i = 0; i < 512; i++ ) - if ( unlikely(!check_descriptor(&descs[i])) ) + if ( unlikely(!check_descriptor(page_get_owner(page), &descs[i])) ) goto fail; unmap_domain_page(descs); @@ -2835,7 +2835,7 @@ long do_update_descriptor(u64 pa, u64 desc) mfn = gmfn_to_mfn(dom, gmfn); if ( (((unsigned int)pa % sizeof(struct desc_struct)) != 0) || !mfn_valid(mfn) || - !check_descriptor(&d) ) + !check_descriptor(dom, &d) ) { UNLOCK_BIGLOCK(dom); return -EINVAL; diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 8d9f6f9e08..928ab8f286 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -791,6 +791,9 @@ void arch_get_xen_caps(xen_capabilities_info_t info) #elif defined(CONFIG_X86_64) p += sprintf(p, "xen-%d.%d-x86_64 ", major, minor); +#ifdef CONFIG_COMPAT + p += sprintf(p, "xen-%d.%d-x86_32p ", major, minor); +#endif if ( hvm_enabled ) { p += sprintf(p, "hvm-%d.%d-x86_32 ", major, minor); diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 95d96b03cd..d2b60ef64a 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -382,7 +382,7 @@ static int do_guest_trap( if ( TI_GET_IF(ti) ) tb->flags |= TBF_INTERRUPT; - if ( unlikely(null_trap_bounce(tb)) ) + if ( unlikely(null_trap_bounce(v, tb)) ) gdprintk(XENLOG_WARNING, "Unhandled %s fault/trap [#%d] in " "domain %d on VCPU %d [ec=%04x]\n", trapstr(trapnr), trapnr, v->domain->domain_id, v->vcpu_id, @@ -673,7 +673,7 @@ void propagate_page_fault(unsigned long addr, u16 error_code) tb->eip = ti->address; if ( TI_GET_IF(ti) ) tb->flags |= TBF_INTERRUPT; - if ( unlikely(null_trap_bounce(tb)) ) + if ( unlikely(null_trap_bounce(v, tb)) ) { printk("Unhandled page fault in domain %d on VCPU %d (ec=%04X)\n", v->domain->domain_id, v->vcpu_id, error_code); @@ -1785,6 +1785,13 @@ void set_tss_desc(unsigned int n, void *addr) (unsigned long)addr, offsetof(struct tss_struct, __cacheline_filler) - 1, 9); +#ifdef CONFIG_COMPAT + _set_tssldt_desc( + compat_gdt_table + __TSS(n) - FIRST_RESERVED_GDT_ENTRY, + (unsigned long)addr, + offsetof(struct tss_struct, __cacheline_filler) - 1, + 11); +#endif } void __init trap_init(void) @@ -1859,7 +1866,7 @@ long do_set_trap_table(XEN_GUEST_HANDLE(trap_info_t) traps) if ( cur.address == 0 ) break; - fixup_guest_code_selector(cur.cs); + fixup_guest_code_selector(current->domain, cur.cs); memcpy(&dst[cur.vector], &cur, sizeof(cur)); diff --git a/xen/arch/x86/x86_32/mm.c b/xen/arch/x86/x86_32/mm.c index 4978b82dad..76303fc275 100644 --- a/xen/arch/x86/x86_32/mm.c +++ b/xen/arch/x86/x86_32/mm.c @@ -230,7 +230,7 @@ long do_stack_switch(unsigned long ss, unsigned long esp) int nr = smp_processor_id(); struct tss_struct *t = &init_tss[nr]; - fixup_guest_stack_selector(ss); + fixup_guest_stack_selector(current->domain, ss); current->arch.guest_context.kernel_ss = ss; current->arch.guest_context.kernel_sp = esp; @@ -241,7 +241,7 @@ long do_stack_switch(unsigned long ss, unsigned long esp) } /* Returns TRUE if given descriptor is valid for GDT or LDT. */ -int check_descriptor(struct desc_struct *d) +int check_descriptor(const struct domain *dom, struct desc_struct *d) { unsigned long base, limit; u32 a = d->a, b = d->b; @@ -261,8 +261,8 @@ int check_descriptor(struct desc_struct *d) * gates (consider a call gate pointing at another kernel descriptor with * DPL 0 -- this would get the OS ring-0 privileges). */ - if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL << 13) ) - d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL << 13); + if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL(dom) << 13) ) + d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL(dom) << 13); if ( !(b & _SEGMENT_S) ) { @@ -284,8 +284,8 @@ int check_descriptor(struct desc_struct *d) /* Validate and fix up the target code selector. */ cs = a >> 16; - fixup_guest_code_selector(cs); - if ( !guest_gate_selector_okay(cs) ) + fixup_guest_code_selector(dom, cs); + if ( !guest_gate_selector_okay(dom, cs) ) goto bad; a = d->a = (d->a & 0xffffU) | (cs << 16); diff --git a/xen/arch/x86/x86_32/traps.c b/xen/arch/x86/x86_32/traps.c index d5d1e5e8f7..3e8c82aba3 100644 --- a/xen/arch/x86/x86_32/traps.c +++ b/xen/arch/x86/x86_32/traps.c @@ -296,7 +296,7 @@ void init_int80_direct_trap(struct vcpu *v) * switch to the Xen stack and we need to swap back to the guest * kernel stack before passing control to the system call entry point. */ - if ( TI_GET_IF(ti) || !guest_gate_selector_okay(ti->cs) || + if ( TI_GET_IF(ti) || !guest_gate_selector_okay(v->domain, ti->cs) || supervisor_mode_kernel ) { v->arch.int80_desc.a = v->arch.int80_desc.b = 0; @@ -326,7 +326,7 @@ static long register_guest_callback(struct callback_register *reg) long ret = 0; struct vcpu *v = current; - fixup_guest_code_selector(reg->address.cs); + fixup_guest_code_selector(v->domain, reg->address.cs); switch ( reg->type ) { diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c index 41f93fe9c5..58bad0662a 100644 --- a/xen/arch/x86/x86_64/asm-offsets.c +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -58,12 +58,16 @@ void __dummy__(void) OFFSET(VCPU_thread_flags, struct vcpu, arch.flags); OFFSET(VCPU_event_addr, struct vcpu, arch.guest_context.event_callback_eip); + OFFSET(VCPU_event_sel, struct vcpu, + arch.guest_context.event_callback_cs); OFFSET(VCPU_failsafe_addr, struct vcpu, arch.guest_context.failsafe_callback_eip); + OFFSET(VCPU_failsafe_sel, struct vcpu, + arch.guest_context.failsafe_callback_cs); OFFSET(VCPU_syscall_addr, struct vcpu, arch.guest_context.syscall_callback_eip); - OFFSET(VCPU_kernel_sp, struct vcpu, - arch.guest_context.kernel_sp); + OFFSET(VCPU_kernel_sp, struct vcpu, arch.guest_context.kernel_sp); + OFFSET(VCPU_kernel_ss, struct vcpu, arch.guest_context.kernel_ss); OFFSET(VCPU_guest_context_flags, struct vcpu, arch.guest_context.flags); OFFSET(VCPU_arch_guest_fpu_ctxt, struct vcpu, arch.guest_context.fpu_ctxt); OFFSET(VCPU_flags, struct vcpu, vcpu_flags); diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index e14d266e12..54180bc511 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -231,7 +231,7 @@ long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) long do_stack_switch(unsigned long ss, unsigned long esp) { - fixup_guest_stack_selector(ss); + fixup_guest_stack_selector(current->domain, ss); current->arch.guest_context.kernel_ss = ss; current->arch.guest_context.kernel_sp = esp; return 0; @@ -291,7 +291,7 @@ long do_set_segment_base(unsigned int which, unsigned long base) /* Returns TRUE if given descriptor is valid for GDT or LDT. */ -int check_descriptor(struct desc_struct *d) +int check_descriptor(const struct domain *dom, struct desc_struct *d) { u32 a = d->a, b = d->b; u16 cs; @@ -301,8 +301,8 @@ int check_descriptor(struct desc_struct *d) goto good; /* Check and fix up the DPL. */ - if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL << 13) ) - d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL << 13); + if ( (b & _SEGMENT_DPL) < (GUEST_KERNEL_RPL(dom) << 13) ) + d->b = b = (b & ~_SEGMENT_DPL) | (GUEST_KERNEL_RPL(dom) << 13); /* All code and data segments are okay. No base/limit checking. */ if ( (b & _SEGMENT_S) ) @@ -318,8 +318,8 @@ int check_descriptor(struct desc_struct *d) /* Validate and fix up the target code selector. */ cs = a >> 16; - fixup_guest_code_selector(cs); - if ( !guest_gate_selector_okay(cs) ) + fixup_guest_code_selector(dom, cs); + if ( !guest_gate_selector_okay(dom, cs) ) goto bad; a = d->a = (d->a & 0xffffU) | (cs << 16); diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 5eb91130a5..9c4a998006 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -178,6 +178,8 @@ asmlinkage void do_double_fault(struct cpu_user_regs *regs) void toggle_guest_mode(struct vcpu *v) { + if ( IS_COMPAT(v->domain) ) + return; v->arch.flags ^= TF_kernel_mode; __asm__ __volatile__ ( "swapgs" ); update_cr3(v); diff --git a/xen/common/Makefile b/xen/common/Makefile index 6f3a9a097e..017348e065 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -3,6 +3,7 @@ obj-y += bitmap.o obj-y += domctl.o obj-y += domain.o obj-y += elf.o +obj-$(CONFIG_COMPAT) += elf32.o obj-y += event_channel.o obj-y += grant_table.o obj-y += kernel.o diff --git a/xen/common/elf.c b/xen/common/elf.c index 42b488b2bf..6a55053e74 100644 --- a/xen/common/elf.c +++ b/xen/common/elf.c @@ -203,7 +203,7 @@ int parseelfimage(struct domain_setup_info *dsi) int h, virt_base_defined, elf_pa_off_defined, virt_entry_defined; if ( !elf_sanity_check(ehdr) ) - return -EINVAL; + return -ENOSYS; if ( (ehdr->e_phoff + (ehdr->e_phnum*ehdr->e_phentsize)) > image_len ) { diff --git a/xen/common/elf32.c b/xen/common/elf32.c new file mode 100644 index 0000000000..566c143667 --- /dev/null +++ b/xen/common/elf32.c @@ -0,0 +1,19 @@ +/****************************************************************************** + * elf32.c + * + * Stub to support 32-bit ELF images on 64-bit platforms. + */ + +#include +#undef ELFSIZE +#define ELFSIZE 32 +#include +#include + +#define xen_elfnote_string xen_elf32note_string +#define xen_elfnote_numeric xen_elf32note_numeric +#define parseelfimage parseelf32image +#define loadelfimage loadelf32image +#define elf_sanity_check elf32_sanity_check + +#include "elf.c" diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 562bb786d4..167b4b4897 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -87,6 +87,7 @@ #if defined(__x86_64__) #define CONFIG_X86_64 1 +#define CONFIG_COMPAT 1 #define asmlinkage @@ -181,13 +182,21 @@ #define DIRECTMAP_VIRT_START (PML4_ADDR(262)) #define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + PML4_ENTRY_BYTES*2) +#define __HYPERVISOR_COMPAT_VIRT_START 0xF5800000 +#define HYPERVISOR_COMPAT_VIRT_START \ + mk_unsigned_long(__HYPERVISOR_COMPAT_VIRT_START) +#define MACH2PHYS_COMPAT_VIRT_START HYPERVISOR_COMPAT_VIRT_START +#define MACH2PHYS_COMPAT_VIRT_END 0xFFE00000 +#define MACH2PHYS_COMPAT_NR_ENTRIES \ + ((MACH2PHYS_COMPAT_VIRT_END-MACH2PHYS_COMPAT_VIRT_START)>>2) + #define PGT_base_page_table PGT_l4_page_table -#define __HYPERVISOR_CS64 0xe010 -#define __HYPERVISOR_CS32 0xe008 +#define __HYPERVISOR_CS64 0xe008 +#define __HYPERVISOR_CS32 0xe038 #define __HYPERVISOR_CS __HYPERVISOR_CS64 #define __HYPERVISOR_DS64 0x0000 -#define __HYPERVISOR_DS32 0xe018 +#define __HYPERVISOR_DS32 0xe010 #define __HYPERVISOR_DS __HYPERVISOR_DS64 /* For generic assembly code: use macros to define operation/operand sizes. */ diff --git a/xen/include/asm-x86/desc.h b/xen/include/asm-x86/desc.h index c2262d79fb..e3bc46b323 100644 --- a/xen/include/asm-x86/desc.h +++ b/xen/include/asm-x86/desc.h @@ -18,31 +18,76 @@ #define LDT_ENTRY_SIZE 8 +#if defined(__x86_64__) + +#define FLAT_COMPAT_RING1_CS 0xe019 /* GDT index 259 */ +#define FLAT_COMPAT_RING1_DS 0xe021 /* GDT index 260 */ +#define FLAT_COMPAT_RING1_SS 0xe021 /* GDT index 260 */ +#define FLAT_COMPAT_RING3_CS 0xe02b /* GDT index 261 */ +#define FLAT_COMPAT_RING3_DS 0xe033 /* GDT index 262 */ +#define FLAT_COMPAT_RING3_SS 0xe033 /* GDT index 262 */ + +#define FLAT_COMPAT_KERNEL_DS FLAT_COMPAT_RING1_DS +#define FLAT_COMPAT_KERNEL_CS FLAT_COMPAT_RING1_CS +#define FLAT_COMPAT_KERNEL_SS FLAT_COMPAT_RING1_SS +#define FLAT_COMPAT_USER_DS FLAT_COMPAT_RING3_DS +#define FLAT_COMPAT_USER_CS FLAT_COMPAT_RING3_CS +#define FLAT_COMPAT_USER_SS FLAT_COMPAT_RING3_SS + +#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) +#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 2) + +#define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY) +#define __LDT(n) (((n)<<2) + __FIRST_LDT_ENTRY) + +#elif defined(__i386__) + +#define FLAT_COMPAT_KERNEL_CS FLAT_KERNEL_CS +#define FLAT_COMPAT_KERNEL_DS FLAT_KERNEL_DS +#define FLAT_COMPAT_KERNEL_SS FLAT_KERNEL_SS +#define FLAT_COMPAT_USER_CS FLAT_USER_CS +#define FLAT_COMPAT_USER_DS FLAT_USER_DS +#define FLAT_COMPAT_USER_SS FLAT_USER_SS + +#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY + +#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) +#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1) + +#define __TSS(n) (((n)<<1) + __FIRST_TSS_ENTRY) +#define __LDT(n) (((n)<<1) + __FIRST_LDT_ENTRY) + +#endif + +#ifndef __ASSEMBLY__ + #define load_TR(n) __asm__ __volatile__ ("ltr %%ax" : : "a" (__TSS(n)<<3) ) #if defined(__x86_64__) -#define GUEST_KERNEL_RPL 3 +#define GUEST_KERNEL_RPL(d) (!IS_COMPAT(d) ? 3 : 1) #elif defined(__i386__) -#define GUEST_KERNEL_RPL 1 +#define GUEST_KERNEL_RPL(d) ((void)(d), 1) #endif /* Fix up the RPL of a guest segment selector. */ -#define __fixup_guest_selector(sel) \ - ((sel) = (((sel) & 3) >= GUEST_KERNEL_RPL) ? (sel) : \ - (((sel) & ~3) | GUEST_KERNEL_RPL)) +#define __fixup_guest_selector(d, sel) \ +({ \ + uint16_t _rpl = GUEST_KERNEL_RPL(d); \ + (sel) = (((sel) & 3) >= _rpl) ? (sel) : (((sel) & ~3) | _rpl); \ +}) /* Stack selectors don't need fixing up if the kernel runs in ring 0. */ #ifdef CONFIG_X86_SUPERVISOR_MODE_KERNEL -#define fixup_guest_stack_selector(ss) ((void)0) +#define fixup_guest_stack_selector(d, ss) ((void)0) #else -#define fixup_guest_stack_selector(ss) __fixup_guest_selector(ss) +#define fixup_guest_stack_selector(d, ss) __fixup_guest_selector(d, ss) #endif /* * Code selectors are always fixed up. It allows the Xen exit stub to detect * return to guest context, even when the guest kernel runs in ring 0. */ -#define fixup_guest_code_selector(cs) __fixup_guest_selector(cs) +#define fixup_guest_code_selector(d, cs) __fixup_guest_selector(d, cs) /* * We need this function because enforcing the correct guest kernel RPL is @@ -57,11 +102,15 @@ * DPL < CPL then they'll be cleared automatically. If SS RPL or DPL differs * from CS RPL then we'll #GP. */ -#define guest_gate_selector_okay(sel) \ +#define guest_gate_selector_okay(d, sel) \ ((((sel)>>3) < FIRST_RESERVED_GDT_ENTRY) || /* Guest seg? */ \ - ((sel) == FLAT_KERNEL_CS) || /* Xen default seg? */ \ + ((sel) == (!IS_COMPAT(d) ? \ + FLAT_KERNEL_CS : /* Xen default seg? */ \ + FLAT_COMPAT_KERNEL_CS)) || /* Xen default compat seg? */ \ ((sel) & 4)) /* LDT seg? */ +#endif /* __ASSEMBLY__ */ + /* These are bitmasks for the high 32 bits of a descriptor table entry. */ #define _SEGMENT_TYPE (15<< 8) #define _SEGMENT_EC ( 1<<10) /* Expand-down or Conforming segment */ @@ -81,12 +130,6 @@ struct desc_struct { #if defined(__x86_64__) -#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) -#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 2) - -#define __TSS(n) (((n)<<2) + __FIRST_TSS_ENTRY) -#define __LDT(n) (((n)<<2) + __FIRST_LDT_ENTRY) - typedef struct { u64 a, b; } idt_entry_t; @@ -118,14 +161,6 @@ do { \ #elif defined(__i386__) -#define __DOUBLEFAULT_TSS_ENTRY FIRST_RESERVED_GDT_ENTRY - -#define __FIRST_TSS_ENTRY (FIRST_RESERVED_GDT_ENTRY + 8) -#define __FIRST_LDT_ENTRY (__FIRST_TSS_ENTRY + 1) - -#define __TSS(n) (((n)<<1) + __FIRST_TSS_ENTRY) -#define __LDT(n) (((n)<<1) + __FIRST_LDT_ENTRY) - typedef struct desc_struct idt_entry_t; #define _set_gate(gate_addr,type,dpl,addr) \ @@ -155,6 +190,11 @@ __asm__ __volatile__ ("movw %w3,0(%2)\n\t" \ #endif extern struct desc_struct gdt_table[]; +#ifdef CONFIG_COMPAT +extern struct desc_struct compat_gdt_table[]; +#else +# define compat_gdt_table gdt_table +#endif struct Xgt_desc_struct { unsigned short size; diff --git a/xen/include/asm-x86/ldt.h b/xen/include/asm-x86/ldt.h index 107e67720b..27f4750558 100644 --- a/xen/include/asm-x86/ldt.h +++ b/xen/include/asm-x86/ldt.h @@ -17,7 +17,8 @@ static inline void load_LDT(struct vcpu *v) else { cpu = smp_processor_id(); - desc = gdt_table + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY; + desc = (!IS_COMPAT(v->domain) ? gdt_table : compat_gdt_table) + + __LDT(cpu) - FIRST_RESERVED_GDT_ENTRY; _set_tssldt_desc(desc, LDT_VIRT_START(v), ents*8-1, 2); __asm__ __volatile__ ( "lldt %%ax" : : "a" (__LDT(cpu)<<3) ); } diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index d561677fed..a3d89a301d 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -244,7 +244,7 @@ unsigned long pae_copy_root(struct vcpu *v, l3_pgentry_t *l3tab); #endif /* CONFIG_PAGING_LEVELS == 3 */ -int check_descriptor(struct desc_struct *d); +int check_descriptor(const struct domain *, struct desc_struct *d); /* * The MPT (machine->physical mapping table) is an array of word-sized diff --git a/xen/include/asm-x86/regs.h b/xen/include/asm-x86/regs.h index 48f8b86c85..90cfee68a8 100644 --- a/xen/include/asm-x86/regs.h +++ b/xen/include/asm-x86/regs.h @@ -38,7 +38,8 @@ enum EFLAGS { ASSERT(diff < STACK_SIZE); \ /* If a guest frame, it must be have guest privs (unless HVM guest). */ \ /* We permit CS==0 which can come from an uninitialised trap entry. */ \ - ASSERT((diff != 0) || vm86_mode(r) || ((r->cs&3) >= GUEST_KERNEL_RPL) || \ + ASSERT((diff != 0) || vm86_mode(r) || \ + ((r->cs&3) >= GUEST_KERNEL_RPL(current->domain)) || \ (r->cs == 0) || is_hvm_vcpu(current)); \ /* If not a guest frame, it must be a hypervisor frame. */ \ ASSERT((diff == 0) || (!vm86_mode(r) && (r->cs == __HYPERVISOR_CS))); \ diff --git a/xen/include/asm-x86/x86_32/regs.h b/xen/include/asm-x86/x86_32/regs.h index 7306b65af5..c65c57ffe4 100644 --- a/xen/include/asm-x86/x86_32/regs.h +++ b/xen/include/asm-x86/x86_32/regs.h @@ -17,7 +17,7 @@ ((dpl) >= (vm86_mode(r) ? 3 : ((r)->cs & 3))) /* Check for null trap callback handler: Is the selector null (0-3)? */ -#define null_trap_bounce(tb) (((tb)->cs & ~3) == 0) +#define null_trap_bounce(v, tb) (((tb)->cs & ~3) == 0) /* Number of bytes of on-stack execution state to be context-switched. */ #define CTXT_SWITCH_STACK_BYTES (sizeof(struct cpu_user_regs)) diff --git a/xen/include/asm-x86/x86_64/regs.h b/xen/include/asm-x86/x86_64/regs.h index 5dadccdab1..5b3d6df972 100644 --- a/xen/include/asm-x86/x86_64/regs.h +++ b/xen/include/asm-x86/x86_64/regs.h @@ -11,13 +11,16 @@ #define ring_3(r) (((r)->cs & 3) == 3) #define guest_kernel_mode(v, r) \ - (ring_3(r) && ((v)->arch.flags & TF_kernel_mode)) + (!IS_COMPAT((v)->domain) ? \ + ring_3(r) && ((v)->arch.flags & TF_kernel_mode) : \ + ring_1(r)) #define permit_softint(dpl, v, r) \ ((dpl) >= (guest_kernel_mode(v, r) ? 1 : 3)) /* Check for null trap callback handler: Is the EIP null? */ -#define null_trap_bounce(tb) ((tb)->eip == 0) +#define null_trap_bounce(v, tb) \ + (!IS_COMPAT((v)->domain) ? (tb)->eip == 0 : ((tb)->cs & ~3) == 0) /* Number of bytes of on-stack execution state to be context-switched. */ /* NB. Segment registers and bases are not saved/restored on x86/64 stack. */ diff --git a/xen/include/public/arch-x86/xen-x86_64.h b/xen/include/public/arch-x86/xen-x86_64.h index 4a4ae28cb0..80135d25ca 100644 --- a/xen/include/public/arch-x86/xen-x86_64.h +++ b/xen/include/public/arch-x86/xen-x86_64.h @@ -141,7 +141,10 @@ struct iret_context { #ifdef __GNUC__ /* Anonymous union includes both 32- and 64-bit names (e.g., eax/rax). */ -#define __DECL_REG(name) union { uint64_t r ## name, e ## name; } +#define __DECL_REG(name) union { \ + uint64_t r ## name, e ## name; \ + uint32_t _e ## name; \ +} #else /* Non-gcc sources must always use the proper 64-bit name (e.g., rax). */ #define __DECL_REG(name) uint64_t r ## name diff --git a/xen/include/public/arch-x86/xen.h b/xen/include/public/arch-x86/xen.h index a4d7c2fd08..34cbdb7c59 100644 --- a/xen/include/public/arch-x86/xen.h +++ b/xen/include/public/arch-x86/xen.h @@ -141,7 +141,17 @@ struct vcpu_guest_context { #else unsigned long event_callback_eip; unsigned long failsafe_callback_eip; +#ifdef __XEN__ + union { + unsigned long syscall_callback_eip; + struct { + unsigned int event_callback_cs; /* compat CS of event cb */ + unsigned int failsafe_callback_cs; /* compat CS of failsafe cb */ + }; + }; +#else unsigned long syscall_callback_eip; +#endif #endif unsigned long vm_assist; /* VMASST_TYPE_* bitmap */ #ifdef __x86_64__ diff --git a/xen/include/xen/elf.h b/xen/include/xen/elf.h index f5bb2841e7..131276a4d6 100644 --- a/xen/include/xen/elf.h +++ b/xen/include/xen/elf.h @@ -525,6 +525,15 @@ extern unsigned long long xen_elfnote_numeric(struct domain_setup_info *dsi, int type, int *defined); extern const char *xen_elfnote_string(struct domain_setup_info *dsi, int type); +#ifdef CONFIG_COMPAT +extern int elf32_sanity_check(const Elf32_Ehdr *ehdr); +extern int loadelf32image(struct domain_setup_info *); +extern int parseelf32image(struct domain_setup_info *); +extern unsigned long long xen_elf32note_numeric(struct domain_setup_info *, + int type, int *defined); +extern const char *xen_elf32note_string(struct domain_setup_info *, int type); +#endif + #ifdef Elf_Ehdr extern int elf_sanity_check(const Elf_Ehdr *ehdr); #endif diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 164368a31f..b1ef550440 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -422,6 +422,9 @@ extern struct domain *domain_list; /* Domain is paused by the hypervisor? */ #define _DOMF_paused 5 #define DOMF_paused (1UL<<_DOMF_paused) + /* Domain is a compatibility one? */ +#define _DOMF_compat 6 +#define DOMF_compat (1UL<<_DOMF_compat) static inline int vcpu_runnable(struct vcpu *v) { @@ -458,6 +461,13 @@ static inline void vcpu_unblock(struct vcpu *v) #define IS_PRIV(_d) ((_d)->is_privileged) +#ifdef CONFIG_COMPAT +#define IS_COMPAT(_d) \ + (test_bit(_DOMF_compat, &(_d)->domain_flags)) +#else +#define IS_COMPAT(_d) 0 +#endif + #define VM_ASSIST(_d,_t) (test_bit((_t), &(_d)->vm_assist)) #define is_hvm_domain(d) ((d)->is_hvm) From c1990f10a76daa10ea01dd11e9ca6fc92cf55716 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:27 +0000 Subject: [PATCH 075/570] Add entry points for handling hypercalls from and returning to compatibility mode guests. Signed-off-by: Jan Beulich --- xen/arch/x86/traps.c | 6 + xen/arch/x86/x86_64/Makefile | 6 + xen/arch/x86/x86_64/asm-offsets.c | 6 + xen/arch/x86/x86_64/compat/entry.S | 395 +++++++++++++++++++++++++++++ xen/arch/x86/x86_64/compat/traps.c | 312 +++++++++++++++++++++++ xen/arch/x86/x86_64/entry.S | 29 ++- xen/arch/x86/x86_64/traps.c | 12 +- xen/include/asm-x86/processor.h | 6 + 8 files changed, 769 insertions(+), 3 deletions(-) create mode 100644 xen/arch/x86/x86_64/compat/entry.S create mode 100644 xen/arch/x86/x86_64/compat/traps.c diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index d2b60ef64a..3b379bd2b5 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -123,6 +123,12 @@ static void show_guest_stack(struct cpu_user_regs *regs) if ( is_hvm_vcpu(current) ) return; + if ( IS_COMPAT(container_of(regs, struct cpu_info, guest_cpu_user_regs)->current_vcpu->domain) ) + { + compat_show_guest_stack(regs, debug_stack_lines); + return; + } + if ( vm86_mode(regs) ) { stack = (unsigned long *)((regs->ss << 4) + (regs->esp & 0xffff)); diff --git a/xen/arch/x86/x86_64/Makefile b/xen/arch/x86/x86_64/Makefile index 3c43c696d1..8cec5b7abd 100644 --- a/xen/arch/x86/x86_64/Makefile +++ b/xen/arch/x86/x86_64/Makefile @@ -2,3 +2,9 @@ obj-y += entry.o obj-y += gpr_switch.o obj-y += mm.o obj-y += traps.o + +ifeq ($(CONFIG_COMPAT),y) +# extra dependencies +entry.o: compat/entry.S +traps.o: compat/traps.c +endif diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c index 58bad0662a..d103503ebb 100644 --- a/xen/arch/x86/x86_64/asm-offsets.c +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -53,6 +53,7 @@ void __dummy__(void) BLANK(); OFFSET(VCPU_processor, struct vcpu, processor); + OFFSET(VCPU_domain, struct vcpu, domain); OFFSET(VCPU_vcpu_info, struct vcpu, vcpu_info); OFFSET(VCPU_trap_bounce, struct vcpu, arch.trap_bounce); OFFSET(VCPU_thread_flags, struct vcpu, arch.flags); @@ -87,6 +88,10 @@ void __dummy__(void) OFFSET(VCPU_vmx_cr2, struct vcpu, arch.hvm_vmx.cpu_cr2); BLANK(); + OFFSET(DOMAIN_domain_flags, struct domain, domain_flags); + DEFINE(_DOMF_compat, _DOMF_compat); + BLANK(); + OFFSET(VMCB_rax, struct vmcb_struct, rax); OFFSET(VMCB_tsc_offset, struct vmcb_struct, tsc_offset); BLANK(); @@ -95,6 +100,7 @@ void __dummy__(void) OFFSET(VCPUINFO_upcall_mask, vcpu_info_t, evtchn_upcall_mask); BLANK(); + OFFSET(CPUINFO_current_vcpu, struct cpu_info, current_vcpu); DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info)); BLANK(); diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S new file mode 100644 index 0000000000..98c184a051 --- /dev/null +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -0,0 +1,395 @@ +/* + * Compatibility hypercall routines. + */ + +#include + +.text + +ENTRY(compat_hypercall) + pushq $0 + movl $TRAP_syscall,4(%rsp) + SAVE_ALL + GET_CURRENT(%rbx) + + cmpl $NR_hypercalls,%eax + jae compat_bad_hypercall +#ifndef NDEBUG + /* Deliberately corrupt parameter regs not used by this hypercall. */ + pushq UREGS_rbx(%rsp); pushq %rcx; pushq %rdx; pushq %rsi; pushq %rdi; pushq UREGS_rbp+5*8(%rsp) + leaq compat_hypercall_args_table(%rip),%r10 + movq $6,%rcx + subb (%r10,%rax,1),%cl + movq %rsp,%rdi + movl $0xDEADBEEF,%eax + rep stosq + popq %r9 ; popq %r8 ; popq %rcx; popq %rdx; popq %rsi; popq %rdi + movl UREGS_rax(%rsp),%eax + pushq %rax + pushq UREGS_rip+8(%rsp) +#else + movl %eax,%eax + movl %ebp,%r9d + movl %edi,%r8d + xchgl %ecx,%esi + movl UREGS_rbx(%rsp),%edi +#endif + leaq compat_hypercall_table(%rip),%r10 + PERFC_INCR(PERFC_hypercalls, %rax) + callq *(%r10,%rax,8) +#ifndef NDEBUG + /* Deliberately corrupt parameter regs used by this hypercall. */ + popq %r10 # Shadow RIP + cmpq %r10,UREGS_rip+8(%rsp) + popq %rcx # Shadow hypercall index + jne compat_skip_clobber /* If RIP has changed then don't clobber. */ + leaq compat_hypercall_args_table(%rip),%r10 + movb (%r10,%rcx,1),%cl + movl $0xDEADBEEF,%r10d + testb %cl,%cl; jz compat_skip_clobber; movl %r10d,UREGS_rbx(%rsp) + cmpb $2, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rcx(%rsp) + cmpb $3, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rdx(%rsp) + cmpb $4, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rsi(%rsp) + cmpb $5, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rdi(%rsp) + cmpb $6, %cl; jb compat_skip_clobber; movl %r10d,UREGS_rbp(%rsp) +compat_skip_clobber: +#endif + movl %eax,UREGS_rax(%rsp) # save the return value + +/* %rbx: struct vcpu */ +compat_test_all_events: + cli # tests must not race interrupts +/*compat_test_softirqs:*/ + movl VCPU_processor(%rbx),%eax + shlq $IRQSTAT_shift,%rax + leaq irq_stat(%rip),%rcx + testl $~0,(%rcx,%rax,1) + jnz compat_process_softirqs + btrq $_VCPUF_nmi_pending,VCPU_flags(%rbx) + jc compat_process_nmi +compat_test_guest_events: + movq VCPU_vcpu_info(%rbx),%rax + testb $0xFF,VCPUINFO_upcall_mask(%rax) + jnz compat_restore_all_guest + testb $0xFF,VCPUINFO_upcall_pending(%rax) + jz compat_restore_all_guest +/*compat_process_guest_events:*/ + sti + leaq VCPU_trap_bounce(%rbx),%rdx + movl VCPU_event_addr(%rbx),%eax + movl %eax,TRAPBOUNCE_eip(%rdx) + movl VCPU_event_sel(%rbx),%eax + movl %eax,TRAPBOUNCE_cs(%rdx) + movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + call compat_create_bounce_frame + jmp compat_test_all_events + + ALIGN +/* %rbx: struct vcpu */ +compat_process_softirqs: + sti + call do_softirq + jmp compat_test_all_events + + ALIGN +/* %rbx: struct vcpu */ +compat_process_nmi: + movl VCPU_nmi_addr(%rbx),%eax + testl %eax,%eax + jz compat_test_all_events + btsq $_VCPUF_nmi_masked,VCPU_flags(%rbx) + jc 1f + sti + leaq VCPU_trap_bounce(%rbx),%rdx + movl %eax,TRAPBOUNCE_eip(%rdx) + movl $FLAT_COMPAT_KERNEL_CS,TRAPBOUNCE_cs(%rdx) + movw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) + call compat_create_bounce_frame + jmp compat_test_all_events +1: + btsq $_VCPUF_nmi_pending,VCPU_flags(%rbx) + jmp compat_test_guest_events + +compat_bad_hypercall: + movl $-ENOSYS,UREGS_rax(%rsp) + jmp compat_test_all_events + +/* %rbx: struct vcpu, interrupts disabled */ +compat_restore_all_guest: + RESTORE_ALL + addq $8,%rsp +CFLT0: iretq + +.section .fixup,"ax" +CFIX0: popq -15*8-8(%rsp) # error_code/entry_vector + SAVE_ALL # 15*8 bytes pushed + movq -8(%rsp),%rsi # error_code/entry_vector + sti # after stack abuse (-1024(%rsp)) + pushq $__HYPERVISOR_DS # SS + leaq 8(%rsp),%rax + pushq %rax # RSP + pushfq # RFLAGS + pushq $__HYPERVISOR_CS # CS + leaq CDBLFLT0(%rip),%rax + pushq %rax # RIP + pushq %rsi # error_code/entry_vector + jmp handle_exception +CDBLFLT0:GET_CURRENT(%rbx) + jmp compat_test_all_events +compat_failsafe_callback: + GET_CURRENT(%rbx) + leaq VCPU_trap_bounce(%rbx),%rdx + movl VCPU_failsafe_addr(%rbx),%eax + movl %eax,TRAPBOUNCE_eip(%rdx) + movl VCPU_failsafe_sel(%rbx),%eax + movl %eax,TRAPBOUNCE_cs(%rdx) + movw $TBF_FAILSAFE,TRAPBOUNCE_flags(%rdx) + btq $_VGCF_failsafe_disables_events,VCPU_guest_context_flags(%rbx) + jnc 1f + orw $TBF_INTERRUPT,TRAPBOUNCE_flags(%rdx) +1: + call compat_create_bounce_frame + jmp compat_test_all_events +.previous +.section __pre_ex_table,"a" + .quad CFLT0,CFIX0 +.previous +.section __ex_table,"a" + .quad CDBLFLT0,compat_failsafe_callback +.previous + +/* %rdx: trap_bounce, %rbx: struct vcpu */ +compat_post_handle_exception: + testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx) + jz compat_test_all_events + call compat_create_bounce_frame + jmp compat_test_all_events + +/* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK: */ +/* {[ERRCODE,] EIP, CS, EFLAGS, [ESP, SS]} */ +/* %rdx: trap_bounce, %rbx: struct vcpu */ +/* On return only %rbx is guaranteed non-clobbered. */ +compat_create_bounce_frame: + mov %fs,%edi + testb $2,UREGS_cs+8(%rsp) + jz 1f + /* Push new frame at registered guest-OS stack base. */ + movl VCPU_kernel_sp(%rbx),%esi +CFLT1: mov VCPU_kernel_ss(%rbx),%fs + subl $2*4,%esi + movl UREGS_rsp+8(%rsp),%eax +CFLT2: movl %eax,%fs:(%rsi) + movl UREGS_ss+8(%rsp),%eax +CFLT3: movl %eax,%fs:4(%rsi) + jmp 2f +1: /* In kernel context already: push new frame at existing %rsp. */ + movl UREGS_rsp+8(%rsp),%esi +CFLT4: mov UREGS_ss+8(%rsp),%fs +2: + movb TRAPBOUNCE_flags(%rdx),%cl + subl $3*4,%esi + movq VCPU_vcpu_info(%rbx),%rax + pushq VCPUINFO_upcall_mask(%rax) + testb $TBF_INTERRUPT,%cl + setnz %ch # TBF_INTERRUPT -> set upcall mask + orb %ch,VCPUINFO_upcall_mask(%rax) + popq %rax + shll $16,%eax # Bits 16-23: saved_upcall_mask + movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS +CFLT5: movl %eax,%fs:4(%rsi) # CS / saved_upcall_mask + shrl $16,%eax + testb %al,%al # Bits 0-7: saved_upcall_mask + setz %ch # %ch == !saved_upcall_mask + movl UREGS_eflags+8(%rsp),%eax + andl $~X86_EFLAGS_IF,%eax + shlb $1,%ch # Bit 9 (EFLAGS.IF) + orb %ch,%ah # Fold EFLAGS.IF into %eax +CFLT6: movl %eax,%fs:2*4(%rsi) # EFLAGS + movl UREGS_rip+8(%rsp),%eax +CFLT7: movl %eax,%fs:(%rsi) # EIP + testb $TBF_EXCEPTION_ERRCODE,%cl + jz 1f + subl $4,%esi + movl TRAPBOUNCE_error_code(%rdx),%eax +CFLT8: movl %eax,%fs:(%rsi) # ERROR CODE +1: + testb $TBF_FAILSAFE,%cl + jz 2f + subl $4*4,%esi + movl %gs,%eax +CFLT9: movl %eax,%fs:3*4(%rsi) # GS +CFLT10: movl %edi,%fs:2*4(%rsi) # FS + movl %es,%eax +CFLT11: movl %eax,%fs:1*4(%rsi) # ES + movl %ds,%eax +CFLT12: movl %eax,%fs:0*4(%rsi) # DS +2: + /* Rewrite our stack frame and return to guest-OS mode. */ + /* IA32 Ref. Vol. 3: TF, VM, RF and NT flags are cleared on trap. */ + movl $TRAP_syscall,UREGS_entry_vector+8(%rsp) + andl $~(X86_EFLAGS_VM|X86_EFLAGS_RF|\ + X86_EFLAGS_NT|X86_EFLAGS_TF),UREGS_eflags+8(%rsp) + mov %fs,UREGS_ss+8(%rsp) + movl %esi,UREGS_rsp+8(%rsp) +CFLT13: mov %edi,%fs + movzwl TRAPBOUNCE_cs(%rdx),%eax + /* Null selectors (0-3) are not allowed. */ + testl $~3,%eax + jz domain_crash_synchronous + movl %eax,UREGS_cs+8(%rsp) + movl TRAPBOUNCE_eip(%rdx),%eax + movl %eax,UREGS_rip+8(%rsp) + movb $0,TRAPBOUNCE_flags(%rdx) + ret +.section .fixup,"ax" +CFIX13: + xorl %edi,%edi + jmp CFLT13 +.previous +.section __ex_table,"a" + .quad CFLT1,domain_crash_synchronous , CFLT2,compat_crash_page_fault + .quad CFLT3,compat_crash_page_fault_4 , CFLT4,domain_crash_synchronous + .quad CFLT5,compat_crash_page_fault_4 , CFLT6,compat_crash_page_fault_8 + .quad CFLT7,compat_crash_page_fault , CFLT8,compat_crash_page_fault + .quad CFLT9,compat_crash_page_fault_12, CFLT10,compat_crash_page_fault_8 + .quad CFLT11,compat_crash_page_fault_4 , CFLT12,compat_crash_page_fault + .quad CFLT13,CFIX13 +.previous + +compat_crash_page_fault_12: + addl $4,%esi +compat_crash_page_fault_8: + addl $4,%esi +compat_crash_page_fault_4: + addl $4,%esi +compat_crash_page_fault: +CFLT14: mov %edi,%fs + movl %esi,%edi + call show_page_walk + jmp domain_crash_synchronous +.section .fixup,"ax" +CFIX14: + xorl %edi,%edi + jmp CFLT14 +.previous +.section __ex_table,"a" + .quad CFLT14,CFIX14 +.previous + +.section .rodata, "a", @progbits + +#define compat_set_trap_table domain_crash_synchronous +#define compat_mmu_update domain_crash_synchronous +#define compat_set_gdt domain_crash_synchronous +#define compat_stack_switch domain_crash_synchronous +#define compat_fpu_taskswitch domain_crash_synchronous +#define compat_arch_sched_op_compat domain_crash_synchronous +#define compat_platform_op domain_crash_synchronous +#define compat_set_debugreg domain_crash_synchronous +#define compat_get_debugreg domain_crash_synchronous +#define compat_update_descriptor domain_crash_synchronous +#define compat_memory_op domain_crash_synchronous +#define compat_multicall domain_crash_synchronous +#define compat_update_va_mapping domain_crash_synchronous +#define compat_set_timer_op domain_crash_synchronous +#define compat_event_channel_op_compat domain_crash_synchronous +#define compat_xen_version domain_crash_synchronous +#define compat_console_io domain_crash_synchronous +#define compat_physdev_op_compat domain_crash_synchronous +#define compat_grant_table_op domain_crash_synchronous +#define compat_vm_assist domain_crash_synchronous +#define compat_update_va_mapping_otherdomain domain_crash_synchronous +#define compat_vcpu_op domain_crash_synchronous +#define compat_mmuext_op domain_crash_synchronous +#define compat_acm_op domain_crash_synchronous +#define compat_nmi_op domain_crash_synchronous +#define compat_arch_sched_op domain_crash_synchronous +#define compat_xenoprof_op domain_crash_synchronous +#define compat_event_channel_op domain_crash_synchronous +#define compat_physdev_op domain_crash_synchronous +#define compat_sysctl domain_crash_synchronous +#define compat_domctl domain_crash_synchronous + +ENTRY(compat_hypercall_table) + .quad compat_set_trap_table /* 0 */ + .quad compat_mmu_update + .quad compat_set_gdt + .quad compat_stack_switch + .quad compat_set_callbacks + .quad compat_fpu_taskswitch /* 5 */ + .quad compat_arch_sched_op_compat + .quad compat_platform_op + .quad compat_set_debugreg + .quad compat_get_debugreg + .quad compat_update_descriptor /* 10 */ + .quad do_ni_hypercall + .quad compat_memory_op + .quad compat_multicall + .quad compat_update_va_mapping + .quad compat_set_timer_op /* 15 */ + .quad compat_event_channel_op_compat + .quad compat_xen_version + .quad compat_console_io + .quad compat_physdev_op_compat + .quad compat_grant_table_op /* 20 */ + .quad compat_vm_assist + .quad compat_update_va_mapping_otherdomain + .quad compat_iret + .quad compat_vcpu_op + .quad do_ni_hypercall /* 25 */ + .quad compat_mmuext_op + .quad compat_acm_op + .quad compat_nmi_op + .quad compat_arch_sched_op + .quad compat_callback_op /* 30 */ + .quad compat_xenoprof_op + .quad compat_event_channel_op + .quad compat_physdev_op + .quad do_ni_hypercall + .quad compat_sysctl /* 35 */ + .quad compat_domctl + .rept NR_hypercalls-((.-compat_hypercall_table)/8) + .quad do_ni_hypercall + .endr + +ENTRY(compat_hypercall_args_table) + .byte 1 /* compat_set_trap_table */ /* 0 */ + .byte 4 /* compat_mmu_update */ + .byte 2 /* compat_set_gdt */ + .byte 2 /* compat_stack_switch */ + .byte 4 /* compat_set_callbacks */ + .byte 1 /* compat_fpu_taskswitch */ /* 5 */ + .byte 2 /* compat_arch_sched_op_compat */ + .byte 1 /* compat_platform_op */ + .byte 2 /* compat_set_debugreg */ + .byte 1 /* compat_get_debugreg */ + .byte 4 /* compat_update_descriptor */ /* 10 */ + .byte 0 /* do_ni_hypercall */ + .byte 2 /* compat_memory_op */ + .byte 2 /* compat_multicall */ + .byte 4 /* compat_update_va_mapping */ + .byte 2 /* compat_set_timer_op */ /* 15 */ + .byte 1 /* compat_event_channel_op_compat */ + .byte 2 /* compat_xen_version */ + .byte 3 /* compat_console_io */ + .byte 1 /* compat_physdev_op_compat */ + .byte 3 /* compat_grant_table_op */ /* 20 */ + .byte 2 /* compat_vm_assist */ + .byte 5 /* compat_update_va_mapping_otherdomain */ + .byte 0 /* compat_iret */ + .byte 3 /* compat_vcpu_op */ + .byte 0 /* do_ni_hypercall */ /* 25 */ + .byte 4 /* compat_mmuext_op */ + .byte 1 /* compat_acm_op */ + .byte 2 /* compat_nmi_op */ + .byte 2 /* compat_arch_sched_op */ + .byte 2 /* compat_callback_op */ /* 30 */ + .byte 2 /* compat_xenoprof_op */ + .byte 2 /* compat_event_channel_op */ + .byte 2 /* compat_physdev_op */ + .byte 0 /* do_ni_hypercall */ + .byte 1 /* compat_sysctl */ /* 35 */ + .byte 1 /* compat_domctl */ + .rept NR_hypercalls-(.-compat_hypercall_args_table) + .byte 0 /* do_ni_hypercall */ + .endr diff --git a/xen/arch/x86/x86_64/compat/traps.c b/xen/arch/x86/x86_64/compat/traps.c new file mode 100644 index 0000000000..ca0d8b46b5 --- /dev/null +++ b/xen/arch/x86/x86_64/compat/traps.c @@ -0,0 +1,312 @@ +#ifdef CONFIG_COMPAT + +#if 0 /* XXX */ +#include +#else +struct compat_xen_callback { + unsigned int cs; + unsigned int eip; +}; +typedef struct compat_xen_callback xen_callback_compat_t; + +struct compat_callback_register { + uint16_t type; + uint16_t flags; + xen_callback_compat_t address; +}; + +struct compat_callback_unregister { + uint16_t type; + uint16_t _unused; +}; +#endif + +void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines) +{ + unsigned int i, *stack, addr; + + stack = (unsigned int *)(unsigned long)regs->_esp; + printk("Guest stack trace from esp=%08lx:\n ", (unsigned long)stack); + + for ( i = 0; i < debug_stack_lines * 8; i++ ) + { + if ( (((long)stack + 3) & (STACK_SIZE - 4)) == 0 ) + break; + if ( get_user(addr, stack) ) + { + if ( i != 0 ) + printk("\n "); + printk("Fault while accessing guest memory."); + i = 1; + break; + } + if ( (i != 0) && ((i % 8) == 0) ) + printk("\n "); + printk(" %08x", addr); + stack++; + } + if ( i == 0 ) + printk("Stack empty."); + printk("\n"); +} + +unsigned int compat_iret(void) +{ + struct cpu_user_regs *regs = guest_cpu_user_regs(); + u32 eflags; + + /* Restore EAX (clobbered by hypercall). */ + if ( unlikely(__get_user(regs->_eax, (u32 __user *)regs->rsp)) ) + goto exit_and_crash; + + /* Restore CS and EIP. */ + if ( unlikely(__get_user(regs->_eip, (u32 __user *)regs->rsp + 1)) || + unlikely(__get_user(regs->cs, (u32 __user *)regs->rsp + 2)) ) + goto exit_and_crash; + + /* + * Fix up and restore EFLAGS. We fix up in a local staging area + * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt. + */ + if ( unlikely(__get_user(eflags, (u32 __user *)regs->rsp + 3)) ) + goto exit_and_crash; + regs->_eflags = (eflags & ~X86_EFLAGS_IOPL) | X86_EFLAGS_IF; + + if ( unlikely(eflags & X86_EFLAGS_VM) ) + { + /* + * Cannot return to VM86 mode: inject a GP fault instead. Note that + * the GP fault is reported on the first VM86 mode instruction, not on + * the IRET (which is why we can simply leave the stack frame as-is + * (except for perhaps having to copy it), which in turn seems better + * than teaching create_bounce_frame() to needlessly deal with vm86 + * mode frames). + */ + const struct trap_info *ti; + u32 x, ksp = current->arch.guest_context.kernel_sp - 40; + unsigned int i; + int rc = 0; + + gdprintk(XENLOG_ERR, "VM86 mode unavailable (ksp:%08X->%08X)\n", + regs->_esp, ksp); + if ( ksp < regs->_esp ) + { + for (i = 1; i < 10; ++i) + { + rc |= __get_user(x, (u32 __user *)regs->rsp + i); + rc |= __put_user(x, (u32 __user *)(unsigned long)ksp + i); + } + } + else if ( ksp > regs->_esp ) + { + for (i = 9; i > 0; ++i) + { + rc |= __get_user(x, (u32 __user *)regs->rsp + i); + rc |= __put_user(x, (u32 __user *)(unsigned long)ksp + i); + } + } + if ( rc ) + goto exit_and_crash; + regs->_esp = ksp; + regs->ss = current->arch.guest_context.kernel_ss; + + ti = ¤t->arch.guest_context.trap_ctxt[13]; + if ( TI_GET_IF(ti) ) + eflags &= ~X86_EFLAGS_IF; + regs->_eflags = eflags & ~(X86_EFLAGS_VM|X86_EFLAGS_RF| + X86_EFLAGS_NT|X86_EFLAGS_TF); + + if ( unlikely(__put_user(0, (u32 __user *)regs->rsp)) ) + goto exit_and_crash; + regs->_eip = ti->address; + regs->cs = ti->cs; + } + else if ( unlikely(ring_0(regs)) ) + goto exit_and_crash; + else if ( !ring_1(regs) ) + { + /* Return to ring 2/3: restore ESP and SS. */ + if ( __get_user(regs->ss, (u32 __user *)regs->rsp + 5) + || __get_user(regs->_esp, (u32 __user *)regs->rsp + 4)) + goto exit_and_crash; + } + else + regs->_esp += 16; + + /* No longer in NMI context. */ + clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags); + + /* Restore upcall mask from supplied EFLAGS.IF. */ + current->vcpu_info->evtchn_upcall_mask = !(eflags & X86_EFLAGS_IF); + + /* + * The hypercall exit path will overwrite EAX with this return + * value. + */ + return regs->_eax; + + exit_and_crash: + gdprintk(XENLOG_ERR, "Fatal error\n"); + domain_crash(current->domain); + return 0; +} + +static long compat_register_guest_callback(struct compat_callback_register *reg) +{ + long ret = 0; + struct vcpu *v = current; + + fixup_guest_code_selector(v->domain, reg->address.cs); + + switch ( reg->type ) + { + case CALLBACKTYPE_event: + v->arch.guest_context.event_callback_cs = reg->address.cs; + v->arch.guest_context.event_callback_eip = reg->address.eip; + break; + + case CALLBACKTYPE_failsafe: + v->arch.guest_context.failsafe_callback_cs = reg->address.cs; + v->arch.guest_context.failsafe_callback_eip = reg->address.eip; + if ( reg->flags & CALLBACKF_mask_events ) + set_bit(_VGCF_failsafe_disables_events, + &v->arch.guest_context.flags); + else + clear_bit(_VGCF_failsafe_disables_events, + &v->arch.guest_context.flags); + break; + + case CALLBACKTYPE_nmi: + ret = register_guest_nmi_callback(reg->address.eip); + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +static long compat_unregister_guest_callback(struct compat_callback_unregister *unreg) +{ + long ret; + + switch ( unreg->type ) + { + case CALLBACKTYPE_nmi: + ret = unregister_guest_nmi_callback(); + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + + +long compat_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg) +{ + long ret; + + switch ( cmd ) + { + case CALLBACKOP_register: + { + struct compat_callback_register reg; + + ret = -EFAULT; + if ( copy_from_guest(®, arg, 1) ) + break; + + ret = compat_register_guest_callback(®); + } + break; + + case CALLBACKOP_unregister: + { + struct compat_callback_unregister unreg; + + ret = -EFAULT; + if ( copy_from_guest(&unreg, arg, 1) ) + break; + + ret = compat_unregister_guest_callback(&unreg); + } + break; + + default: + ret = -EINVAL; + break; + } + + return ret; +} + +long compat_set_callbacks(unsigned long event_selector, + unsigned long event_address, + unsigned long failsafe_selector, + unsigned long failsafe_address) +{ + struct compat_callback_register event = { + .type = CALLBACKTYPE_event, + .address = { + .cs = event_selector, + .eip = event_address + } + }; + struct compat_callback_register failsafe = { + .type = CALLBACKTYPE_failsafe, + .address = { + .cs = failsafe_selector, + .eip = failsafe_address + } + }; + + compat_register_guest_callback(&event); + compat_register_guest_callback(&failsafe); + + return 0; +} + +#endif /* CONFIG_COMPAT */ + +static void hypercall_page_initialise_ring1_kernel(void *hypercall_page) +{ + char *p; + int i; + + /* Fill in all the transfer points with template machine code. */ + + for ( i = 0; i < (PAGE_SIZE / 32); i++ ) + { + p = (char *)(hypercall_page + (i * 32)); + *(u8 *)(p+ 0) = 0xb8; /* mov $,%eax */ + *(u32 *)(p+ 1) = i; + *(u16 *)(p+ 5) = 0x82cd; /* int $0x82 */ + *(u8 *)(p+ 7) = 0xc3; /* ret */ + } + + /* + * HYPERVISOR_iret is special because it doesn't return and expects a + * special stack frame. Guests jump at this transfer point instead of + * calling it. + */ + p = (char *)(hypercall_page + (__HYPERVISOR_iret * 32)); + *(u8 *)(p+ 0) = 0x50; /* push %eax */ + *(u8 *)(p+ 1) = 0xb8; /* mov $__HYPERVISOR_iret,%eax */ + *(u32 *)(p+ 2) = __HYPERVISOR_iret; + *(u16 *)(p+ 6) = 0x82cd; /* int $0x82 */ +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S index b28b644c33..24f7ea6eb5 100644 --- a/xen/arch/x86/x86_64/entry.S +++ b/xen/arch/x86/x86_64/entry.S @@ -324,7 +324,16 @@ domain_crash_synchronous: GET_GUEST_REGS(%rax) movq %rax,%rsp # create_bounce_frame() temporarily clobbers CS.RPL. Fix up. +#ifdef CONFIG_COMPAT + movq CPUINFO_current_vcpu(%rax),%rax + movq VCPU_domain(%rax),%rax + btl $_DOMF_compat,DOMAIN_domain_flags(%rax) + setnc %al + leal (%rax,%rax,2),%eax + orb %al,UREGS_cs(%rsp) +#else orb $3,UREGS_cs(%rsp) +#endif # printk(domain_crash_synchronous_string) leaq domain_crash_synchronous_string(%rip),%rdi xorl %eax,%eax @@ -336,8 +345,15 @@ domain_crash_synchronous: ENTRY(ret_from_intr) GET_CURRENT(%rbx) testb $3,UREGS_cs(%rsp) - jnz test_all_events - jmp restore_all_xen + jz restore_all_xen +#ifndef CONFIG_COMPAT + jmp test_all_events +#else + movq VCPU_domain(%rbx),%rax + btl $_DOMF_compat,DOMAIN_domain_flags(%rax) + jnc test_all_events + jmp compat_test_all_events +#endif ALIGN /* No special register assumptions. */ @@ -355,6 +371,11 @@ handle_exception: testb $3,UREGS_cs(%rsp) jz restore_all_xen leaq VCPU_trap_bounce(%rbx),%rdx +#ifdef CONFIG_COMPAT + movq VCPU_domain(%rbx),%rax + btl $_DOMF_compat,DOMAIN_domain_flags(%rax) + jc compat_post_handle_exception +#endif testb $TBF_EXCEPTION,TRAPBOUNCE_flags(%rdx) jz test_all_events call create_bounce_frame @@ -612,3 +633,7 @@ ENTRY(hypercall_args_table) .rept NR_hypercalls-(.-hypercall_args_table) .byte 0 /* do_ni_hypercall */ .endr + +#ifdef CONFIG_COMPAT +#include "compat/entry.S" +#endif diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 9c4a998006..8ec8934815 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -246,6 +246,7 @@ unsigned long do_iret(void) } asmlinkage void syscall_enter(void); +asmlinkage void compat_hypercall(void); void __init percpu_traps_init(void) { char *stack_bottom, *stack; @@ -257,6 +258,11 @@ void __init percpu_traps_init(void) set_intr_gate(TRAP_double_fault, &double_fault); idt_table[TRAP_double_fault].a |= 1UL << 32; /* IST1 */ idt_table[TRAP_nmi].a |= 2UL << 32; /* IST2 */ + +#ifdef CONFIG_COMPAT + /* The hypercall entry vector is only accessible from ring 1. */ + _set_gate(idt_table+HYPERCALL_VECTOR, 15, 1, &compat_hypercall); +#endif } stack_bottom = (char *)get_stack_bottom(); @@ -503,12 +509,16 @@ static void hypercall_page_initialise_ring3_kernel(void *hypercall_page) *(u16 *)(p+ 9) = 0x050f; /* syscall */ } +#include "compat/traps.c" + void hypercall_page_initialise(struct domain *d, void *hypercall_page) { if ( is_hvm_domain(d) ) hvm_hypercall_page_initialise(d, hypercall_page); - else + else if ( !IS_COMPAT(d) ) hypercall_page_initialise_ring3_kernel(hypercall_page); + else + hypercall_page_initialise_ring1_kernel(hypercall_page); } /* diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h index 7a18e0d3d7..0d1d2533ce 100644 --- a/xen/include/asm-x86/processor.h +++ b/xen/include/asm-x86/processor.h @@ -559,6 +559,12 @@ void show_execution_state(struct cpu_user_regs *regs); void show_page_walk(unsigned long addr); asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs); +#ifdef CONFIG_COMPAT +void compat_show_guest_stack(struct cpu_user_regs *, int lines); +#else +#define compat_show_guest_stack(regs, lines) ((void)0) +#endif + /* Dumps current register and stack state. */ #define dump_execution_state() \ /* NB. Needs interrupts enabled else we end up in fatal_trap(). */ \ From 6224725e9357f6056cff046ba5da4c52f0bace8c Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:28 +0000 Subject: [PATCH 076/570] Add logic to generate headers reflecting the compatibility mode layout of hypercall arguments. Provide infrastructure for accessing handles passed from compatibility mode guests. Vector those hypercalls not needing any translation to their native implementations. Signed-off-by: Jan Beulich --- xen/Makefile | 2 + xen/Rules.mk | 1 + xen/arch/x86/x86_64/compat/entry.S | 39 +++---- xen/arch/x86/x86_64/compat/traps.c | 19 --- xen/common/Makefile | 2 + xen/common/compat/Makefile | 4 + xen/common/compat/kernel.c | 59 ++++++++++ xen/common/kernel.c | 19 ++- xen/include/Makefile | 57 +++++++++ xen/include/asm-x86/compat.h | 6 + xen/include/asm-x86/x86_64/uaccess.h | 13 +++ xen/include/xen/compat.h | 167 +++++++++++++++++++++++++++ 12 files changed, 341 insertions(+), 47 deletions(-) create mode 100644 xen/common/compat/Makefile create mode 100644 xen/common/compat/kernel.c create mode 100644 xen/include/Makefile create mode 100644 xen/include/asm-x86/compat.h create mode 100644 xen/include/xen/compat.h diff --git a/xen/Makefile b/xen/Makefile index dcd1b0934e..b391513ccc 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -48,6 +48,7 @@ _debug: .PHONY: _clean _clean: delete-unfresh-files $(MAKE) -C tools clean + $(MAKE) -f $(BASEDIR)/Rules.mk -C include clean $(MAKE) -f $(BASEDIR)/Rules.mk -C common clean $(MAKE) -f $(BASEDIR)/Rules.mk -C drivers clean $(MAKE) -f $(BASEDIR)/Rules.mk -C acm clean @@ -69,6 +70,7 @@ $(TARGET): delete-unfresh-files $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/compile.h $(MAKE) -f $(BASEDIR)/Rules.mk include/xen/acm_policy.h [ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm + $(MAKE) -f $(BASEDIR)/Rules.mk -C include $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) asm-offsets.s $(MAKE) -f $(BASEDIR)/Rules.mk include/asm-$(TARGET_ARCH)/asm-offsets.h $(MAKE) -f $(BASEDIR)/Rules.mk -C arch/$(TARGET_ARCH) $(TARGET) diff --git a/xen/Rules.mk b/xen/Rules.mk index 08c26aca44..28ee66b64d 100644 --- a/xen/Rules.mk +++ b/xen/Rules.mk @@ -34,6 +34,7 @@ TARGET := $(BASEDIR)/xen HDRS := $(wildcard $(BASEDIR)/include/xen/*.h) HDRS += $(wildcard $(BASEDIR)/include/public/*.h) +HDRS += $(wildcard $(BASEDIR)/include/compat/*.h) HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/*.h) HDRS += $(wildcard $(BASEDIR)/include/asm-$(TARGET_ARCH)/$(TARGET_SUBARCH)/*.h) diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 98c184a051..0b79fd708f 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -281,28 +281,19 @@ CFIX14: #define compat_set_trap_table domain_crash_synchronous #define compat_mmu_update domain_crash_synchronous #define compat_set_gdt domain_crash_synchronous -#define compat_stack_switch domain_crash_synchronous -#define compat_fpu_taskswitch domain_crash_synchronous -#define compat_arch_sched_op_compat domain_crash_synchronous #define compat_platform_op domain_crash_synchronous -#define compat_set_debugreg domain_crash_synchronous -#define compat_get_debugreg domain_crash_synchronous #define compat_update_descriptor domain_crash_synchronous #define compat_memory_op domain_crash_synchronous #define compat_multicall domain_crash_synchronous #define compat_update_va_mapping domain_crash_synchronous #define compat_set_timer_op domain_crash_synchronous #define compat_event_channel_op_compat domain_crash_synchronous -#define compat_xen_version domain_crash_synchronous -#define compat_console_io domain_crash_synchronous #define compat_physdev_op_compat domain_crash_synchronous #define compat_grant_table_op domain_crash_synchronous -#define compat_vm_assist domain_crash_synchronous #define compat_update_va_mapping_otherdomain domain_crash_synchronous #define compat_vcpu_op domain_crash_synchronous #define compat_mmuext_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous -#define compat_nmi_op domain_crash_synchronous #define compat_arch_sched_op domain_crash_synchronous #define compat_xenoprof_op domain_crash_synchronous #define compat_event_channel_op domain_crash_synchronous @@ -314,29 +305,29 @@ ENTRY(compat_hypercall_table) .quad compat_set_trap_table /* 0 */ .quad compat_mmu_update .quad compat_set_gdt - .quad compat_stack_switch + .quad do_stack_switch .quad compat_set_callbacks - .quad compat_fpu_taskswitch /* 5 */ - .quad compat_arch_sched_op_compat + .quad do_fpu_taskswitch /* 5 */ + .quad do_sched_op_compat .quad compat_platform_op - .quad compat_set_debugreg - .quad compat_get_debugreg + .quad do_set_debugreg + .quad do_get_debugreg .quad compat_update_descriptor /* 10 */ - .quad do_ni_hypercall + .quad compat_ni_hypercall .quad compat_memory_op .quad compat_multicall .quad compat_update_va_mapping .quad compat_set_timer_op /* 15 */ .quad compat_event_channel_op_compat .quad compat_xen_version - .quad compat_console_io + .quad do_console_io .quad compat_physdev_op_compat .quad compat_grant_table_op /* 20 */ .quad compat_vm_assist .quad compat_update_va_mapping_otherdomain .quad compat_iret .quad compat_vcpu_op - .quad do_ni_hypercall /* 25 */ + .quad compat_ni_hypercall /* 25 */ .quad compat_mmuext_op .quad compat_acm_op .quad compat_nmi_op @@ -345,11 +336,11 @@ ENTRY(compat_hypercall_table) .quad compat_xenoprof_op .quad compat_event_channel_op .quad compat_physdev_op - .quad do_ni_hypercall + .quad compat_ni_hypercall .quad compat_sysctl /* 35 */ .quad compat_domctl .rept NR_hypercalls-((.-compat_hypercall_table)/8) - .quad do_ni_hypercall + .quad compat_ni_hypercall .endr ENTRY(compat_hypercall_args_table) @@ -359,12 +350,12 @@ ENTRY(compat_hypercall_args_table) .byte 2 /* compat_stack_switch */ .byte 4 /* compat_set_callbacks */ .byte 1 /* compat_fpu_taskswitch */ /* 5 */ - .byte 2 /* compat_arch_sched_op_compat */ + .byte 2 /* compat_sched_op_compat */ .byte 1 /* compat_platform_op */ .byte 2 /* compat_set_debugreg */ .byte 1 /* compat_get_debugreg */ .byte 4 /* compat_update_descriptor */ /* 10 */ - .byte 0 /* do_ni_hypercall */ + .byte 0 /* compat_ni_hypercall */ .byte 2 /* compat_memory_op */ .byte 2 /* compat_multicall */ .byte 4 /* compat_update_va_mapping */ @@ -378,7 +369,7 @@ ENTRY(compat_hypercall_args_table) .byte 5 /* compat_update_va_mapping_otherdomain */ .byte 0 /* compat_iret */ .byte 3 /* compat_vcpu_op */ - .byte 0 /* do_ni_hypercall */ /* 25 */ + .byte 0 /* compat_ni_hypercall */ /* 25 */ .byte 4 /* compat_mmuext_op */ .byte 1 /* compat_acm_op */ .byte 2 /* compat_nmi_op */ @@ -387,9 +378,9 @@ ENTRY(compat_hypercall_args_table) .byte 2 /* compat_xenoprof_op */ .byte 2 /* compat_event_channel_op */ .byte 2 /* compat_physdev_op */ - .byte 0 /* do_ni_hypercall */ + .byte 0 /* compat_ni_hypercall */ .byte 1 /* compat_sysctl */ /* 35 */ .byte 1 /* compat_domctl */ .rept NR_hypercalls-(.-compat_hypercall_args_table) - .byte 0 /* do_ni_hypercall */ + .byte 0 /* compat_ni_hypercall */ .endr diff --git a/xen/arch/x86/x86_64/compat/traps.c b/xen/arch/x86/x86_64/compat/traps.c index ca0d8b46b5..a368748b1a 100644 --- a/xen/arch/x86/x86_64/compat/traps.c +++ b/xen/arch/x86/x86_64/compat/traps.c @@ -1,25 +1,6 @@ #ifdef CONFIG_COMPAT -#if 0 /* XXX */ #include -#else -struct compat_xen_callback { - unsigned int cs; - unsigned int eip; -}; -typedef struct compat_xen_callback xen_callback_compat_t; - -struct compat_callback_register { - uint16_t type; - uint16_t flags; - xen_callback_compat_t address; -}; - -struct compat_callback_unregister { - uint16_t type; - uint16_t _unused; -}; -#endif void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines) { diff --git a/xen/common/Makefile b/xen/common/Makefile index 017348e065..680fd60b8c 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -35,5 +35,7 @@ obj-$(xenoprof) += xenoprof.o obj-$(CONFIG_XENCOMM) += xencomm.o +subdir-$(CONFIG_COMPAT) += compat + # Object file contains changeset and compiler information. version.o: $(BASEDIR)/include/xen/compile.h diff --git a/xen/common/compat/Makefile b/xen/common/compat/Makefile new file mode 100644 index 0000000000..39e1c8ee3d --- /dev/null +++ b/xen/common/compat/Makefile @@ -0,0 +1,4 @@ +obj-y += kernel.o + +# extra dependencies +kernel.o: ../kernel.c diff --git a/xen/common/compat/kernel.c b/xen/common/compat/kernel.c new file mode 100644 index 0000000000..0618dbe8ad --- /dev/null +++ b/xen/common/compat/kernel.c @@ -0,0 +1,59 @@ +/****************************************************************************** + * kernel.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define xen_extraversion compat_extraversion +#define xen_extraversion_t compat_extraversion_t + +#define xen_compile_info compat_compile_info +#define xen_compile_info_t compat_compile_info_t + +CHECK_TYPE(capabilities_info); + +#define xen_platform_parameters compat_platform_parameters +#define xen_platform_parameters_t compat_platform_parameters_t +#undef HYPERVISOR_VIRT_START +#define HYPERVISOR_VIRT_START HYPERVISOR_COMPAT_VIRT_START + +#define xen_changeset_info compat_changeset_info +#define xen_changeset_info_t compat_changeset_info_t + +#define xen_feature_info compat_feature_info +#define xen_feature_info_t compat_feature_info_t + +CHECK_TYPE(domain_handle); + +#define xennmi_callback compat_nmi_callback +#define xennmi_callback_t compat_nmi_callback_t + +#define DO(fn) int compat_##fn +#define COMPAT + +#include "../kernel.c" + +int compat_disabled = 0; +boolean_param("no-pv-compat", compat_disabled); + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/kernel.c b/xen/common/kernel.c index 9dc321325e..bf46640526 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -11,11 +11,14 @@ #include #include #include +#include #include #include #include #include +#ifndef COMPAT + int tainted; void cmdline_parse(char *cmdline) @@ -116,11 +119,15 @@ void add_taint(unsigned flag) tainted |= flag; } +# define DO(fn) long do_##fn + +#endif + /* * Simple hypercalls. */ -long do_xen_version(int cmd, XEN_GUEST_HANDLE(void) arg) +DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg) { switch ( cmd ) { @@ -230,6 +237,8 @@ long do_xen_version(int cmd, XEN_GUEST_HANDLE(void) arg) return -ENOSYS; } +#ifndef COMPAT + long register_guest_nmi_callback(unsigned long address) { struct vcpu *v = current; @@ -260,7 +269,9 @@ long unregister_guest_nmi_callback(void) return 0; } -long do_nmi_op(unsigned int cmd, XEN_GUEST_HANDLE(void) arg) +#endif + +DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg) { struct xennmi_callback cb; long rc = 0; @@ -284,12 +295,12 @@ long do_nmi_op(unsigned int cmd, XEN_GUEST_HANDLE(void) arg) return rc; } -long do_vm_assist(unsigned int cmd, unsigned int type) +DO(vm_assist)(unsigned int cmd, unsigned int type) { return vm_assist(current->domain, cmd, type); } -long do_ni_hypercall(void) +DO(ni_hypercall)(void) { /* No-op hypercall. */ return -ENOSYS; diff --git a/xen/include/Makefile b/xen/include/Makefile new file mode 100644 index 0000000000..1cc0d79baf --- /dev/null +++ b/xen/include/Makefile @@ -0,0 +1,57 @@ +ifneq ($(CONFIG_COMPAT),) + +compat-arch-$(CONFIG_X86) := x86_32 + +headers-y := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g') +headers-y := $(filter-out %/dom0_ops.h,$(headers-y)) +headers-y += compat/arch-$(compat-arch-y).h + +cppflags-y := -include public/xen-compat.h +cppflags-$(CONFIG_X86) += -m32 + +# 8-byte types are 4-byte aligned on x86_32 ... +prefix-$(CONFIG_X86) := \#pragma pack(push, 4) +suffix-$(CONFIG_X86) := \#pragma pack(pop) + +endif + +.PHONY: all +all: $(headers-y) + +compat/%.h: compat/%.i Makefile + id=_$$(echo $@ | sed 'y,abcdefghijklmnopqrstuvwxyz-/.,ABCDEFGHIJKLMNOPQRSTUVWXYZ___,'); \ + echo "#ifndef $$id" >$@.new; \ + echo "#define $$id" >>$@.new; \ + echo "#include " >>$@.new; \ + $(if $(filter-out compat/arch-%.h,$@),echo "#include <$(patsubst compat/%,public/%,$@)>" >>$@.new;) \ + $(if $(prefix-y),echo "$(prefix-y)" >>$@.new;) \ + grep -v '^# [[:digit:]]' $< | \ + sed -e 's,__InClUdE__,#include,' \ + -e 's,"xen-compat.h",,' \ + -e 's,\(struct\|union\|enum\)[[:space:]]\+\(xen_\?\)\?\([[:alpha:]_]\),\1 compat_\3,g' \ + -e 's,_t\([^[:alnum:]_]\|$$\),_compat_t\1,g' \ + -e 's,\(8\|16\|32\|64\)_compat_t\([^[:alnum:]_]\|$$\),\1_t\2,g' \ + -e 's,\(^\|[^[:alnum:]_]\)xen_\?\([[:alnum:]_]*\)_compat_t\([^[:alnum:]_]\|$$\),\1compat_\2_t\3,g' \ + -e 's,\(^\|[^[:alnum:]_]\)XEN_\?,\1COMPAT_,' \ + -e 's,\(^\|[^[:alnum:]_]\)Xen_\?,\1Compat_,' \ + -e 's,\(^\|[^[:alnum:]]\)long\([^[:alnum:]]\|$$\),\1int\2,g' | \ + uniq >>$@.new; \ + $(if $(suffix-y),echo "$(suffix-y)" >>$@.new;) \ + echo "#endif /* $$id */" >>$@.new + mv -f $@.new $@ + +compat/%.i: compat/%.c Makefile + $(CPP) $(CFLAGS) $(cppflags-y) -o $@ $< + +compat/%.c: public/%.h Makefile + mkdir -p $(@D) + grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \ + sed -e 's,^[[:space:]]*#[[:space:]]*include[[:space:]]\+,__InClUdE__ ,' \ + -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:upper:]_]*_GUEST_HANDLE\),#define HIDE_\1,' \ + -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:lower:]_]*_guest_handle\),#define hide_\1,' \ + -e 's,XEN_GUEST_HANDLE\(_[[:xdigit:]]\+\)\?,COMPAT_HANDLE,g' \ + >$@.new + mv -f $@.new $@ + +clean:: + rm -rf compat diff --git a/xen/include/asm-x86/compat.h b/xen/include/asm-x86/compat.h new file mode 100644 index 0000000000..37a0cffdc2 --- /dev/null +++ b/xen/include/asm-x86/compat.h @@ -0,0 +1,6 @@ +/****************************************************************************** + * compat.h + */ + +typedef uint32_t compat_ptr_t; +typedef unsigned long full_ptr_t; diff --git a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h index 4d5f65c890..c51e1a8739 100644 --- a/xen/include/asm-x86/x86_64/uaccess.h +++ b/xen/include/asm-x86/x86_64/uaccess.h @@ -15,6 +15,19 @@ #define array_access_ok(addr, count, size) (__addr_ok(addr)) +#ifdef CONFIG_COMPAT + +#define __compat_addr_ok(addr) \ + ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START) + +#define compat_access_ok(addr, size) __compat_addr_ok((addr) + (size)) + +#define compat_array_access_ok(addr,count,size) \ + (likely((count) < (~0U / (size))) && \ + compat_access_ok(addr, (count) * (size))) + +#endif + #define __put_user_size(x,ptr,size,retval,errret) \ do { \ retval = 0; \ diff --git a/xen/include/xen/compat.h b/xen/include/xen/compat.h new file mode 100644 index 0000000000..375ba39352 --- /dev/null +++ b/xen/include/xen/compat.h @@ -0,0 +1,167 @@ +/****************************************************************************** + * compat.h + */ + +#ifndef __XEN_COMPAT_H__ +#define __XEN_COMPAT_H__ + +#include + +#ifdef CONFIG_COMPAT + +#include +#include +#include + +#define __DEFINE_COMPAT_HANDLE(name, type) \ + typedef struct { \ + compat_ptr_t c; \ + type *_[0] __attribute__((__packed__)); \ + } __compat_handle_ ## name + +#define DEFINE_COMPAT_HANDLE(name) __DEFINE_COMPAT_HANDLE(name, name) +#define COMPAT_HANDLE(name) __compat_handle_ ## name + +/* Is the compat handle a NULL reference? */ +#define compat_handle_is_null(hnd) ((hnd).c == 0) + +/* Offset the given compat handle into the array it refers to. */ +#define compat_handle_add_offset(hnd, nr) \ + ((hnd).c += (nr) * sizeof(**(hnd)._)) + +/* Cast a compat handle to the specified type of handle. */ +#define compat_handle_cast(chnd, type) ({ \ + type *_x = (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c; \ + (XEN_GUEST_HANDLE(type)) { _x }; \ +}) + +#define guest_from_compat_handle(ghnd, chnd) \ + set_xen_guest_handle(ghnd, \ + (__typeof__(**(chnd)._) *)(full_ptr_t)(chnd).c) + +/* + * Copy an array of objects to guest context via a compat handle, + * specifying an offset into the guest array. + */ +#define copy_to_compat_offset(hnd, off, ptr, nr) ({ \ + const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ + const typeof(*(ptr)) *const _y = (ptr); \ + copy_to_user(_x + (off), _y, sizeof(*_x) * (nr)); \ +}) + +/* + * Copy an array of objects from guest context via a compat handle, + * specifying an offset into the guest array. + */ +#define copy_from_compat_offset(ptr, hnd, off, nr) ({ \ + const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ + const typeof(ptr) _y = (ptr); \ + copy_from_user(_y, _x + (off), sizeof(*_x) * (nr)); \ +}) + +#define copy_to_compat(hnd, ptr, nr) \ + copy_to_compat_offset(hnd, 0, ptr, nr) + +#define copy_from_compat(ptr, hnd, nr) \ + copy_from_compat_offset(ptr, hnd, 0, nr) + +/* Copy sub-field of a structure to guest context via a compat handle. */ +#define copy_field_to_compat(hnd, ptr, field) ({ \ + typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ + const typeof((ptr)->field) *const _y = &(ptr)->field; \ + copy_to_user(_x, _y, sizeof(*_x)); \ +}) + +/* Copy sub-field of a structure from guest context via a compat handle. */ +#define copy_field_from_compat(ptr, hnd, field) ({ \ + typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ + typeof((ptr)->field) *const _y = &(ptr)->field; \ + copy_from_user(_y, _x, sizeof(*_x)); \ +}) + +/* + * Pre-validate a guest handle. + * Allows use of faster __copy_* functions. + */ +#define compat_handle_okay(hnd, nr) \ + compat_array_access_ok((void *)(full_ptr_t)(hnd).c, (nr), sizeof(**(hnd)._)) + +#define __copy_to_compat_offset(hnd, off, ptr, nr) ({ \ + const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ + const typeof(*(ptr)) *const _y = (ptr); \ + __copy_to_user(_x + (off), _y, sizeof(*_x) * (nr)); \ +}) + +#define __copy_from_compat_offset(ptr, hnd, off, nr) ({ \ + const typeof(ptr) _x = (typeof(**(hnd)._) *)(full_ptr_t)(hnd).c; \ + const typeof(ptr) _y = (ptr); \ + __copy_from_user(_y, _x + (off), sizeof(*_x) * (nr)); \ +}) + +#define __copy_to_compat(hnd, ptr, nr) \ + __copy_to_compat_offset(hnd, 0, ptr, nr) + +#define __copy_from_compat(ptr, hnd, nr) \ + __copy_from_compat_offset(ptr, hnd, 0, nr) + +#define __copy_field_to_compat(hnd, ptr, field) ({ \ + typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ + const typeof((ptr)->field) *const _y = &(ptr)->field; \ + __copy_to_user(_x, _y, sizeof(*_x)); \ +}) + +#define __copy_field_from_compat(ptr, hnd, field) ({ \ + typeof((ptr)->field) *const _x = &((typeof(**(hnd)._) *)(full_ptr_t)(hnd).c)->field; \ + typeof((ptr)->field) *const _y = &(ptr)->field; \ + __copy_from_user(_y, _x, sizeof(*_x)); \ +}) + + +#define CHECK_TYPE(name) \ + typedef int __checkT ## name[1 - ((xen_ ## name ## _t *)0 != \ + (compat_ ## name ## _t *)0) * 2] +#define CHECK_TYPE_(k, n) \ + typedef int __checkT ## k ## _ ## n[1 - ((k xen_ ## n *)0 != \ + (k compat_ ## n *)0) * 2] + +#define CHECK_SIZE(name) \ + typedef int __checkS ## name[1 - (sizeof(xen_ ## name ## _t) != \ + sizeof(compat_ ## name ## _t)) * 2] +#define CHECK_SIZE_(k, n) \ + typedef int __checkS ## k ## _ ## n[1 - (sizeof(k xen_ ## n) != \ + sizeof(k compat_ ## n)) * 2] + +#define CHECK_FIELD(t, f) \ + typedef int __checkF ## t ## __ ## f[1 - (&((xen_ ## t ## _t *)0)->f != \ + &((compat_ ## t ## _t *)0)->f) * 2] +#define CHECK_FIELD_(k, n, f) \ + typedef int __checkF ## k ## _ ## n ## __ ## f[1 - (&((k xen_ ## n *)0)->f != \ + &((k compat_ ## n *)0)->f) * 2] + +#define CHECK_SUBFIELD_1(t, f1, f2) \ + typedef int __checkF1 ## t ## __ ## f1 ## __ ## f2 \ + [1 - (&((xen_ ## t ## _t *)0)->f1.f2 != \ + &((compat_ ## t ## _t *)0)->f1.f2) * 2] +#define CHECK_SUBFIELD_1_(k, n, f1, f2) \ + typedef int __checkF1 ## k ## _ ## n ## __ ## f1 ## __ ## f2 \ + [1 - (&((k xen_ ## n *)0)->f1.f2 != \ + &((k compat_ ## n *)0)->f1.f2) * 2] + +#define CHECK_SUBFIELD_2(t, f1, f2, f3) \ + typedef int __checkF2 ## t ## __ ## f1 ## __ ## f2 ## __ ## f3 \ + [1 - (&((xen_ ## t ## _t *)0)->f1.f2.f3 != \ + &((compat_ ## t ## _t *)0)->f1.f2.f3) * 2] +#define CHECK_SUBFIELD_2_(k, n, f1, f2, f3) \ + typedef int __checkF2 ## k ## _ ## n ## __ ## f1 ## __ ## f2 ## __ ## f3 \ + [1 - (&((k xen_ ## n *)0)->f1.f2.f3 != \ + &((k compat_ ## n *)0)->f1.f2.f3) * 2] + +extern int compat_disabled; + +/* In-place translation functons: */ +struct start_info; +void xlat_start_info(struct start_info *, enum XLAT_start_info_console); + +#endif + +#endif /* __XEN_COMPAT_H__ */ From 8589463a257a56c0316b002b7d8affc5709e4672 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:28 +0000 Subject: [PATCH 077/570] Handle the creation of startup info for compatibility mode guests. This includes a script to auto-generate checking or translation code between native and compatibility mode hypercall argument structures. Signed-off-by: Jan Beulich --- Config.mk | 2 + xen/arch/x86/domain_build.c | 6 + xen/arch/x86/setup.c | 12 + xen/common/compat/Makefile | 1 + xen/common/compat/xlat.c | 32 +++ xen/include/Makefile | 9 +- xen/include/xlat.lst | 5 + xen/tools/get-fields.sh | 425 ++++++++++++++++++++++++++++++++++++ 8 files changed, 491 insertions(+), 1 deletion(-) create mode 100644 xen/common/compat/xlat.c create mode 100644 xen/include/xlat.lst create mode 100644 xen/tools/get-fields.sh diff --git a/Config.mk b/Config.mk index 08873d69d4..6a7ed679ac 100644 --- a/Config.mk +++ b/Config.mk @@ -11,6 +11,8 @@ XEN_OS ?= $(shell uname -s) CONFIG_$(XEN_OS) := y +SHELL ?= /bin/sh + # Tools to run on system hosting the build HOSTCC = gcc HOSTCFLAGS = -Wall -Werror -Wstrict-prototypes -O2 -fomit-frame-pointer diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 0e15b153e1..f9e6dafce1 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -848,6 +849,11 @@ int construct_dom0(struct domain *d, si->console.dom0.info_size = sizeof(struct dom0_vga_console_info); } +#ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) + xlat_start_info(si, XLAT_start_info_console_dom0); +#endif + /* Reinstate the caller's page tables. */ write_ptbase(current); local_irq_enable(); diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 928ab8f286..76b3848174 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -18,6 +18,10 @@ #include #include #include +#ifdef CONFIG_COMPAT +#include +#include +#endif #include #include #include @@ -546,6 +550,14 @@ void __init __start_xen(multiboot_info_t *mbi) BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE); BUILD_BUG_ON(sizeof(vcpu_info_t) != 64); +#ifdef CONFIG_COMPAT + BUILD_BUG_ON(sizeof(((struct compat_platform_op *)0)->u) != + sizeof(((struct compat_platform_op *)0)->u.pad)); + BUILD_BUG_ON(sizeof(start_info_compat_t) > PAGE_SIZE); + BUILD_BUG_ON(sizeof(shared_info_compat_t) > PAGE_SIZE); + BUILD_BUG_ON(sizeof(vcpu_info_compat_t) != 64); +#endif + /* Check definitions in public headers match internal defs. */ BUILD_BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START); #ifdef HYPERVISOR_VIRT_END diff --git a/xen/common/compat/Makefile b/xen/common/compat/Makefile index 39e1c8ee3d..ba581f053c 100644 --- a/xen/common/compat/Makefile +++ b/xen/common/compat/Makefile @@ -1,4 +1,5 @@ obj-y += kernel.o +obj-y += xlat.o # extra dependencies kernel.o: ../kernel.c diff --git a/xen/common/compat/xlat.c b/xen/common/compat/xlat.c new file mode 100644 index 0000000000..63f08b36f8 --- /dev/null +++ b/xen/common/compat/xlat.c @@ -0,0 +1,32 @@ +/****************************************************************************** + * xlat.c + */ + +#include +#include +#include +#include + +/* In-place translation functons: */ +void xlat_start_info(struct start_info *native, + enum XLAT_start_info_console console) +{ + struct compat_start_info *compat = (void *)native; + + BUILD_BUG_ON(sizeof(*native) < sizeof(*compat)); + XLAT_start_info(compat, native); +} + +#define xen_dom0_vga_console_info dom0_vga_console_info +CHECK_dom0_vga_console_info; +#undef dom0_vga_console_info + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/Makefile b/xen/include/Makefile index 1cc0d79baf..57d8fe93de 100644 --- a/xen/include/Makefile +++ b/xen/include/Makefile @@ -4,7 +4,7 @@ compat-arch-$(CONFIG_X86) := x86_32 headers-y := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g') headers-y := $(filter-out %/dom0_ops.h,$(headers-y)) -headers-y += compat/arch-$(compat-arch-y).h +headers-y += compat/arch-$(compat-arch-y).h compat/xlat.h cppflags-y := -include public/xen-compat.h cppflags-$(CONFIG_X86) += -m32 @@ -53,5 +53,12 @@ compat/%.c: public/%.h Makefile >$@.new mv -f $@.new $@ +compat/xlat.h: xlat.lst $(filter-out compat/xlat.h,$(headers-y)) $(BASEDIR)/tools/get-fields.sh Makefile + grep -v '^[[:space:]]*#' xlat.lst | \ + while read what name hdr; do \ + $(SHELL) $(BASEDIR)/tools/get-fields.sh "$$what" compat_$$name $$(echo compat/$$hdr | sed 's,@arch@,$(compat-arch-y),g') || exit $$?; \ + done >$@.new + mv -f $@.new $@ + clean:: rm -rf compat diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst new file mode 100644 index 0000000000..8b7c96278a --- /dev/null +++ b/xen/include/xlat.lst @@ -0,0 +1,5 @@ +# First column indicator: +# ! - needs translation +# ? - needs checking +? dom0_vga_console_info xen.h +! start_info xen.h diff --git a/xen/tools/get-fields.sh b/xen/tools/get-fields.sh new file mode 100644 index 0000000000..01af5eaaf3 --- /dev/null +++ b/xen/tools/get-fields.sh @@ -0,0 +1,425 @@ +#!/bin/sh +test -n "$1" -a -n "$2" -a -n "$3" +set -ef + +get_fields() { + local level=1 aggr=0 name= fields= + for token in $2 + do + case "$token" in + struct|union) + test $level != 1 || aggr=1 fields= name= + ;; + "{") + level=$(expr $level + 1) + ;; + "}") + level=$(expr $level - 1) + if [ $level = 1 -a $name = $1 ] + then + echo "$fields }" + return 0 + fi + ;; + [[:alpha:]_]*) + test $aggr = 0 -o -n "$name" || name="$token" + ;; + esac + test $aggr = 0 || fields="$fields $token" + done +} + +build_enums() { + local level=1 kind= fields= members= named= id= token + for token in $2 + do + case "$token" in + struct|union) + test $level != 2 || fields=" " + kind="$token;$kind" + ;; + "{") + level=$(expr $level + 1) + ;; + "}") + level=$(expr $level - 1) + if [ $level = 1 ] + then + if [ "${kind%%;*}" = union ] + then + echo + echo "enum XLAT_$1 {" + for m in $members + do + echo " XLAT_${1}_$m," + done + echo "};" + fi + return 0 + elif [ $level = 2 ] + then + named='?' + fi + ;; + [[:alpha:]]*) + id=$token + if [ -n "$named" -a -n "${kind#*;}" ] + then + build_enums ${1}_$token "$fields" + named='!' + fi + ;; + ",") + test $level != 2 || members="$members $id" + ;; + ";") + test $level != 2 || members="$members $id" + test -z "$named" || kind=${kind#*;} + named= + ;; + esac + test -z "$fields" || fields="$fields $token" + done +} + +handle_field() { + if [ -z "$5" ] + then + echo " \\" + if [ -z "$4" ] + then + echo -n "$1(_d_)->$3 = (_s_)->$3;" + else + echo -n "$1XLAT_${2}_HNDL_$(echo $3 | sed 's,\.,_,g')(_d_, _s_);" + fi + elif [ -z "$(echo "$5" | sed 's,[^{}],,g')" ] + then + local tag=$(echo "$5" | sed 's,[[:space:]]*\(struct\|union\)[[:space:]]\+\(compat_\)\?\([[:alnum:]_]\+\)[[:space:]].*,\3,') + echo " \\" + echo -n "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);" + else + local level=1 kind= fields= id= array= arrlvl=1 array_type= type= token + for token in $5 + do + case "$token" in + struct|union) + test $level != 2 || fields=" " + if [ $level == 1 ] + then + kind=$token + if [ $kind = union ] + then + echo " \\" + echo -n "${1}switch ($(echo $3 | sed 's,\.,_,g')) {" + fi + fi + ;; + "{") + level=$(expr $level + 1) id= + ;; + "}") + level=$(expr $level - 1) id= + if [ $level == 1 -a $kind = union ] + then + echo " \\" + echo -n "$1}" + fi + ;; + "[") + if [ $level != 2 -o $arrlvl != 1 ] + then + : + elif [ -z "$array" ] + then + array=" " + else + array="$array;" + fi + arrlvl=$(expr $arrlvl + 1) + ;; + "]") + arrlvl=$(expr $arrlvl - 1) + ;; + COMPAT_HANDLE\(*\)) + if [ $level == 2 -a -z "$id" ] + then + type=${token#COMPAT_HANDLE?} + type=${type%?} + type=${type#compat_} + fi + ;; + compat_domain_handle_t) + if [ $level == 2 -a -z "$id" ] + then + array_type=$token + fi + ;; + [[:alpha:]]*) + id=$token + ;; + [\,\;]) + if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] + then + if [ $kind = union ] + then + echo " \\" + echo -n "${1}case XLAT_${2}_$(echo $3.$id | sed 's,\.,_,g'):" + handle_field "$1 " $2 $3.$id "$type" "$fields" + elif [ -z "$array" -a -z "$array_type" ] + then + handle_field "$1" $2 $3.$id "$type" "$fields" + elif [ -z "$array" ] + then + copy_array " " $3.$id + else + handle_array "$1" $2 $3.$id "${array#*;}" "$type" "$fields" + fi + test "$token" != ";" || fields= id= type= + array= + if [ $kind = union ] + then + echo " \\" + echo -n "$1 break;" + fi + fi + ;; + *) + if [ -n "$array" ] + then + array="$array $token" + fi + ;; + esac + test -z "$fields" || fields="$fields $token" + done + fi +} + +copy_array() { + echo " \\" + echo "${1}if ((_d_)->$2 != (_s_)->$2) \\" + echo -n "$1 memcpy((_d_)->$2, (_s_)->$2, sizeof((_d_)->$2));" +} + +handle_array() { + local i="i$(echo $4 | sed 's,[^;], ,g' | wc -w)" + echo " \\" + echo "$1{ \\" + echo "$1 unsigned int $i; \\" + echo -n "$1 for ($i = 0; $i < "${4%%;*}"; ++$i) {" + if [ "$4" = "${4#*;}" ] + then + handle_field "$1 " $2 $3[$i] "$5" "$6" + else + handle_array "$1 " $2 $3[$i] "${4#*;}" "$5" "$6" + fi + echo " \\" + echo "$1 } \\" + echo -n "$1}" +} + +build_body() { + echo + echo -n "#define XLAT_$1(_d_, _s_)" + local level=1 fields= id= array= arrlvl=1 array_type= type= token + for token in $2 + do + case "$token" in + struct|union) + test $level != 2 || fields=" " + ;; + "{") + level=$(expr $level + 1) id= + ;; + "}") + level=$(expr $level - 1) id= + ;; + "[") + if [ $level != 2 -o $arrlvl != 1 ] + then + : + elif [ -z "$array" ] + then + array=" " + else + array="$array;" + fi + arrlvl=$(expr $arrlvl + 1) + ;; + "]") + arrlvl=$(expr $arrlvl - 1) + ;; + COMPAT_HANDLE\(*\)) + if [ $level == 2 -a -z "$id" ] + then + type=${token#COMPAT_HANDLE?} + type=${type%?} + type=${type#compat_} + fi + ;; + compat_domain_handle_t) + if [ $level == 2 -a -z "$id" ] + then + array_type=$token + fi + ;; + [[:alpha:]_]*) + if [ -n "$array" ] + then + array="$array $token" + else + id=$token + fi + ;; + [\,\;]) + if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] + then + if [ -z "$array" -a -z "$array_type" ] + then + handle_field " " $1 $id "$type" "$fields" + elif [ -z "$array" ] + then + copy_array " " $id + else + handle_array " " $1 $id "${array#*;}" "$type" "$fields" + fi + test "$token" != ";" || fields= id= type= + array= + fi + ;; + *) + if [ -n "$array" ] + then + array="$array $token" + fi + ;; + esac + test -z "$fields" || fields="$fields $token" + done + echo "" +} + +check_field() { + if [ -z "$(echo "$4" | sed 's,[^{}],,g')" ] + then + echo "; \\" + local n=$(echo $3 | sed 's,[^.], ,g' | wc -w) + if [ -n "$4" ] + then + for n in $4 + do + case $n in + struct|union) + ;; + [[:alpha:]_]*) + echo -n " CHECK_$n" + break + ;; + *) + echo "Malformed compound declaration: '$n'" >&2 + exit 1 + ;; + esac + done + elif [ $n = 0 ] + then + echo -n " CHECK_FIELD_($1, $2, $3)" + else + echo -n " CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | sed 's!\.!, !g'))" + fi + else + local level=1 fields= id= token + for token in $4 + do + case "$token" in + struct|union) + test $level != 2 || fields=" " + ;; + "{") + level=$(expr $level + 1) id= + ;; + "}") + level=$(expr $level - 1) id= + ;; + [[:alpha:]]*) + id=$token + ;; + [\,\;]) + if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] + then + check_field $1 $2 $3.$id "$fields" + test "$token" != ";" || fields= id= + fi + ;; + esac + test -z "$fields" || fields="$fields $token" + done + fi +} + +build_check() { + echo + echo "#define CHECK_$1 \\" + local level=1 fields= kind= id= arrlvl=1 token + for token in $2 + do + case "$token" in + struct|union) + if [ $level == 1 ] + then + kind=$token + echo -n " CHECK_SIZE_($kind, $1)" + elif [ $level == 2 ] + then + fields=" " + fi + ;; + "{") + level=$(expr $level + 1) id= + ;; + "}") + level=$(expr $level - 1) id= + ;; + "[") + arrlvl=$(expr $arrlvl + 1) + ;; + "]") + arrlvl=$(expr $arrlvl - 1) + ;; + [[:alpha:]_]*) + test $level != 2 -o $arrlvl != 1 || id=$token + ;; + [\,\;]) + if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] + then + check_field $kind $1 $id "$fields" + test "$token" != ";" || fields= id= + fi + ;; + esac + test -z "$fields" || fields="$fields $token" + done + echo "" +} + +fields="$(get_fields $(echo $2 | sed 's,^compat_xen,compat_,') "$(sed -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")" +if [ -z "$fields" ] +then + echo "Fields of '$2' not found in '$3'" >&2 + exit 1 +fi +name=${2#compat_} +name=${name#xen} +case "$1" in +"!") + build_enums $name "$fields" + build_body $name "$fields" + ;; +"?") + build_check $name "$fields" + ;; +*) + echo "Invalid translation indicator: '$1'" >&2 + exit 1 + ;; +esac From fa5b1a1d19aed783a5461e4ea9c0bd6a23f9d863 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:29 +0000 Subject: [PATCH 078/570] Handle shared info (having different layout for native and compatibility mode guests) accesses. Signed-off-by: Jan Beulich --- xen/arch/x86/crash.c | 3 +- xen/arch/x86/domain.c | 12 ++--- xen/arch/x86/domain_build.c | 5 +- xen/arch/x86/irq.c | 12 ++--- xen/arch/x86/mm/shadow/common.c | 3 +- xen/arch/x86/setup.c | 5 +- xen/arch/x86/time.c | 12 ++--- xen/arch/x86/traps.c | 7 +-- xen/arch/x86/x86_64/asm-offsets.c | 13 ++++- xen/arch/x86/x86_64/compat/entry.S | 8 +-- xen/arch/x86/x86_64/compat/traps.c | 2 +- xen/arch/x86/x86_64/traps.c | 5 +- xen/common/compat/xlat.c | 4 ++ xen/common/domain.c | 2 +- xen/common/event_channel.c | 21 ++++---- xen/common/kernel.c | 5 +- xen/common/keyhandler.c | 13 ++--- xen/common/schedule.c | 17 ++++--- xen/include/Makefile | 5 +- xen/include/asm-ia64/shared.h | 4 ++ xen/include/asm-powerpc/shared.h | 4 ++ xen/include/asm-x86/compat.h | 2 + xen/include/asm-x86/event.h | 14 +++--- xen/include/asm-x86/shared.h | 78 ++++++++++++++++++++++++++++++ xen/include/public/xen.h | 4 ++ xen/include/xen/compat.h | 6 +++ xen/include/xen/sched.h | 11 ++++- xen/include/xen/shared.h | 54 +++++++++++++++++++++ xen/include/xlat.lst | 1 + 29 files changed, 261 insertions(+), 71 deletions(-) create mode 100644 xen/include/asm-ia64/shared.h create mode 100644 xen/include/asm-powerpc/shared.h create mode 100644 xen/include/asm-x86/shared.h create mode 100644 xen/include/xen/shared.h diff --git a/xen/arch/x86/crash.c b/xen/arch/x86/crash.c index a754cbbaab..73eb4724a8 100644 --- a/xen/arch/x86/crash.c +++ b/xen/arch/x86/crash.c @@ -25,6 +25,7 @@ #include #include #include +#include #include static atomic_t waiting_for_crash_ipi; @@ -103,7 +104,7 @@ void machine_crash_shutdown(void) info = kexec_crash_save_info(); info->dom0_pfn_to_mfn_frame_list_list = - dom0->shared_info->arch.pfn_to_mfn_frame_list_list; + arch_get_pfn_to_mfn_frame_list_list(dom0); } /* diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index ec8fc20a1c..ea41527f1c 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -534,10 +534,10 @@ static void load_segments(struct vcpu *n) /* CS longword also contains full evtchn_upcall_mask. */ cs_and_mask = (unsigned short)regs->cs | - ((unsigned int)n->vcpu_info->evtchn_upcall_mask << 16); + ((unsigned int)vcpu_info(n, evtchn_upcall_mask) << 16); /* Fold upcall mask into RFLAGS.IF. */ eflags = regs->_eflags & ~X86_EFLAGS_IF; - eflags |= !n->vcpu_info->evtchn_upcall_mask << 9; + eflags |= !vcpu_info(n, evtchn_upcall_mask) << 9; if ( !ring_1(regs) ) { @@ -562,7 +562,7 @@ static void load_segments(struct vcpu *n) if ( test_bit(_VGCF_failsafe_disables_events, &n->arch.guest_context.flags) ) - n->vcpu_info->evtchn_upcall_mask = 1; + vcpu_info(n, evtchn_upcall_mask) = 1; regs->entry_vector = TRAP_syscall; regs->_eflags &= 0xFFFCBEFFUL; @@ -580,11 +580,11 @@ static void load_segments(struct vcpu *n) /* CS longword also contains full evtchn_upcall_mask. */ cs_and_mask = (unsigned long)regs->cs | - ((unsigned long)n->vcpu_info->evtchn_upcall_mask << 32); + ((unsigned long)vcpu_info(n, evtchn_upcall_mask) << 32); /* Fold upcall mask into RFLAGS.IF. */ rflags = regs->rflags & ~X86_EFLAGS_IF; - rflags |= !n->vcpu_info->evtchn_upcall_mask << 9; + rflags |= !vcpu_info(n, evtchn_upcall_mask) << 9; if ( put_user(regs->ss, rsp- 1) | put_user(regs->rsp, rsp- 2) | @@ -605,7 +605,7 @@ static void load_segments(struct vcpu *n) if ( test_bit(_VGCF_failsafe_disables_events, &n->arch.guest_context.flags) ) - n->vcpu_info->evtchn_upcall_mask = 1; + vcpu_info(n, evtchn_upcall_mask) = 1; regs->entry_vector = TRAP_syscall; regs->rflags &= ~(X86_EFLAGS_AC|X86_EFLAGS_VM|X86_EFLAGS_RF| diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index f9e6dafce1..ce8f308fc3 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -328,6 +328,7 @@ int construct_dom0(struct domain *d, l1_pgentry_t gdt_l1e; set_bit(_DOMF_compat, &d->domain_flags); + v->vcpu_info = (void *)&d->shared_info->compat.vcpu_info[0]; if ( nr_pages != (unsigned int)nr_pages ) nr_pages = UINT_MAX; @@ -730,7 +731,7 @@ int construct_dom0(struct domain *d, /* Mask all upcalls... */ for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - d->shared_info->vcpu_info[i].evtchn_upcall_mask = 1; + shared_info(d, vcpu_info[i].evtchn_upcall_mask) = 1; if ( opt_dom0_max_vcpus == 0 ) opt_dom0_max_vcpus = num_online_cpus(); @@ -738,6 +739,8 @@ int construct_dom0(struct domain *d, opt_dom0_max_vcpus = num_online_cpus(); if ( opt_dom0_max_vcpus > MAX_VIRT_CPUS ) opt_dom0_max_vcpus = MAX_VIRT_CPUS; + if ( opt_dom0_max_vcpus > BITS_PER_GUEST_LONG(d) ) + opt_dom0_max_vcpus = BITS_PER_GUEST_LONG(d); printk("Dom0 has maximum %u VCPUs\n", opt_dom0_max_vcpus); for ( i = 1; i < opt_dom0_max_vcpus; i++ ) diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index 1821a56e24..74016d2906 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -332,7 +333,7 @@ int pirq_guest_unmask(struct domain *d) irq < NR_IRQS; irq = find_next_bit(d->pirq_mask, NR_IRQS, irq+1) ) { - if ( !test_bit(d->pirq_to_evtchn[irq], s->evtchn_mask) ) + if ( !test_bit(d->pirq_to_evtchn[irq], __shared_info_addr(d, s, evtchn_mask)) ) __pirq_guest_eoi(d, irq); } @@ -624,14 +625,13 @@ static void dump_irqs(unsigned char key) printk("%u(%c%c%c%c)", d->domain_id, (test_bit(d->pirq_to_evtchn[irq], - d->shared_info->evtchn_pending) ? + shared_info_addr(d, evtchn_pending)) ? 'P' : '-'), - (test_bit(d->pirq_to_evtchn[irq]/BITS_PER_LONG, - &d->shared_info->vcpu_info[0]. - evtchn_pending_sel) ? + (test_bit(d->pirq_to_evtchn[irq]/BITS_PER_GUEST_LONG(d), + vcpu_info_addr(d->vcpu[0], evtchn_pending_sel)) ? 'S' : '-'), (test_bit(d->pirq_to_evtchn[irq], - d->shared_info->evtchn_mask) ? + shared_info_addr(d, evtchn_mask)) ? 'M' : '-'), (test_bit(irq, d->pirq_mask) ? 'M' : '-')); diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index fc68fd9242..baa57351c8 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -36,6 +36,7 @@ #include #include #include +#include #include "private.h" @@ -2917,7 +2918,7 @@ sh_alloc_log_dirty_bitmap(struct domain *d) { ASSERT(d->arch.shadow.dirty_bitmap == NULL); d->arch.shadow.dirty_bitmap_size = - (d->shared_info->arch.max_pfn + (BITS_PER_LONG - 1)) & + (arch_get_max_pfn(d) + (BITS_PER_LONG - 1)) & ~(BITS_PER_LONG - 1); d->arch.shadow.dirty_bitmap = xmalloc_array(unsigned long, diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 76b3848174..8770a29509 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -548,14 +548,13 @@ void __init __start_xen(multiboot_info_t *mbi) BUILD_BUG_ON(sizeof(start_info_t) > PAGE_SIZE); BUILD_BUG_ON(sizeof(shared_info_t) > PAGE_SIZE); - BUILD_BUG_ON(sizeof(vcpu_info_t) != 64); + BUILD_BUG_ON(sizeof(struct vcpu_info) != 64); #ifdef CONFIG_COMPAT BUILD_BUG_ON(sizeof(((struct compat_platform_op *)0)->u) != sizeof(((struct compat_platform_op *)0)->u.pad)); BUILD_BUG_ON(sizeof(start_info_compat_t) > PAGE_SIZE); - BUILD_BUG_ON(sizeof(shared_info_compat_t) > PAGE_SIZE); - BUILD_BUG_ON(sizeof(vcpu_info_compat_t) != 64); + BUILD_BUG_ON(sizeof(struct compat_vcpu_info) != 64); #endif /* Check definitions in public headers match internal defs. */ diff --git a/xen/arch/x86/time.c b/xen/arch/x86/time.c index 83eec9b9d9..387b18c20a 100644 --- a/xen/arch/x86/time.c +++ b/xen/arch/x86/time.c @@ -676,7 +676,7 @@ static inline void __update_vcpu_system_time(struct vcpu *v) struct vcpu_time_info *u; t = &this_cpu(cpu_time); - u = &v->vcpu_info->time; + u = &vcpu_info(v, time); version_update_begin(&u->version); @@ -690,7 +690,7 @@ static inline void __update_vcpu_system_time(struct vcpu *v) void update_vcpu_system_time(struct vcpu *v) { - if ( v->vcpu_info->time.tsc_timestamp != + if ( vcpu_info(v, time.tsc_timestamp) != this_cpu(cpu_time).local_tsc_stamp ) __update_vcpu_system_time(v); } @@ -698,10 +698,10 @@ void update_vcpu_system_time(struct vcpu *v) void update_domain_wallclock_time(struct domain *d) { spin_lock(&wc_lock); - version_update_begin(&d->shared_info->wc_version); - d->shared_info->wc_sec = wc_sec + d->time_offset_seconds; - d->shared_info->wc_nsec = wc_nsec; - version_update_end(&d->shared_info->wc_version); + version_update_begin(&shared_info(d, wc_version)); + shared_info(d, wc_sec) = wc_sec + d->time_offset_seconds; + shared_info(d, wc_nsec) = wc_nsec; + version_update_end(&shared_info(d, wc_version)); spin_unlock(&wc_lock); } diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 3b379bd2b5..5d7137f3a7 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -58,6 +58,7 @@ #include #include #include +#include #include #include @@ -665,7 +666,7 @@ void propagate_page_fault(unsigned long addr, u16 error_code) struct trap_bounce *tb = &v->arch.trap_bounce; v->arch.guest_context.ctrlreg[2] = addr; - v->vcpu_info->arch.cr2 = addr; + arch_set_cr2(v, addr); /* Re-set error_code.user flag appropriately for the guest. */ error_code &= ~PFEC_user_mode; @@ -1390,7 +1391,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 2: /* Write CR2 */ v->arch.guest_context.ctrlreg[2] = *reg; - v->vcpu_info->arch.cr2 = *reg; + arch_set_cr2(v, *reg); break; case 3: /* Write CR3 */ @@ -1601,7 +1602,7 @@ static void nmi_dom0_report(unsigned int reason_idx) if ( ((d = dom0) == NULL) || ((v = d->vcpu[0]) == NULL) ) return; - set_bit(reason_idx, &d->shared_info->arch.nmi_reason); + set_bit(reason_idx, nmi_reason(d)); if ( test_and_set_bit(_VCPUF_nmi_pending, &v->vcpu_flags) ) raise_softirq(NMI_SOFTIRQ); /* not safe to wake up a vcpu here */ diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c index d103503ebb..7a86371630 100644 --- a/xen/arch/x86/x86_64/asm-offsets.c +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -7,6 +7,9 @@ #include #include #include +#ifdef CONFIG_COMPAT +#include +#endif #include #include @@ -96,10 +99,16 @@ void __dummy__(void) OFFSET(VMCB_tsc_offset, struct vmcb_struct, tsc_offset); BLANK(); - OFFSET(VCPUINFO_upcall_pending, vcpu_info_t, evtchn_upcall_pending); - OFFSET(VCPUINFO_upcall_mask, vcpu_info_t, evtchn_upcall_mask); + OFFSET(VCPUINFO_upcall_pending, struct vcpu_info, evtchn_upcall_pending); + OFFSET(VCPUINFO_upcall_mask, struct vcpu_info, evtchn_upcall_mask); BLANK(); +#ifdef CONFIG_COMPAT + OFFSET(COMPAT_VCPUINFO_upcall_pending, struct compat_vcpu_info, evtchn_upcall_pending); + OFFSET(COMPAT_VCPUINFO_upcall_mask, struct compat_vcpu_info, evtchn_upcall_mask); + BLANK(); +#endif + OFFSET(CPUINFO_current_vcpu, struct cpu_info, current_vcpu); DEFINE(CPUINFO_sizeof, sizeof(struct cpu_info)); BLANK(); diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 0b79fd708f..e6e1943db8 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -69,9 +69,9 @@ compat_test_all_events: jc compat_process_nmi compat_test_guest_events: movq VCPU_vcpu_info(%rbx),%rax - testb $0xFF,VCPUINFO_upcall_mask(%rax) + testb $0xFF,COMPAT_VCPUINFO_upcall_mask(%rax) jnz compat_restore_all_guest - testb $0xFF,VCPUINFO_upcall_pending(%rax) + testb $0xFF,COMPAT_VCPUINFO_upcall_pending(%rax) jz compat_restore_all_guest /*compat_process_guest_events:*/ sti @@ -189,10 +189,10 @@ CFLT4: mov UREGS_ss+8(%rsp),%fs movb TRAPBOUNCE_flags(%rdx),%cl subl $3*4,%esi movq VCPU_vcpu_info(%rbx),%rax - pushq VCPUINFO_upcall_mask(%rax) + pushq COMPAT_VCPUINFO_upcall_mask(%rax) testb $TBF_INTERRUPT,%cl setnz %ch # TBF_INTERRUPT -> set upcall mask - orb %ch,VCPUINFO_upcall_mask(%rax) + orb %ch,COMPAT_VCPUINFO_upcall_mask(%rax) popq %rax shll $16,%eax # Bits 16-23: saved_upcall_mask movw UREGS_cs+8(%rsp),%ax # Bits 0-15: CS diff --git a/xen/arch/x86/x86_64/compat/traps.c b/xen/arch/x86/x86_64/compat/traps.c index a368748b1a..834a6ba1f0 100644 --- a/xen/arch/x86/x86_64/compat/traps.c +++ b/xen/arch/x86/x86_64/compat/traps.c @@ -118,7 +118,7 @@ unsigned int compat_iret(void) clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags); /* Restore upcall mask from supplied EFLAGS.IF. */ - current->vcpu_info->evtchn_upcall_mask = !(eflags & X86_EFLAGS_IF); + vcpu_info(current, evtchn_upcall_mask) = !(eflags & X86_EFLAGS_IF); /* * The hypercall exit path will overwrite EAX with this return diff --git a/xen/arch/x86/x86_64/traps.c b/xen/arch/x86/x86_64/traps.c index 8ec8934815..65d9c427dc 100644 --- a/xen/arch/x86/x86_64/traps.c +++ b/xen/arch/x86/x86_64/traps.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -52,7 +53,7 @@ void show_registers(struct cpu_user_regs *regs) if ( guest_mode(regs) ) { context = "guest"; - fault_crs[2] = current->vcpu_info->arch.cr2; + fault_crs[2] = arch_get_cr2(current); } else { @@ -234,7 +235,7 @@ unsigned long do_iret(void) clear_bit(_VCPUF_nmi_masked, ¤t->vcpu_flags); /* Restore upcall mask from supplied EFLAGS.IF. */ - current->vcpu_info->evtchn_upcall_mask = !(iret_saved.rflags & EF_IE); + vcpu_info(current, evtchn_upcall_mask) = !(iret_saved.rflags & EF_IE); /* Saved %rax gets written back to regs->rax in entry.S. */ return iret_saved.rax; diff --git a/xen/common/compat/xlat.c b/xen/common/compat/xlat.c index 63f08b36f8..b8969afb43 100644 --- a/xen/common/compat/xlat.c +++ b/xen/common/compat/xlat.c @@ -21,6 +21,10 @@ void xlat_start_info(struct start_info *native, CHECK_dom0_vga_console_info; #undef dom0_vga_console_info +#define xen_vcpu_time_info vcpu_time_info +CHECK_vcpu_time_info; +#undef xen_vcpu_time_info + /* * Local variables: * mode: C diff --git a/xen/common/domain.c b/xen/common/domain.c index c61de823ac..8afab95a31 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -90,7 +90,7 @@ struct vcpu *alloc_vcpu( v->domain = d; v->vcpu_id = vcpu_id; - v->vcpu_info = &d->shared_info->vcpu_info[vcpu_id]; + v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]); spin_lock_init(&v->pause_lock); v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline; diff --git a/xen/common/event_channel.c b/xen/common/event_channel.c index b0d23eb8e0..70665a7e78 100644 --- a/xen/common/event_channel.c +++ b/xen/common/event_channel.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -33,7 +34,7 @@ #define bucket_from_port(d,p) \ ((d)->evtchn[(p)/EVTCHNS_PER_BUCKET]) #define port_is_valid(d,p) \ - (((p) >= 0) && ((p) < MAX_EVTCHNS) && \ + (((p) >= 0) && ((p) < MAX_EVTCHNS(d)) && \ (bucket_from_port(d,p) != NULL)) #define evtchn_from_port(d,p) \ (&(bucket_from_port(d,p))[(p)&(EVTCHNS_PER_BUCKET-1)]) @@ -82,7 +83,7 @@ static int get_free_port(struct domain *d) if ( evtchn_from_port(d, port)->state == ECS_FREE ) return port; - if ( port == MAX_EVTCHNS ) + if ( port == MAX_EVTCHNS(d) ) return -ENOSPC; chn = xmalloc_array(struct evtchn, EVTCHNS_PER_BUCKET); @@ -517,12 +518,12 @@ void evtchn_set_pending(struct vcpu *v, int port) * others may require explicit memory barriers. */ - if ( test_and_set_bit(port, s->evtchn_pending) ) + if ( test_and_set_bit(port, __shared_info_addr(d, s, evtchn_pending)) ) return; - if ( !test_bit (port, s->evtchn_mask) && - !test_and_set_bit(port / BITS_PER_LONG, - &v->vcpu_info->evtchn_pending_sel) ) + if ( !test_bit (port, __shared_info_addr(d, s, evtchn_mask)) && + !test_and_set_bit(port / BITS_PER_GUEST_LONG(d), + vcpu_info_addr(v, evtchn_pending_sel)) ) { vcpu_mark_events_pending(v); } @@ -720,10 +721,10 @@ static long evtchn_unmask(evtchn_unmask_t *unmask) * These operations must happen in strict order. Based on * include/xen/event.h:evtchn_set_pending(). */ - if ( test_and_clear_bit(port, s->evtchn_mask) && - test_bit (port, s->evtchn_pending) && - !test_and_set_bit (port / BITS_PER_LONG, - &v->vcpu_info->evtchn_pending_sel) ) + if ( test_and_clear_bit(port, __shared_info_addr(d, s, evtchn_mask)) && + test_bit (port, __shared_info_addr(d, s, evtchn_pending)) && + !test_and_set_bit (port / BITS_PER_GUEST_LONG(d), + vcpu_info_addr(v, evtchn_pending_sel)) ) { vcpu_mark_events_pending(v); } diff --git a/xen/common/kernel.c b/xen/common/kernel.c index bf46640526..016270b2c5 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -16,6 +16,9 @@ #include #include #include +#ifdef CONFIG_X86 +#include +#endif #ifndef COMPAT @@ -253,7 +256,7 @@ long register_guest_nmi_callback(unsigned long address) * If no handler was registered we can 'lose the NMI edge'. Re-assert it * now. */ - if ( d->shared_info->arch.nmi_reason != 0 ) + if ( arch_get_nmi_reason(d) != 0 ) set_bit(_VCPUF_nmi_pending, &v->vcpu_flags); #endif diff --git a/xen/common/keyhandler.c b/xen/common/keyhandler.c index 85fe6d89ca..3b5aeb05e2 100644 --- a/xen/common/keyhandler.c +++ b/xen/common/keyhandler.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -171,8 +172,8 @@ static void dump_domains(unsigned char key) v->vcpu_id, v->processor, test_bit(_VCPUF_running, &v->vcpu_flags) ? 'T':'F', v->vcpu_flags, - v->vcpu_info->evtchn_upcall_pending, - v->vcpu_info->evtchn_upcall_mask); + vcpu_info(v, evtchn_upcall_pending), + vcpu_info(v, evtchn_upcall_mask)); cpuset_print(cpuset, sizeof(cpuset), v->vcpu_dirty_cpumask); printk("dirty_cpus=%s ", cpuset); cpuset_print(cpuset, sizeof(cpuset), v->cpu_affinity); @@ -181,11 +182,11 @@ static void dump_domains(unsigned char key) printk(" Notifying guest (virq %d, port %d, stat %d/%d/%d)\n", VIRQ_DEBUG, v->virq_to_evtchn[VIRQ_DEBUG], test_bit(v->virq_to_evtchn[VIRQ_DEBUG], - d->shared_info->evtchn_pending), + shared_info_addr(d, evtchn_pending)), test_bit(v->virq_to_evtchn[VIRQ_DEBUG], - d->shared_info->evtchn_mask), - test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_LONG, - &v->vcpu_info->evtchn_pending_sel)); + shared_info_addr(d, evtchn_mask)), + test_bit(v->virq_to_evtchn[VIRQ_DEBUG]/BITS_PER_GUEST_LONG(d), + vcpu_info_addr(v, evtchn_pending_sel))); send_guest_vcpu_virq(v, VIRQ_DEBUG); } } diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 10f63b85bf..4083426cb0 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -277,10 +277,11 @@ static long do_block(void) static long do_poll(struct sched_poll *sched_poll) { - struct vcpu *v = current; - evtchn_port_t port; - long rc = 0; - unsigned int i; + struct vcpu *v = current; + struct domain *d = v->domain; + evtchn_port_t port; + long rc = 0; + unsigned int i; /* Fairly arbitrary limit. */ if ( sched_poll->nr_ports > 128 ) @@ -292,7 +293,7 @@ static long do_poll(struct sched_poll *sched_poll) /* These operations must occur in order. */ set_bit(_VCPUF_blocked, &v->vcpu_flags); set_bit(_VCPUF_polling, &v->vcpu_flags); - set_bit(_DOMF_polling, &v->domain->domain_flags); + set_bit(_DOMF_polling, &d->domain_flags); /* Check for events /after/ setting flags: avoids wakeup waiting race. */ for ( i = 0; i < sched_poll->nr_ports; i++ ) @@ -302,18 +303,18 @@ static long do_poll(struct sched_poll *sched_poll) goto out; rc = -EINVAL; - if ( port >= MAX_EVTCHNS ) + if ( port >= MAX_EVTCHNS(d) ) goto out; rc = 0; - if ( test_bit(port, v->domain->shared_info->evtchn_pending) ) + if ( test_bit(port, shared_info_addr(d, evtchn_pending)) ) goto out; } if ( sched_poll->timeout != 0 ) set_timer(&v->poll_timer, sched_poll->timeout); - TRACE_2D(TRC_SCHED_BLOCK, v->domain->domain_id, v->vcpu_id); + TRACE_2D(TRC_SCHED_BLOCK, d->domain_id, v->vcpu_id); raise_softirq(SCHEDULE_SOFTIRQ); return 0; diff --git a/xen/include/Makefile b/xen/include/Makefile index 57d8fe93de..416c3a8fee 100644 --- a/xen/include/Makefile +++ b/xen/include/Makefile @@ -29,6 +29,7 @@ compat/%.h: compat/%.i Makefile sed -e 's,__InClUdE__,#include,' \ -e 's,"xen-compat.h",,' \ -e 's,\(struct\|union\|enum\)[[:space:]]\+\(xen_\?\)\?\([[:alpha:]_]\),\1 compat_\3,g' \ + -e 's,@KeeP@,,g' \ -e 's,_t\([^[:alnum:]_]\|$$\),_compat_t\1,g' \ -e 's,\(8\|16\|32\|64\)_compat_t\([^[:alnum:]_]\|$$\),\1_t\2,g' \ -e 's,\(^\|[^[:alnum:]_]\)xen_\?\([[:alnum:]_]*\)_compat_t\([^[:alnum:]_]\|$$\),\1compat_\2_t\3,g' \ @@ -43,13 +44,15 @@ compat/%.h: compat/%.i Makefile compat/%.i: compat/%.c Makefile $(CPP) $(CFLAGS) $(cppflags-y) -o $@ $< -compat/%.c: public/%.h Makefile +compat/%.c: public/%.h xlat.lst Makefile mkdir -p $(@D) grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \ sed -e 's,^[[:space:]]*#[[:space:]]*include[[:space:]]\+,__InClUdE__ ,' \ -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:upper:]_]*_GUEST_HANDLE\),#define HIDE_\1,' \ -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:lower:]_]*_guest_handle\),#define hide_\1,' \ -e 's,XEN_GUEST_HANDLE\(_[[:xdigit:]]\+\)\?,COMPAT_HANDLE,g' \ + $(foreach n,$(shell sed -n 's,^[[:space:]]*?[[:space:]]\+\([[:alnum:]_]*\)[[:space:]].*,\1,p' xlat.lst), \ + -e 's,\(struct\|union\)[[:space:]]\+\(xen_\?\)\?$n[[:space:]]\+\([[:alpha:]_]\),\1 @KeeP@\2$n \3,g') \ >$@.new mv -f $@.new $@ diff --git a/xen/include/asm-ia64/shared.h b/xen/include/asm-ia64/shared.h new file mode 100644 index 0000000000..4f1ebb2a5d --- /dev/null +++ b/xen/include/asm-ia64/shared.h @@ -0,0 +1,4 @@ +#ifndef __XEN_ASM_SHARED_H__ +#define __XEN_ASM_SHARED_H__ + +#endif /* __XEN_ASM_SHARED_H__ */ diff --git a/xen/include/asm-powerpc/shared.h b/xen/include/asm-powerpc/shared.h new file mode 100644 index 0000000000..4f1ebb2a5d --- /dev/null +++ b/xen/include/asm-powerpc/shared.h @@ -0,0 +1,4 @@ +#ifndef __XEN_ASM_SHARED_H__ +#define __XEN_ASM_SHARED_H__ + +#endif /* __XEN_ASM_SHARED_H__ */ diff --git a/xen/include/asm-x86/compat.h b/xen/include/asm-x86/compat.h index 37a0cffdc2..f9df74ece8 100644 --- a/xen/include/asm-x86/compat.h +++ b/xen/include/asm-x86/compat.h @@ -2,5 +2,7 @@ * compat.h */ +#define COMPAT_BITS_PER_LONG 32 + typedef uint32_t compat_ptr_t; typedef unsigned long full_ptr_t; diff --git a/xen/include/asm-x86/event.h b/xen/include/asm-x86/event.h index 7085bd3138..475339550b 100644 --- a/xen/include/asm-x86/event.h +++ b/xen/include/asm-x86/event.h @@ -9,6 +9,8 @@ #ifndef __ASM_EVENT_H__ #define __ASM_EVENT_H__ +#include + static inline void vcpu_kick(struct vcpu *v) { /* @@ -28,7 +30,7 @@ static inline void vcpu_kick(struct vcpu *v) static inline void vcpu_mark_events_pending(struct vcpu *v) { - if ( !test_and_set_bit(0, &v->vcpu_info->evtchn_upcall_pending) ) + if ( !test_and_set_bit(0, &vcpu_info(v, evtchn_upcall_pending)) ) vcpu_kick(v); } @@ -36,23 +38,23 @@ static inline int local_events_need_delivery(void) { struct vcpu *v = current; /* Note: Bitwise operations result in fast code with no branches. */ - return (!!v->vcpu_info->evtchn_upcall_pending & - !v->vcpu_info->evtchn_upcall_mask); + return (!!vcpu_info(v, evtchn_upcall_pending) & + !vcpu_info(v, evtchn_upcall_mask)); } static inline int local_event_delivery_is_enabled(void) { - return !current->vcpu_info->evtchn_upcall_mask; + return !vcpu_info(current, evtchn_upcall_mask); } static inline void local_event_delivery_disable(void) { - current->vcpu_info->evtchn_upcall_mask = 1; + vcpu_info(current, evtchn_upcall_mask) = 1; } static inline void local_event_delivery_enable(void) { - current->vcpu_info->evtchn_upcall_mask = 0; + vcpu_info(current, evtchn_upcall_mask) = 0; } /* No arch specific virq definition now. Default to global. */ diff --git a/xen/include/asm-x86/shared.h b/xen/include/asm-x86/shared.h new file mode 100644 index 0000000000..32275dd285 --- /dev/null +++ b/xen/include/asm-x86/shared.h @@ -0,0 +1,78 @@ +#ifndef __XEN_X86_SHARED_H__ +#define __XEN_X86_SHARED_H__ + +#ifdef CONFIG_COMPAT + +#define nmi_reason(d) (!IS_COMPAT(d) ? \ + (void *)&(d)->shared_info->native.arch.nmi_reason : \ + (void *)&(d)->shared_info->compat.arch.nmi_reason) + +#define GET_SET_SHARED(type, field) \ +static inline type arch_get_##field(const struct domain *d) \ +{ \ + return !IS_COMPAT(d) ? \ + d->shared_info->native.arch.field : \ + d->shared_info->compat.arch.field; \ +} \ +static inline void arch_set_##field(struct domain *d, \ + type val) \ +{ \ + if ( !IS_COMPAT(d) ) \ + d->shared_info->native.arch.field = val; \ + else \ + d->shared_info->compat.arch.field = val; \ +} + +#define GET_SET_VCPU(type, field) \ +static inline type arch_get_##field(const struct vcpu *v) \ +{ \ + return !IS_COMPAT(v->domain) ? \ + v->vcpu_info->native.arch.field : \ + v->vcpu_info->compat.arch.field; \ +} \ +static inline void arch_set_##field(struct vcpu *v, \ + type val) \ +{ \ + if ( !IS_COMPAT(v->domain) ) \ + v->vcpu_info->native.arch.field = val; \ + else \ + v->vcpu_info->compat.arch.field = val; \ +} + +#else + +#define nmi_reason(d) ((void *)&(d)->shared_info->arch.nmi_reason) + +#define GET_SET_SHARED(type, field) \ +static inline type arch_get_##field(const struct domain *d) \ +{ \ + return d->shared_info->arch.field; \ +} \ +static inline void arch_set_##field(struct domain *d, \ + type val) \ +{ \ + d->shared_info->arch.field = val; \ +} + +#define GET_SET_VCPU(type, field) \ +static inline type arch_get_##field(const struct vcpu *v) \ +{ \ + return v->vcpu_info->arch.field; \ +} \ +static inline void arch_set_##field(struct vcpu *v, \ + type val) \ +{ \ + v->vcpu_info->arch.field = val; \ +} +#endif + +GET_SET_SHARED(unsigned long, max_pfn) +GET_SET_SHARED(xen_pfn_t, pfn_to_mfn_frame_list_list) +GET_SET_SHARED(unsigned long, nmi_reason) + +GET_SET_VCPU(unsigned long, cr2) + +#undef GET_SET_VCPU +#undef GET_SET_SHARED + +#endif /* __XEN_X86_SHARED_H__ */ diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h index 3e0bc68ad1..de365d6459 100644 --- a/xen/include/public/xen.h +++ b/xen/include/public/xen.h @@ -408,7 +408,9 @@ struct vcpu_info { struct arch_vcpu_info arch; struct vcpu_time_info time; }; /* 64 bytes (x86) */ +#ifndef __XEN__ typedef struct vcpu_info vcpu_info_t; +#endif /* * Xen/kernel shared data -- pointer provided in start_info. @@ -466,7 +468,9 @@ struct shared_info { struct arch_shared_info arch; }; +#ifndef __XEN__ typedef struct shared_info shared_info_t; +#endif /* * Start-of-day memory layout for the initial domain (DOM0): diff --git a/xen/include/xen/compat.h b/xen/include/xen/compat.h index 375ba39352..48d3b68898 100644 --- a/xen/include/xen/compat.h +++ b/xen/include/xen/compat.h @@ -162,6 +162,12 @@ extern int compat_disabled; struct start_info; void xlat_start_info(struct start_info *, enum XLAT_start_info_console); +#define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG) + +#else + +#define BITS_PER_GUEST_LONG(d) BITS_PER_LONG + #endif #endif /* __XEN_COMPAT_H__ */ diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index b1ef550440..533a5763f5 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include #include @@ -23,9 +24,15 @@ extern rwlock_t domlist_lock; /* A global pointer to the initial domain (DOM0). */ extern struct domain *dom0; -#define MAX_EVTCHNS NR_EVENT_CHANNELS +#ifndef CONFIG_COMPAT +#define MAX_EVTCHNS(d) NR_EVENT_CHANNELS +#else +#define MAX_EVTCHNS(d) (!IS_COMPAT(d) ? \ + NR_EVENT_CHANNELS : \ + sizeof(unsigned int) * sizeof(unsigned int) * 64) +#endif #define EVTCHNS_PER_BUCKET 128 -#define NR_EVTCHN_BUCKETS (MAX_EVTCHNS / EVTCHNS_PER_BUCKET) +#define NR_EVTCHN_BUCKETS (NR_EVENT_CHANNELS / EVTCHNS_PER_BUCKET) struct evtchn { diff --git a/xen/include/xen/shared.h b/xen/include/xen/shared.h new file mode 100644 index 0000000000..ee0510cf67 --- /dev/null +++ b/xen/include/xen/shared.h @@ -0,0 +1,54 @@ +#ifndef __XEN_SHARED_H__ +#define __XEN_SHARED_H__ + +#include + +#ifdef CONFIG_COMPAT + +#include + +typedef union { + struct shared_info native; + struct compat_shared_info compat; +} shared_info_t; + +#define __shared_info(d, s, field) (*(!IS_COMPAT(d) ? \ + &(s)->native.field : \ + &(s)->compat.field)) +#define __shared_info_addr(d, s, field) (!IS_COMPAT(d) ? \ + (void *)&(s)->native.field : \ + (void *)&(s)->compat.field) + +#define shared_info(d, field) __shared_info(d, (d)->shared_info, field) +#define shared_info_addr(d, field) __shared_info_addr(d, (d)->shared_info, field) + +typedef union { + struct vcpu_info native; + struct compat_vcpu_info compat; +} vcpu_info_t; + +#define vcpu_info(v, field) (*(!IS_COMPAT((v)->domain) ? \ + &(v)->vcpu_info->native.field : \ + &(v)->vcpu_info->compat.field)) +#define vcpu_info_addr(v, field) (!IS_COMPAT((v)->domain) ? \ + (void *)&(v)->vcpu_info->native.field : \ + (void *)&(v)->vcpu_info->compat.field) + +#else + +typedef struct shared_info shared_info_t; + +#define __shared_info(d, s, field) ((s)->field) +#define __shared_info_addr(d, s, field) ((void *)&(s)->field) + +#define shared_info(d, field) ((d)->shared_info->field) +#define shared_info_addr(d, field) ((void *)&(d)->shared_info->field) + +typedef struct vcpu_info vcpu_info_t; + +#define vcpu_info(v, field) ((v)->vcpu_info->field) +#define vcpu_info_addr(v, field) ((void *)&(v)->vcpu_info->field) + +#endif + +#endif /* __XEN_SHARED_H__ */ diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 8b7c96278a..fadfee9db5 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -3,3 +3,4 @@ # ? - needs checking ? dom0_vga_console_info xen.h ! start_info xen.h +? vcpu_time_info xen.h From cb44adaed67314e37a58d7ddab1b367007678baa Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:30 +0000 Subject: [PATCH 079/570] Add page table setup and handling, including the creation of an m2p table meaningful to compatibility mode guests. Signed-off-by: Jan Beulich --- xen/arch/x86/domain.c | 74 ++++++++-- xen/arch/x86/domain_build.c | 119 ++++++++++++--- xen/arch/x86/domctl.c | 7 +- xen/arch/x86/e820.c | 35 +++++ xen/arch/x86/mm.c | 175 +++++++++++++++-------- xen/arch/x86/x86_64/mm.c | 72 +++++++++- xen/common/compat/kernel.c | 2 +- xen/include/asm-x86/config.h | 30 +++- xen/include/asm-x86/domain.h | 4 + xen/include/asm-x86/mm.h | 9 ++ xen/include/asm-x86/page.h | 5 + xen/include/asm-x86/x86_32/page-2level.h | 2 +- xen/include/asm-x86/x86_32/page-3level.h | 2 +- xen/include/asm-x86/x86_64/page.h | 7 +- xen/include/asm-x86/x86_64/uaccess.h | 2 +- 15 files changed, 441 insertions(+), 104 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index ea41527f1c..6602aeccc4 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -127,6 +127,28 @@ void free_vcpu_struct(struct vcpu *v) xfree(v); } +#ifdef CONFIG_COMPAT +static int setup_compat_l4(struct vcpu *v) +{ + struct page_info *pg = alloc_domheap_page(NULL); + l4_pgentry_t *l4tab; + + if ( !pg ) + return -ENOMEM; + l4tab = copy_page(page_to_virt(pg), idle_pg_table); + l4tab[l4_table_offset(LINEAR_PT_VIRT_START)] = + l4e_from_page(pg, __PAGE_HYPERVISOR); + l4tab[l4_table_offset(PERDOMAIN_VIRT_START)] = + l4e_from_paddr(__pa(v->domain->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); + v->arch.guest_table = pagetable_from_page(pg); + v->arch.guest_table_user = v->arch.guest_table; + + return 0; +} +#else +#define setup_compat_l4(v) 0 +#endif + int vcpu_initialise(struct vcpu *v) { struct domain *d = v->domain; @@ -161,11 +183,16 @@ int vcpu_initialise(struct vcpu *v) v->arch.perdomain_ptes = d->arch.mm_perdomain_pt + (v->vcpu_id << GDT_LDT_VCPU_SHIFT); + if ( IS_COMPAT(d) && (rc = setup_compat_l4(v)) != 0 ) + return rc; + return 0; } void vcpu_destroy(struct vcpu *v) { + if ( IS_COMPAT(v->domain) ) + free_domheap_page(pagetable_get_page(v->arch.guest_table)); } int arch_domain_create(struct domain *d) @@ -219,6 +246,10 @@ int arch_domain_create(struct domain *d) #endif /* __x86_64__ */ +#ifdef CONFIG_COMPAT + HYPERVISOR_COMPAT_VIRT_START(d) = __HYPERVISOR_COMPAT_VIRT_START; +#endif + shadow_domain_init(d); if ( !is_idle_domain(d) ) @@ -349,18 +380,41 @@ int arch_set_info_guest( if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 ) return rc; - cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3])); - - if ( shadow_mode_refcounts(d) - ? !get_page(mfn_to_page(cr3_pfn), d) - : !get_page_and_type(mfn_to_page(cr3_pfn), d, - PGT_base_page_table) ) + if ( !IS_COMPAT(d) ) { - destroy_gdt(v); - return -EINVAL; - } + cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3])); - v->arch.guest_table = pagetable_from_pfn(cr3_pfn); + if ( shadow_mode_refcounts(d) + ? !get_page(mfn_to_page(cr3_pfn), d) + : !get_page_and_type(mfn_to_page(cr3_pfn), d, + PGT_base_page_table) ) + { + destroy_gdt(v); + return -EINVAL; + } + + v->arch.guest_table = pagetable_from_pfn(cr3_pfn); + } +#ifdef CONFIG_COMPAT + else + { + l4_pgentry_t *l4tab; + + cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c->ctrlreg[3])); + + if ( shadow_mode_refcounts(d) + ? !get_page(mfn_to_page(cr3_pfn), d) + : !get_page_and_type(mfn_to_page(cr3_pfn), d, + PGT_l3_page_table) ) + { + destroy_gdt(v); + return -EINVAL; + } + + l4tab = __va(pagetable_get_paddr(v->arch.guest_table)); + *l4tab = l4e_from_pfn(cr3_pfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED); + } +#endif } if ( v->vcpu_id == 0 ) diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index ce8f308fc3..3b721b45c7 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -91,9 +91,11 @@ string_param("dom0_ioports_disable", opt_dom0_ioports_disable); #define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) #define L3_PROT (_PAGE_PRESENT) #elif defined(__x86_64__) -/* Allow ring-3 access in long mode as guest cannot use ring 1. */ +/* Allow ring-3 access in long mode as guest cannot use ring 1 ... */ #define BASE_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_USER) #define L1_PROT (BASE_PROT|_PAGE_GUEST_KERNEL) +/* ... except for compatibility mode guests. */ +#define COMPAT_L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) #define L2_PROT (BASE_PROT|_PAGE_DIRTY) #define L3_PROT (BASE_PROT|_PAGE_DIRTY) #define L4_PROT (BASE_PROT|_PAGE_DIRTY) @@ -262,8 +264,8 @@ int construct_dom0(struct domain *d, start_info_t *si; struct vcpu *v = d->vcpu[0]; const char *p; - unsigned long hypercall_page; - int hypercall_page_defined; + unsigned long long value; + int value_defined; #if defined(__i386__) char *image_start = (char *)_image_start; /* use lowmem mappings */ char *initrd_start = (char *)_initrd_start; /* use lowmem mappings */ @@ -323,6 +325,7 @@ int construct_dom0(struct domain *d, rc = parseelfimage(&dsi); #ifdef CONFIG_COMPAT if ( rc == -ENOSYS + && !compat_disabled && (rc = parseelf32image(&dsi)) == 0 ) { l1_pgentry_t gdt_l1e; @@ -370,10 +373,37 @@ int construct_dom0(struct domain *d, #ifdef CONFIG_COMPAT if ( IS_COMPAT(d) ) + { + value = xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HV_START_LOW, &value_defined); p = xen_elf32note_string(&dsi, XEN_ELFNOTE_FEATURES); + } else #endif + { + value = xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HV_START_LOW, &value_defined); p = xen_elfnote_string(&dsi, XEN_ELFNOTE_FEATURES); + } + if ( value_defined ) + { +#if CONFIG_PAGING_LEVELS < 4 + unsigned long mask = (1UL << L2_PAGETABLE_SHIFT) - 1; +#else + unsigned long mask = !IS_COMPAT(d) + ? (1UL << L4_PAGETABLE_SHIFT) - 1 + : (1UL << L2_PAGETABLE_SHIFT) - 1; +#endif + + value = (value + mask) & ~mask; +#ifdef CONFIG_COMPAT + HYPERVISOR_COMPAT_VIRT_START(d) = max_t(unsigned int, m2p_compat_vstart, value); + if ( value > (!IS_COMPAT(d) ? + HYPERVISOR_VIRT_START : + __HYPERVISOR_COMPAT_VIRT_START) ) +#else + if ( value > HYPERVISOR_VIRT_START ) +#endif + panic("Domain 0 expects too high a hypervisor start address.\n"); + } if ( p != NULL ) { parse_features(p, @@ -400,7 +430,9 @@ int construct_dom0(struct domain *d, vinitrd_start = round_pgup(dsi.v_end); vinitrd_end = vinitrd_start + initrd_len; vphysmap_start = round_pgup(vinitrd_end); - vphysmap_end = vphysmap_start + (nr_pages * sizeof(unsigned long)); + vphysmap_end = vphysmap_start + (nr_pages * (!IS_COMPAT(d) ? + sizeof(unsigned long) : + sizeof(unsigned int))); vstartinfo_start = round_pgup(vphysmap_end); vstartinfo_end = (vstartinfo_start + sizeof(struct start_info) + @@ -429,7 +461,9 @@ int construct_dom0(struct domain *d, ((_l) & ~((1UL<<(_s))-1))) >> (_s)) if ( (1 + /* # L4 */ NR(dsi.v_start, v_end, L4_PAGETABLE_SHIFT) + /* # L3 */ - NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) + /* # L2 */ + (!IS_COMPAT(d) ? + NR(dsi.v_start, v_end, L3_PAGETABLE_SHIFT) : /* # L2 */ + 4) + /* # compat L2 */ NR(dsi.v_start, v_end, L2_PAGETABLE_SHIFT)) /* # L1 */ <= nr_pt_pages ) break; @@ -619,8 +653,10 @@ int construct_dom0(struct domain *d, #elif defined(__x86_64__) /* Overlap with Xen protected area? */ - if ( (dsi.v_start < HYPERVISOR_VIRT_END) && - (v_end > HYPERVISOR_VIRT_START) ) + if ( !IS_COMPAT(d) ? + ((dsi.v_start < HYPERVISOR_VIRT_END) && + (v_end > HYPERVISOR_VIRT_START)) : + (v_end > HYPERVISOR_COMPAT_VIRT_START(d)) ) { printk("DOM0 image overlaps with Xen private area.\n"); return -EINVAL; @@ -633,8 +669,18 @@ int construct_dom0(struct domain *d, } /* WARNING: The new domain must have its 'processor' field filled in! */ - maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table; - l4start = l4tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; + if ( !IS_COMPAT(d) ) + { + maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l4_page_table; + l4start = l4tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; + } + else + { + page = alloc_domheap_page(NULL); + if ( !page ) + panic("Not enough RAM for domain 0 PML4.\n"); + l4start = l4tab = page_to_virt(page); + } memcpy(l4tab, idle_pg_table, PAGE_SIZE); l4tab[l4_table_offset(LINEAR_PT_VIRT_START)] = l4e_from_paddr(__pa(l4start), __PAGE_HYPERVISOR); @@ -679,7 +725,7 @@ int construct_dom0(struct domain *d, *l2tab = l2e_from_paddr(__pa(l1start), L2_PROT); l2tab++; } - *l1tab = l1e_from_pfn(mfn, L1_PROT); + *l1tab = l1e_from_pfn(mfn, !IS_COMPAT(d) ? L1_PROT : COMPAT_L1_PROT); l1tab++; page = mfn_to_page(mfn); @@ -690,6 +736,30 @@ int construct_dom0(struct domain *d, mfn++; } +#ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) + { + /* Ensure the first four L3 entries are all populated. */ + for ( i = 0, l3tab = l3start; i < 4; ++i, ++l3tab ) + { + if ( !l3e_get_intpte(*l3tab) ) + { + maddr_to_page(mpt_alloc)->u.inuse.type_info = PGT_l2_page_table; + l2tab = __va(mpt_alloc); mpt_alloc += PAGE_SIZE; + clear_page(l2tab); + *l3tab = l3e_from_paddr(__pa(l2tab), L3_PROT); + } + if ( i == 3 ) + l3e_get_page(*l3tab)->u.inuse.type_info |= PGT_pae_xen_l2; + } + /* Install read-only guest visible MPT mapping. */ + l2tab = l3e_to_l2e(l3start[3]); + memcpy(&l2tab[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)], + &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)], + COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*l2tab)); + } +#endif + /* Pages that are part of page tables must be read only. */ l4tab = l4start + l4_table_offset(vpt_start); l3start = l3tab = l4e_to_l3e(*l4tab); @@ -708,7 +778,8 @@ int construct_dom0(struct domain *d, page->u.inuse.type_info |= PGT_validated | 1; /* Top-level p.t. is pinned. */ - if ( (page->u.inuse.type_info & PGT_type_mask) == PGT_l4_page_table ) + if ( (page->u.inuse.type_info & PGT_type_mask) == + (!IS_COMPAT(d) ? PGT_l4_page_table : PGT_l3_page_table) ) { page->count_info += 1; page->u.inuse.type_info += 1 | PGT_pinned; @@ -761,26 +832,26 @@ int construct_dom0(struct domain *d, if ( IS_COMPAT(d) ) { (void)loadelf32image(&dsi); - hypercall_page = - xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); + value = + xen_elf32note_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &value_defined); } else #endif { (void)loadelfimage(&dsi); - hypercall_page = - xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &hypercall_page_defined); + value = + xen_elfnote_numeric(&dsi, XEN_ELFNOTE_HYPERCALL_PAGE, &value_defined); } - if ( hypercall_page_defined ) + if ( value_defined ) { - if ( (hypercall_page < dsi.v_start) || (hypercall_page >= v_end) ) + if ( (value < dsi.v_start) || (value >= v_end) ) { write_ptbase(current); local_irq_enable(); printk("Invalid HYPERCALL_PAGE field in ELF notes.\n"); return -1; } - hypercall_page_initialise(d, (void *)hypercall_page); + hypercall_page_initialise(d, (void *)(unsigned long)value); } /* Copy the initial ramdisk. */ @@ -798,7 +869,7 @@ int construct_dom0(struct domain *d, si->shared_info = virt_to_maddr(d->shared_info); si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; - si->pt_base = vpt_start; + si->pt_base = vpt_start + 2 * PAGE_SIZE * !!IS_COMPAT(d); si->nr_pt_frames = nr_pt_pages; si->mfn_list = vphysmap_start; sprintf(si->magic, "xen-%i.%i-x86_%d%s", @@ -814,7 +885,10 @@ int construct_dom0(struct domain *d, if ( pfn > REVERSE_START ) mfn = alloc_epfn - (pfn - REVERSE_START); #endif - ((unsigned long *)vphysmap_start)[pfn] = mfn; + if ( !IS_COMPAT(d) ) + ((unsigned long *)vphysmap_start)[pfn] = mfn; + else + ((unsigned int *)vphysmap_start)[pfn] = mfn; set_gpfn_from_mfn(mfn, pfn); } while ( pfn < nr_pages ) @@ -827,7 +901,10 @@ int construct_dom0(struct domain *d, #ifndef NDEBUG #define pfn (nr_pages - 1 - (pfn - (alloc_epfn - alloc_spfn))) #endif - ((unsigned long *)vphysmap_start)[pfn] = mfn; + if ( !IS_COMPAT(d) ) + ((unsigned long *)vphysmap_start)[pfn] = mfn; + else + ((unsigned int *)vphysmap_start)[pfn] = mfn; set_gpfn_from_mfn(mfn, pfn); #undef pfn page++; pfn++; diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index d78e3b18ce..59e03e086c 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -311,7 +311,12 @@ void arch_getdomaininfo_ctxt( if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) ) c->flags |= VGCF_in_kernel; - c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); + if ( !IS_COMPAT(v->domain) ) + c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); +#ifdef CONFIG_COMPAT + else + c->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); +#endif c->vm_assist = v->domain->vm_assist; } diff --git a/xen/arch/x86/e820.c b/xen/arch/x86/e820.c index b12eb68c87..95daf54302 100644 --- a/xen/arch/x86/e820.c +++ b/xen/arch/x86/e820.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -341,6 +342,39 @@ static void __init clip_4gb(void) #define clip_4gb() ((void)0) #endif +#ifdef CONFIG_COMPAT +static void __init clip_compat(void) +{ + unsigned long long limit; + unsigned int i; + + if ( compat_disabled ) + return; + /* 32-bit guests restricted to 166 GB (with current memory allocator). */ + limit = (unsigned long long)(MACH2PHYS_COMPAT_VIRT_END - + __HYPERVISOR_COMPAT_VIRT_START) << 10; + for ( i = 0; i < e820.nr_map; i++ ) + { + if ( (e820.map[i].addr + e820.map[i].size) <= limit ) + continue; + printk("WARNING: Only the first %Lu GB of the physical memory map " + "can be accessed\n" + " by compatibility mode guests. " + "Truncating the memory map...\n", + limit >> 30); + if ( e820.map[i].addr >= limit ) + e820.nr_map = i; + else + { + e820.map[i].size = limit - e820.map[i].addr; + e820.nr_map = i + 1; + } + } +} +#else +#define clip_compat() ((void)0) +#endif + static void __init clip_mem(void) { int i; @@ -374,6 +408,7 @@ static void __init machine_specific_memory_setup( *raw_nr = nr; (void)copy_e820_map(raw, nr); clip_4gb(); + clip_compat(); clip_mem(); } diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index c8a3834e65..cc10a6df3f 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -126,13 +126,6 @@ */ #define MMU_UPDATE_PREEMPTED (~(~0U>>1)) -static void free_l2_table(struct page_info *page); -static void free_l1_table(struct page_info *page); - -static int mod_l2_entry(l2_pgentry_t *, l2_pgentry_t, unsigned long, - unsigned long type); -static int mod_l1_entry(l1_pgentry_t *, l1_pgentry_t, unsigned long gl1mfn); - /* Used to defer flushing of memory structures. */ struct percpu_mm_info { #define DOP_FLUSH_TLB (1<<0) /* Flush the local TLB. */ @@ -158,6 +151,15 @@ struct page_info *frame_table; unsigned long max_page; unsigned long total_pages; +#ifdef CONFIG_COMPAT +l2_pgentry_t *compat_idle_pg_table_l2 = NULL; +#define l3_disallow_mask(d) (!IS_COMPAT(d) ? \ + L3_DISALLOW_MASK : \ + COMPAT_L3_DISALLOW_MASK) +#else +#define l3_disallow_mask(d) L3_DISALLOW_MASK +#endif + void __init init_frametable(void) { unsigned long nr_pages, page_step, i, mfn; @@ -661,9 +663,9 @@ get_page_from_l3e( if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) return 1; - if ( unlikely((l3e_get_flags(l3e) & L3_DISALLOW_MASK)) ) + if ( unlikely((l3e_get_flags(l3e) & l3_disallow_mask(d))) ) { - MEM_LOG("Bad L3 flags %x", l3e_get_flags(l3e) & L3_DISALLOW_MASK); + MEM_LOG("Bad L3 flags %x", l3e_get_flags(l3e) & l3_disallow_mask(d)); return 0; } @@ -700,9 +702,10 @@ get_page_from_l4e( #ifdef __x86_64__ #ifdef USER_MAPPINGS_ARE_GLOBAL -#define adjust_guest_l1e(pl1e) \ +#define adjust_guest_l1e(pl1e, d) \ do { \ - if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) ) \ + if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) && \ + likely(!IS_COMPAT(d)) ) \ { \ /* _PAGE_GUEST_KERNEL page cannot have the Global bit set. */ \ if ( (l1e_get_flags((pl1e)) & (_PAGE_GUEST_KERNEL|_PAGE_GLOBAL)) \ @@ -716,39 +719,55 @@ get_page_from_l4e( } \ } while ( 0 ) #else -#define adjust_guest_l1e(pl1e) \ +#define adjust_guest_l1e(pl1e, d) \ do { \ - if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) ) \ + if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) && \ + likely(!IS_COMPAT(d)) ) \ l1e_add_flags((pl1e), _PAGE_USER); \ } while ( 0 ) #endif -#define adjust_guest_l2e(pl2e) \ +#define adjust_guest_l2e(pl2e, d) \ do { \ - if ( likely(l2e_get_flags((pl2e)) & _PAGE_PRESENT) ) \ + if ( likely(l2e_get_flags((pl2e)) & _PAGE_PRESENT) && \ + likely(!IS_COMPAT(d)) ) \ l2e_add_flags((pl2e), _PAGE_USER); \ } while ( 0 ) -#define adjust_guest_l3e(pl3e) \ +#define adjust_guest_l3e(pl3e, d) \ do { \ if ( likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \ - l3e_add_flags((pl3e), _PAGE_USER); \ + l3e_add_flags((pl3e), likely(!IS_COMPAT(d)) ? \ + _PAGE_USER : \ + _PAGE_USER|_PAGE_RW); \ } while ( 0 ) -#define adjust_guest_l4e(pl4e) \ +#define adjust_guest_l4e(pl4e, d) \ do { \ - if ( likely(l4e_get_flags((pl4e)) & _PAGE_PRESENT) ) \ + if ( likely(l4e_get_flags((pl4e)) & _PAGE_PRESENT) && \ + likely(!IS_COMPAT(d)) ) \ l4e_add_flags((pl4e), _PAGE_USER); \ } while ( 0 ) #else /* !defined(__x86_64__) */ -#define adjust_guest_l1e(_p) ((void)0) -#define adjust_guest_l2e(_p) ((void)0) -#define adjust_guest_l3e(_p) ((void)0) +#define adjust_guest_l1e(_p, _d) ((void)(_d)) +#define adjust_guest_l2e(_p, _d) ((void)(_d)) +#define adjust_guest_l3e(_p, _d) ((void)(_d)) #endif +#ifdef CONFIG_COMPAT +#define unadjust_guest_l3e(pl3e, d) \ + do { \ + if ( unlikely(IS_COMPAT(d)) && \ + likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \ + l3e_remove_flags((pl3e), _PAGE_USER|_PAGE_RW|_PAGE_ACCESSED); \ + } while ( 0 ) +#else +#define unadjust_guest_l3e(_p, _d) ((void)(_d)) +#endif + void put_page_from_l1e(l1_pgentry_t l1e, struct domain *d) { unsigned long pfn = l1e_get_pfn(l1e); @@ -850,7 +869,7 @@ static int alloc_l1_table(struct page_info *page) unlikely(!get_page_from_l1e(pl1e[i], d)) ) goto fail; - adjust_guest_l1e(pl1e[i]); + adjust_guest_l1e(pl1e[i], d); } unmap_domain_page(pl1e); @@ -866,13 +885,20 @@ static int alloc_l1_table(struct page_info *page) return 0; } -#ifdef CONFIG_X86_PAE -static int create_pae_xen_mappings(l3_pgentry_t *pl3e) +#if defined(CONFIG_X86_PAE) || defined(CONFIG_COMPAT) +static int create_pae_xen_mappings(struct domain *d, l3_pgentry_t *pl3e) { struct page_info *page; - l2_pgentry_t *pl2e, l2e; + l2_pgentry_t *pl2e; l3_pgentry_t l3e3; +#ifndef CONFIG_COMPAT + l2_pgentry_t l2e; int i; +#else + + if ( !IS_COMPAT(d) ) + return 1; +#endif pl3e = (l3_pgentry_t *)((unsigned long)pl3e & PAGE_MASK); @@ -905,6 +931,7 @@ static int create_pae_xen_mappings(l3_pgentry_t *pl3e) /* Xen private mappings. */ pl2e = map_domain_page(l3e_get_pfn(l3e3)); +#ifndef CONFIG_COMPAT memcpy(&pl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)], &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT], L2_PAGETABLE_XEN_SLOTS * sizeof(l2_pgentry_t)); @@ -922,11 +949,20 @@ static int create_pae_xen_mappings(l3_pgentry_t *pl3e) l2e = l2e_from_pfn(l3e_get_pfn(pl3e[i]), __PAGE_HYPERVISOR); l2e_write(&pl2e[l2_table_offset(LINEAR_PT_VIRT_START) + i], l2e); } +#else + memcpy(&pl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)], + &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)], + COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*pl2e)); +#endif unmap_domain_page(pl2e); return 1; } +#else +# define create_pae_xen_mappings(d, pl3e) (1) +#endif +#ifdef CONFIG_X86_PAE /* Flush a pgdir update into low-memory caches. */ static void pae_flush_pgd( unsigned long mfn, unsigned int idx, l3_pgentry_t nl3e) @@ -961,12 +997,8 @@ static void pae_flush_pgd( flush_tlb_mask(d->domain_dirty_cpumask); } - -#elif CONFIG_X86_64 -# define create_pae_xen_mappings(pl3e) (1) -# define pae_flush_pgd(mfn, idx, nl3e) ((void)0) #else -# define create_pae_xen_mappings(pl3e) (1) +# define pae_flush_pgd(mfn, idx, nl3e) ((void)0) #endif static int alloc_l2_table(struct page_info *page, unsigned long type) @@ -980,11 +1012,11 @@ static int alloc_l2_table(struct page_info *page, unsigned long type) for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ ) { - if ( is_guest_l2_slot(type, i) && + if ( is_guest_l2_slot(d, type, i) && unlikely(!get_page_from_l2e(pl2e[i], pfn, d)) ) goto fail; - adjust_guest_l2e(pl2e[i]); + adjust_guest_l2e(pl2e[i], d); } #if CONFIG_PAGING_LEVELS == 2 @@ -1007,7 +1039,7 @@ static int alloc_l2_table(struct page_info *page, unsigned long type) fail: MEM_LOG("Failure in alloc_l2_table: entry %d", i); while ( i-- > 0 ) - if ( is_guest_l2_slot(type, i) ) + if ( is_guest_l2_slot(d, type, i) ) put_page_from_l2e(pl2e[i], pfn); unmap_domain_page(pl2e); @@ -1039,13 +1071,24 @@ static int alloc_l3_table(struct page_info *page) #endif pl3e = map_domain_page(pfn); + + /* + * PAE guests allocate full pages, but aren't required to initialize + * more than the first four entries; when running in compatibility + * mode, however, the full page is visible to the MMU, and hence all + * 512 entries must be valid/verified, which is most easily achieved + * by clearing them out. + */ + if ( IS_COMPAT(d) ) + memset(pl3e + 4, 0, (L3_PAGETABLE_ENTRIES - 4) * sizeof(*pl3e)); + for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ ) { -#ifdef CONFIG_X86_PAE - if ( i == 3 ) +#if defined(CONFIG_X86_PAE) || defined(CONFIG_COMPAT) + if ( (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d)) && i == 3 ) { if ( !(l3e_get_flags(pl3e[i]) & _PAGE_PRESENT) || - (l3e_get_flags(pl3e[i]) & L3_DISALLOW_MASK) || + (l3e_get_flags(pl3e[i]) & l3_disallow_mask(d)) || !get_page_and_type_from_pagenr(l3e_get_pfn(pl3e[i]), PGT_l2_page_table | PGT_pae_xen_l2, @@ -1058,10 +1101,10 @@ static int alloc_l3_table(struct page_info *page) unlikely(!get_page_from_l3e(pl3e[i], pfn, d)) ) goto fail; - adjust_guest_l3e(pl3e[i]); + adjust_guest_l3e(pl3e[i], d); } - if ( !create_pae_xen_mappings(pl3e) ) + if ( !create_pae_xen_mappings(d, pl3e) ) goto fail; unmap_domain_page(pl3e); @@ -1094,7 +1137,7 @@ static int alloc_l4_table(struct page_info *page) unlikely(!get_page_from_l4e(pl4e[i], pfn, d)) ) goto fail; - adjust_guest_l4e(pl4e[i]); + adjust_guest_l4e(pl4e[i], d); } /* Xen private mappings. */ @@ -1142,6 +1185,9 @@ static void free_l1_table(struct page_info *page) static void free_l2_table(struct page_info *page) { +#ifdef CONFIG_COMPAT + struct domain *d = page_get_owner(page); +#endif unsigned long pfn = page_to_mfn(page); l2_pgentry_t *pl2e; int i; @@ -1149,7 +1195,7 @@ static void free_l2_table(struct page_info *page) pl2e = map_domain_page(pfn); for ( i = 0; i < L2_PAGETABLE_ENTRIES; i++ ) - if ( is_guest_l2_slot(page->u.inuse.type_info, i) ) + if ( is_guest_l2_slot(d, page->u.inuse.type_info, i) ) put_page_from_l2e(pl2e[i], pfn); unmap_domain_page(pl2e); @@ -1162,6 +1208,7 @@ static void free_l2_table(struct page_info *page) static void free_l3_table(struct page_info *page) { + struct domain *d = page_get_owner(page); unsigned long pfn = page_to_mfn(page); l3_pgentry_t *pl3e; int i; @@ -1170,7 +1217,10 @@ static void free_l3_table(struct page_info *page) for ( i = 0; i < L3_PAGETABLE_ENTRIES; i++ ) if ( is_guest_l3_slot(i) ) + { put_page_from_l3e(pl3e[i], pfn); + unadjust_guest_l3e(pl3e[i], d); + } unmap_domain_page(pl3e); } @@ -1270,7 +1320,7 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e, return 0; } - adjust_guest_l1e(nl1e); + adjust_guest_l1e(nl1e, d); /* Fast path for identical mapping, r/w and presence. */ if ( !l1e_has_changed(ol1e, nl1e, _PAGE_RW | _PAGE_PRESENT) ) @@ -1303,8 +1353,9 @@ static int mod_l2_entry(l2_pgentry_t *pl2e, unsigned long type) { l2_pgentry_t ol2e; + struct domain *d = current->domain; - if ( unlikely(!is_guest_l2_slot(type,pgentry_ptr_to_slot(pl2e))) ) + if ( unlikely(!is_guest_l2_slot(d, type, pgentry_ptr_to_slot(pl2e))) ) { MEM_LOG("Illegal L2 update attempt in Xen-private area %p", pl2e); return 0; @@ -1322,7 +1373,7 @@ static int mod_l2_entry(l2_pgentry_t *pl2e, return 0; } - adjust_guest_l2e(nl2e); + adjust_guest_l2e(nl2e, d); /* Fast path for identical mapping and presence. */ if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT)) @@ -1354,6 +1405,7 @@ static int mod_l3_entry(l3_pgentry_t *pl3e, unsigned long pfn) { l3_pgentry_t ol3e; + struct domain *d = current->domain; int okay; if ( unlikely(!is_guest_l3_slot(pgentry_ptr_to_slot(pl3e))) ) @@ -1362,12 +1414,13 @@ static int mod_l3_entry(l3_pgentry_t *pl3e, return 0; } -#ifdef CONFIG_X86_PAE +#if defined(CONFIG_X86_PAE) || defined(CONFIG_COMPAT) /* * Disallow updates to final L3 slot. It contains Xen mappings, and it * would be a pain to ensure they remain continuously valid throughout. */ - if ( pgentry_ptr_to_slot(pl3e) >= 3 ) + if ( (CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d)) && + pgentry_ptr_to_slot(pl3e) >= 3 ) return 0; #endif @@ -1376,14 +1429,14 @@ static int mod_l3_entry(l3_pgentry_t *pl3e, if ( l3e_get_flags(nl3e) & _PAGE_PRESENT ) { - if ( unlikely(l3e_get_flags(nl3e) & L3_DISALLOW_MASK) ) + if ( unlikely(l3e_get_flags(nl3e) & l3_disallow_mask(d)) ) { MEM_LOG("Bad L3 flags %x", - l3e_get_flags(nl3e) & L3_DISALLOW_MASK); + l3e_get_flags(nl3e) & l3_disallow_mask(d)); return 0; } - adjust_guest_l3e(nl3e); + adjust_guest_l3e(nl3e, d); /* Fast path for identical mapping and presence. */ if (!l3e_has_changed(ol3e, nl3e, _PAGE_PRESENT)) @@ -1403,7 +1456,7 @@ static int mod_l3_entry(l3_pgentry_t *pl3e, return 0; } - okay = create_pae_xen_mappings(pl3e); + okay = create_pae_xen_mappings(d, pl3e); BUG_ON(!okay); pae_flush_pgd(pfn, pgentry_ptr_to_slot(pl3e), nl3e); @@ -1441,7 +1494,7 @@ static int mod_l4_entry(l4_pgentry_t *pl4e, return 0; } - adjust_guest_l4e(nl4e); + adjust_guest_l4e(nl4e, current->domain); /* Fast path for identical mapping and presence. */ if (!l4e_has_changed(ol4e, nl4e, _PAGE_PRESENT)) @@ -2265,8 +2318,7 @@ int do_mmu_update( case PGT_l2_page_table: { l2_pgentry_t l2e = l2e_from_intpte(req.val); - okay = mod_l2_entry( - (l2_pgentry_t *)va, l2e, mfn, type_info); + okay = mod_l2_entry(va, l2e, mfn, type_info); } break; #if CONFIG_PAGING_LEVELS >= 3 @@ -2279,11 +2331,12 @@ int do_mmu_update( #endif #if CONFIG_PAGING_LEVELS >= 4 case PGT_l4_page_table: - { - l4_pgentry_t l4e = l4e_from_intpte(req.val); - okay = mod_l4_entry(va, l4e, mfn); - } - break; + if ( !IS_COMPAT(FOREIGNDOM) ) + { + l4_pgentry_t l4e = l4e_from_intpte(req.val); + okay = mod_l4_entry(va, l4e, mfn); + } + break; #endif } @@ -2387,7 +2440,7 @@ static int create_grant_pte_mapping( ASSERT(spin_is_locked(&d->big_lock)); - adjust_guest_l1e(nl1e); + adjust_guest_l1e(nl1e, d); gmfn = pte_addr >> PAGE_SHIFT; mfn = gmfn_to_mfn(d, gmfn); @@ -2508,7 +2561,7 @@ static int create_grant_va_mapping( ASSERT(spin_is_locked(&d->big_lock)); - adjust_guest_l1e(nl1e); + adjust_guest_l1e(nl1e, d); pl1e = guest_map_l1e(v, va, &gl1mfn); if ( !pl1e ) @@ -3173,7 +3226,7 @@ static int ptwr_emulated_update( } } - adjust_guest_l1e(nl1e); + adjust_guest_l1e(nl1e, d); /* Checked successfully: do the update (write or cmpxchg). */ pl1e = map_domain_page(page_to_mfn(page)); diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 54180bc511..135bf095b8 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -31,6 +31,10 @@ #include #include +#ifdef CONFIG_COMPAT +unsigned int m2p_compat_vstart = __HYPERVISOR_COMPAT_VIRT_START; +#endif + struct page_info *alloc_xen_pagetable(void) { extern int early_boot; @@ -121,6 +125,47 @@ void __init paging_init(void) l2_ro_mpt++; } +#ifdef CONFIG_COMPAT + if ( !compat_disabled ) + { + /* Create user-accessible L2 directory to map the MPT for compatibility guests. */ + BUILD_BUG_ON(l4_table_offset(RDWR_MPT_VIRT_START) != + l4_table_offset(HIRO_COMPAT_MPT_VIRT_START)); + l3_ro_mpt = l4e_to_l3e(idle_pg_table[l4_table_offset(HIRO_COMPAT_MPT_VIRT_START)]); + if ( (l2_pg = alloc_domheap_page(NULL)) == NULL ) + goto nomem; + compat_idle_pg_table_l2 = l2_ro_mpt = clear_page(page_to_virt(l2_pg)); + l3e_write(&l3_ro_mpt[l3_table_offset(HIRO_COMPAT_MPT_VIRT_START)], + l3e_from_page(l2_pg, __PAGE_HYPERVISOR)); + l2_ro_mpt += l2_table_offset(HIRO_COMPAT_MPT_VIRT_START); + /* + * Allocate and map the compatibility mode machine-to-phys table. + */ + mpt_size = (mpt_size >> 1) + (1UL << (L2_PAGETABLE_SHIFT - 1)); + if ( mpt_size > RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START ) + mpt_size = RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START; + mpt_size &= ~((1UL << L2_PAGETABLE_SHIFT) - 1UL); + if ( m2p_compat_vstart + mpt_size < MACH2PHYS_COMPAT_VIRT_END ) + m2p_compat_vstart = MACH2PHYS_COMPAT_VIRT_END - mpt_size; + for ( i = 0; i < (mpt_size >> L2_PAGETABLE_SHIFT); i++ ) + { + if ( (l1_pg = alloc_domheap_pages(NULL, PAGETABLE_ORDER, 0)) == NULL ) + goto nomem; + map_pages_to_xen( + RDWR_COMPAT_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT), + page_to_mfn(l1_pg), + 1UL << PAGETABLE_ORDER, + PAGE_HYPERVISOR); + memset((void *)(RDWR_COMPAT_MPT_VIRT_START + (i << L2_PAGETABLE_SHIFT)), + 0x55, + 1UL << L2_PAGETABLE_SHIFT); + /* NB. Cannot be GLOBAL as the pt entries get copied into per-VM space. */ + l2e_write(l2_ro_mpt, l2e_from_page(l1_pg, _PAGE_PSE|_PAGE_PRESENT)); + l2_ro_mpt++; + } + } +#endif + /* Set up linear page table mapping. */ l4e_write(&idle_pg_table[l4_table_offset(LINEAR_PT_VIRT_START)], l4e_from_paddr(__pa(idle_pg_table), __PAGE_HYPERVISOR)); @@ -182,6 +227,30 @@ void subarch_init_memory(void) share_xen_page_with_privileged_guests(page, XENSHARE_readonly); } } +#ifdef CONFIG_COMPAT + if ( !compat_disabled ) + { + for ( v = RDWR_COMPAT_MPT_VIRT_START; + v != RDWR_COMPAT_MPT_VIRT_END; + v += 1 << L2_PAGETABLE_SHIFT ) + { + l3e = l4e_to_l3e(idle_pg_table[l4_table_offset(v)])[ + l3_table_offset(v)]; + if ( !(l3e_get_flags(l3e) & _PAGE_PRESENT) ) + continue; + l2e = l3e_to_l2e(l3e)[l2_table_offset(v)]; + if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) + continue; + m2p_start_mfn = l2e_get_pfn(l2e); + + for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ ) + { + struct page_info *page = mfn_to_page(m2p_start_mfn + i); + share_xen_page_with_privileged_guests(page, XENSHARE_readonly); + } + } + } +#endif } long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) @@ -189,7 +258,8 @@ long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) struct xen_machphys_mfn_list xmml; l3_pgentry_t l3e; l2_pgentry_t l2e; - unsigned long mfn, v; + unsigned long v; + xen_pfn_t mfn; unsigned int i; long rc = 0; diff --git a/xen/common/compat/kernel.c b/xen/common/compat/kernel.c index 0618dbe8ad..07b1166ffd 100644 --- a/xen/common/compat/kernel.c +++ b/xen/common/compat/kernel.c @@ -27,7 +27,7 @@ CHECK_TYPE(capabilities_info); #define xen_platform_parameters compat_platform_parameters #define xen_platform_parameters_t compat_platform_parameters_t #undef HYPERVISOR_VIRT_START -#define HYPERVISOR_VIRT_START HYPERVISOR_COMPAT_VIRT_START +#define HYPERVISOR_VIRT_START HYPERVISOR_COMPAT_VIRT_START(current->domain) #define xen_changeset_info compat_changeset_info #define xen_changeset_info_t compat_changeset_info_t diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index 167b4b4897..dca9bbe39c 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -129,7 +129,11 @@ * Page-frame information array. * 0xffff828800000000 - 0xffff828bffffffff [16GB, 2^34 bytes, PML4:261] * ioremap()/fixmap area. - * 0xffff828c00000000 - 0xffff82ffffffffff [464GB, PML4:261] + * 0xffff828c00000000 - 0xffff828c3fffffff [1GB, 2^30 bytes, PML4:261] + * Compatibility machine-to-phys translation table. + * 0xffff828c40000000 - 0xffff828c7fffffff [1GB, 2^30 bytes, PML4:261] + * High read-only compatibility machine-to-phys translation table. + * 0xffff828c80000000 - 0xffff82ffffffffff [462GB, PML4:261] * Reserved for future use. * 0xffff830000000000 - 0xffff83ffffffffff [1TB, 2^40 bytes, PML4:262-263] * 1:1 direct mapping of all physical memory. Xen and its heap live here. @@ -178,17 +182,33 @@ /* Slot 261: ioremap()/fixmap area (16GB). */ #define IOREMAP_VIRT_START (FRAMETABLE_VIRT_END) #define IOREMAP_VIRT_END (IOREMAP_VIRT_START + (16UL<<30)) +/* Slot 261: compatibility machine-to-phys conversion table (1GB). */ +#define RDWR_COMPAT_MPT_VIRT_START IOREMAP_VIRT_END +#define RDWR_COMPAT_MPT_VIRT_END (RDWR_COMPAT_MPT_VIRT_START + (1UL << 30)) +/* Slot 261: high read-only compatibility machine-to-phys conversion table (1GB). */ +#define HIRO_COMPAT_MPT_VIRT_START RDWR_COMPAT_MPT_VIRT_END +#define HIRO_COMPAT_MPT_VIRT_END (HIRO_COMPAT_MPT_VIRT_START + (1UL << 30)) /* Slot 262-263: A direct 1:1 mapping of all of physical memory. */ #define DIRECTMAP_VIRT_START (PML4_ADDR(262)) #define DIRECTMAP_VIRT_END (DIRECTMAP_VIRT_START + PML4_ENTRY_BYTES*2) +#ifndef __ASSEMBLY__ + +/* This is not a fixed value, just a lower limit. */ #define __HYPERVISOR_COMPAT_VIRT_START 0xF5800000 -#define HYPERVISOR_COMPAT_VIRT_START \ - mk_unsigned_long(__HYPERVISOR_COMPAT_VIRT_START) +#define HYPERVISOR_COMPAT_VIRT_START(d) ((d)->arch.hv_compat_vstart) #define MACH2PHYS_COMPAT_VIRT_START HYPERVISOR_COMPAT_VIRT_START #define MACH2PHYS_COMPAT_VIRT_END 0xFFE00000 -#define MACH2PHYS_COMPAT_NR_ENTRIES \ - ((MACH2PHYS_COMPAT_VIRT_END-MACH2PHYS_COMPAT_VIRT_START)>>2) +#define MACH2PHYS_COMPAT_NR_ENTRIES(d) \ + ((MACH2PHYS_COMPAT_VIRT_END-MACH2PHYS_COMPAT_VIRT_START(d))>>2) + +#define COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d) \ + l2_table_offset(HYPERVISOR_COMPAT_VIRT_START(d)) +#define COMPAT_L2_PAGETABLE_LAST_XEN_SLOT l2_table_offset(~0U) +#define COMPAT_L2_PAGETABLE_XEN_SLOTS(d) \ + (COMPAT_L2_PAGETABLE_LAST_XEN_SLOT - COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d) + 1) + +#endif #define PGT_base_page_table PGT_l4_page_table diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index efda6dd263..0e6ef7aee4 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -98,6 +98,10 @@ struct arch_domain struct mapcache mapcache; #endif +#ifdef CONFIG_COMPAT + unsigned int hv_compat_vstart; +#endif + /* I/O-port admin-specified access capabilities. */ struct rangeset *ioport_caps; diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index a3d89a301d..d29e182cc7 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -257,7 +257,16 @@ int check_descriptor(const struct domain *, struct desc_struct *d); #define INVALID_M2P_ENTRY (~0UL) #define VALID_M2P(_e) (!((_e) & (1UL<<(BITS_PER_LONG-1)))) +#ifdef CONFIG_COMPAT +#define compat_machine_to_phys_mapping ((unsigned int *)RDWR_COMPAT_MPT_VIRT_START) +#define set_gpfn_from_mfn(mfn, pfn) \ + ((void)(compat_disabled || \ + (mfn) >= (RDWR_COMPAT_MPT_VIRT_END - RDWR_COMPAT_MPT_VIRT_START) / 4 || \ + (compat_machine_to_phys_mapping[(mfn)] = (unsigned int)(pfn))), \ + machine_to_phys_mapping[(mfn)] = (pfn)) +#else #define set_gpfn_from_mfn(mfn, pfn) (machine_to_phys_mapping[(mfn)] = (pfn)) +#endif #define get_gpfn_from_mfn(mfn) (machine_to_phys_mapping[(mfn)]) diff --git a/xen/include/asm-x86/page.h b/xen/include/asm-x86/page.h index e2bbc6c03f..53ddc287fc 100644 --- a/xen/include/asm-x86/page.h +++ b/xen/include/asm-x86/page.h @@ -206,6 +206,7 @@ typedef struct { u32 pfn; } pagetable_t; typedef struct { u64 pfn; } pagetable_t; #endif #define pagetable_get_paddr(x) ((paddr_t)(x).pfn << PAGE_SHIFT) +#define pagetable_get_page(x) mfn_to_page((x).pfn) #define pagetable_get_pfn(x) ((x).pfn) #define pagetable_is_null(x) ((x).pfn == 0) #define pagetable_from_pfn(pfn) ((pagetable_t) { (pfn) }) @@ -287,6 +288,10 @@ extern l2_pgentry_t idle_pg_table_l2[ROOT_PAGETABLE_ENTRIES*L2_PAGETABLE_ENTRI #else extern root_pgentry_t idle_pg_table[ROOT_PAGETABLE_ENTRIES]; extern l2_pgentry_t idle_pg_table_l2[ROOT_PAGETABLE_ENTRIES]; +#ifdef CONFIG_COMPAT +extern l2_pgentry_t *compat_idle_pg_table_l2; +extern unsigned int m2p_compat_vstart; +#endif #endif void paging_init(void); void setup_idle_pagetable(void); diff --git a/xen/include/asm-x86/x86_32/page-2level.h b/xen/include/asm-x86/x86_32/page-2level.h index 14a1d6411f..79e25024b4 100644 --- a/xen/include/asm-x86/x86_32/page-2level.h +++ b/xen/include/asm-x86/x86_32/page-2level.h @@ -42,7 +42,7 @@ typedef l2_pgentry_t root_pgentry_t; /* misc */ #define is_guest_l1_slot(_s) (1) -#define is_guest_l2_slot(_t,_s) ((_s) < L2_PAGETABLE_FIRST_XEN_SLOT) +#define is_guest_l2_slot(_d, _t,_s) ((_s) < L2_PAGETABLE_FIRST_XEN_SLOT) /* * PTE pfn and flags: diff --git a/xen/include/asm-x86/x86_32/page-3level.h b/xen/include/asm-x86/x86_32/page-3level.h index 6837933675..59ac4e1190 100644 --- a/xen/include/asm-x86/x86_32/page-3level.h +++ b/xen/include/asm-x86/x86_32/page-3level.h @@ -67,7 +67,7 @@ typedef l3_pgentry_t root_pgentry_t; /* misc */ #define is_guest_l1_slot(s) (1) -#define is_guest_l2_slot(t,s) \ +#define is_guest_l2_slot(d,t,s) \ ( !((t) & PGT_pae_xen_l2) || \ ((s) < (L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES - 1))) ) #define is_guest_l3_slot(s) (1) diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h index e6dcb1c025..b1f59b8f13 100644 --- a/xen/include/asm-x86/x86_64/page.h +++ b/xen/include/asm-x86/x86_64/page.h @@ -54,7 +54,10 @@ typedef l4_pgentry_t root_pgentry_t; #define l4_linear_offset(_a) (((_a) & VADDR_MASK) >> L4_PAGETABLE_SHIFT) #define is_guest_l1_slot(_s) (1) -#define is_guest_l2_slot(_t, _s) (1) +#define is_guest_l2_slot(_d, _t, _s) \ + ( !IS_COMPAT(_d) || \ + !((_t) & PGT_pae_xen_l2) || \ + ((_s) < COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(_d)) ) #define is_guest_l3_slot(_s) (1) #define is_guest_l4_slot(_s) \ (((_s) < ROOT_PAGETABLE_FIRST_XEN_SLOT) || \ @@ -93,6 +96,8 @@ typedef l4_pgentry_t root_pgentry_t; #define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) #define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) +#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */ + #define PAGE_HYPERVISOR (__PAGE_HYPERVISOR | _PAGE_GLOBAL) #define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL) diff --git a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h index c51e1a8739..a07ec5514c 100644 --- a/xen/include/asm-x86/x86_64/uaccess.h +++ b/xen/include/asm-x86/x86_64/uaccess.h @@ -18,7 +18,7 @@ #ifdef CONFIG_COMPAT #define __compat_addr_ok(addr) \ - ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START) + ((unsigned long)(addr) < HYPERVISOR_COMPAT_VIRT_START(current->domain)) #define compat_access_ok(addr, size) __compat_addr_ok((addr) + (size)) From 8d6e195a2defe04a82af0831969843ce0ed806a0 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:30 +0000 Subject: [PATCH 080/570] Adjust emulation code to deal with compatibility mode guests. This includes enhancements to emulate_privileged_op() that aren't directly related to such guests. Signed-off-by: Jan Beulich --- xen/arch/x86/domain.c | 14 ++ xen/arch/x86/mm.c | 31 ++- xen/arch/x86/traps.c | 282 ++++++++++++++++++++++----- xen/arch/x86/x86_64/mm.c | 6 +- xen/include/asm-x86/desc.h | 7 + xen/include/asm-x86/mm.h | 5 + xen/include/asm-x86/x86_32/uaccess.h | 2 +- xen/include/asm-x86/x86_64/uaccess.h | 2 +- 8 files changed, 296 insertions(+), 53 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 6602aeccc4..0ff815cc25 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1055,6 +1055,20 @@ void domain_relinquish_resources(struct domain *d) { /* Drop ref to guest_table (from new_guest_cr3(), svm/vmx cr3 handling, * or sh_update_paging_modes()) */ +#ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) + { + pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table))); + if ( pfn != 0 ) + { + if ( shadow_mode_refcounts(d) ) + put_page(mfn_to_page(pfn)); + else + put_page_and_type(mfn_to_page(pfn)); + } + continue; + } +#endif pfn = pagetable_get_pfn(v->arch.guest_table); if ( pfn != 0 ) { diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index cc10a6df3f..baa5a381e6 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1765,6 +1765,33 @@ int new_guest_cr3(unsigned long mfn) if ( is_hvm_domain(d) && !hvm_paging_enabled(v) ) return 0; +#ifdef CONFIG_COMPAT + if ( IS_COMPAT(d) ) + { + l4_pgentry_t l4e = l4e_from_pfn(mfn, _PAGE_PRESENT|_PAGE_RW|_PAGE_USER|_PAGE_ACCESSED); + + if ( shadow_mode_refcounts(d) ) + { + okay = get_page_from_pagenr(mfn, d); + old_base_mfn = l4e_get_pfn(l4e); + if ( okay && old_base_mfn ) + put_page(mfn_to_page(old_base_mfn)); + } + else + okay = mod_l4_entry(__va(pagetable_get_paddr(v->arch.guest_table)), + l4e, 0); + if ( unlikely(!okay) ) + { + MEM_LOG("Error while installing new compat baseptr %lx", mfn); + return 0; + } + + invalidate_shadow_ldt(v); + write_ptbase(v); + + return 1; + } +#endif if ( shadow_mode_refcounts(d) ) { okay = get_page_from_pagenr(mfn, d); @@ -3204,7 +3231,7 @@ static int ptwr_emulated_update( nl1e = l1e_from_intpte(val); if ( unlikely(!get_page_from_l1e(gl1e_to_ml1e(d, nl1e), d)) ) { - if ( (CONFIG_PAGING_LEVELS == 3) && + if ( (CONFIG_PAGING_LEVELS == 3 || IS_COMPAT(d)) && (bytes == 4) && !do_cmpxchg && (l1e_get_flags(nl1e) & _PAGE_PRESENT) ) @@ -3347,7 +3374,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, goto bail; ptwr_ctxt.ctxt.regs = guest_cpu_user_regs(); - ptwr_ctxt.ctxt.mode = X86EMUL_MODE_HOST; + ptwr_ctxt.ctxt.mode = !IS_COMPAT(d) ? X86EMUL_MODE_HOST : X86EMUL_MODE_PROT32; ptwr_ctxt.cr2 = addr; ptwr_ctxt.pte = pte; if ( x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) ) diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index 5d7137f3a7..cf1defeae3 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -977,6 +977,64 @@ long do_fpu_taskswitch(int set) return 0; } +static int read_descriptor(unsigned int sel, + const struct vcpu *v, + const struct cpu_user_regs * regs, + unsigned long *base, + unsigned long *limit, + unsigned int *ar, + unsigned int vm86attr) +{ + struct desc_struct desc; + + if ( !vm86_mode(regs) ) + { + if ( sel < 4) + desc.b = desc.a = 0; + else if ( __get_user(desc, + (const struct desc_struct *)(!(sel & 4) + ? GDT_VIRT_START(v) + : LDT_VIRT_START(v)) + + (sel >> 3)) ) + return 0; + if ( !(vm86attr & _SEGMENT_CODE) ) + desc.b &= ~_SEGMENT_L; + } + else + { + desc.a = (sel << 20) | 0xffff; + desc.b = vm86attr | (sel >> 12); + } + + *ar = desc.b & 0x00f0ff00; + if ( !(desc.b & _SEGMENT_L) ) + { + *base = (desc.a >> 16) + ((desc.b & 0xff) << 16) + (desc.b & 0xff000000); + *limit = (desc.a & 0xffff) | (desc.b & 0x000f0000); + if ( desc.b & _SEGMENT_G ) + *limit = ((*limit + 1) << 12) - 1; +#ifndef NDEBUG + if ( !vm86_mode(regs) && sel > 3 ) + { + unsigned int a, l; + unsigned char valid; + + __asm__("larl %2, %0\n\tsetz %1" : "=r" (a), "=rm" (valid) : "rm" (sel)); + BUG_ON(valid && (a & 0x00f0ff00) != *ar); + __asm__("lsll %2, %0\n\tsetz %1" : "=r" (l), "=rm" (valid) : "rm" (sel)); + BUG_ON(valid && l != *limit); + } +#endif + } + else + { + *base = 0UL; + *limit = ~0UL; + } + + return 1; +} + /* Has the guest requested sufficient permission for this I/O access? */ static inline int guest_io_okay( unsigned int port, unsigned int bytes, @@ -1041,65 +1099,113 @@ unsigned long guest_to_host_gpr_switch(unsigned long) __attribute__((__regparm__(1))); /* Instruction fetch with error handling. */ -#define insn_fetch(_type, _size, cs, eip) \ -({ unsigned long _rc, _x, _ptr = eip; \ - if ( vm86_mode(regs) ) \ - _ptr += cs << 4; \ - if ( (_rc = copy_from_user(&_x, (_type *)_ptr, sizeof(_type))) != 0 ) \ +#define insn_fetch(type, base, eip, limit) \ +({ unsigned long _rc, _ptr = (base) + (eip); \ + type _x; \ + if ( (limit) < sizeof(_x) - 1 || (eip) > (limit) - (sizeof(_x) - 1) ) \ + goto fail; \ + if ( (_rc = copy_from_user(&_x, (type *)_ptr, sizeof(_x))) != 0 ) \ { \ - propagate_page_fault(eip + sizeof(_type) - _rc, 0); \ + propagate_page_fault(_ptr + sizeof(_x) - _rc, 0); \ return EXCRET_fault_fixed; \ } \ - eip += _size; (_type)_x; }) + (eip) += sizeof(_x); _x; }) + +#if defined(CONFIG_X86_32) +# define read_sreg(regs, sr) ((regs)->sr) +#elif defined(CONFIG_X86_64) +# define read_sreg(regs, sr) read_segment_register(sr) +#endif static int emulate_privileged_op(struct cpu_user_regs *regs) { struct vcpu *v = current; - unsigned long *reg, eip = regs->eip, cs = regs->cs, res; - u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0; - unsigned int port, i, op_bytes = 4, data, rc; + unsigned long *reg, eip = regs->eip, res; + u8 opcode, modrm_reg = 0, modrm_rm = 0, rep_prefix = 0, rex = 0; + enum { lm_seg_none, lm_seg_fs, lm_seg_gs } lm_ovr = lm_seg_none; + unsigned int port, i, data_sel, ar, data, rc; + unsigned int op_bytes, op_default, ad_bytes, ad_default; +#define rd_ad(reg) (ad_bytes >= sizeof(regs->reg) \ + ? regs->reg \ + : ad_bytes == 4 \ + ? (u32)regs->reg \ + : (u16)regs->reg) +#define wr_ad(reg, val) (ad_bytes >= sizeof(regs->reg) \ + ? regs->reg = (val) \ + : ad_bytes == 4 \ + ? (*(u32 *)®s->reg = (val)) \ + : (*(u16 *)®s->reg = (val))) + unsigned long code_base, code_limit; char io_emul_stub[16]; void (*io_emul)(struct cpu_user_regs *) __attribute__((__regparm__(1))); u32 l, h; + if ( !read_descriptor(regs->cs, v, regs, + &code_base, &code_limit, &ar, + _SEGMENT_CODE|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) ) + goto fail; + op_default = op_bytes = (ar & (_SEGMENT_L|_SEGMENT_DB)) ? 4 : 2; + ad_default = ad_bytes = (ar & _SEGMENT_L) ? 8 : op_default; + if ( !(ar & (_SEGMENT_CODE|_SEGMENT_S|_SEGMENT_P)) ) + goto fail; + + /* emulating only opcodes not allowing SS to be default */ + data_sel = read_sreg(regs, ds); + /* Legacy prefixes. */ - for ( i = 0; i < 8; i++ ) + for ( i = 0; i < 8; i++, rex == opcode || (rex = 0) ) { - switch ( opcode = insn_fetch(u8, 1, cs, eip) ) + switch ( opcode = insn_fetch(u8, code_base, eip, code_limit) ) { case 0x66: /* operand-size override */ - op_bytes ^= 6; /* switch between 2/4 bytes */ - break; + op_bytes = op_default ^ 6; /* switch between 2/4 bytes */ + continue; case 0x67: /* address-size override */ + ad_bytes = ad_default != 4 ? 4 : 2; /* switch to 2/4 bytes */ + continue; case 0x2e: /* CS override */ + data_sel = regs->cs; + continue; case 0x3e: /* DS override */ + data_sel = read_sreg(regs, ds); + continue; case 0x26: /* ES override */ + data_sel = read_sreg(regs, es); + continue; case 0x64: /* FS override */ + data_sel = read_sreg(regs, fs); + lm_ovr = lm_seg_fs; + continue; case 0x65: /* GS override */ + data_sel = read_sreg(regs, gs); + lm_ovr = lm_seg_gs; + continue; case 0x36: /* SS override */ + data_sel = regs->ss; + continue; case 0xf0: /* LOCK */ + continue; case 0xf2: /* REPNE/REPNZ */ - break; case 0xf3: /* REP/REPE/REPZ */ rep_prefix = 1; - break; + continue; default: - goto done_prefixes; + if ( (ar & _SEGMENT_L) && (opcode & 0xf0) == 0x40 ) + { + rex = opcode; + continue; + } + break; } + break; } - done_prefixes: -#ifdef __x86_64__ /* REX prefix. */ - if ( (opcode & 0xf0) == 0x40 ) - { - modrm_reg = (opcode & 4) << 1; /* REX.R */ - modrm_rm = (opcode & 1) << 3; /* REX.B */ - - /* REX.W and REX.X do not need to be decoded. */ - opcode = insn_fetch(u8, 1, cs, eip); - } -#endif + if ( rex & 8 ) /* REX.W */ + op_bytes = 4; /* emulating only opcodes not supporting 64-bit operands */ + modrm_reg = (rex & 4) << 1; /* REX.R */ + /* REX.X does not need to be decoded. */ + modrm_rm = (rex & 1) << 3; /* REX.B */ if ( opcode == 0x0f ) goto twobyte_opcode; @@ -1107,16 +1213,68 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) /* Input/Output String instructions. */ if ( (opcode >= 0x6c) && (opcode <= 0x6f) ) { - if ( rep_prefix && (regs->ecx == 0) ) + unsigned long data_base, data_limit; + + if ( rep_prefix && (rd_ad(ecx) == 0) ) goto done; + if ( !(opcode & 2) ) + { + data_sel = read_sreg(regs, es); + lm_ovr = lm_seg_none; + } + + if ( !(ar & _SEGMENT_L) ) + { + if ( !read_descriptor(data_sel, v, regs, + &data_base, &data_limit, &ar, + _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) ) + goto fail; + if ( !(ar & (_SEGMENT_S|_SEGMENT_P)) || + (opcode & 2 ? + (ar & _SEGMENT_CODE) && !(ar & _SEGMENT_WR) : + (ar & _SEGMENT_CODE) || !(ar & _SEGMENT_WR)) ) + goto fail; + } +#ifdef CONFIG_X86_64 + else + { + if ( lm_ovr == lm_seg_none || data_sel < 4 ) + { + switch ( lm_ovr ) + { + case lm_seg_none: + data_base = 0UL; + break; + case lm_seg_fs: + data_base = v->arch.guest_context.fs_base; + break; + case lm_seg_gs: + if ( guest_kernel_mode(v, regs) ) + data_base = v->arch.guest_context.gs_base_kernel; + else + data_base = v->arch.guest_context.gs_base_user; + break; + } + } + else + read_descriptor(data_sel, v, regs, + &data_base, &data_limit, &ar, + 0); + data_limit = ~0UL; + ar = _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P; + } +#endif + continue_io_string: switch ( opcode ) { case 0x6c: /* INSB */ op_bytes = 1; case 0x6d: /* INSW/INSL */ - if ( !guest_io_okay((u16)regs->edx, op_bytes, v, regs) ) + if ( data_limit < op_bytes - 1 || + rd_ad(edi) > data_limit - (op_bytes - 1) || + !guest_io_okay((u16)regs->edx, op_bytes, v, regs) ) goto fail; port = (u16)regs->edx; switch ( op_bytes ) @@ -1134,24 +1292,26 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) data = (u32)(guest_inl_okay(port, v, regs) ? inl(port) : ~0); break; } - if ( (rc = copy_to_user((void *)regs->edi, &data, op_bytes)) != 0 ) + if ( (rc = copy_to_user((void *)data_base + rd_ad(edi), &data, op_bytes)) != 0 ) { - propagate_page_fault(regs->edi + op_bytes - rc, + propagate_page_fault(data_base + rd_ad(edi) + op_bytes - rc, PFEC_write_access); return EXCRET_fault_fixed; } - regs->edi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes); + wr_ad(edi, regs->edi + (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes)); break; case 0x6e: /* OUTSB */ op_bytes = 1; case 0x6f: /* OUTSW/OUTSL */ - if ( !guest_io_okay((u16)regs->edx, op_bytes, v, regs) ) + if ( data_limit < op_bytes - 1 || + rd_ad(esi) > data_limit - (op_bytes - 1) || + !guest_io_okay((u16)regs->edx, op_bytes, v, regs) ) goto fail; - rc = copy_from_user(&data, (void *)regs->esi, op_bytes); + rc = copy_from_user(&data, (void *)data_base + rd_ad(esi), op_bytes); if ( rc != 0 ) { - propagate_page_fault(regs->esi + op_bytes - rc, 0); + propagate_page_fault(data_base + rd_ad(esi) + op_bytes - rc, 0); return EXCRET_fault_fixed; } port = (u16)regs->edx; @@ -1172,11 +1332,11 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) outl((u32)data, port); break; } - regs->esi += (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes); + wr_ad(esi, regs->esi + (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes)); break; } - if ( rep_prefix && (--regs->ecx != 0) ) + if ( rep_prefix && (wr_ad(ecx, regs->ecx - 1) != 0) ) { if ( !hypercall_preempt_check() ) goto continue_io_string; @@ -1216,7 +1376,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 0xe4: /* IN imm8,%al */ op_bytes = 1; case 0xe5: /* IN imm8,%eax */ - port = insn_fetch(u8, 1, cs, eip); + port = insn_fetch(u8, code_base, eip, code_limit); io_emul_stub[7] = port; /* imm8 */ exec_in: if ( !guest_io_okay(port, op_bytes, v, regs) ) @@ -1258,7 +1418,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 0xe6: /* OUT %al,imm8 */ op_bytes = 1; case 0xe7: /* OUT %eax,imm8 */ - port = insn_fetch(u8, 1, cs, eip); + port = insn_fetch(u8, code_base, eip, code_limit); io_emul_stub[7] = port; /* imm8 */ exec_out: if ( !guest_io_okay(port, op_bytes, v, regs) ) @@ -1311,7 +1471,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) goto fail; /* Privileged (ring 0) instructions. */ - opcode = insn_fetch(u8, 1, cs, eip); + opcode = insn_fetch(u8, code_base, eip, code_limit); switch ( opcode ) { case 0x06: /* CLTS */ @@ -1329,7 +1489,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) break; case 0x20: /* MOV CR?, */ - opcode = insn_fetch(u8, 1, cs, eip); + opcode = insn_fetch(u8, code_base, eip, code_limit); modrm_reg |= (opcode >> 3) & 7; modrm_rm |= (opcode >> 0) & 7; reg = decode_register(modrm_rm, regs, 0); @@ -1345,8 +1505,14 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) break; case 3: /* Read CR3 */ - *reg = xen_pfn_to_cr3(mfn_to_gmfn( - v->domain, pagetable_get_pfn(v->arch.guest_table))); + if ( !IS_COMPAT(v->domain) ) + *reg = xen_pfn_to_cr3(mfn_to_gmfn( + v->domain, pagetable_get_pfn(v->arch.guest_table))); +#ifdef CONFIG_COMPAT + else + *reg = compat_pfn_to_cr3(mfn_to_gmfn( + v->domain, l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table))))); +#endif break; case 4: /* Read CR4 */ @@ -1363,7 +1529,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) break; case 0x21: /* MOV DR?, */ - opcode = insn_fetch(u8, 1, cs, eip); + opcode = insn_fetch(u8, code_base, eip, code_limit); modrm_reg |= (opcode >> 3) & 7; modrm_rm |= (opcode >> 0) & 7; reg = decode_register(modrm_rm, regs, 0); @@ -1373,7 +1539,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) break; case 0x22: /* MOV ,CR? */ - opcode = insn_fetch(u8, 1, cs, eip); + opcode = insn_fetch(u8, code_base, eip, code_limit); modrm_reg |= (opcode >> 3) & 7; modrm_rm |= (opcode >> 0) & 7; reg = decode_register(modrm_rm, regs, 0); @@ -1396,7 +1562,12 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) case 3: /* Write CR3 */ LOCK_BIGLOCK(v->domain); - rc = new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg))); + if ( !IS_COMPAT(v->domain) ) + rc = new_guest_cr3(gmfn_to_mfn(v->domain, xen_cr3_to_pfn(*reg))); +#ifdef CONFIG_COMPAT + else + rc = new_guest_cr3(gmfn_to_mfn(v->domain, compat_cr3_to_pfn(*reg))); +#endif UNLOCK_BIGLOCK(v->domain); if ( rc == 0 ) /* not okay */ goto fail; @@ -1416,7 +1587,7 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) break; case 0x23: /* MOV ,DR? */ - opcode = insn_fetch(u8, 1, cs, eip); + opcode = insn_fetch(u8, code_base, eip, code_limit); modrm_reg |= (opcode >> 3) & 7; modrm_rm |= (opcode >> 0) & 7; reg = decode_register(modrm_rm, regs, 0); @@ -1429,18 +1600,24 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) { #ifdef CONFIG_X86_64 case MSR_FS_BASE: + if ( IS_COMPAT(v->domain) ) + goto fail; if ( wrmsr_safe(MSR_FS_BASE, regs->eax, regs->edx) ) goto fail; v->arch.guest_context.fs_base = ((u64)regs->edx << 32) | regs->eax; break; case MSR_GS_BASE: + if ( IS_COMPAT(v->domain) ) + goto fail; if ( wrmsr_safe(MSR_GS_BASE, regs->eax, regs->edx) ) goto fail; v->arch.guest_context.gs_base_kernel = ((u64)regs->edx << 32) | regs->eax; break; case MSR_SHADOW_GS_BASE: + if ( IS_COMPAT(v->domain) ) + goto fail; if ( wrmsr_safe(MSR_SHADOW_GS_BASE, regs->eax, regs->edx) ) goto fail; v->arch.guest_context.gs_base_user = @@ -1465,14 +1642,20 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) { #ifdef CONFIG_X86_64 case MSR_FS_BASE: + if ( IS_COMPAT(v->domain) ) + goto fail; regs->eax = v->arch.guest_context.fs_base & 0xFFFFFFFFUL; regs->edx = v->arch.guest_context.fs_base >> 32; break; case MSR_GS_BASE: + if ( IS_COMPAT(v->domain) ) + goto fail; regs->eax = v->arch.guest_context.gs_base_kernel & 0xFFFFFFFFUL; regs->edx = v->arch.guest_context.gs_base_kernel >> 32; break; case MSR_SHADOW_GS_BASE: + if ( IS_COMPAT(v->domain) ) + goto fail; regs->eax = v->arch.guest_context.gs_base_user & 0xFFFFFFFFUL; regs->edx = v->arch.guest_context.gs_base_user >> 32; break; @@ -1501,6 +1684,9 @@ static int emulate_privileged_op(struct cpu_user_regs *regs) goto fail; } +#undef wr_ad +#undef rd_ad + done: regs->eip = eip; return EXCRET_fault_fixed; diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 135bf095b8..64448004df 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -376,7 +376,11 @@ int check_descriptor(const struct domain *dom, struct desc_struct *d) /* All code and data segments are okay. No base/limit checking. */ if ( (b & _SEGMENT_S) ) - goto good; + { + if ( !IS_COMPAT(dom) || !(b & _SEGMENT_L) ) + goto good; + goto bad; + } /* Invalid type 0 is harmless. It is used for 2nd half of a call gate. */ if ( (b & _SEGMENT_TYPE) == 0x000 ) diff --git a/xen/include/asm-x86/desc.h b/xen/include/asm-x86/desc.h index e3bc46b323..154f76736b 100644 --- a/xen/include/asm-x86/desc.h +++ b/xen/include/asm-x86/desc.h @@ -113,12 +113,19 @@ /* These are bitmasks for the high 32 bits of a descriptor table entry. */ #define _SEGMENT_TYPE (15<< 8) +#define _SEGMENT_WR ( 1<< 9) /* Writeable (data) or Readable (code) + segment */ #define _SEGMENT_EC ( 1<<10) /* Expand-down or Conforming segment */ #define _SEGMENT_CODE ( 1<<11) /* Code (vs data) segment for non-system segments */ #define _SEGMENT_S ( 1<<12) /* System descriptor (yes iff S==0) */ #define _SEGMENT_DPL ( 3<<13) /* Descriptor Privilege Level */ #define _SEGMENT_P ( 1<<15) /* Segment Present */ +#ifdef __x86_64 +#define _SEGMENT_L ( 1<<21) /* 64-bit segment */ +#else +#define _SEGMENT_L 0 +#endif #define _SEGMENT_DB ( 1<<22) /* 16- or 32-bit segment */ #define _SEGMENT_G ( 1<<23) /* Granularity */ diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index d29e182cc7..cf585e1e29 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -279,6 +279,11 @@ int check_descriptor(const struct domain *, struct desc_struct *d); #define INVALID_MFN (~0UL) +#ifdef CONFIG_COMPAT +#define compat_pfn_to_cr3(pfn) (((unsigned)(pfn) << 12) | ((unsigned)(pfn) >> 20)) +#define compat_cr3_to_pfn(cr3) (((unsigned)(cr3) >> 12) | ((unsigned)(cr3) << 20)) +#endif + #ifdef MEMORY_GUARD void memguard_init(void); void memguard_guard_range(void *p, unsigned long l); diff --git a/xen/include/asm-x86/x86_32/uaccess.h b/xen/include/asm-x86/x86_32/uaccess.h index 1ea7f86cae..947593fd08 100644 --- a/xen/include/asm-x86/x86_32/uaccess.h +++ b/xen/include/asm-x86/x86_32/uaccess.h @@ -83,7 +83,7 @@ do { \ case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break; \ case 4: __get_user_asm(x,ptr,retval,"l","","=r",errret);break; \ case 8: __get_user_u64(x,ptr,retval,errret);break; \ - default: (x) = __get_user_bad(); \ + default: __get_user_bad(); \ } \ } while (0) diff --git a/xen/include/asm-x86/x86_64/uaccess.h b/xen/include/asm-x86/x86_64/uaccess.h index a07ec5514c..565a33c81d 100644 --- a/xen/include/asm-x86/x86_64/uaccess.h +++ b/xen/include/asm-x86/x86_64/uaccess.h @@ -48,7 +48,7 @@ do { \ case 2: __get_user_asm(x,ptr,retval,"w","w","=r",errret);break; \ case 4: __get_user_asm(x,ptr,retval,"l","k","=r",errret);break; \ case 8: __get_user_asm(x,ptr,retval,"q","","=r",errret); break; \ - default: (x) = __get_user_bad(); \ + default: __get_user_bad(); \ } \ } while (0) From b8a7efe8528aa0a82c06431b652a8e922bf15994 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:31 +0000 Subject: [PATCH 081/570] Enable compatibility mode operation for HYPERVISOR_memory_op, HYPERVISOR_update_descriptor, HYPERVISOR_update_va_mapping. This also introduces infrastructure to do argument translation. Signed-off-by: Jan Beulich --- xen/arch/x86/domain.c | 277 +++++++++++++++++++--- xen/arch/x86/domain_build.c | 4 + xen/arch/x86/mm.c | 13 +- xen/arch/x86/x86_64/Makefile | 1 + xen/arch/x86/x86_64/compat/entry.S | 4 - xen/arch/x86/x86_64/compat/mm.c | 148 ++++++++++++ xen/arch/x86/x86_64/mm.c | 3 + xen/common/compat/Makefile | 1 + xen/common/compat/memory.c | 364 +++++++++++++++++++++++++++++ xen/common/memory.c | 22 +- xen/include/asm-x86/config.h | 22 +- xen/include/asm-x86/domain.h | 1 + xen/include/asm-x86/mm.h | 10 + xen/include/xen/compat.h | 2 + xen/include/xen/hypercall.h | 19 +- xen/include/xlat.lst | 6 + 16 files changed, 837 insertions(+), 60 deletions(-) create mode 100644 xen/arch/x86/x86_64/compat/mm.c create mode 100644 xen/common/compat/memory.c diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 0ff815cc25..189bb03e00 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -128,10 +128,98 @@ void free_vcpu_struct(struct vcpu *v) } #ifdef CONFIG_COMPAT + +int setup_arg_xlat_area(struct vcpu *v, l4_pgentry_t *l4tab) +{ + struct domain *d = v->domain; + unsigned i; + struct page_info *pg; + + if ( !d->arch.mm_arg_xlat_l3 ) + { + pg = alloc_domheap_page(NULL); + if ( !pg ) + return -ENOMEM; + d->arch.mm_arg_xlat_l3 = clear_page(page_to_virt(pg)); + } + + l4tab[l4_table_offset(COMPAT_ARG_XLAT_VIRT_BASE)] = + l4e_from_paddr(__pa(d->arch.mm_arg_xlat_l3), __PAGE_HYPERVISOR); + + for ( i = 0; i < COMPAT_ARG_XLAT_PAGES; ++i ) + { + unsigned long va = COMPAT_ARG_XLAT_VIRT_START(v->vcpu_id) + i * PAGE_SIZE; + l2_pgentry_t *l2tab; + l1_pgentry_t *l1tab; + + if ( !l3e_get_intpte(d->arch.mm_arg_xlat_l3[l3_table_offset(va)]) ) + { + pg = alloc_domheap_page(NULL); + if ( !pg ) + return -ENOMEM; + clear_page(page_to_virt(pg)); + d->arch.mm_arg_xlat_l3[l3_table_offset(va)] = l3e_from_page(pg, __PAGE_HYPERVISOR); + } + l2tab = l3e_to_l2e(d->arch.mm_arg_xlat_l3[l3_table_offset(va)]); + if ( !l2e_get_intpte(l2tab[l2_table_offset(va)]) ) + { + pg = alloc_domheap_page(NULL); + if ( !pg ) + return -ENOMEM; + clear_page(page_to_virt(pg)); + l2tab[l2_table_offset(va)] = l2e_from_page(pg, __PAGE_HYPERVISOR); + } + l1tab = l2e_to_l1e(l2tab[l2_table_offset(va)]); + BUG_ON(l1e_get_intpte(l1tab[l1_table_offset(va)])); + pg = alloc_domheap_page(NULL); + if ( !pg ) + return -ENOMEM; + l1tab[l1_table_offset(va)] = l1e_from_page(pg, PAGE_HYPERVISOR); + } + + return 0; +} + +static void release_arg_xlat_area(struct domain *d) +{ + if ( d->arch.mm_arg_xlat_l3 ) + { + unsigned l3; + + for ( l3 = 0; l3 < L3_PAGETABLE_ENTRIES; ++l3 ) + { + if ( l3e_get_intpte(d->arch.mm_arg_xlat_l3[l3]) ) + { + l2_pgentry_t *l2tab = l3e_to_l2e(d->arch.mm_arg_xlat_l3[l3]); + unsigned l2; + + for ( l2 = 0; l2 < L2_PAGETABLE_ENTRIES; ++l2 ) + { + if ( l2e_get_intpte(l2tab[l2]) ) + { + l1_pgentry_t *l1tab = l2e_to_l1e(l2tab[l2]); + unsigned l1; + + for ( l1 = 0; l1 < L1_PAGETABLE_ENTRIES; ++l1 ) + { + if ( l1e_get_intpte(l1tab[l1]) ) + free_domheap_page(l1e_get_page(l1tab[l1])); + } + free_domheap_page(l2e_get_page(l2tab[l2])); + } + } + free_domheap_page(l3e_get_page(d->arch.mm_arg_xlat_l3[l3])); + } + } + free_domheap_page(virt_to_page(d->arch.mm_arg_xlat_l3)); + } +} + static int setup_compat_l4(struct vcpu *v) { struct page_info *pg = alloc_domheap_page(NULL); l4_pgentry_t *l4tab; + int rc; if ( !pg ) return -ENOMEM; @@ -143,10 +231,26 @@ static int setup_compat_l4(struct vcpu *v) v->arch.guest_table = pagetable_from_page(pg); v->arch.guest_table_user = v->arch.guest_table; + if ( (rc = setup_arg_xlat_area(v, l4tab)) < 0 ) + { + free_domheap_page(pg); + return rc; + } + return 0; } + +static void release_compat_l4(struct vcpu *v) +{ + free_domheap_page(pagetable_get_page(v->arch.guest_table)); + v->arch.guest_table = pagetable_null(); + v->arch.guest_table_user = pagetable_null(); +} + #else +#define release_arg_xlat_area(d) ((void)0) #define setup_compat_l4(v) 0 +#define release_compat_l4(v) ((void)0) #endif int vcpu_initialise(struct vcpu *v) @@ -192,7 +296,7 @@ int vcpu_initialise(struct vcpu *v) void vcpu_destroy(struct vcpu *v) { if ( IS_COMPAT(v->domain) ) - free_domheap_page(pagetable_get_page(v->arch.guest_table)); + release_compat_l4(v); } int arch_domain_create(struct domain *d) @@ -301,6 +405,9 @@ void arch_domain_destroy(struct domain *d) free_domheap_page(virt_to_page(d->arch.mm_perdomain_l3)); #endif + if ( IS_COMPAT(d) ) + release_arg_xlat_area(d); + free_xenheap_page(d->shared_info); } @@ -935,49 +1042,55 @@ unsigned long hypercall_create_continuation( for ( i = 0; *p != '\0'; i++ ) mcs->call.args[i] = next_arg(p, args); + if ( IS_COMPAT(current->domain) ) + { + for ( ; i < 6; i++ ) + mcs->call.args[i] = 0; + } } else { regs = guest_cpu_user_regs(); -#if defined(__i386__) regs->eax = op; + regs->eip -= 2; /* re-execute 'syscall' / 'int 0x82' */ - if ( supervisor_mode_kernel || is_hvm_vcpu(current) ) - regs->eip &= ~31; /* re-execute entire hypercall entry stub */ +#ifdef __x86_64__ + if ( !IS_COMPAT(current->domain) ) + { + for ( i = 0; *p != '\0'; i++ ) + { + arg = next_arg(p, args); + switch ( i ) + { + case 0: regs->rdi = arg; break; + case 1: regs->rsi = arg; break; + case 2: regs->rdx = arg; break; + case 3: regs->r10 = arg; break; + case 4: regs->r8 = arg; break; + case 5: regs->r9 = arg; break; + } + } + } else - regs->eip -= 2; /* re-execute 'int 0x82' */ - - for ( i = 0; *p != '\0'; i++ ) - { - arg = next_arg(p, args); - switch ( i ) - { - case 0: regs->ebx = arg; break; - case 1: regs->ecx = arg; break; - case 2: regs->edx = arg; break; - case 3: regs->esi = arg; break; - case 4: regs->edi = arg; break; - case 5: regs->ebp = arg; break; - } - } -#elif defined(__x86_64__) - regs->rax = op; - regs->rip -= 2; /* re-execute 'syscall' */ - - for ( i = 0; *p != '\0'; i++ ) - { - arg = next_arg(p, args); - switch ( i ) - { - case 0: regs->rdi = arg; break; - case 1: regs->rsi = arg; break; - case 2: regs->rdx = arg; break; - case 3: regs->r10 = arg; break; - case 4: regs->r8 = arg; break; - case 5: regs->r9 = arg; break; - } - } #endif + { + if ( supervisor_mode_kernel || is_hvm_vcpu(current) ) + regs->eip &= ~31; /* re-execute entire hypercall entry stub */ + + for ( i = 0; *p != '\0'; i++ ) + { + arg = next_arg(p, args); + switch ( i ) + { + case 0: regs->ebx = arg; break; + case 1: regs->ecx = arg; break; + case 2: regs->edx = arg; break; + case 3: regs->esi = arg; break; + case 4: regs->edi = arg; break; + case 5: regs->ebp = arg; break; + } + } + } } va_end(args); @@ -985,6 +1098,98 @@ unsigned long hypercall_create_continuation( return op; } +#ifdef CONFIG_COMPAT +int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...) +{ + int rc = 0; + struct mc_state *mcs = &this_cpu(mc_state); + struct cpu_user_regs *regs; + unsigned int i, cval = 0; + unsigned long nval = 0; + va_list args; + + BUG_ON(*id > 5); + BUG_ON(mask & (1U << *id)); + + va_start(args, mask); + + if ( test_bit(_MCSF_in_multicall, &mcs->flags) ) + { + if ( !test_bit(_MCSF_call_preempted, &mcs->flags) ) + return 0; + for ( i = 0; i < 6; ++i, mask >>= 1 ) + { + if ( mask & 1 ) + { + nval = va_arg(args, unsigned long); + cval = va_arg(args, unsigned int); + if ( cval == nval ) + mask &= ~1U; + else + BUG_ON(nval == (unsigned int)nval); + } + else if ( id && *id == i ) + { + *id = mcs->call.args[i]; + id = NULL; + } + if ( (mask & 1) && mcs->call.args[i] == nval ) + ++rc; + else + { + cval = mcs->call.args[i]; + BUG_ON(mcs->call.args[i] != cval); + } + mcs->compat_call.args[i] = cval; + } + } + else + { + regs = guest_cpu_user_regs(); + for ( i = 0; i < 6; ++i, mask >>= 1 ) + { + unsigned long *reg; + + switch ( i ) + { + case 0: reg = ®s->ebx; break; + case 1: reg = ®s->ecx; break; + case 2: reg = ®s->edx; break; + case 3: reg = ®s->esi; break; + case 4: reg = ®s->edi; break; + case 5: reg = ®s->ebp; break; + default: BUG(); reg = NULL; break; + } + if ( (mask & 1) ) + { + nval = va_arg(args, unsigned long); + cval = va_arg(args, unsigned int); + if ( cval == nval ) + mask &= ~1U; + else + BUG_ON(nval == (unsigned int)nval); + } + else if ( id && *id == i ) + { + *id = *reg; + id = NULL; + } + if ( (mask & 1) && *reg == nval ) + { + *reg = cval; + ++rc; + } + else + BUG_ON(*reg != (unsigned int)*reg); + } + } + + va_end(args); + + return rc; +} +#endif + static void relinquish_memory(struct domain *d, struct list_head *list) { struct list_head *ent; diff --git a/xen/arch/x86/domain_build.c b/xen/arch/x86/domain_build.c index 3b721b45c7..e55b13840d 100644 --- a/xen/arch/x86/domain_build.c +++ b/xen/arch/x86/domain_build.c @@ -688,7 +688,11 @@ int construct_dom0(struct domain *d, l4e_from_paddr(__pa(d->arch.mm_perdomain_l3), __PAGE_HYPERVISOR); v->arch.guest_table = pagetable_from_paddr(__pa(l4start)); if ( IS_COMPAT(d) ) + { v->arch.guest_table_user = v->arch.guest_table; + if ( setup_arg_xlat_area(v, l4start) < 0 ) + panic("Not enough RAM for domain 0 hypercall argument translation.\n"); + } l4tab += l4_table_offset(dsi.v_start); mfn = alloc_spfn; diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index baa5a381e6..3c6cf41c2e 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1147,9 +1147,12 @@ static int alloc_l4_table(struct page_info *page) pl4e[l4_table_offset(LINEAR_PT_VIRT_START)] = l4e_from_pfn(pfn, __PAGE_HYPERVISOR); pl4e[l4_table_offset(PERDOMAIN_VIRT_START)] = - l4e_from_page( - virt_to_page(page_get_owner(page)->arch.mm_perdomain_l3), - __PAGE_HYPERVISOR); + l4e_from_page(virt_to_page(d->arch.mm_perdomain_l3), + __PAGE_HYPERVISOR); + if ( IS_COMPAT(d) ) + pl4e[l4_table_offset(COMPAT_ARG_XLAT_VIRT_BASE)] = + l4e_from_page(virt_to_page(d->arch.mm_arg_xlat_l3), + __PAGE_HYPERVISOR); return 1; @@ -2756,7 +2759,9 @@ int do_update_va_mapping(unsigned long va, u64 val64, flush_tlb_mask(d->domain_dirty_cpumask); break; default: - if ( unlikely(get_user(vmask, (unsigned long *)bmap_ptr)) ) + if ( unlikely(!IS_COMPAT(d) ? + get_user(vmask, (unsigned long *)bmap_ptr) : + get_user(vmask, (unsigned int *)bmap_ptr)) ) rc = -EFAULT; pmask = vcpumask_to_pcpumask(d, vmask); flush_tlb_mask(pmask); diff --git a/xen/arch/x86/x86_64/Makefile b/xen/arch/x86/x86_64/Makefile index 8cec5b7abd..b9e0ab46c3 100644 --- a/xen/arch/x86/x86_64/Makefile +++ b/xen/arch/x86/x86_64/Makefile @@ -6,5 +6,6 @@ obj-y += traps.o ifeq ($(CONFIG_COMPAT),y) # extra dependencies entry.o: compat/entry.S +mm.o: compat/mm.c traps.o: compat/traps.c endif diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index e6e1943db8..65d96592a1 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -282,15 +282,11 @@ CFIX14: #define compat_mmu_update domain_crash_synchronous #define compat_set_gdt domain_crash_synchronous #define compat_platform_op domain_crash_synchronous -#define compat_update_descriptor domain_crash_synchronous -#define compat_memory_op domain_crash_synchronous #define compat_multicall domain_crash_synchronous -#define compat_update_va_mapping domain_crash_synchronous #define compat_set_timer_op domain_crash_synchronous #define compat_event_channel_op_compat domain_crash_synchronous #define compat_physdev_op_compat domain_crash_synchronous #define compat_grant_table_op domain_crash_synchronous -#define compat_update_va_mapping_otherdomain domain_crash_synchronous #define compat_vcpu_op domain_crash_synchronous #define compat_mmuext_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous diff --git a/xen/arch/x86/x86_64/compat/mm.c b/xen/arch/x86/x86_64/compat/mm.c new file mode 100644 index 0000000000..866369e558 --- /dev/null +++ b/xen/arch/x86/x86_64/compat/mm.c @@ -0,0 +1,148 @@ +#ifdef CONFIG_COMPAT + +#include + +int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi) +{ + return do_update_descriptor(pa_lo | ((u64)pa_hi << 32), + desc_lo | ((u64)desc_hi << 32)); +} + +int compat_arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg) +{ + struct compat_machphys_mfn_list xmml; + l2_pgentry_t l2e; + unsigned long v; + compat_pfn_t mfn; + unsigned int i; + int rc = 0; + + switch ( op ) + { + case XENMEM_add_to_physmap: + { + struct compat_add_to_physmap cmp; + struct xen_add_to_physmap *nat = (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id); + + if ( copy_from_guest(&cmp, arg, 1) ) + return -EFAULT; + + XLAT_add_to_physmap(nat, &cmp); + rc = arch_memory_op(op, guest_handle_from_ptr(nat, void)); + + break; + } + + case XENMEM_set_memory_map: + { + struct compat_foreign_memory_map cmp; + struct xen_foreign_memory_map *nat = (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id); + + if ( copy_from_guest(&cmp, arg, 1) ) + return -EFAULT; + +#define XLAT_memory_map_HNDL_buffer(_d_, _s_) \ + guest_from_compat_handle((_d_)->buffer, (_s_)->buffer) + XLAT_foreign_memory_map(nat, &cmp); +#undef XLAT_memory_map_HNDL_buffer + + rc = arch_memory_op(op, guest_handle_from_ptr(nat, void)); + + break; + } + + case XENMEM_memory_map: + case XENMEM_machine_memory_map: + { + struct compat_memory_map cmp; + struct xen_memory_map *nat = (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id); + + if ( copy_from_guest(&cmp, arg, 1) ) + return -EFAULT; + +#define XLAT_memory_map_HNDL_buffer(_d_, _s_) \ + guest_from_compat_handle((_d_)->buffer, (_s_)->buffer) + XLAT_memory_map(nat, &cmp); +#undef XLAT_memory_map_HNDL_buffer + + rc = arch_memory_op(op, guest_handle_from_ptr(nat, void)); + if ( rc < 0 ) + break; + +#define XLAT_memory_map_HNDL_buffer(_d_, _s_) ((void)0) + XLAT_memory_map(&cmp, nat); +#undef XLAT_memory_map_HNDL_buffer + if ( copy_to_guest(arg, &cmp, 1) ) + rc = -EFAULT; + + break; + } + + case XENMEM_machphys_mapping: + { + struct domain *d = current->domain; + struct compat_machphys_mapping mapping = { + .v_start = MACH2PHYS_COMPAT_VIRT_START(d), + .v_end = MACH2PHYS_COMPAT_VIRT_END, + .max_mfn = MACH2PHYS_COMPAT_NR_ENTRIES(d) - 1 + }; + + if ( copy_to_guest(arg, &mapping, 1) ) + rc = -EFAULT; + + break; + } + + case XENMEM_machphys_mfn_list: + if ( copy_from_guest(&xmml, arg, 1) ) + return -EFAULT; + + for ( i = 0, v = RDWR_COMPAT_MPT_VIRT_START; + (i != xmml.max_extents) && (v != RDWR_COMPAT_MPT_VIRT_END); + i++, v += 1 << L2_PAGETABLE_SHIFT ) + { + l2e = compat_idle_pg_table_l2[l2_table_offset(v)]; + if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ) + break; + mfn = l2e_get_pfn(l2e) + l1_table_offset(v); + if ( copy_to_compat_offset(xmml.extent_start, i, &mfn, 1) ) + return -EFAULT; + } + + xmml.nr_extents = i; + if ( copy_to_guest(arg, &xmml, 1) ) + rc = -EFAULT; + + break; + + default: + rc = -ENOSYS; + break; + } + + return rc; +} + +int compat_update_va_mapping(unsigned int va, u32 lo, u32 hi, + unsigned int flags) +{ + return do_update_va_mapping(va, lo | ((u64)hi << 32), flags); +} + +int compat_update_va_mapping_otherdomain(unsigned long va, u32 lo, u32 hi, + unsigned long flags, + domid_t domid) +{ + return do_update_va_mapping_otherdomain(va, lo | ((u64)hi << 32), flags, domid); +} +#endif /* CONFIG_COMPAT */ + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/x86_64/mm.c b/xen/arch/x86/x86_64/mm.c index 64448004df..a482c10a06 100644 --- a/xen/arch/x86/x86_64/mm.c +++ b/xen/arch/x86/x86_64/mm.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -407,6 +408,8 @@ int check_descriptor(const struct domain *dom, struct desc_struct *d) return 0; } +#include "compat/mm.c" + /* * Local variables: * mode: C diff --git a/xen/common/compat/Makefile b/xen/common/compat/Makefile index ba581f053c..5510e645d1 100644 --- a/xen/common/compat/Makefile +++ b/xen/common/compat/Makefile @@ -1,4 +1,5 @@ obj-y += kernel.o +obj-y += memory.o obj-y += xlat.o # extra dependencies diff --git a/xen/common/compat/memory.c b/xen/common/compat/memory.c new file mode 100644 index 0000000000..1301e42f04 --- /dev/null +++ b/xen/common/compat/memory.c @@ -0,0 +1,364 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int compat_memory_op(unsigned int cmd, XEN_GUEST_HANDLE(void) compat) +{ + int rc, split, op = cmd & MEMOP_CMD_MASK; + unsigned int start_extent = cmd >> MEMOP_EXTENT_SHIFT; + + do + { + unsigned int i, end_extent = 0; + union { + XEN_GUEST_HANDLE(void) hnd; + struct xen_memory_reservation *rsrv; + struct xen_memory_exchange *xchg; + struct xen_translate_gpfn_list *xlat; + } nat; + union { + struct compat_memory_reservation rsrv; + struct compat_memory_exchange xchg; + struct compat_translate_gpfn_list xlat; + } cmp; + + set_xen_guest_handle(nat.hnd, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); + split = 0; + switch ( op ) + { + xen_pfn_t *space; + + case XENMEM_increase_reservation: + case XENMEM_decrease_reservation: + case XENMEM_populate_physmap: + if ( copy_from_guest(&cmp.rsrv, compat, 1) ) + return start_extent; + + /* Is size too large for us to encode a continuation? */ + if ( cmp.rsrv.nr_extents > (UINT_MAX >> MEMOP_EXTENT_SHIFT) ) + return start_extent; + + if ( !compat_handle_is_null(cmp.rsrv.extent_start) && + !compat_handle_okay(cmp.rsrv.extent_start, cmp.rsrv.nr_extents) ) + return start_extent; + + end_extent = start_extent + (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.rsrv)) / + sizeof(*space); + if ( end_extent > cmp.rsrv.nr_extents ) + end_extent = cmp.rsrv.nr_extents; + + space = (xen_pfn_t *)(nat.rsrv + 1); +#define XLAT_memory_reservation_HNDL_extent_start(_d_, _s_) \ + do \ + { \ + if ( !compat_handle_is_null((_s_)->extent_start) ) \ + { \ + set_xen_guest_handle((_d_)->extent_start, space - start_extent); \ + if ( op != XENMEM_increase_reservation ) \ + { \ + for ( i = start_extent; i < end_extent; ++i ) \ + { \ + compat_pfn_t pfn; \ + if ( __copy_from_compat_offset(&pfn, (_s_)->extent_start, i, 1) ) \ + { \ + end_extent = i; \ + split = -1; \ + break; \ + } \ + *space++ = pfn; \ + } \ + } \ + } \ + else \ + { \ + set_xen_guest_handle((_d_)->extent_start, NULL); \ + end_extent = cmp.rsrv.nr_extents; \ + } \ + } while (0) + XLAT_memory_reservation(nat.rsrv, &cmp.rsrv); +#undef XLAT_memory_reservation_HNDL_extent_start + + if ( end_extent < cmp.rsrv.nr_extents ) + { + nat.rsrv->nr_extents = end_extent; + ++split; + } + + break; + + case XENMEM_exchange: + { + int order_delta; + + if ( copy_from_guest(&cmp.xchg, compat, 1) ) + return -EFAULT; + + order_delta = cmp.xchg.out.extent_order - cmp.xchg.in.extent_order; + /* Various sanity checks. */ + if ( (cmp.xchg.nr_exchanged > cmp.xchg.in.nr_extents) || + (order_delta > 0 && (cmp.xchg.nr_exchanged & ((1U << order_delta) - 1))) || + /* Sizes of input and output lists do not overflow an int? */ + ((~0U >> cmp.xchg.in.extent_order) < cmp.xchg.in.nr_extents) || + ((~0U >> cmp.xchg.out.extent_order) < cmp.xchg.out.nr_extents) || + /* Sizes of input and output lists match? */ + ((cmp.xchg.in.nr_extents << cmp.xchg.in.extent_order) != + (cmp.xchg.out.nr_extents << cmp.xchg.out.extent_order)) ) + return -EINVAL; + + start_extent = cmp.xchg.nr_exchanged; + end_extent = (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.xchg)) / + (((1U << __builtin_abs(order_delta)) + 1) * + sizeof(*space)); + if ( end_extent == 0 ) + { + printk("Cannot translate compatibility mode XENMEM_exchange extents (%u,%u)\n", + cmp.xchg.in.extent_order, cmp.xchg.out.extent_order); + return -E2BIG; + } + if ( order_delta > 0 ) + end_extent <<= order_delta; + end_extent += start_extent; + if ( end_extent > cmp.xchg.in.nr_extents ) + end_extent = cmp.xchg.in.nr_extents; + + space = (xen_pfn_t *)(nat.xchg + 1); + /* Code below depends upon .in preceding .out. */ + BUILD_BUG_ON(offsetof(xen_memory_exchange_t, in) > offsetof(xen_memory_exchange_t, out)); +#define XLAT_memory_reservation_HNDL_extent_start(_d_, _s_) \ + do \ + { \ + set_xen_guest_handle((_d_)->extent_start, space - start_extent); \ + for ( i = start_extent; i < end_extent; ++i ) \ + { \ + compat_pfn_t pfn; \ + if ( __copy_from_compat_offset(&pfn, (_s_)->extent_start, i, 1) ) \ + return -EFAULT; \ + *space++ = pfn; \ + } \ + if ( order_delta > 0 ) \ + { \ + start_extent >>= order_delta; \ + end_extent >>= order_delta; \ + } \ + else \ + { \ + start_extent <<= -order_delta; \ + end_extent <<= -order_delta; \ + } \ + order_delta = -order_delta; \ + } while (0) + XLAT_memory_exchange(nat.xchg, &cmp.xchg); +#undef XLAT_memory_reservation_HNDL_extent_start + + if ( end_extent < cmp.xchg.in.nr_extents ) + { + nat.xchg->in.nr_extents = end_extent; + if ( order_delta >= 0 ) + nat.xchg->out.nr_extents = end_extent >> order_delta; + else + nat.xchg->out.nr_extents = end_extent << order_delta; + ++split; + } + + break; + } + + case XENMEM_current_reservation: + case XENMEM_maximum_reservation: + { +#define xen_domid_t domid_t +#define compat_domid_t domid_compat_t + CHECK_TYPE(domid); +#undef compat_domid_t +#undef xen_domid_t + } + case XENMEM_maximum_ram_page: + nat.hnd = compat; + break; + + case XENMEM_translate_gpfn_list: + if ( copy_from_guest(&cmp.xlat, compat, 1) ) + return -EFAULT; + + /* Is size too large for us to encode a continuation? */ + if ( cmp.xlat.nr_gpfns > (UINT_MAX >> MEMOP_EXTENT_SHIFT) ) + return -EINVAL; + + if ( !compat_handle_okay(cmp.xlat.gpfn_list, cmp.xlat.nr_gpfns) || + !compat_handle_okay(cmp.xlat.mfn_list, cmp.xlat.nr_gpfns) ) + return -EFAULT; + + end_extent = start_extent + (COMPAT_ARG_XLAT_SIZE - sizeof(*nat.xlat)) / + sizeof(*space); + if ( end_extent > cmp.xlat.nr_gpfns ) + end_extent = cmp.xlat.nr_gpfns; + + space = (xen_pfn_t *)(nat.xlat + 1); + /* Code below depends upon .gpfn_list preceding .mfn_list. */ + BUILD_BUG_ON(offsetof(xen_translate_gpfn_list_t, gpfn_list) > offsetof(xen_translate_gpfn_list_t, mfn_list)); +#define XLAT_translate_gpfn_list_HNDL_gpfn_list(_d_, _s_) \ + do \ + { \ + set_xen_guest_handle((_d_)->gpfn_list, space - start_extent); \ + for ( i = start_extent; i < end_extent; ++i ) \ + { \ + compat_pfn_t pfn; \ + if ( __copy_from_compat_offset(&pfn, (_s_)->gpfn_list, i, 1) ) \ + return -EFAULT; \ + *space++ = pfn; \ + } \ + } while (0) +#define XLAT_translate_gpfn_list_HNDL_mfn_list(_d_, _s_) \ + (_d_)->mfn_list = (_d_)->gpfn_list + XLAT_translate_gpfn_list(nat.xlat, &cmp.xlat); +#undef XLAT_translate_gpfn_list_HNDL_mfn_list +#undef XLAT_translate_gpfn_list_HNDL_gpfn_list + + if ( end_extent < cmp.xlat.nr_gpfns ) + { + nat.xlat->nr_gpfns = end_extent; + ++split; + } + + break; + + default: + return compat_arch_memory_op(cmd, compat); + } + + rc = do_memory_op(cmd, nat.hnd); + if ( rc < 0 ) + return rc; + + cmd = 0; + if ( hypercall_xlat_continuation(&cmd, 0x02, nat.hnd, compat) ) + { + BUG_ON(rc != __HYPERVISOR_memory_op); + BUG_ON((cmd & MEMOP_CMD_MASK) != op); + split = -1; + } + + switch ( op ) + { + case XENMEM_increase_reservation: + case XENMEM_decrease_reservation: + case XENMEM_populate_physmap: + end_extent = split >= 0 ? rc : cmd >> MEMOP_EXTENT_SHIFT; + if ( op != XENMEM_decrease_reservation && + !guest_handle_is_null(nat.rsrv->extent_start) ) + { + for ( ; start_extent < end_extent; ++start_extent ) + { + compat_pfn_t pfn = nat.rsrv->extent_start.p[start_extent]; + + BUG_ON(pfn != nat.rsrv->extent_start.p[start_extent]); + if ( __copy_to_compat_offset(cmp.rsrv.extent_start, start_extent, &pfn, 1) ) + { + if ( split >= 0 ) + { + rc = start_extent; + split = 0; + } + else + /* + * Short of being able to cancel the continuation, + * force it to restart here; eventually we shall + * get out of this state. + */ + rc = (start_extent << MEMOP_EXTENT_SHIFT) | op; + break; + } + } + } + else + start_extent = end_extent; + break; + + case XENMEM_exchange: + { + DEFINE_XEN_GUEST_HANDLE(compat_memory_exchange_t); + int order_delta; + + BUG_ON(split >= 0 && rc); + BUG_ON(end_extent < nat.xchg->nr_exchanged); + end_extent = nat.xchg->nr_exchanged; + + order_delta = cmp.xchg.out.extent_order - cmp.xchg.in.extent_order; + if ( order_delta > 0 ) + { + start_extent >>= order_delta; + BUG_ON(end_extent & ((1U << order_delta) - 1)); + end_extent >>= order_delta; + } + else + { + start_extent <<= -order_delta; + end_extent <<= -order_delta; + } + + for ( ; start_extent < end_extent; ++start_extent ) + { + compat_pfn_t pfn = nat.xchg->out.extent_start.p[start_extent]; + + BUG_ON(pfn != nat.xchg->out.extent_start.p[start_extent]); + /* Note that we ignore errors accessing the output extent list. */ + __copy_to_compat_offset(cmp.xchg.out.extent_start, start_extent, &pfn, 1); + } + + cmp.xchg.nr_exchanged = nat.xchg->nr_exchanged; + if ( copy_field_to_guest(guest_handle_cast(compat, compat_memory_exchange_t), + &cmp.xchg, nr_exchanged) ) + { + if ( split < 0 ) + /* Cannot cancel the continuation... */ + domain_crash(current->domain); + return -EFAULT; + } + break; + } + + case XENMEM_maximum_ram_page: + case XENMEM_current_reservation: + case XENMEM_maximum_reservation: + break; + + case XENMEM_translate_gpfn_list: + if ( split < 0 ) + end_extent = cmd >> MEMOP_EXTENT_SHIFT; + else + BUG_ON(rc); + + for ( ; start_extent < end_extent; ++start_extent ) + { + compat_pfn_t pfn = nat.xlat->mfn_list.p[start_extent]; + + BUG_ON(pfn != nat.xlat->mfn_list.p[start_extent]); + if ( __copy_to_compat_offset(cmp.xlat.mfn_list, start_extent, &pfn, 1) ) + { + if ( split < 0 ) + /* Cannot cancel the continuation... */ + domain_crash(current->domain); + return -EFAULT; + } + } + break; + + default: + domain_crash(current->domain); + split = 0; + break; + } + + cmd = op | (start_extent << MEMOP_EXTENT_SHIFT); + if ( split > 0 && hypercall_preempt_check() ) + return hypercall_create_continuation( + __HYPERVISOR_memory_op, "ih", cmd, compat); + } while ( split > 0 ); + + return rc; +} diff --git a/xen/common/memory.c b/xen/common/memory.c index f17ae4b913..1d9e6d1044 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -17,18 +17,12 @@ #include #include #include +#include #include #include #include #include -/* - * To allow safe resume of do_memory_op() after preemption, we need to know - * at what point in the page list to resume. For this purpose I steal the - * high-order bits of the @cmd parameter, which are otherwise unused and zero. - */ -#define START_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */ - struct memop_args { /* INPUT */ struct domain *domain; /* Domain to be affected. */ @@ -236,7 +230,7 @@ static long translate_gpfn_list( return -EFAULT; /* Is size too large for us to encode a continuation? */ - if ( op.nr_gpfns > (ULONG_MAX >> START_EXTENT_SHIFT) ) + if ( op.nr_gpfns > (ULONG_MAX >> MEMOP_EXTENT_SHIFT) ) return -EINVAL; if ( !guest_handle_okay(op.gpfn_list, op.nr_gpfns) || @@ -511,20 +505,20 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE(void) arg) struct memop_args args; domid_t domid; - op = cmd & ((1 << START_EXTENT_SHIFT) - 1); + op = cmd & MEMOP_CMD_MASK; switch ( op ) { case XENMEM_increase_reservation: case XENMEM_decrease_reservation: case XENMEM_populate_physmap: - start_extent = cmd >> START_EXTENT_SHIFT; + start_extent = cmd >> MEMOP_EXTENT_SHIFT; if ( copy_from_guest(&reservation, arg, 1) ) return start_extent; /* Is size too large for us to encode a continuation? */ - if ( reservation.nr_extents > (ULONG_MAX >> START_EXTENT_SHIFT) ) + if ( reservation.nr_extents > (ULONG_MAX >> MEMOP_EXTENT_SHIFT) ) return start_extent; if ( unlikely(start_extent > reservation.nr_extents) ) @@ -574,7 +568,7 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE(void) arg) if ( args.preempted ) return hypercall_create_continuation( __HYPERVISOR_memory_op, "lh", - op | (rc << START_EXTENT_SHIFT), arg); + op | (rc << MEMOP_EXTENT_SHIFT), arg); break; @@ -606,14 +600,14 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE(void) arg) break; case XENMEM_translate_gpfn_list: - progress = cmd >> START_EXTENT_SHIFT; + progress = cmd >> MEMOP_EXTENT_SHIFT; rc = translate_gpfn_list( guest_handle_cast(arg, xen_translate_gpfn_list_t), &progress); if ( rc == -EAGAIN ) return hypercall_create_continuation( __HYPERVISOR_memory_op, "lh", - op | (progress << START_EXTENT_SHIFT), arg); + op | (progress << MEMOP_EXTENT_SHIFT), arg); break; default: diff --git a/xen/include/asm-x86/config.h b/xen/include/asm-x86/config.h index dca9bbe39c..71e3dd8e4a 100644 --- a/xen/include/asm-x86/config.h +++ b/xen/include/asm-x86/config.h @@ -108,7 +108,7 @@ /* * Memory layout: * 0x0000000000000000 - 0x00007fffffffffff [128TB, 2^47 bytes, PML4:0-255] - * Guest-defined use. + * Guest-defined use (see below for compatibility mode guests). * 0x0000800000000000 - 0xffff7fffffffffff [16EB] * Inaccessible: current arch only supports 48-bit sign-extended VAs. * 0xffff800000000000 - 0xffff803fffffffff [256GB, 2^38 bytes, PML4:256] @@ -141,6 +141,18 @@ * Reserved for future use. * 0xffff880000000000 - 0xffffffffffffffff [120TB, PML4:272-511] * Guest-defined use. + * + * Compatibility guest area layout: + * 0x0000000000000000 - 0x00000000f57fffff [3928MB, PML4:0] + * Guest-defined use. + * 0x0000000f58000000 - 0x00000000ffffffff [168MB, PML4:0] + * Read-only machine-to-phys translation table (GUEST ACCESSIBLE). + * 0x0000000000000000 - 0x00000000ffffffff [508GB, PML4:0] + * Unused. + * 0x0000008000000000 - 0x000000ffffffffff [512GB, 2^39 bytes, PML4:1] + * Hypercall argument translation area. + * 0x0000010000000000 - 0x00007fffffffffff [127TB, 2^46 bytes, PML4:2-255] + * Reserved for future use. */ @@ -210,6 +222,14 @@ #endif +#define COMPAT_ARG_XLAT_VIRT_BASE (1UL << ROOT_PAGETABLE_SHIFT) +#define COMPAT_ARG_XLAT_SHIFT 0 +#define COMPAT_ARG_XLAT_PAGES (1U << COMPAT_ARG_XLAT_SHIFT) +#define COMPAT_ARG_XLAT_SIZE (COMPAT_ARG_XLAT_PAGES << PAGE_SHIFT) +#define COMPAT_ARG_XLAT_VIRT_START(vcpu_id) \ + (COMPAT_ARG_XLAT_VIRT_BASE + ((unsigned long)(vcpu_id) << \ + (PAGE_SHIFT + COMPAT_ARG_XLAT_SHIFT + 1))) + #define PGT_base_page_table PGT_l4_page_table #define __HYPERVISOR_CS64 0xe008 diff --git a/xen/include/asm-x86/domain.h b/xen/include/asm-x86/domain.h index 0e6ef7aee4..83315353e1 100644 --- a/xen/include/asm-x86/domain.h +++ b/xen/include/asm-x86/domain.h @@ -100,6 +100,7 @@ struct arch_domain #ifdef CONFIG_COMPAT unsigned int hv_compat_vstart; + l3_pgentry_t *mm_arg_xlat_l3; #endif /* I/O-port admin-specified access capabilities. */ diff --git a/xen/include/asm-x86/mm.h b/xen/include/asm-x86/mm.h index cf585e1e29..405a753b39 100644 --- a/xen/include/asm-x86/mm.h +++ b/xen/include/asm-x86/mm.h @@ -329,10 +329,20 @@ int __sync_lazy_execstate(void); /* Arch-specific portion of memory_op hypercall. */ long arch_memory_op(int op, XEN_GUEST_HANDLE(void) arg); long subarch_memory_op(int op, XEN_GUEST_HANDLE(void) arg); +#ifdef CONFIG_COMPAT +int compat_arch_memory_op(int op, XEN_GUEST_HANDLE(void)); +int compat_subarch_memory_op(int op, XEN_GUEST_HANDLE(void)); +#endif int steal_page( struct domain *d, struct page_info *page, unsigned int memflags); int map_ldt_shadow_page(unsigned int); +#ifdef CONFIG_COMPAT +int setup_arg_xlat_area(struct vcpu *, l4_pgentry_t *); +#else +# define setup_arg_xlat_area(vcpu, l4tab) 0 +#endif + #endif /* __ASM_X86_MM_H__ */ diff --git a/xen/include/xen/compat.h b/xen/include/xen/compat.h index 48d3b68898..b06842f592 100644 --- a/xen/include/xen/compat.h +++ b/xen/include/xen/compat.h @@ -158,6 +158,8 @@ extern int compat_disabled; +int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...); + /* In-place translation functons: */ struct start_info; void xlat_start_info(struct start_info *, enum XLAT_start_info_console); diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h index b8fc94d2c6..415ea330e3 100644 --- a/xen/include/xen/hypercall.h +++ b/xen/include/xen/hypercall.h @@ -42,9 +42,17 @@ extern long do_platform_op( XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op); +/* + * To allow safe resume of do_memory_op() after preemption, we need to know + * at what point in the page list to resume. For this purpose I steal the + * high-order bits of the @cmd parameter, which are otherwise unused and zero. + */ +#define MEMOP_EXTENT_SHIFT 4 /* cmd[:4] == start_extent */ +#define MEMOP_CMD_MASK ((1 << MEMOP_EXTENT_SHIFT) - 1) + extern long do_memory_op( - int cmd, + unsigned long cmd, XEN_GUEST_HANDLE(void) arg); extern long @@ -108,4 +116,13 @@ do_kexec_op( int arg1, XEN_GUEST_HANDLE(void) arg); +#ifdef CONFIG_COMPAT + +extern int +compat_memory_op( + unsigned int cmd, + XEN_GUEST_HANDLE(void) arg); + +#endif + #endif /* __XEN_HYPERCALL_H__ */ diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index fadfee9db5..d2e61528c5 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -4,3 +4,9 @@ ? dom0_vga_console_info xen.h ! start_info xen.h ? vcpu_time_info xen.h +! add_to_physmap memory.h +! foreign_memory_map memory.h +! memory_exchange memory.h +! memory_map memory.h +! memory_reservation memory.h +! translate_gpfn_list memory.h From 6630b25a6c268116f5cc816d5a7da7c7bd700510 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:31 +0000 Subject: [PATCH 082/570] Enable compatibility mode operation for HYPERVISOR_mmu_update and HYPERVISOR_mmuext_op. Signed-off-by: Jan Beulich --- xen/arch/x86/mm.c | 16 ++-- xen/arch/x86/x86_64/compat/entry.S | 4 +- xen/arch/x86/x86_64/compat/mm.c | 148 +++++++++++++++++++++++++++++ xen/common/compat/xlat.c | 4 + xen/include/asm-x86/hypercall.h | 7 ++ xen/include/xlat.lst | 2 + 6 files changed, 170 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 3c6cf41c2e..bad639f692 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -106,6 +106,7 @@ #include #include #include +#include #include #define MEM_LOG(_f, _a...) gdprintk(XENLOG_WARNING , _f "\n" , ## _a) @@ -119,13 +120,6 @@ #define PTE_UPDATE_WITH_CMPXCHG #endif -/* - * Both do_mmuext_op() and do_mmu_update(): - * We steal the m.s.b. of the @count parameter to indicate whether this - * invocation of do_mmu_update() is resuming a previously preempted call. - */ -#define MMU_UPDATE_PREEMPTED (~(~0U>>1)) - /* Used to defer flushing of memory structures. */ struct percpu_mm_info { #define DOP_FLUSH_TLB (1<<0) /* Flush the local TLB. */ @@ -2033,6 +2027,8 @@ int do_mmuext_op( goto pin_page; case MMUEXT_PIN_L4_TABLE: + if ( IS_COMPAT(FOREIGNDOM) ) + break; type = PGT_l4_page_table; pin_page: @@ -2096,7 +2092,11 @@ int do_mmuext_op( #ifdef __x86_64__ case MMUEXT_NEW_USER_BASEPTR: - okay = 1; + if ( IS_COMPAT(FOREIGNDOM) ) + { + okay = 0; + break; + } if (likely(mfn != 0)) { if ( shadow_mode_refcounts(d) ) diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 65d96592a1..923392192e 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -279,7 +279,6 @@ CFIX14: .section .rodata, "a", @progbits #define compat_set_trap_table domain_crash_synchronous -#define compat_mmu_update domain_crash_synchronous #define compat_set_gdt domain_crash_synchronous #define compat_platform_op domain_crash_synchronous #define compat_multicall domain_crash_synchronous @@ -288,7 +287,6 @@ CFIX14: #define compat_physdev_op_compat domain_crash_synchronous #define compat_grant_table_op domain_crash_synchronous #define compat_vcpu_op domain_crash_synchronous -#define compat_mmuext_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous #define compat_arch_sched_op domain_crash_synchronous #define compat_xenoprof_op domain_crash_synchronous @@ -299,7 +297,7 @@ CFIX14: ENTRY(compat_hypercall_table) .quad compat_set_trap_table /* 0 */ - .quad compat_mmu_update + .quad do_mmu_update .quad compat_set_gdt .quad do_stack_switch .quad compat_set_callbacks diff --git a/xen/arch/x86/x86_64/compat/mm.c b/xen/arch/x86/x86_64/compat/mm.c index 866369e558..874774660a 100644 --- a/xen/arch/x86/x86_64/compat/mm.c +++ b/xen/arch/x86/x86_64/compat/mm.c @@ -1,6 +1,8 @@ #ifdef CONFIG_COMPAT +#include #include +#include int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi) { @@ -135,6 +137,152 @@ int compat_update_va_mapping_otherdomain(unsigned long va, u32 lo, u32 hi, { return do_update_va_mapping_otherdomain(va, lo | ((u64)hi << 32), flags, domid); } + +DEFINE_XEN_GUEST_HANDLE(mmuext_op_compat_t); + +int compat_mmuext_op(XEN_GUEST_HANDLE(mmuext_op_compat_t) cmp_uops, + unsigned int count, + XEN_GUEST_HANDLE(uint) pdone, + unsigned int foreigndom) +{ + unsigned int i, preempt_mask; + int rc = 0; + XEN_GUEST_HANDLE(mmuext_op_t) nat_ops; + + preempt_mask = count & MMU_UPDATE_PREEMPTED; + count ^= preempt_mask; + + if ( unlikely(!guest_handle_okay(cmp_uops, count)) ) + return -EFAULT; + + set_xen_guest_handle(nat_ops, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); + + for ( ; count; count -= i ) + { + mmuext_op_t *nat_op = nat_ops.p; + unsigned int limit; + int err; + + if ( hypercall_preempt_check() ) + { + rc = hypercall_create_continuation( + __HYPERVISOR_mmuext_op, "hihi", + cmp_uops, count | MMU_UPDATE_PREEMPTED, pdone, foreigndom); + break; + } + + limit = COMPAT_ARG_XLAT_SIZE / sizeof(*nat_op); + + for ( i = 0; i < min(limit, count); ++i ) + { + mmuext_op_compat_t cmp_op; + enum XLAT_mmuext_op_arg1 arg1; + enum XLAT_mmuext_op_arg2 arg2; + + if ( unlikely(__copy_from_guest(&cmp_op, cmp_uops, 1) != 0) ) + { + rc = -EFAULT; + break; + } + + switch ( cmp_op.cmd ) + { + case MMUEXT_PIN_L1_TABLE: + case MMUEXT_PIN_L2_TABLE: + case MMUEXT_PIN_L3_TABLE: + case MMUEXT_PIN_L4_TABLE: + case MMUEXT_UNPIN_TABLE: + case MMUEXT_NEW_BASEPTR: + arg1 = XLAT_mmuext_op_arg1_mfn; + break; + default: + arg1 = XLAT_mmuext_op_arg1_linear_addr; + break; + case MMUEXT_NEW_USER_BASEPTR: + rc = -EINVAL; + case MMUEXT_TLB_FLUSH_LOCAL: + case MMUEXT_TLB_FLUSH_MULTI: + case MMUEXT_TLB_FLUSH_ALL: + case MMUEXT_FLUSH_CACHE: + arg1 = -1; + break; + } + + if ( rc ) + break; + + switch ( cmp_op.cmd ) + { + case MMUEXT_SET_LDT: + arg2 = XLAT_mmuext_op_arg2_nr_ents; + break; + case MMUEXT_TLB_FLUSH_MULTI: + case MMUEXT_INVLPG_MULTI: + arg2 = XLAT_mmuext_op_arg2_vcpumask; + break; + default: + arg2 = -1; + break; + } + +#define XLAT_mmuext_op_HNDL_arg2_vcpumask(_d_, _s_) \ + do \ + { \ + unsigned int vcpumask; \ + if ( i < --limit ) \ + { \ + (_d_)->arg2.vcpumask.p = (void *)(nat_ops.p + limit); \ + if ( copy_from_compat(&vcpumask, (_s_)->arg2.vcpumask, 1) == 0 ) \ + *(unsigned long *)(_d_)->arg2.vcpumask.p = vcpumask; \ + else \ + rc = -EFAULT; \ + } \ + } while(0) + XLAT_mmuext_op(nat_op, &cmp_op); +#undef XLAT_mmuext_op_HNDL_arg2_vcpumask + + if ( rc || i >= limit ) + break; + + guest_handle_add_offset(cmp_uops, 1); + ++nat_op; + } + + err = do_mmuext_op(nat_ops, i | preempt_mask, pdone, foreigndom); + + if ( err ) + { + BUILD_BUG_ON(__HYPERVISOR_mmuext_op <= 0); + if ( err == __HYPERVISOR_mmuext_op ) + { + struct cpu_user_regs *regs = guest_cpu_user_regs(); + unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED; + + BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED)); + BUG_ON(left > count); + guest_handle_add_offset(nat_ops, count - left); + BUG_ON(left + i < count); + guest_handle_add_offset(cmp_uops, (signed int)(count - left - i)); + left = 1; + BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops)); + BUG_ON(left != regs->ecx); + regs->ecx += count - i; + } + else + BUG_ON(rc > 0); + rc = err; + } + + if ( rc ) + break; + + /* Force do_mmuext_op() to not start counting from zero again. */ + preempt_mask = MMU_UPDATE_PREEMPTED; + } + + return rc; +} + #endif /* CONFIG_COMPAT */ /* diff --git a/xen/common/compat/xlat.c b/xen/common/compat/xlat.c index b8969afb43..1440001ba0 100644 --- a/xen/common/compat/xlat.c +++ b/xen/common/compat/xlat.c @@ -21,6 +21,10 @@ void xlat_start_info(struct start_info *native, CHECK_dom0_vga_console_info; #undef dom0_vga_console_info +#define xen_mmu_update mmu_update +CHECK_mmu_update; +#undef xen_mmu_update + #define xen_vcpu_time_info vcpu_time_info CHECK_vcpu_time_info; #undef xen_vcpu_time_info diff --git a/xen/include/asm-x86/hypercall.h b/xen/include/asm-x86/hypercall.h index 860fb2ce77..ee911a91b0 100644 --- a/xen/include/asm-x86/hypercall.h +++ b/xen/include/asm-x86/hypercall.h @@ -8,6 +8,13 @@ #include #include +/* + * Both do_mmuext_op() and do_mmu_update(): + * We steal the m.s.b. of the @count parameter to indicate whether this + * invocation of do_mmu_update() is resuming a previously preempted call. + */ +#define MMU_UPDATE_PREEMPTED (~(~0U>>1)) + extern long do_event_channel_op_compat( XEN_GUEST_HANDLE(evtchn_op_t) uop); diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index d2e61528c5..0027ed65c0 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -2,6 +2,8 @@ # ! - needs translation # ? - needs checking ? dom0_vga_console_info xen.h +? mmu_update xen.h +! mmuext_op xen.h ! start_info xen.h ? vcpu_time_info xen.h ! add_to_physmap memory.h From 248b44f921e1823a7976b7f5629e3dda308555f0 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:32 +0000 Subject: [PATCH 083/570] Enable compatibility mode operation for HYPERVISOR_physdev_op and HYPERVISOR_event_channel_op. Signed-off-by: Jan Beulich --- xen/arch/x86/compat.c | 14 +++++++-- xen/arch/x86/physdev.c | 13 ++++++-- xen/arch/x86/x86_64/Makefile | 5 ++++ xen/arch/x86/x86_64/compat.c | 30 +++++++++++++++++++ xen/arch/x86/x86_64/compat/entry.S | 8 ++--- xen/arch/x86/x86_64/physdev.c | 48 ++++++++++++++++++++++++++++++ xen/common/compat/xlat.c | 26 +++++++++++++++- xen/include/asm-x86/hypercall.h | 9 ++++++ xen/include/xlat.lst | 11 +++++++ 9 files changed, 152 insertions(+), 12 deletions(-) create mode 100644 xen/arch/x86/x86_64/compat.c create mode 100644 xen/arch/x86/x86_64/physdev.c diff --git a/xen/arch/x86/compat.c b/xen/arch/x86/compat.c index 431c4560fd..a4fda062d6 100644 --- a/xen/arch/x86/compat.c +++ b/xen/arch/x86/compat.c @@ -9,17 +9,23 @@ #include #include +#ifndef COMPAT +typedef long ret_t; +#endif + /* Legacy hypercall (as of 0x00030202). */ -long do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop) +ret_t do_physdev_op_compat(XEN_GUEST_HANDLE(physdev_op_t) uop) { struct physdev_op op; if ( unlikely(copy_from_guest(&op, uop, 1) != 0) ) return -EFAULT; - return do_physdev_op(op.cmd, (XEN_GUEST_HANDLE(void)) { &uop.p->u }); + return do_physdev_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void)); } +#ifndef COMPAT + /* Legacy hypercall (as of 0x00030202). */ long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop) { @@ -28,5 +34,7 @@ long do_event_channel_op_compat(XEN_GUEST_HANDLE(evtchn_op_t) uop) if ( unlikely(copy_from_guest(&op, uop, 1) != 0) ) return -EFAULT; - return do_event_channel_op(op.cmd, (XEN_GUEST_HANDLE(void)) {&uop.p->u }); + return do_event_channel_op(op.cmd, guest_handle_from_ptr(&uop.p->u, void)); } + +#endif diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index d24aad62aa..356e4079be 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -9,9 +9,14 @@ #include #include #include +#include #include #include +#ifndef COMPAT +typedef long ret_t; +#endif + int ioapic_guest_read( unsigned long physbase, unsigned int reg, u32 *pval); @@ -19,10 +24,10 @@ int ioapic_guest_write( unsigned long physbase, unsigned int reg, u32 pval); -long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) +ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) { int irq; - long ret; + ret_t ret; switch ( cmd ) { @@ -129,7 +134,11 @@ long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) (set_iobitmap.nr_ports > 65536) ) break; ret = 0; +#ifndef COMPAT current->arch.iobmp = set_iobitmap.bitmap; +#else + guest_from_compat_handle(current->arch.iobmp, set_iobitmap.bitmap); +#endif current->arch.iobmp_limit = set_iobitmap.nr_ports; break; } diff --git a/xen/arch/x86/x86_64/Makefile b/xen/arch/x86/x86_64/Makefile index b9e0ab46c3..dc1f0be689 100644 --- a/xen/arch/x86/x86_64/Makefile +++ b/xen/arch/x86/x86_64/Makefile @@ -3,9 +3,14 @@ obj-y += gpr_switch.o obj-y += mm.o obj-y += traps.o +obj-$(CONFIG_COMPAT) += compat.o +obj-$(CONFIG_COMPAT) += physdev.o + ifeq ($(CONFIG_COMPAT),y) # extra dependencies +compat.o: ../compat.c entry.o: compat/entry.S mm.o: compat/mm.c +physdev.o: ../physdev.c traps.o: compat/traps.c endif diff --git a/xen/arch/x86/x86_64/compat.c b/xen/arch/x86/x86_64/compat.c new file mode 100644 index 0000000000..2a14d18a13 --- /dev/null +++ b/xen/arch/x86/x86_64/compat.c @@ -0,0 +1,30 @@ +/****************************************************************************** + * compat.c + */ + +#include +#include +#include +#include + +DEFINE_XEN_GUEST_HANDLE(physdev_op_compat_t); +#define physdev_op compat_physdev_op +#define physdev_op_t physdev_op_compat_t +#define do_physdev_op compat_physdev_op +#define do_physdev_op_compat(x) compat_physdev_op_compat(_##x) + +#define COMPAT +#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) +typedef int ret_t; + +#include "../compat.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 923392192e..5bb7309bac 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -283,15 +283,11 @@ CFIX14: #define compat_platform_op domain_crash_synchronous #define compat_multicall domain_crash_synchronous #define compat_set_timer_op domain_crash_synchronous -#define compat_event_channel_op_compat domain_crash_synchronous -#define compat_physdev_op_compat domain_crash_synchronous #define compat_grant_table_op domain_crash_synchronous #define compat_vcpu_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous #define compat_arch_sched_op domain_crash_synchronous #define compat_xenoprof_op domain_crash_synchronous -#define compat_event_channel_op domain_crash_synchronous -#define compat_physdev_op domain_crash_synchronous #define compat_sysctl domain_crash_synchronous #define compat_domctl domain_crash_synchronous @@ -312,7 +308,7 @@ ENTRY(compat_hypercall_table) .quad compat_multicall .quad compat_update_va_mapping .quad compat_set_timer_op /* 15 */ - .quad compat_event_channel_op_compat + .quad do_event_channel_op_compat .quad compat_xen_version .quad do_console_io .quad compat_physdev_op_compat @@ -328,7 +324,7 @@ ENTRY(compat_hypercall_table) .quad compat_arch_sched_op .quad compat_callback_op /* 30 */ .quad compat_xenoprof_op - .quad compat_event_channel_op + .quad do_event_channel_op .quad compat_physdev_op .quad compat_ni_hypercall .quad compat_sysctl /* 35 */ diff --git a/xen/arch/x86/x86_64/physdev.c b/xen/arch/x86/x86_64/physdev.c new file mode 100644 index 0000000000..42b8269e4d --- /dev/null +++ b/xen/arch/x86/x86_64/physdev.c @@ -0,0 +1,48 @@ +/****************************************************************************** + * physdev.c + */ + +#include +#include +#include +#include +#include +#include +#include + +#define do_physdev_op compat_physdev_op + +#define physdev_apic compat_physdev_apic +#define physdev_apic_t physdev_apic_compat_t + +#define physdev_eoi compat_physdev_eoi +#define physdev_eoi_t physdev_eoi_compat_t + +#define physdev_set_iobitmap compat_physdev_set_iobitmap +#define physdev_set_iobitmap_t physdev_set_iobitmap_compat_t + +#define physdev_set_iopl compat_physdev_set_iopl +#define physdev_set_iopl_t physdev_set_iopl_compat_t + +#define physdev_irq compat_physdev_irq +#define physdev_irq_t physdev_irq_compat_t + +#define physdev_irq_status_query compat_physdev_irq_status_query +#define physdev_irq_status_query_t physdev_irq_status_query_compat_t + +#define COMPAT +#undef guest_handle_okay +#define guest_handle_okay compat_handle_okay +typedef int ret_t; + +#include "../physdev.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/compat/xlat.c b/xen/common/compat/xlat.c index 1440001ba0..cae7debcbf 100644 --- a/xen/common/compat/xlat.c +++ b/xen/common/compat/xlat.c @@ -4,8 +4,8 @@ #include #include -#include #include +#include /* In-place translation functons: */ void xlat_start_info(struct start_info *native, @@ -21,6 +21,30 @@ void xlat_start_info(struct start_info *native, CHECK_dom0_vga_console_info; #undef dom0_vga_console_info +#define xen_evtchn_alloc_unbound evtchn_alloc_unbound +#define xen_evtchn_bind_interdomain evtchn_bind_interdomain +#define xen_evtchn_bind_ipi evtchn_bind_ipi +#define xen_evtchn_bind_pirq evtchn_bind_pirq +#define xen_evtchn_bind_vcpu evtchn_bind_vcpu +#define xen_evtchn_bind_virq evtchn_bind_virq +#define xen_evtchn_close evtchn_close +#define xen_evtchn_op evtchn_op +#define xen_evtchn_send evtchn_send +#define xen_evtchn_status evtchn_status +#define xen_evtchn_unmask evtchn_unmask +CHECK_evtchn_op; +#undef xen_evtchn_alloc_unbound +#undef xen_evtchn_bind_interdomain +#undef xen_evtchn_bind_ipi +#undef xen_evtchn_bind_pirq +#undef xen_evtchn_bind_vcpu +#undef xen_evtchn_bind_virq +#undef xen_evtchn_close +#undef xen_evtchn_op +#undef xen_evtchn_send +#undef xen_evtchn_status +#undef xen_evtchn_unmask + #define xen_mmu_update mmu_update CHECK_mmu_update; #undef xen_mmu_update diff --git a/xen/include/asm-x86/hypercall.h b/xen/include/asm-x86/hypercall.h index ee911a91b0..34216f2435 100644 --- a/xen/include/asm-x86/hypercall.h +++ b/xen/include/asm-x86/hypercall.h @@ -123,4 +123,13 @@ do_set_callbacks( #endif +#ifdef CONFIG_COMPAT + +extern int +compat_physdev_op( + int cmd, + XEN_GUEST_HANDLE(void) arg); + +#endif + #endif /* __ASM_X86_HYPERCALL_H__ */ diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 0027ed65c0..45f000ddbe 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -6,6 +6,17 @@ ! mmuext_op xen.h ! start_info xen.h ? vcpu_time_info xen.h +? evtchn_alloc_unbound event_channel.h +? evtchn_bind_interdomain event_channel.h +? evtchn_bind_ipi event_channel.h +? evtchn_bind_pirq event_channel.h +? evtchn_bind_vcpu event_channel.h +? evtchn_bind_virq event_channel.h +? evtchn_close event_channel.h +? evtchn_op event_channel.h +? evtchn_send event_channel.h +? evtchn_status event_channel.h +? evtchn_unmask event_channel.h ! add_to_physmap memory.h ! foreign_memory_map memory.h ! memory_exchange memory.h From 10254dc1047c99da362d4e481b1ea5b713ae4ca3 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:33 +0000 Subject: [PATCH 084/570] Enable compatibility mode operation for HYPERVISOR_vcpu_op. Signed-off-by: Jan Beulich --- xen/arch/x86/domain.c | 25 +++++-- xen/arch/x86/x86_64/Makefile | 1 + xen/arch/x86/x86_64/compat/entry.S | 1 - xen/arch/x86/x86_64/domain.c | 68 +++++++++++++++++++ xen/common/compat/Makefile | 1 + xen/common/compat/domain.c | 102 +++++++++++++++++++++++++++++ xen/common/compat/xlat.c | 9 +++ xen/include/asm-x86/hypercall.h | 4 ++ xen/include/xen/compat.h | 2 + xen/include/xen/sched.h | 14 ++++ xen/include/xlat.lst | 4 ++ 11 files changed, 225 insertions(+), 6 deletions(-) create mode 100644 xen/arch/x86/x86_64/domain.c create mode 100644 xen/common/compat/domain.c diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 189bb03e00..2476271e56 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -40,6 +40,9 @@ #include #include #include +#ifdef CONFIG_COMPAT +#include +#endif DEFINE_PER_CPU(struct vcpu *, curr_vcpu); @@ -559,16 +562,16 @@ arch_do_vcpu_op( break; rc = 0; - v->runstate_guest = area.addr.h; + runstate_guest(v) = area.addr.h; if ( v == current ) { - __copy_to_guest(v->runstate_guest, &v->runstate, 1); + __copy_to_guest(runstate_guest(v), &v->runstate, 1); } else { vcpu_runstate_get(v, &runstate); - __copy_to_guest(v->runstate_guest, &runstate, 1); + __copy_to_guest(runstate_guest(v), &runstate, 1); } break; @@ -970,8 +973,20 @@ void context_switch(struct vcpu *prev, struct vcpu *next) context_saved(prev); /* Update per-VCPU guest runstate shared memory area (if registered). */ - if ( !guest_handle_is_null(next->runstate_guest) ) - __copy_to_guest(next->runstate_guest, &next->runstate, 1); + if ( !guest_handle_is_null(runstate_guest(next)) ) + { + if ( !IS_COMPAT(next->domain) ) + __copy_to_guest(runstate_guest(next), &next->runstate, 1); +#ifdef CONFIG_COMPAT + else + { + struct compat_vcpu_runstate_info info; + + XLAT_vcpu_runstate_info(&info, &next->runstate); + __copy_to_guest(next->runstate_guest.compat, &info, 1); + } +#endif + } schedule_tail(next); BUG(); diff --git a/xen/arch/x86/x86_64/Makefile b/xen/arch/x86/x86_64/Makefile index dc1f0be689..5709de3694 100644 --- a/xen/arch/x86/x86_64/Makefile +++ b/xen/arch/x86/x86_64/Makefile @@ -4,6 +4,7 @@ obj-y += mm.o obj-y += traps.o obj-$(CONFIG_COMPAT) += compat.o +obj-$(CONFIG_COMPAT) += domain.o obj-$(CONFIG_COMPAT) += physdev.o ifeq ($(CONFIG_COMPAT),y) diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 5bb7309bac..0615474490 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -284,7 +284,6 @@ CFIX14: #define compat_multicall domain_crash_synchronous #define compat_set_timer_op domain_crash_synchronous #define compat_grant_table_op domain_crash_synchronous -#define compat_vcpu_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous #define compat_arch_sched_op domain_crash_synchronous #define compat_xenoprof_op domain_crash_synchronous diff --git a/xen/arch/x86/x86_64/domain.c b/xen/arch/x86/x86_64/domain.c new file mode 100644 index 0000000000..775e536f4d --- /dev/null +++ b/xen/arch/x86/x86_64/domain.c @@ -0,0 +1,68 @@ +/****************************************************************************** + * arch/x86/x86_64/domain.c + * + */ + +#include +#include +#include +#include +#include + +int +arch_compat_vcpu_op( + int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg) +{ + long rc = 0; + + switch ( cmd ) + { + case VCPUOP_register_runstate_memory_area: + { + struct compat_vcpu_register_runstate_memory_area area; + struct compat_vcpu_runstate_info info; + + rc = -EFAULT; + if ( copy_from_guest(&area, arg, 1) ) + break; + + if ( area.addr.h.c != area.addr.p || + !compat_handle_okay(area.addr.h, 1) ) + break; + + rc = 0; + guest_from_compat_handle(v->runstate_guest.compat, area.addr.h); + + if ( v == current ) + { + XLAT_vcpu_runstate_info(&info, &v->runstate); + } + else + { + struct vcpu_runstate_info runstate; + + vcpu_runstate_get(v, &runstate); + XLAT_vcpu_runstate_info(&info, &v->runstate); + } + __copy_to_guest(v->runstate_guest.compat, &info, 1); + + break; + } + + default: + rc = -ENOSYS; + break; + } + + return rc; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/compat/Makefile b/xen/common/compat/Makefile index 5510e645d1..9a54a43c50 100644 --- a/xen/common/compat/Makefile +++ b/xen/common/compat/Makefile @@ -1,3 +1,4 @@ +obj-y += domain.o obj-y += kernel.o obj-y += memory.o obj-y += xlat.o diff --git a/xen/common/compat/domain.c b/xen/common/compat/domain.c new file mode 100644 index 0000000000..fbe7602e8d --- /dev/null +++ b/xen/common/compat/domain.c @@ -0,0 +1,102 @@ +/****************************************************************************** + * domain.c + * + */ + +#include +#include +#include +#include +#include +#include +#include + +int compat_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg) +{ + struct domain *d = current->domain; + struct vcpu *v; + long rc = 0; + + if ( (vcpuid < 0) || (vcpuid >= MAX_VIRT_CPUS) ) + return -EINVAL; + + if ( (v = d->vcpu[vcpuid]) == NULL ) + return -ENOENT; + + switch ( cmd ) + { + case VCPUOP_initialise: + { + struct compat_vcpu_guest_context *cmp_ctxt; + struct vcpu_guest_context *nat_ctxt; + + if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL ) + { + rc = -ENOMEM; + break; + } + + if ( copy_from_guest(cmp_ctxt, arg, 1) ) + { + xfree(cmp_ctxt); + rc = -EFAULT; + break; + } + + if ( (nat_ctxt = xmalloc(struct vcpu_guest_context)) == NULL ) + { + rc = -ENOMEM; + break; + } + + memset(nat_ctxt, 0, sizeof(*nat_ctxt)); + XLAT_vcpu_guest_context(nat_ctxt, cmp_ctxt); + xfree(cmp_ctxt); + + LOCK_BIGLOCK(d); + rc = -EEXIST; + if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) + rc = boot_vcpu(d, vcpuid, nat_ctxt); + UNLOCK_BIGLOCK(d); + + xfree(nat_ctxt); + break; + } + + case VCPUOP_up: + case VCPUOP_down: + case VCPUOP_is_up: + rc = do_vcpu_op(cmd, vcpuid, arg); + break; + + case VCPUOP_get_runstate_info: + { + union { + struct vcpu_runstate_info nat; + struct compat_vcpu_runstate_info cmp; + } runstate; + + vcpu_runstate_get(v, &runstate.nat); + xlat_vcpu_runstate_info(&runstate.nat); + if ( copy_to_guest(arg, &runstate.cmp, 1) ) + rc = -EFAULT; + break; + } + + default: + rc = arch_compat_vcpu_op(cmd, v, arg); + break; + } + + return rc; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/compat/xlat.c b/xen/common/compat/xlat.c index cae7debcbf..2a8dc6decf 100644 --- a/xen/common/compat/xlat.c +++ b/xen/common/compat/xlat.c @@ -6,6 +6,7 @@ #include #include #include +#include /* In-place translation functons: */ void xlat_start_info(struct start_info *native, @@ -17,6 +18,14 @@ void xlat_start_info(struct start_info *native, XLAT_start_info(compat, native); } +void xlat_vcpu_runstate_info(struct vcpu_runstate_info *native) +{ + struct compat_vcpu_runstate_info *compat = (void *)native; + + BUILD_BUG_ON(sizeof(*native) < sizeof(*compat)); + XLAT_vcpu_runstate_info(compat, native); +} + #define xen_dom0_vga_console_info dom0_vga_console_info CHECK_dom0_vga_console_info; #undef dom0_vga_console_info diff --git a/xen/include/asm-x86/hypercall.h b/xen/include/asm-x86/hypercall.h index 34216f2435..fa9476c1d3 100644 --- a/xen/include/asm-x86/hypercall.h +++ b/xen/include/asm-x86/hypercall.h @@ -130,6 +130,10 @@ compat_physdev_op( int cmd, XEN_GUEST_HANDLE(void) arg); +extern int +arch_compat_vcpu_op( + int cmd, struct vcpu *v, XEN_GUEST_HANDLE(void) arg); + #endif #endif /* __ASM_X86_HYPERCALL_H__ */ diff --git a/xen/include/xen/compat.h b/xen/include/xen/compat.h index b06842f592..d5b733ec58 100644 --- a/xen/include/xen/compat.h +++ b/xen/include/xen/compat.h @@ -163,6 +163,8 @@ int hypercall_xlat_continuation(unsigned int *id, unsigned int mask, ...); /* In-place translation functons: */ struct start_info; void xlat_start_info(struct start_info *, enum XLAT_start_info_console); +struct vcpu_runstate_info; +void xlat_vcpu_runstate_info(struct vcpu_runstate_info *); #define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG) diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 533a5763f5..81bb634f20 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -18,6 +18,11 @@ #include #include +#ifdef CONFIG_COMPAT +#include +DEFINE_XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t); +#endif + extern unsigned long volatile jiffies; extern rwlock_t domlist_lock; @@ -82,7 +87,16 @@ struct vcpu void *sched_priv; /* scheduler-specific data */ struct vcpu_runstate_info runstate; +#ifndef CONFIG_COMPAT +# define runstate_guest(v) ((v)->runstate_guest) XEN_GUEST_HANDLE(vcpu_runstate_info_t) runstate_guest; /* guest address */ +#else +# define runstate_guest(v) ((v)->runstate_guest.native) + union { + XEN_GUEST_HANDLE(vcpu_runstate_info_t) native; + XEN_GUEST_HANDLE(vcpu_runstate_info_compat_t) compat; + } runstate_guest; /* guest address */ +#endif unsigned long vcpu_flags; diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 45f000ddbe..bfd017b744 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -6,6 +6,9 @@ ! mmuext_op xen.h ! start_info xen.h ? vcpu_time_info xen.h +! cpu_user_regs arch-@arch@.h +! trap_info arch-@arch@.h +! vcpu_guest_context arch-@arch@.h ? evtchn_alloc_unbound event_channel.h ? evtchn_bind_interdomain event_channel.h ? evtchn_bind_ipi event_channel.h @@ -23,3 +26,4 @@ ! memory_map memory.h ! memory_reservation memory.h ! translate_gpfn_list memory.h +! vcpu_runstate_info vcpu.h From ff311267b0e2ebe889e5b4067469be9028d94b8b Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:33 +0000 Subject: [PATCH 085/570] Merge vcpuop compat header creation Signed-off-by: Emmanuel Ackaouy --- xen/include/Makefile | 2 ++ xen/include/xlat.lst | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/xen/include/Makefile b/xen/include/Makefile index 416c3a8fee..d2efb237c3 100644 --- a/xen/include/Makefile +++ b/xen/include/Makefile @@ -4,6 +4,8 @@ compat-arch-$(CONFIG_X86) := x86_32 headers-y := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g') headers-y := $(filter-out %/dom0_ops.h,$(headers-y)) +headers-$(CONFIG_X86) += compat/arch-x86/xen.h +headers-$(CONFIG_X86) += compat/arch-x86/xen-$(compat-arch-y).h headers-y += compat/arch-$(compat-arch-y).h compat/xlat.h cppflags-y := -include public/xen-compat.h diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index bfd017b744..df786c0d53 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -6,9 +6,9 @@ ! mmuext_op xen.h ! start_info xen.h ? vcpu_time_info xen.h -! cpu_user_regs arch-@arch@.h -! trap_info arch-@arch@.h -! vcpu_guest_context arch-@arch@.h +! cpu_user_regs arch-x86/xen-@arch@.h +! trap_info arch-x86/xen.h +! vcpu_guest_context arch-x86/xen.h ? evtchn_alloc_unbound event_channel.h ? evtchn_bind_interdomain event_channel.h ? evtchn_bind_ipi event_channel.h From cda335c279bf3da50dc8f47691896928bac2e529 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:34 +0000 Subject: [PATCH 086/570] Enable compatibility mode operation for HYPERVISOR_set_trap_table and HYPERVISOR_set_gdt. Signed-off-by: Jan Beulich --- xen/arch/x86/x86_64/compat/entry.S | 2 -- xen/arch/x86/x86_64/compat/mm.c | 33 ++++++++++++++++++++++ xen/arch/x86/x86_64/compat/traps.c | 45 ++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 0615474490..47cd1e3864 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -278,8 +278,6 @@ CFIX14: .section .rodata, "a", @progbits -#define compat_set_trap_table domain_crash_synchronous -#define compat_set_gdt domain_crash_synchronous #define compat_platform_op domain_crash_synchronous #define compat_multicall domain_crash_synchronous #define compat_set_timer_op domain_crash_synchronous diff --git a/xen/arch/x86/x86_64/compat/mm.c b/xen/arch/x86/x86_64/compat/mm.c index 874774660a..ae833ff4a6 100644 --- a/xen/arch/x86/x86_64/compat/mm.c +++ b/xen/arch/x86/x86_64/compat/mm.c @@ -4,6 +4,39 @@ #include #include +int compat_set_gdt(XEN_GUEST_HANDLE(uint) frame_list, unsigned int entries) +{ + unsigned int i, nr_pages = (entries + 511) / 512; + unsigned long frames[16]; + long ret; + + /* Rechecked in set_gdt, but ensures a sane limit for copy_from_user(). */ + if ( entries > FIRST_RESERVED_GDT_ENTRY ) + return -EINVAL; + + if ( !guest_handle_okay(frame_list, nr_pages) ) + return -EFAULT; + + for ( i = 0; i < nr_pages; ++i ) + { + unsigned int frame; + + if ( __copy_from_guest(&frame, frame_list, 1) ) + return -EFAULT; + frames[i] = frame; + guest_handle_add_offset(frame_list, 1); + } + + LOCK_BIGLOCK(current->domain); + + if ( (ret = set_gdt(current, frames, entries)) == 0 ) + local_flush_tlb(); + + UNLOCK_BIGLOCK(current->domain); + + return ret; +} + int compat_update_descriptor(u32 pa_lo, u32 pa_hi, u32 desc_lo, u32 desc_hi) { return do_update_descriptor(pa_lo | ((u64)pa_hi << 32), diff --git a/xen/arch/x86/x86_64/compat/traps.c b/xen/arch/x86/x86_64/compat/traps.c index 834a6ba1f0..938732ba9f 100644 --- a/xen/arch/x86/x86_64/compat/traps.c +++ b/xen/arch/x86/x86_64/compat/traps.c @@ -1,6 +1,8 @@ #ifdef CONFIG_COMPAT +#include #include +#include void compat_show_guest_stack(struct cpu_user_regs *regs, int debug_stack_lines) { @@ -252,6 +254,49 @@ long compat_set_callbacks(unsigned long event_selector, return 0; } +DEFINE_XEN_GUEST_HANDLE(trap_info_compat_t); + +int compat_set_trap_table(XEN_GUEST_HANDLE(trap_info_compat_t) traps) +{ + struct compat_trap_info cur; + struct trap_info *dst = current->arch.guest_context.trap_ctxt; + long rc = 0; + + /* If no table is presented then clear the entire virtual IDT. */ + if ( guest_handle_is_null(traps) ) + { + memset(dst, 0, 256 * sizeof(*dst)); + return 0; + } + + for ( ; ; ) + { + if ( hypercall_preempt_check() ) + { + rc = hypercall_create_continuation( + __HYPERVISOR_set_trap_table, "h", traps); + break; + } + + if ( copy_from_guest(&cur, traps, 1) ) + { + rc = -EFAULT; + break; + } + + if ( cur.address == 0 ) + break; + + fixup_guest_code_selector(current->domain, cur.cs); + + XLAT_trap_info(dst + cur.vector, &cur); + + guest_handle_add_offset(traps, 1); + } + + return rc; +} + #endif /* CONFIG_COMPAT */ static void hypercall_page_initialise_ring1_kernel(void *hypercall_page) From 75a2a59383d0e0bb7c89917a3fdad683bad4996c Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:34 +0000 Subject: [PATCH 087/570] Enable compatibility mode operation for HYPERVISOR_multicall. Signed-off-by: Jan Beulich --- xen/arch/x86/x86_64/asm-offsets.c | 12 ++++++++++++ xen/arch/x86/x86_64/compat/entry.S | 1 - xen/common/compat/Makefile | 2 ++ xen/common/compat/multicall.c | 31 ++++++++++++++++++++++++++++++ xen/common/multicall.c | 5 ++++- xen/include/asm-x86/multicall.h | 25 ++++++++++++++++++++++++ xen/include/xen/multicall.h | 10 +++++++++- 7 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 xen/common/compat/multicall.c diff --git a/xen/arch/x86/x86_64/asm-offsets.c b/xen/arch/x86/x86_64/asm-offsets.c index 7a86371630..001a781235 100644 --- a/xen/arch/x86/x86_64/asm-offsets.c +++ b/xen/arch/x86/x86_64/asm-offsets.c @@ -135,5 +135,17 @@ void __dummy__(void) OFFSET(MULTICALL_result, struct multicall_entry, result); BLANK(); +#ifdef CONFIG_COMPAT + OFFSET(COMPAT_MULTICALL_op, struct compat_multicall_entry, op); + OFFSET(COMPAT_MULTICALL_arg0, struct compat_multicall_entry, args[0]); + OFFSET(COMPAT_MULTICALL_arg1, struct compat_multicall_entry, args[1]); + OFFSET(COMPAT_MULTICALL_arg2, struct compat_multicall_entry, args[2]); + OFFSET(COMPAT_MULTICALL_arg3, struct compat_multicall_entry, args[3]); + OFFSET(COMPAT_MULTICALL_arg4, struct compat_multicall_entry, args[4]); + OFFSET(COMPAT_MULTICALL_arg5, struct compat_multicall_entry, args[5]); + OFFSET(COMPAT_MULTICALL_result, struct compat_multicall_entry, result); + BLANK(); +#endif + DEFINE(IRQSTAT_shift, LOG_2(sizeof(irq_cpustat_t))); } diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 47cd1e3864..fa62fe4160 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -279,7 +279,6 @@ CFIX14: .section .rodata, "a", @progbits #define compat_platform_op domain_crash_synchronous -#define compat_multicall domain_crash_synchronous #define compat_set_timer_op domain_crash_synchronous #define compat_grant_table_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous diff --git a/xen/common/compat/Makefile b/xen/common/compat/Makefile index 9a54a43c50..dfab7bc77c 100644 --- a/xen/common/compat/Makefile +++ b/xen/common/compat/Makefile @@ -1,7 +1,9 @@ obj-y += domain.o obj-y += kernel.o obj-y += memory.o +obj-y += multicall.o obj-y += xlat.o # extra dependencies kernel.o: ../kernel.c +multicall.o: ../multicall.c diff --git a/xen/common/compat/multicall.c b/xen/common/compat/multicall.c new file mode 100644 index 0000000000..17b12d6462 --- /dev/null +++ b/xen/common/compat/multicall.c @@ -0,0 +1,31 @@ +/****************************************************************************** + * multicall.c + */ + +#include +#include +#include + +#define COMPAT +typedef int ret_t; +#undef do_multicall_call + +DEFINE_XEN_GUEST_HANDLE(multicall_entry_compat_t); +#define multicall_entry compat_multicall_entry +#define multicall_entry_t multicall_entry_compat_t +#define do_multicall_call compat_multicall_call +#define call compat_call +#define do_multicall(l, n) compat_multicall(_##l, n) +#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) + +#include "../multicall.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/multicall.c b/xen/common/multicall.c index 499e6bd62c..1a43838ca0 100644 --- a/xen/common/multicall.c +++ b/xen/common/multicall.c @@ -13,9 +13,12 @@ #include #include +#ifndef COMPAT DEFINE_PER_CPU(struct mc_state, mc_state); +typedef long ret_t; +#endif -long +ret_t do_multicall( XEN_GUEST_HANDLE(multicall_entry_t) call_list, unsigned int nr_calls) { diff --git a/xen/include/asm-x86/multicall.h b/xen/include/asm-x86/multicall.h index 1ce7866c3e..8414dca055 100644 --- a/xen/include/asm-x86/multicall.h +++ b/xen/include/asm-x86/multicall.h @@ -35,6 +35,31 @@ "r8", "r9", "r10", "r11" ); \ } while ( 0 ) +#define compat_multicall_call(_call) \ + do { \ + __asm__ __volatile__ ( \ + " movl "STR(COMPAT_MULTICALL_op)"(%0),%%eax; " \ + " leaq compat_hypercall_table(%%rip),%%rdi; " \ + " cmpl $("STR(NR_hypercalls)"),%%eax; " \ + " jae 2f; " \ + " movq (%%rdi,%%rax,8),%%rax; " \ + " movl "STR(COMPAT_MULTICALL_arg0)"(%0),%%edi; " \ + " movl "STR(COMPAT_MULTICALL_arg1)"(%0),%%esi; " \ + " movl "STR(COMPAT_MULTICALL_arg2)"(%0),%%edx; " \ + " movl "STR(COMPAT_MULTICALL_arg3)"(%0),%%ecx; " \ + " movl "STR(COMPAT_MULTICALL_arg4)"(%0),%%r8d; " \ + " callq *%%rax; " \ + "1: movl %%eax,"STR(COMPAT_MULTICALL_result)"(%0)\n"\ + ".section .fixup,\"ax\"\n" \ + "2: movl $-"STR(ENOSYS)",%%eax\n" \ + " jmp 1b\n" \ + ".previous\n" \ + : : "b" (_call) \ + /* all the caller-saves registers */ \ + : "rax", "rcx", "rdx", "rsi", "rdi", \ + "r8", "r9", "r10", "r11" ); \ + } while ( 0 ) + #else #define do_multicall_call(_call) \ diff --git a/xen/include/xen/multicall.h b/xen/include/xen/multicall.h index 5d8b4db1ca..34cdb4664f 100644 --- a/xen/include/xen/multicall.h +++ b/xen/include/xen/multicall.h @@ -7,6 +7,9 @@ #include #include +#ifdef CONFIG_COMPAT +#include +#endif #define _MCSF_in_multicall 0 #define _MCSF_call_preempted 1 @@ -14,7 +17,12 @@ #define MCSF_call_preempted (1<<_MCSF_call_preempted) struct mc_state { unsigned long flags; - struct multicall_entry call; + union { + struct multicall_entry call; +#ifdef CONFIG_COMPAT + struct compat_multicall_entry compat_call; +#endif + }; }; DECLARE_PER_CPU(struct mc_state, mc_state); From 2942f45e09fb239f07af6d980f6a60e5d92ae04e Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:35 +0000 Subject: [PATCH 088/570] Enable compatibility mode operation for HYPERVISOR_sched_op and HYPERVISOR_set_timer_op. Signed-off-by: Jan Beulich --- xen/arch/x86/x86_64/compat/entry.S | 6 ++-- xen/common/Makefile | 5 +++ xen/common/compat/schedule.c | 51 ++++++++++++++++++++++++++++++ xen/common/schedule.c | 17 ++++++++-- xen/include/xlat.lst | 3 ++ 5 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 xen/common/compat/schedule.c diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index fa62fe4160..a7decff144 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -279,10 +279,8 @@ CFIX14: .section .rodata, "a", @progbits #define compat_platform_op domain_crash_synchronous -#define compat_set_timer_op domain_crash_synchronous #define compat_grant_table_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous -#define compat_arch_sched_op domain_crash_synchronous #define compat_xenoprof_op domain_crash_synchronous #define compat_sysctl domain_crash_synchronous #define compat_domctl domain_crash_synchronous @@ -317,7 +315,7 @@ ENTRY(compat_hypercall_table) .quad compat_mmuext_op .quad compat_acm_op .quad compat_nmi_op - .quad compat_arch_sched_op + .quad compat_sched_op .quad compat_callback_op /* 30 */ .quad compat_xenoprof_op .quad do_event_channel_op @@ -359,7 +357,7 @@ ENTRY(compat_hypercall_args_table) .byte 4 /* compat_mmuext_op */ .byte 1 /* compat_acm_op */ .byte 2 /* compat_nmi_op */ - .byte 2 /* compat_arch_sched_op */ + .byte 2 /* compat_sched_op */ .byte 2 /* compat_callback_op */ /* 30 */ .byte 2 /* compat_xenoprof_op */ .byte 2 /* compat_event_channel_op */ diff --git a/xen/common/Makefile b/xen/common/Makefile index 680fd60b8c..2beaa128c0 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -39,3 +39,8 @@ subdir-$(CONFIG_COMPAT) += compat # Object file contains changeset and compiler information. version.o: $(BASEDIR)/include/xen/compile.h + +ifeq ($(CONFIG_COMPAT),y) +# extra dependencies +schedule.o: compat/schedule.c +endif diff --git a/xen/common/compat/schedule.c b/xen/common/compat/schedule.c new file mode 100644 index 0000000000..5795279978 --- /dev/null +++ b/xen/common/compat/schedule.c @@ -0,0 +1,51 @@ +/**************************************************************************** + * schedule.c + * + */ + +#include + +#define COMPAT +#define ret_t int + +#define do_sched_op compat_sched_op + +#define xen_sched_shutdown sched_shutdown +CHECK_sched_shutdown; +#undef xen_sched_shutdown + +#define xen_sched_remote_shutdown sched_remote_shutdown +CHECK_sched_remote_shutdown; +#undef xen_sched_remote_shutdown + +static int compat_poll(struct compat_sched_poll *compat) +{ + struct sched_poll native; + +#define XLAT_sched_poll_HNDL_ports(_d_, _s_) \ + guest_from_compat_handle((_d_)->ports, (_s_)->ports) + XLAT_sched_poll(&native, compat); +#undef XLAT_sched_poll_HNDL_ports + + return do_poll(&native); +} + +#define do_poll compat_poll +#define sched_poll compat_sched_poll + +#include "../schedule.c" + +int compat_set_timer_op(u32 lo, s32 hi) +{ + return do_set_timer_op(((s64)hi << 32) | lo); +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 4083426cb0..69fbb02634 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -13,6 +13,7 @@ * */ +#ifndef COMPAT #include #include #include @@ -366,9 +367,13 @@ long do_sched_op_compat(int cmd, unsigned long arg) return ret; } -long do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg) +typedef long ret_t; + +#endif /* !COMPAT */ + +ret_t do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg) { - long ret = 0; + ret_t ret = 0; switch ( cmd ) { @@ -445,6 +450,8 @@ long do_sched_op(int cmd, XEN_GUEST_HANDLE(void) arg) return ret; } +#ifndef COMPAT + /* Per-domain one-shot-timer hypercall. */ long do_set_timer_op(s_time_t timeout) { @@ -736,6 +743,12 @@ void dump_runq(unsigned char key) local_irq_restore(flags); } +#ifdef CONFIG_COMPAT +#include "compat/schedule.c" +#endif + +#endif /* !COMPAT */ + /* * Local variables: * mode: C diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index df786c0d53..5ac6430a91 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -26,4 +26,7 @@ ! memory_map memory.h ! memory_reservation memory.h ! translate_gpfn_list memory.h +! sched_poll sched.h +? sched_remote_shutdown sched.h +? sched_shutdown sched.h ! vcpu_runstate_info vcpu.h From e41630cef3c84ac6cf15f57be909fe0bb1376da7 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:35 +0000 Subject: [PATCH 089/570] Enable compatibility mode operation for HYPERVISOR_grant_table_op. Signed-off-by: Jan Beulich --- xen/arch/x86/x86_64/compat/entry.S | 1 - xen/common/Makefile | 1 + xen/common/compat/grant_table.c | 218 +++++++++++++++++++++++++++++ xen/common/grant_table.c | 4 + xen/include/xlat.lst | 7 + 5 files changed, 230 insertions(+), 1 deletion(-) create mode 100644 xen/common/compat/grant_table.c diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index a7decff144..d9d70a248c 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -279,7 +279,6 @@ CFIX14: .section .rodata, "a", @progbits #define compat_platform_op domain_crash_synchronous -#define compat_grant_table_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous #define compat_xenoprof_op domain_crash_synchronous #define compat_sysctl domain_crash_synchronous diff --git a/xen/common/Makefile b/xen/common/Makefile index 2beaa128c0..625d5a122a 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -42,5 +42,6 @@ version.o: $(BASEDIR)/include/xen/compile.h ifeq ($(CONFIG_COMPAT),y) # extra dependencies +grant_table.o: compat/grant_table.c schedule.o: compat/schedule.c endif diff --git a/xen/common/compat/grant_table.c b/xen/common/compat/grant_table.c new file mode 100644 index 0000000000..9680a1779d --- /dev/null +++ b/xen/common/compat/grant_table.c @@ -0,0 +1,218 @@ +/****************************************************************************** + * common/compat/grant_table.c + * + */ + +#include + +#define xen_grant_entry grant_entry +CHECK_grant_entry; +#undef xen_grant_entry + +#define xen_gnttab_map_grant_ref gnttab_map_grant_ref +CHECK_gnttab_map_grant_ref; +#undef xen_gnttab_map_grant_ref + +#define xen_gnttab_unmap_grant_ref gnttab_unmap_grant_ref +CHECK_gnttab_unmap_grant_ref; +#undef xen_gnttab_unmap_grant_ref + +DEFINE_XEN_GUEST_HANDLE(gnttab_setup_table_compat_t); +DEFINE_XEN_GUEST_HANDLE(gnttab_transfer_compat_t); +DEFINE_XEN_GUEST_HANDLE(gnttab_copy_compat_t); + +#define xen_gnttab_dump_table gnttab_dump_table +CHECK_gnttab_dump_table; +#undef xen_gnttab_dump_table + +int compat_grant_table_op(unsigned int cmd, + XEN_GUEST_HANDLE(void) cmp_uop, + unsigned int count) +{ + int rc = 0; + unsigned int i; + + switch ( cmd ) + { +#define CASE(name) \ + case GNTTABOP_##name: \ + if ( unlikely(!guest_handle_okay(guest_handle_cast(cmp_uop, \ + gnttab_##name##_compat_t), \ + count)) ) \ + rc = -EFAULT; \ + break + +#ifndef CHECK_gnttab_map_grant_ref + CASE(map_grant_ref); +#endif + +#ifndef CHECK_gnttab_unmap_grant_ref + CASE(unmap_grant_ref); +#endif + +#ifndef CHECK_gnttab_setup_table + CASE(setup_table); +#endif + +#ifndef CHECK_gnttab_transfer + CASE(transfer); +#endif + +#ifndef CHECK_gnttab_copy + CASE(copy); +#endif + +#ifndef CHECK_gnttab_dump_table + CASE(dump_table); +#endif + +#undef CASE + default: + return do_grant_table_op(cmd, cmp_uop, count); + } + + if ( count > 512 ) + rc = -EINVAL; + + for ( i = 0; i < count && rc == 0; ) + { + unsigned int n; + union { + XEN_GUEST_HANDLE(void) uop; + struct gnttab_setup_table *setup; + struct gnttab_transfer *xfer; + struct gnttab_copy *copy; + } nat; + union { + struct compat_gnttab_setup_table setup; + struct compat_gnttab_transfer xfer; + struct compat_gnttab_copy copy; + } cmp; + + set_xen_guest_handle(nat.uop, (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); + switch ( cmd ) + { + case GNTTABOP_setup_table: + if ( unlikely(count > 1) ) + rc = -EINVAL; + else if ( unlikely(__copy_from_guest(&cmp.setup, cmp_uop, 1)) ) + rc = -EFAULT; + else if ( unlikely(!compat_handle_okay(cmp.setup.frame_list, cmp.setup.nr_frames)) ) + rc = -EFAULT; + else + { + BUILD_BUG_ON((COMPAT_ARG_XLAT_SIZE - sizeof(*nat.setup)) / sizeof(*nat.setup->frame_list.p) < NR_GRANT_FRAMES); +#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \ + set_xen_guest_handle((_d_)->frame_list, (unsigned long *)(nat.setup + 1)) + XLAT_gnttab_setup_table(nat.setup, &cmp.setup); +#undef XLAT_gnttab_setup_table_HNDL_frame_list + rc = gnttab_setup_table(guest_handle_cast(nat.uop, gnttab_setup_table_t), 1); + } + if ( rc == 0 ) + { + BUG_ON(nat.setup->nr_frames > NR_GRANT_FRAMES); +#define XLAT_gnttab_setup_table_HNDL_frame_list(_d_, _s_) \ + do \ + { \ + if ( (_s_)->status == GNTST_okay ) \ + { \ + for ( i = 0; i < (_s_)->nr_frames; ++i ) \ + { \ + unsigned int frame = (_s_)->frame_list.p[i]; \ + BUG_ON(frame != (_s_)->frame_list.p[i]); \ + (void)__copy_to_compat_offset((_d_)->frame_list, i, &frame, 1); \ + } \ + } \ + } while (0) + XLAT_gnttab_setup_table(&cmp.setup, nat.setup); +#undef XLAT_gnttab_setup_table_HNDL_frame_list + if ( unlikely(__copy_to_guest(cmp_uop, &cmp.setup, 1)) ) + rc = -EFAULT; + else + i = 1; + } + break; + + case GNTTABOP_transfer: + for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.xfer) && i < count && rc == 0; ++i, ++n ) + { + if ( unlikely(__copy_from_guest_offset(&cmp.xfer, cmp_uop, i, 1)) ) + rc = -EFAULT; + else + { + XLAT_gnttab_transfer(nat.xfer + n, &cmp.xfer); + } + } + if ( rc == 0 ) + rc = gnttab_transfer(guest_handle_cast(nat.uop, gnttab_transfer_t), n); + if ( rc == 0 ) + { + XEN_GUEST_HANDLE(gnttab_transfer_compat_t) xfer; + + xfer = guest_handle_cast(cmp_uop, gnttab_transfer_compat_t); + guest_handle_add_offset(xfer, i); + while ( n-- ) + { + guest_handle_add_offset(xfer, -1); + if ( __copy_field_to_guest(xfer, nat.xfer, status) ) + rc = -EFAULT; + } + } + break; + + case GNTTABOP_copy: + for ( n = 0; i < COMPAT_ARG_XLAT_SIZE / sizeof(*nat.copy) && i < count && rc == 0; ++i, ++n ) + { + if ( unlikely(__copy_from_guest_offset(&cmp.copy, cmp_uop, i, 1)) ) + rc = -EFAULT; + else + { + enum XLAT_gnttab_copy_source_u source_u; + enum XLAT_gnttab_copy_dest_u dest_u; + + if ( cmp.copy.flags & GNTCOPY_source_gref ) + source_u = XLAT_gnttab_copy_source_u_ref; + else + source_u = XLAT_gnttab_copy_source_u_gmfn; + if ( cmp.copy.flags & GNTCOPY_dest_gref ) + dest_u = XLAT_gnttab_copy_dest_u_ref; + else + dest_u = XLAT_gnttab_copy_dest_u_gmfn; + XLAT_gnttab_copy(nat.copy + n, &cmp.copy); + } + } + if ( rc == 0 ) + rc = gnttab_copy(guest_handle_cast(nat.uop, gnttab_copy_t), n); + if ( rc == 0 ) + { + XEN_GUEST_HANDLE(gnttab_copy_compat_t) copy; + + copy = guest_handle_cast(cmp_uop, gnttab_copy_compat_t); + guest_handle_add_offset(copy, i); + while ( n-- ) + { + guest_handle_add_offset(copy, -1); + if ( __copy_field_to_guest(copy, nat.copy, status) ) + rc = -EFAULT; + } + } + break; + + default: + domain_crash(current->domain); + break; + } + } + + return rc; +} + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index 3a6bc9587f..3df8af4116 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -1048,6 +1048,10 @@ do_grant_table_op( return rc; } +#ifdef CONFIG_COMPAT +#include "compat/grant_table.c" +#endif + int grant_table_create( struct domain *d) diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 5ac6430a91..c3152f239b 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -20,6 +20,13 @@ ? evtchn_send event_channel.h ? evtchn_status event_channel.h ? evtchn_unmask event_channel.h +! gnttab_copy grant_table.h +? gnttab_dump_table grant_table.h +? gnttab_map_grant_ref grant_table.h +! gnttab_setup_table grant_table.h +! gnttab_transfer grant_table.h +? gnttab_unmap_grant_ref grant_table.h +? grant_entry grant_table.h ! add_to_physmap memory.h ! foreign_memory_map memory.h ! memory_exchange memory.h From f5404d9805bc400ef5ed4d626c38828db4b662b5 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:36 +0000 Subject: [PATCH 090/570] Enable compatibility mode operation for HYPERVISOR_platformop. Signed-off-by: Jan Beulich --- xen/arch/x86/platform_hypercall.c | 19 +++++++++++++--- xen/arch/x86/x86_64/Makefile | 2 ++ xen/arch/x86/x86_64/compat/entry.S | 1 - xen/arch/x86/x86_64/platform_hypercall.c | 29 ++++++++++++++++++++++++ 4 files changed, 47 insertions(+), 4 deletions(-) create mode 100644 xen/arch/x86/x86_64/platform_hypercall.c diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c index 7d2ee6f496..766a357e65 100644 --- a/xen/arch/x86/platform_hypercall.c +++ b/xen/arch/x86/platform_hypercall.c @@ -23,11 +23,17 @@ #include #include "cpu/mtrr/mtrr.h" -long do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) +#ifndef COMPAT +typedef long ret_t; +DEFINE_SPINLOCK(xenpf_lock); +#else +extern spinlock_t xenpf_lock; +#endif + +ret_t do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) { - long ret = 0; + ret_t ret = 0; struct xen_platform_op curop, *op = &curop; - static DEFINE_SPINLOCK(xenpf_lock); if ( !IS_PRIV(current->domain) ) return -EPERM; @@ -105,8 +111,15 @@ long do_platform_op(XEN_GUEST_HANDLE(xen_platform_op_t) u_xenpf_op) case XENPF_microcode_update: { extern int microcode_update(XEN_GUEST_HANDLE(void), unsigned long len); +#ifndef COMPAT ret = microcode_update(op->u.microcode.data, op->u.microcode.length); +#else + XEN_GUEST_HANDLE(void) data; + + guest_from_compat_handle(data, op->u.microcode.data); + ret = microcode_update(data, op->u.microcode.length); +#endif } break; diff --git a/xen/arch/x86/x86_64/Makefile b/xen/arch/x86/x86_64/Makefile index 5709de3694..509f442a3c 100644 --- a/xen/arch/x86/x86_64/Makefile +++ b/xen/arch/x86/x86_64/Makefile @@ -6,6 +6,7 @@ obj-y += traps.o obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_COMPAT) += domain.o obj-$(CONFIG_COMPAT) += physdev.o +obj-$(CONFIG_COMPAT) += platform_hypercall.o ifeq ($(CONFIG_COMPAT),y) # extra dependencies @@ -13,5 +14,6 @@ compat.o: ../compat.c entry.o: compat/entry.S mm.o: compat/mm.c physdev.o: ../physdev.c +platform_hypercall.o: ../platform_hypercall.c traps.o: compat/traps.c endif diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index d9d70a248c..792854eb83 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -278,7 +278,6 @@ CFIX14: .section .rodata, "a", @progbits -#define compat_platform_op domain_crash_synchronous #define compat_acm_op domain_crash_synchronous #define compat_xenoprof_op domain_crash_synchronous #define compat_sysctl domain_crash_synchronous diff --git a/xen/arch/x86/x86_64/platform_hypercall.c b/xen/arch/x86/x86_64/platform_hypercall.c new file mode 100644 index 0000000000..2ce7c12dc1 --- /dev/null +++ b/xen/arch/x86/x86_64/platform_hypercall.c @@ -0,0 +1,29 @@ +/****************************************************************************** + * platform_hypercall.c + * + */ + +#include +#include +#include + +DEFINE_XEN_GUEST_HANDLE(compat_platform_op_t); +#define xen_platform_op compat_platform_op +#define xen_platform_op_t compat_platform_op_t +#define do_platform_op(x) compat_platform_op(_##x) + +#define COMPAT +#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) +typedef int ret_t; + +#include "../platform_hypercall.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ From 62320af21e472e4e27791dd5858cc323776aa340 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:37 +0000 Subject: [PATCH 091/570] Enable compatibility mode operation for HYPERVISOR_acm_op. Signed-off-by: Jan Beulich --- xen/arch/x86/x86_64/compat/entry.S | 1 - xen/common/Makefile | 1 + xen/common/acm_ops.c | 15 ++++++++-- xen/common/compat/acm_ops.c | 47 ++++++++++++++++++++++++++++++ xen/include/xlat.lst | 1 + 5 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 xen/common/compat/acm_ops.c diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 792854eb83..c0c900cbb7 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -278,7 +278,6 @@ CFIX14: .section .rodata, "a", @progbits -#define compat_acm_op domain_crash_synchronous #define compat_xenoprof_op domain_crash_synchronous #define compat_sysctl domain_crash_synchronous #define compat_domctl domain_crash_synchronous diff --git a/xen/common/Makefile b/xen/common/Makefile index 625d5a122a..ac4683bb82 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -42,6 +42,7 @@ version.o: $(BASEDIR)/include/xen/compile.h ifeq ($(CONFIG_COMPAT),y) # extra dependencies +acm_ops.o: compat/acm_ops.c grant_table.o: compat/grant_table.c schedule.o: compat/schedule.c endif diff --git a/xen/common/acm_ops.c b/xen/common/acm_ops.c index d6ed629398..f9d8a72da6 100644 --- a/xen/common/acm_ops.c +++ b/xen/common/acm_ops.c @@ -15,6 +15,7 @@ * */ +#ifndef COMPAT #include #include #include @@ -28,6 +29,10 @@ #include #include +typedef long ret_t; + +#endif /* !COMPAT */ + #ifndef ACM_SECURITY @@ -40,6 +45,7 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) #else +#ifndef COMPAT int acm_authorize_acm_ops(struct domain *d) { /* currently, policy management functions are restricted to privileged domains */ @@ -47,11 +53,12 @@ int acm_authorize_acm_ops(struct domain *d) return -EPERM; return 0; } +#endif -long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) +ret_t do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) { - long rc = -EFAULT; + ret_t rc = -EFAULT; if (acm_authorize_acm_ops(current->domain)) return -EPERM; @@ -219,6 +226,10 @@ long do_acm_op(int cmd, XEN_GUEST_HANDLE(void) arg) #endif +#if defined(CONFIG_COMPAT) && !defined(COMPAT) +#include "compat/acm_ops.c" +#endif + /* * Local variables: * mode: C diff --git a/xen/common/compat/acm_ops.c b/xen/common/compat/acm_ops.c new file mode 100644 index 0000000000..28af1a8e6c --- /dev/null +++ b/xen/common/compat/acm_ops.c @@ -0,0 +1,47 @@ +/****************************************************************************** + * compat/acm_ops.c + */ + +#include +#include + +#define COMPAT +#define ret_t int + +#define do_acm_op compat_acm_op + +static inline XEN_GUEST_HANDLE(void) acm_xlat_handle(COMPAT_HANDLE(void) cmp) +{ + XEN_GUEST_HANDLE(void) nat; + + guest_from_compat_handle(nat, cmp); + return nat; +} + +#define acm_setpolicy compat_acm_setpolicy +#define acm_set_policy(h, sz) acm_set_policy(acm_xlat_handle(h), sz) + +#define acm_getpolicy compat_acm_getpolicy +#define acm_get_policy(h, sz) acm_get_policy(acm_xlat_handle(h), sz) + +#define acm_dumpstats compat_acm_dumpstats +#define acm_dump_statistics(h, sz) acm_dump_statistics(acm_xlat_handle(h), sz) + +#define acm_getssid compat_acm_getssid +#define acm_get_ssid(r, h, sz) acm_get_ssid(r, acm_xlat_handle(h), sz) + +#define xen_acm_getdecision acm_getdecision +CHECK_acm_getdecision; +#undef xen_acm_getdecision + +#include "../acm_ops.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index c3152f239b..540bbd7de1 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -9,6 +9,7 @@ ! cpu_user_regs arch-x86/xen-@arch@.h ! trap_info arch-x86/xen.h ! vcpu_guest_context arch-x86/xen.h +? acm_getdecision acm_ops.h ? evtchn_alloc_unbound event_channel.h ? evtchn_bind_interdomain event_channel.h ? evtchn_bind_ipi event_channel.h From b0a4c24ddae72f424710456f054297153565222f Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:37 +0000 Subject: [PATCH 092/570] Enable compatibility mode operation for HYPERVISOR_xenoprof_op. Signed-off-by: Jan Beulich --- xen/arch/x86/x86_64/compat/entry.S | 1 - xen/common/Makefile | 1 + xen/common/compat/xenoprof.c | 40 ++++++++++++++++++ xen/common/xenoprof.c | 68 +++++++++++++++++++----------- xen/include/public/xenoprof.h | 2 + xen/include/xen/xenoprof.h | 26 +++++++++++- xen/include/xlat.lst | 2 + 7 files changed, 113 insertions(+), 27 deletions(-) create mode 100644 xen/common/compat/xenoprof.c diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index c0c900cbb7..28642aa338 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -278,7 +278,6 @@ CFIX14: .section .rodata, "a", @progbits -#define compat_xenoprof_op domain_crash_synchronous #define compat_sysctl domain_crash_synchronous #define compat_domctl domain_crash_synchronous diff --git a/xen/common/Makefile b/xen/common/Makefile index ac4683bb82..1997f461c2 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -45,4 +45,5 @@ ifeq ($(CONFIG_COMPAT),y) acm_ops.o: compat/acm_ops.c grant_table.o: compat/grant_table.c schedule.o: compat/schedule.c +xenoprof.o: compat/xenoprof.c endif diff --git a/xen/common/compat/xenoprof.c b/xen/common/compat/xenoprof.c new file mode 100644 index 0000000000..e1cad00d2a --- /dev/null +++ b/xen/common/compat/xenoprof.c @@ -0,0 +1,40 @@ +/* + * compat/xenoprof.c + */ + +#include + +#define COMPAT + +#define do_xenoprof_op compat_xenoprof_op + +#define xen_oprof_init xenoprof_init +CHECK_oprof_init; +#undef xen_oprof_init + +#define xenoprof_get_buffer compat_oprof_get_buffer +#define xenoprof_op_get_buffer compat_oprof_op_get_buffer + +#define xen_domid_t domid_t +#define compat_domid_t domid_compat_t +CHECK_TYPE(domid); +#undef compat_domid_t +#undef xen_domid_t + +#define xen_oprof_passive xenoprof_passive +CHECK_oprof_passive; +#undef xen_oprof_passive + +#define xenoprof_counter compat_oprof_counter + +#include "../xenoprof.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/xenoprof.c b/xen/common/xenoprof.c index f297859de5..d61e3f173e 100644 --- a/xen/common/xenoprof.c +++ b/xen/common/xenoprof.c @@ -9,6 +9,7 @@ * VA Linux Systems Japan K.K. */ +#ifndef COMPAT #include #include #include @@ -72,7 +73,7 @@ static void xenoprof_reset_stat(void) static void xenoprof_reset_buf(struct domain *d) { int j; - struct xenoprof_buf *buf; + xenoprof_buf_t *buf; if ( d->xenoprof == NULL ) { @@ -86,8 +87,8 @@ static void xenoprof_reset_buf(struct domain *d) buf = d->xenoprof->vcpu[j].buffer; if ( buf != NULL ) { - buf->event_head = 0; - buf->event_tail = 0; + xenoprof_buf(d, buf, event_head) = 0; + xenoprof_buf(d, buf, event_tail) = 0; } } } @@ -166,15 +167,24 @@ static int alloc_xenoprof_struct( for_each_vcpu ( d, v ) nvcpu++; + bufsize = sizeof(struct xenoprof_buf); + i = sizeof(struct event_log); +#ifdef CONFIG_COMPAT + d->xenoprof->is_compat = IS_COMPAT(is_passive ? dom0 : d); + if ( XENOPROF_COMPAT(d->xenoprof) ) + { + bufsize = sizeof(struct compat_oprof_buf); + i = sizeof(struct compat_event_log); + } +#endif + /* reduce max_samples if necessary to limit pages allocated */ max_bufsize = (MAX_OPROF_SHARED_PAGES * PAGE_SIZE) / nvcpu; - max_max_samples = ( (max_bufsize - sizeof(struct xenoprof_buf)) / - sizeof(struct event_log) ) + 1; + max_max_samples = ( (max_bufsize - bufsize) / i ) + 1; if ( (unsigned)max_samples > max_max_samples ) max_samples = max_max_samples; - bufsize = sizeof(struct xenoprof_buf) + - (max_samples - 1) * sizeof(struct event_log); + bufsize += (max_samples - 1) * i; npages = (nvcpu * bufsize - 1) / PAGE_SIZE + 1; d->xenoprof->rawbuf = alloc_xenheap_pages(get_order_from_pages(npages)); @@ -195,11 +205,12 @@ static int alloc_xenoprof_struct( i = 0; for_each_vcpu ( d, v ) { + xenoprof_buf_t *buf = (xenoprof_buf_t *)&d->xenoprof->rawbuf[i * bufsize]; + d->xenoprof->vcpu[v->vcpu_id].event_size = max_samples; - d->xenoprof->vcpu[v->vcpu_id].buffer = - (struct xenoprof_buf *)&d->xenoprof->rawbuf[i * bufsize]; - d->xenoprof->vcpu[v->vcpu_id].buffer->event_size = max_samples; - d->xenoprof->vcpu[v->vcpu_id].buffer->vcpu_id = v->vcpu_id; + d->xenoprof->vcpu[v->vcpu_id].buffer = buf; + xenoprof_buf(d, buf, event_size) = max_samples; + xenoprof_buf(d, buf, vcpu_id) = v->vcpu_id; i++; /* in the unlikely case that the number of active vcpus changes */ @@ -406,8 +417,9 @@ static int add_passive_list(XEN_GUEST_HANDLE(void) arg) void xenoprof_log_event( struct vcpu *vcpu, unsigned long eip, int mode, int event) { + struct domain *d = vcpu->domain; struct xenoprof_vcpu *v; - struct xenoprof_buf *buf; + xenoprof_buf_t *buf; int head; int tail; int size; @@ -417,13 +429,13 @@ void xenoprof_log_event( /* ignore samples of un-monitored domains */ /* Count samples in idle separate from other unmonitored domains */ - if ( !is_profiled(vcpu->domain) ) + if ( !is_profiled(d) ) { others_samples++; return; } - v = &vcpu->domain->xenoprof->vcpu[vcpu->vcpu_id]; + v = &d->xenoprof->vcpu[vcpu->vcpu_id]; /* Sanity check. Should never happen */ if ( v->buffer == NULL ) @@ -432,10 +444,10 @@ void xenoprof_log_event( return; } - buf = vcpu->domain->xenoprof->vcpu[vcpu->vcpu_id].buffer; + buf = v->buffer; - head = buf->event_head; - tail = buf->event_tail; + head = xenoprof_buf(d, buf, event_head); + tail = xenoprof_buf(d, buf, event_tail); size = v->event_size; /* make sure indexes in shared buffer are sane */ @@ -447,28 +459,28 @@ void xenoprof_log_event( if ( (head == tail - 1) || (head == size - 1 && tail == 0) ) { - buf->lost_samples++; + xenoprof_buf(d, buf, lost_samples)++; lost_samples++; } else { - buf->event_log[head].eip = eip; - buf->event_log[head].mode = mode; - buf->event_log[head].event = event; + xenoprof_buf(d, buf, event_log[head].eip) = eip; + xenoprof_buf(d, buf, event_log[head].mode) = mode; + xenoprof_buf(d, buf, event_log[head].event) = event; head++; if ( head >= size ) head = 0; - buf->event_head = head; + xenoprof_buf(d, buf, event_head) = head; if ( is_active(vcpu->domain) ) active_samples++; else passive_samples++; if ( mode == 0 ) - buf->user_samples++; + xenoprof_buf(d, buf, user_samples)++; else if ( mode == 1 ) - buf->kernel_samples++; + xenoprof_buf(d, buf, kernel_samples)++; else - buf->xen_samples++; + xenoprof_buf(d, buf, xen_samples)++; } } @@ -494,6 +506,8 @@ static int xenoprof_op_init(XEN_GUEST_HANDLE(void) arg) return 0; } +#endif /* !COMPAT */ + static int xenoprof_op_get_buffer(XEN_GUEST_HANDLE(void) arg) { struct xenoprof_get_buffer xenoprof_get_buffer; @@ -732,6 +746,10 @@ int do_xenoprof_op(int op, XEN_GUEST_HANDLE(void) arg) return ret; } +#if defined(CONFIG_COMPAT) && !defined(COMPAT) +#include "compat/xenoprof.c" +#endif + /* * Local variables: * mode: C diff --git a/xen/include/public/xenoprof.h b/xen/include/public/xenoprof.h index 709b60fa1f..d16d8ca3f6 100644 --- a/xen/include/public/xenoprof.h +++ b/xen/include/public/xenoprof.h @@ -74,8 +74,10 @@ struct xenoprof_buf { uint64_t lost_samples; struct event_log event_log[1]; }; +#ifndef __XEN__ typedef struct xenoprof_buf xenoprof_buf_t; DEFINE_XEN_GUEST_HANDLE(xenoprof_buf_t); +#endif struct xenoprof_init { int32_t num_events; diff --git a/xen/include/xen/xenoprof.h b/xen/include/xen/xenoprof.h index b9fe9de528..8983f0c987 100644 --- a/xen/include/xen/xenoprof.h +++ b/xen/include/xen/xenoprof.h @@ -10,6 +10,7 @@ #ifndef __XEN_XENOPROF_H__ #define __XEN_XENOPROF_H__ +#include #include #include @@ -22,9 +23,19 @@ #define XENOPROF_READY 2 #define XENOPROF_PROFILING 3 +#ifndef CONFIG_COMPAT +typedef struct xenoprof_buf xenoprof_buf_t; +#else +#include +typedef union { + struct xenoprof_buf native; + struct compat_oprof_buf compat; +} xenoprof_buf_t; +#endif + struct xenoprof_vcpu { int event_size; - struct xenoprof_buf *buffer; + xenoprof_buf_t *buffer; }; struct xenoprof { @@ -35,9 +46,22 @@ struct xenoprof { int domain_type; int domain_ready; int is_primary; +#ifdef CONFIG_COMPAT + int is_compat; +#endif struct xenoprof_vcpu vcpu [MAX_VIRT_CPUS]; }; +#ifndef CONFIG_COMPAT +#define XENOPROF_COMPAT(x) 0 +#define xenoprof_buf(d, b, field) ((b)->field) +#else +#define XENOPROF_COMPAT(x) ((x)->is_compat) +#define xenoprof_buf(d, b, field) (*(!(d)->xenoprof->is_compat ? \ + &(b)->native.field : \ + &(b)->compat.field)) +#endif + struct domain; void free_xenoprof_pages(struct domain *d); diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 540bbd7de1..be9f112802 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -38,3 +38,5 @@ ? sched_remote_shutdown sched.h ? sched_shutdown sched.h ! vcpu_runstate_info vcpu.h +? xenoprof_init xenoprof.h +? xenoprof_passive xenoprof.h From a6f33d81e1b8a2012ea6b34387ef59d6f4bec2b1 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:38 +0000 Subject: [PATCH 093/570] Enable compatibility mode operation for HYPERVISOR_sysctl. Signed-off-by: Jan Beulich --- xen/arch/x86/sysctl.c | 8 ++- xen/arch/x86/x86_64/Makefile | 2 + xen/arch/x86/x86_64/compat/entry.S | 1 - xen/arch/x86/x86_64/sysctl.c | 33 ++++++++++ xen/common/compat/Makefile | 2 + xen/common/compat/sysctl.c | 102 +++++++++++++++++++++++++++++ xen/common/sysctl.c | 20 +++--- xen/include/xen/domain.h | 4 ++ xen/include/xen/perfc.h | 3 + xen/include/xlat.lst | 5 ++ 10 files changed, 168 insertions(+), 12 deletions(-) create mode 100644 xen/arch/x86/x86_64/sysctl.c create mode 100644 xen/common/compat/sysctl.c diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c index 0f265825bd..be96055290 100644 --- a/xen/arch/x86/sysctl.c +++ b/xen/arch/x86/sysctl.c @@ -25,10 +25,14 @@ #include #include -long arch_do_sysctl( +#ifndef COMPAT +typedef long ret_t; +#endif + +ret_t arch_do_sysctl( struct xen_sysctl *sysctl, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) { - long ret = 0; + ret_t ret = 0; switch ( sysctl->cmd ) { diff --git a/xen/arch/x86/x86_64/Makefile b/xen/arch/x86/x86_64/Makefile index 509f442a3c..fad1ca83f2 100644 --- a/xen/arch/x86/x86_64/Makefile +++ b/xen/arch/x86/x86_64/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_COMPAT) += domain.o obj-$(CONFIG_COMPAT) += physdev.o obj-$(CONFIG_COMPAT) += platform_hypercall.o +obj-$(CONFIG_COMPAT) += sysctl.o ifeq ($(CONFIG_COMPAT),y) # extra dependencies @@ -15,5 +16,6 @@ entry.o: compat/entry.S mm.o: compat/mm.c physdev.o: ../physdev.c platform_hypercall.o: ../platform_hypercall.c +sysctl.o: ../sysctl.c traps.o: compat/traps.c endif diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 28642aa338..0a532d2ced 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -278,7 +278,6 @@ CFIX14: .section .rodata, "a", @progbits -#define compat_sysctl domain_crash_synchronous #define compat_domctl domain_crash_synchronous ENTRY(compat_hypercall_table) diff --git a/xen/arch/x86/x86_64/sysctl.c b/xen/arch/x86/x86_64/sysctl.c new file mode 100644 index 0000000000..66e2d5d93d --- /dev/null +++ b/xen/arch/x86/x86_64/sysctl.c @@ -0,0 +1,33 @@ +/****************************************************************************** + * Arch-specific compatibility sysctl.c + */ + +#include +#include + +DEFINE_XEN_GUEST_HANDLE(compat_sysctl_t); +#define xen_sysctl compat_sysctl +#define xen_sysctl_t compat_sysctl_t +#define arch_do_sysctl(x, h) arch_compat_sysctl(x, _##h) + +#define xen_sysctl_physinfo compat_sysctl_physinfo +#define xen_sysctl_physinfo_t compat_sysctl_physinfo_t + +#define xen_sysctl_ioport_emulation compat_sysctl_ioport_emulation +#define xen_sysctl_ioport_emulation_t compat_sysctl_ioport_emulation_t + +#define COMPAT +#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) +typedef int ret_t; + +#include "../sysctl.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/compat/Makefile b/xen/common/compat/Makefile index dfab7bc77c..2210dd05f9 100644 --- a/xen/common/compat/Makefile +++ b/xen/common/compat/Makefile @@ -2,8 +2,10 @@ obj-y += domain.o obj-y += kernel.o obj-y += memory.o obj-y += multicall.o +obj-y += sysctl.o obj-y += xlat.o # extra dependencies kernel.o: ../kernel.c multicall.o: ../multicall.c +sysctl.o: ../sysctl.c diff --git a/xen/common/compat/sysctl.c b/xen/common/compat/sysctl.c new file mode 100644 index 0000000000..9aa5fba783 --- /dev/null +++ b/xen/common/compat/sysctl.c @@ -0,0 +1,102 @@ +/****************************************************************************** + * compat/sysctl.c + */ + +#include +#include +#include +#include +#include +#include + +DEFINE_XEN_GUEST_HANDLE(compat_sysctl_t); +#define xen_sysctl compat_sysctl +#define xen_sysctl_t compat_sysctl_t +#define do_sysctl(h) compat_sysctl(_##h) +#define arch_do_sysctl(x, h) arch_compat_sysctl(x, _##h) + +#define xen_sysctl_readconsole compat_sysctl_readconsole +#define xen_sysctl_readconsole_t compat_sysctl_readconsole_t + +static int compat_tb_control(struct compat_sysctl_tbuf_op *cmp_tbc) +{ + struct xen_sysctl_tbuf_op nat_tbc; + int ret; + +#define XLAT_ctl_cpumap_HNDL_bitmap(_d_, _s_) \ + guest_from_compat_handle((_d_)->bitmap, (_s_)->bitmap) + XLAT_sysctl_tbuf_op(&nat_tbc, cmp_tbc); +#undef XLAT_ctl_cpumap_HNDL_bitmap + ret = tb_control(&nat_tbc); +#define XLAT_ctl_cpumap_HNDL_bitmap(_d_, _s_) ((void)0) + XLAT_sysctl_tbuf_op(cmp_tbc, &nat_tbc); +#undef XLAT_ctl_cpumap_HNDL_bitmap + return ret; +} +#define xen_sysctl_tbuf_op compat_sysctl_tbuf_op +#define xen_sysctl_tbuf_op_t compat_sysctl_tbuf_op_t +#define tb_control(p) compat_tb_control(p) + +#define xen_sysctl_sched_id compat_sysctl_sched_id +#define xen_sysctl_sched_id_t compat_sysctl_sched_id_t + +static void compat_getdomaininfo(struct domain *d, struct compat_domctl_getdomaininfo *ci) +{ + struct xen_domctl_getdomaininfo ni; + + getdomaininfo(d, &ni); + XLAT_domctl_getdomaininfo(ci, &ni); +} +#define xen_sysctl_getdomaininfolist compat_sysctl_getdomaininfolist +#define xen_sysctl_getdomaininfolist_t compat_sysctl_getdomaininfolist_t +#define xen_domctl_getdomaininfo compat_domctl_getdomaininfo +#define xen_domctl_getdomaininfo_t compat_domctl_getdomaininfo_t +#define getdomaininfo(d, i) compat_getdomaininfo(d, i) + +#ifdef PERF_COUNTERS +static int compat_perfc_control(struct compat_sysctl_perfc_op *cmp_pc) +{ + CHECK_sysctl_perfc_desc; + CHECK_TYPE(sysctl_perfc_val); + struct xen_sysctl_perfc_op nat_pc; + int ret; + +#define XLAT_sysctl_perfc_op_HNDL_desc(_d_, _s_) \ + guest_from_compat_handle((_d_)->desc, (_s_)->desc) +#define XLAT_sysctl_perfc_op_HNDL_val(_d_, _s_) \ + guest_from_compat_handle((_d_)->val, (_s_)->val) + XLAT_sysctl_perfc_op(&nat_pc, cmp_pc); +#undef XLAT_sysctl_perfc_op_HNDL_val +#undef XLAT_sysctl_perfc_op_HNDL_desc + ret = perfc_control(&nat_pc); +#define XLAT_sysctl_perfc_op_HNDL_desc(_d_, _s_) +#define XLAT_sysctl_perfc_op_HNDL_val(_d_, _s_) + XLAT_sysctl_perfc_op(cmp_pc, &nat_pc); +#undef XLAT_sysctl_perfc_op_HNDL_val +#undef XLAT_sysctl_perfc_op_HNDL_desc + return ret; +} +#define xen_sysctl_perfc_op compat_sysctl_perfc_op +#define xen_sysctl_perfc_op_t compat_sysctl_perfc_op_t +#define perfc_control(p) compat_perfc_control(p) +#endif + +#define COMPAT +#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) +#define _u_sysctl u_sysctl +#undef guest_handle_cast +#define guest_handle_cast compat_handle_cast +#define copy_to_xxx_offset copy_to_compat_offset +typedef int ret_t; + +#include "../sysctl.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c index 9f991f39b3..33a5108079 100644 --- a/xen/common/sysctl.c +++ b/xen/common/sysctl.c @@ -21,14 +21,17 @@ #include #include -extern long arch_do_sysctl( - struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl); -extern void getdomaininfo( - struct domain *d, struct xen_domctl_getdomaininfo *info); +#ifndef COMPAT +typedef long ret_t; +#define copy_to_xxx_offset copy_to_guest_offset +#endif -long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) +extern ret_t arch_do_sysctl( + struct xen_sysctl *op, XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl); + +ret_t do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) { - long ret = 0; + ret_t ret = 0; struct xen_sysctl curop, *op = &curop; static DEFINE_SPINLOCK(sysctl_lock); @@ -98,8 +101,8 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) put_domain(d); - if ( copy_to_guest_offset(op->u.getdomaininfolist.buffer, - num_domains, &info, 1) ) + if ( copy_to_xxx_offset(op->u.getdomaininfolist.buffer, + num_domains, &info, 1) ) { ret = -EFAULT; break; @@ -123,7 +126,6 @@ long do_sysctl(XEN_GUEST_HANDLE(xen_sysctl_t) u_sysctl) #ifdef PERF_COUNTERS case XEN_SYSCTL_perfc_op: { - extern int perfc_control(xen_sysctl_perfc_op_t *); ret = perfc_control(&op->u.perfc_op); if ( copy_to_guest(u_sysctl, op, 1) ) ret = -EFAULT; diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index 70e8902a73..fd0b3ab0ff 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -11,6 +11,10 @@ struct vcpu *alloc_idle_vcpu(unsigned int cpu_id); struct domain *alloc_domain(domid_t domid); void free_domain(struct domain *d); +struct xen_domctl_getdomaininfo; +void getdomaininfo( + struct domain *d, struct xen_domctl_getdomaininfo *info); + /* * Arch-specifics. */ diff --git a/xen/include/xen/perfc.h b/xen/include/xen/perfc.h index ab2b84b00c..97ef9cd2ed 100644 --- a/xen/include/xen/perfc.h +++ b/xen/include/xen/perfc.h @@ -102,6 +102,9 @@ extern struct perfcounter perfcounters; #else #define perfc_incr_histo(_x,_v,_n) ((void)0) #endif + +struct xen_sysctl_perfc_op; +int perfc_control(struct xen_sysctl_perfc_op *); #else /* PERF_COUNTERS */ diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index be9f112802..18e0d0c21b 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -10,6 +10,8 @@ ! trap_info arch-x86/xen.h ! vcpu_guest_context arch-x86/xen.h ? acm_getdecision acm_ops.h +! ctl_cpumap domctl.h +! domctl_getdomaininfo domctl.h ? evtchn_alloc_unbound event_channel.h ? evtchn_bind_interdomain event_channel.h ? evtchn_bind_ipi event_channel.h @@ -37,6 +39,9 @@ ! sched_poll sched.h ? sched_remote_shutdown sched.h ? sched_shutdown sched.h +? sysctl_perfc_desc sysctl.h +! sysctl_perfc_op sysctl.h +! sysctl_tbuf_op sysctl.h ! vcpu_runstate_info vcpu.h ? xenoprof_init xenoprof.h ? xenoprof_passive xenoprof.h From 97a138cbdd968113843f8a4ee91d42cc1fbd4cf9 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:39 +0000 Subject: [PATCH 094/570] Enable compatibility mode operation for HYPERVISOR_domctl. Also add logic to switch a domain to/from compatibility mode (supposed to happen early after domain creation only). Signed-off-by: Jan Beulich --- xen/arch/ia64/xen/domain.c | 18 ++-- xen/arch/powerpc/domain.c | 4 +- xen/arch/powerpc/domctl.c | 6 +- xen/arch/x86/domain.c | 163 +++++++++++++++++++++++++---- xen/arch/x86/domctl.c | 97 ++++++++++++----- xen/arch/x86/mm/shadow/common.c | 2 +- xen/arch/x86/x86_32/traps.c | 2 +- xen/arch/x86/x86_64/Makefile | 2 + xen/arch/x86/x86_64/compat/entry.S | 2 - xen/arch/x86/x86_64/compat/traps.c | 2 +- xen/arch/x86/x86_64/domctl.c | 111 ++++++++++++++++++++ xen/common/compat/Makefile | 2 + xen/common/compat/domain.c | 15 +-- xen/common/compat/domctl.c | 137 ++++++++++++++++++++++++ xen/common/compat/sysctl.c | 7 -- xen/common/domain.c | 51 +++++++-- xen/common/domctl.c | 96 ++++++++++++++--- xen/common/schedule.c | 2 - xen/include/asm-x86/shadow.h | 2 +- xen/include/public/domctl.h | 5 + xen/include/xen/compat.h | 3 + xen/include/xen/domain.h | 13 ++- xen/include/xen/sched.h | 8 +- xen/include/xlat.lst | 4 +- 24 files changed, 637 insertions(+), 117 deletions(-) create mode 100644 xen/arch/x86/x86_64/domctl.c create mode 100644 xen/common/compat/domctl.c diff --git a/xen/arch/ia64/xen/domain.c b/xen/arch/ia64/xen/domain.c index cd43c13d35..073614f4f6 100644 --- a/xen/arch/ia64/xen/domain.c +++ b/xen/arch/ia64/xen/domain.c @@ -522,14 +522,14 @@ void arch_domain_destroy(struct domain *d) deallocate_rid_range(d); } -void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) +void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) { int i; - struct vcpu_extra_regs *er = &c->extra_regs; + struct vcpu_extra_regs *er = &c.nat->extra_regs; - c->user_regs = *vcpu_regs (v); - c->privregs_pfn = get_gpfn_from_mfn(virt_to_maddr(v->arch.privregs) >> - PAGE_SHIFT); + c.nat->user_regs = *vcpu_regs(v); + c.nat->privregs_pfn = get_gpfn_from_mfn(virt_to_maddr(v->arch.privregs) >> + PAGE_SHIFT); /* Fill extra regs. */ for (i = 0; i < 8; i++) { @@ -549,12 +549,12 @@ void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) er->iva = v->arch.iva; } -int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) +int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) { struct pt_regs *regs = vcpu_regs (v); struct domain *d = v->domain; - *regs = c->user_regs; + *regs = c.nat->user_regs; if (!d->arch.is_vti) { /* domain runs at PL2/3 */ @@ -562,9 +562,9 @@ int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c) regs->ar_rsc |= (2 << 2); /* force PL2/3 */ } - if (c->flags & VGCF_EXTRA_REGS) { + if (c.nat->flags & VGCF_EXTRA_REGS) { int i; - struct vcpu_extra_regs *er = &c->extra_regs; + struct vcpu_extra_regs *er = &c.nat->extra_regs; for (i = 0; i < 8; i++) { vcpu_set_itr(v, i, er->itrs[i].pte, diff --git a/xen/arch/powerpc/domain.c b/xen/arch/powerpc/domain.c index 45ed959945..44665df197 100644 --- a/xen/arch/powerpc/domain.c +++ b/xen/arch/powerpc/domain.c @@ -150,9 +150,9 @@ void vcpu_destroy(struct vcpu *v) { } -int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_t *c) +int arch_set_info_guest(struct vcpu *v, vcpu_guest_context_u c) { - memcpy(&v->arch.ctxt, &c->user_regs, sizeof(c->user_regs)); + memcpy(&v->arch.ctxt, &c.nat->user_regs, sizeof(c.nat->user_regs)); printk("Domain[%d].%d: initializing\n", v->domain->domain_id, v->vcpu_id); diff --git a/xen/arch/powerpc/domctl.c b/xen/arch/powerpc/domctl.c index c51430d132..20e6e536a8 100644 --- a/xen/arch/powerpc/domctl.c +++ b/xen/arch/powerpc/domctl.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -29,10 +30,9 @@ #include #include -void arch_getdomaininfo_ctxt(struct vcpu *, vcpu_guest_context_t *); -void arch_getdomaininfo_ctxt(struct vcpu *v, vcpu_guest_context_t *c) +void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) { - memcpy(&c->user_regs, &v->arch.ctxt, sizeof(struct cpu_user_regs)); + memcpy(&c.nat->user_regs, &v->arch.ctxt, sizeof(struct cpu_user_regs)); /* XXX fill in rest of vcpu_guest_context_t */ } diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 2476271e56..acff71b90f 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -250,6 +251,69 @@ static void release_compat_l4(struct vcpu *v) v->arch.guest_table_user = pagetable_null(); } +static inline int may_switch_mode(struct domain *d) +{ + return 1; /* XXX */ +} + +int switch_native(struct domain *d) +{ + l1_pgentry_t gdt_l1e; + unsigned int vcpuid; + + if ( !d ) + return -EINVAL; + if ( !may_switch_mode(d) ) + return -EACCES; + if ( !IS_COMPAT(d) ) + return 0; + + clear_bit(_DOMF_compat, &d->domain_flags); + release_arg_xlat_area(d); + + /* switch gdt */ + gdt_l1e = l1e_from_page(virt_to_page(gdt_table), PAGE_HYPERVISOR); + for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ ) + { + d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) + + FIRST_RESERVED_GDT_PAGE)] = gdt_l1e; + if (d->vcpu[vcpuid]) + release_compat_l4(d->vcpu[vcpuid]); + } + + return 0; +} + +int switch_compat(struct domain *d) +{ + l1_pgentry_t gdt_l1e; + unsigned int vcpuid; + + if ( !d ) + return -EINVAL; + if ( compat_disabled ) + return -ENOSYS; + if ( !may_switch_mode(d) ) + return -EACCES; + if ( IS_COMPAT(d) ) + return 0; + + set_bit(_DOMF_compat, &d->domain_flags); + + /* switch gdt */ + gdt_l1e = l1e_from_page(virt_to_page(compat_gdt_table), PAGE_HYPERVISOR); + for ( vcpuid = 0; vcpuid < MAX_VIRT_CPUS; vcpuid++ ) + { + d->arch.mm_perdomain_pt[((vcpuid << GDT_LDT_VCPU_SHIFT) + + FIRST_RESERVED_GDT_PAGE)] = gdt_l1e; + if (d->vcpu[vcpuid] + && setup_compat_l4(d->vcpu[vcpuid]) != 0) + return -ENOMEM; + } + + return 0; +} + #else #define release_arg_xlat_area(d) ((void)0) #define setup_compat_l4(v) 0 @@ -416,43 +480,80 @@ void arch_domain_destroy(struct domain *d) /* This is called by arch_final_setup_guest and do_boot_vcpu */ int arch_set_info_guest( - struct vcpu *v, struct vcpu_guest_context *c) + struct vcpu *v, vcpu_guest_context_u c) { struct domain *d = v->domain; +#ifdef CONFIG_COMPAT +#define c(fld) (!IS_COMPAT(d) ? (c.nat->fld) : (c.cmp->fld)) +#else +#define c(fld) (c.nat->fld) +#endif unsigned long cr3_pfn = INVALID_MFN; + unsigned long flags = c(flags); int i, rc; if ( !is_hvm_vcpu(v) ) { - fixup_guest_stack_selector(d, c->user_regs.ss); - fixup_guest_stack_selector(d, c->kernel_ss); - fixup_guest_code_selector(d, c->user_regs.cs); - - if ( CONFIG_PAGING_LEVELS < 4 || IS_COMPAT(d) ) + if ( !IS_COMPAT(d) ) { - fixup_guest_code_selector(d, c->event_callback_cs); - fixup_guest_code_selector(d, c->failsafe_callback_cs); + fixup_guest_stack_selector(d, c.nat->user_regs.ss); + fixup_guest_stack_selector(d, c.nat->kernel_ss); + fixup_guest_code_selector(d, c.nat->user_regs.cs); +#ifdef __i386__ + fixup_guest_code_selector(d, c.nat->event_callback_cs); + fixup_guest_code_selector(d, c.nat->failsafe_callback_cs); +#endif + + for ( i = 0; i < 256; i++ ) + fixup_guest_code_selector(d, c.nat->trap_ctxt[i].cs); + + /* LDT safety checks. */ + if ( ((c.nat->ldt_base & (PAGE_SIZE-1)) != 0) || + (c.nat->ldt_ents > 8192) || + !array_access_ok(c.nat->ldt_base, + c.nat->ldt_ents, + LDT_ENTRY_SIZE) ) + return -EINVAL; } +#ifdef CONFIG_COMPAT + else + { + fixup_guest_stack_selector(d, c.cmp->user_regs.ss); + fixup_guest_stack_selector(d, c.cmp->kernel_ss); + fixup_guest_code_selector(d, c.cmp->user_regs.cs); + fixup_guest_code_selector(d, c.cmp->event_callback_cs); + fixup_guest_code_selector(d, c.cmp->failsafe_callback_cs); - for ( i = 0; i < 256; i++ ) - fixup_guest_code_selector(d, c->trap_ctxt[i].cs); + for ( i = 0; i < 256; i++ ) + fixup_guest_code_selector(d, c.cmp->trap_ctxt[i].cs); - /* LDT safety checks. */ - if ( ((c->ldt_base & (PAGE_SIZE-1)) != 0) || - (c->ldt_ents > 8192) || - !array_access_ok(c->ldt_base, c->ldt_ents, LDT_ENTRY_SIZE) ) - return -EINVAL; + /* LDT safety checks. */ + if ( ((c.cmp->ldt_base & (PAGE_SIZE-1)) != 0) || + (c.cmp->ldt_ents > 8192) || + !compat_array_access_ok(c.cmp->ldt_base, + c.cmp->ldt_ents, + LDT_ENTRY_SIZE) ) + return -EINVAL; + } +#endif } clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags); - if ( c->flags & VGCF_i387_valid ) + if ( flags & VGCF_I387_VALID ) set_bit(_VCPUF_fpu_initialised, &v->vcpu_flags); v->arch.flags &= ~TF_kernel_mode; - if ( (c->flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ ) + if ( (flags & VGCF_in_kernel) || is_hvm_vcpu(v)/*???*/ ) v->arch.flags |= TF_kernel_mode; - memcpy(&v->arch.guest_context, c, sizeof(*c)); + if ( !IS_COMPAT(v->domain) ) + memcpy(&v->arch.guest_context, c.nat, sizeof(*c.nat)); +#ifdef CONFIG_COMPAT + else + { + XLAT_vcpu_guest_context(&v->arch.guest_context, c.cmp); + } +#endif /* Only CR0.TS is modifiable by guest or admin. */ v->arch.guest_context.ctrlreg[0] &= X86_CR0_TS; @@ -480,19 +581,34 @@ int arch_set_info_guest( memset(v->arch.guest_context.debugreg, 0, sizeof(v->arch.guest_context.debugreg)); for ( i = 0; i < 8; i++ ) - (void)set_debugreg(v, i, c->debugreg[i]); + (void)set_debugreg(v, i, c(debugreg[i])); if ( v->vcpu_id == 0 ) - d->vm_assist = c->vm_assist; + d->vm_assist = c(vm_assist); if ( !is_hvm_vcpu(v) ) { - if ( (rc = (int)set_gdt(v, c->gdt_frames, c->gdt_ents)) != 0 ) + if ( !IS_COMPAT(d) ) + rc = (int)set_gdt(v, c.nat->gdt_frames, c.nat->gdt_ents); +#ifdef CONFIG_COMPAT + else + { + unsigned long gdt_frames[ARRAY_SIZE(c.cmp->gdt_frames)]; + unsigned int i, n = (c.cmp->gdt_ents + 511) / 512; + + if ( n > ARRAY_SIZE(c.cmp->gdt_frames) ) + return -EINVAL; + for ( i = 0; i < n; ++i ) + gdt_frames[i] = c.cmp->gdt_frames[i]; + rc = (int)set_gdt(v, gdt_frames, c.cmp->gdt_ents); + } +#endif + if ( rc != 0 ) return rc; if ( !IS_COMPAT(d) ) { - cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c->ctrlreg[3])); + cr3_pfn = gmfn_to_mfn(d, xen_cr3_to_pfn(c.nat->ctrlreg[3])); if ( shadow_mode_refcounts(d) ? !get_page(mfn_to_page(cr3_pfn), d) @@ -510,7 +626,7 @@ int arch_set_info_guest( { l4_pgentry_t *l4tab; - cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c->ctrlreg[3])); + cr3_pfn = gmfn_to_mfn(d, compat_cr3_to_pfn(c.cmp->ctrlreg[3])); if ( shadow_mode_refcounts(d) ? !get_page(mfn_to_page(cr3_pfn), d) @@ -539,6 +655,7 @@ int arch_set_info_guest( update_cr3(v); return 0; +#undef c } long diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 59e03e086c..f1b63ffb66 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -23,12 +24,21 @@ #include #include #include +#ifdef CONFIG_COMPAT +#include +#endif -long arch_do_domctl( +#ifndef COMPAT +#define _long long +#define copy_from_xxx_offset copy_from_guest_offset +#define copy_to_xxx_offset copy_to_guest_offset +#endif + +_long arch_do_domctl( struct xen_domctl *domctl, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) { - long ret = 0; + _long ret = 0; switch ( domctl->cmd ) { @@ -40,7 +50,9 @@ long arch_do_domctl( d = find_domain_by_id(domctl->domain); if ( d != NULL ) { - ret = shadow_domctl(d, &domctl->u.shadow_op, u_domctl); + ret = shadow_domctl(d, + &domctl->u.shadow_op, + guest_handle_cast(u_domctl, void)); put_domain(d); copy_to_guest(u_domctl, domctl, 1); } @@ -123,12 +135,12 @@ long arch_do_domctl( case XEN_DOMCTL_getpageframeinfo2: { -#define GPF2_BATCH (PAGE_SIZE / sizeof(long)) +#define GPF2_BATCH (PAGE_SIZE / sizeof(_long)) int n,j; int num = domctl->u.getpageframeinfo2.num; domid_t dom = domctl->domain; struct domain *d; - unsigned long *l_arr; + unsigned _long *l_arr; ret = -ESRCH; if ( unlikely((d = find_domain_by_id(dom)) == NULL) ) @@ -148,9 +160,9 @@ long arch_do_domctl( { int k = ((num-n)>GPF2_BATCH)?GPF2_BATCH:(num-n); - if ( copy_from_guest_offset(l_arr, - domctl->u.getpageframeinfo2.array, - n, k) ) + if ( copy_from_xxx_offset(l_arr, + domctl->u.getpageframeinfo2.array, + n, k) ) { ret = -EINVAL; break; @@ -159,13 +171,13 @@ long arch_do_domctl( for ( j = 0; j < k; j++ ) { struct page_info *page; - unsigned long mfn = l_arr[j]; + unsigned _long mfn = l_arr[j]; page = mfn_to_page(mfn); if ( likely(mfn_valid(mfn) && get_page(page, d)) ) { - unsigned long type = 0; + unsigned _long type = 0; switch( page->u.inuse.type_info & PGT_type_mask ) { @@ -193,8 +205,8 @@ long arch_do_domctl( } - if ( copy_to_guest_offset(domctl->u.getpageframeinfo2.array, - n, l_arr, k) ) + if ( copy_to_xxx_offset(domctl->u.getpageframeinfo2.array, + n, l_arr, k) ) { ret = -EINVAL; break; @@ -214,7 +226,7 @@ long arch_do_domctl( int i; struct domain *d = find_domain_by_id(domctl->domain); unsigned long max_pfns = domctl->u.getmemlist.max_pfns; - unsigned long mfn; + xen_pfn_t mfn; struct list_head *list_ent; ret = -EINVAL; @@ -229,8 +241,8 @@ long arch_do_domctl( { mfn = page_to_mfn(list_entry( list_ent, struct page_info, list)); - if ( copy_to_guest_offset(domctl->u.getmemlist.buffer, - i, &mfn, 1) ) + if ( copy_to_xxx_offset(domctl->u.getmemlist.buffer, + i, &mfn, 1) ) { ret = -EFAULT; break; @@ -289,37 +301,68 @@ long arch_do_domctl( return ret; } -void arch_getdomaininfo_ctxt( - struct vcpu *v, struct vcpu_guest_context *c) +#ifndef COMPAT +void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) { - memcpy(c, &v->arch.guest_context, sizeof(*c)); +#ifdef CONFIG_COMPAT +#define c(fld) (!IS_COMPAT(v->domain) ? (c.nat->fld) : (c.cmp->fld)) +#else +#define c(fld) (c.nat->fld) +#endif + unsigned long flags; + + if ( !IS_COMPAT(v->domain) ) + memcpy(c.nat, &v->arch.guest_context, sizeof(*c.nat)); +#ifdef CONFIG_COMPAT + else + { + XLAT_vcpu_guest_context(c.cmp, &v->arch.guest_context); + } +#endif if ( is_hvm_vcpu(v) ) { - hvm_store_cpu_guest_regs(v, &c->user_regs, c->ctrlreg); + if ( !IS_COMPAT(v->domain) ) + hvm_store_cpu_guest_regs(v, &c.nat->user_regs, c.nat->ctrlreg); +#ifdef CONFIG_COMPAT + else + { + struct cpu_user_regs user_regs; + typeof(c.nat->ctrlreg) ctrlreg; + unsigned i; + + hvm_store_cpu_guest_regs(v, &user_regs, ctrlreg); + XLAT_cpu_user_regs(&c.cmp->user_regs, &user_regs); + for ( i = 0; i < ARRAY_SIZE(c.cmp->ctrlreg); ++i ) + c.cmp->ctrlreg[i] = ctrlreg[i]; + } +#endif } else { /* IOPL privileges are virtualised: merge back into returned eflags. */ - BUG_ON((c->user_regs.eflags & EF_IOPL) != 0); - c->user_regs.eflags |= v->arch.iopl << 12; + BUG_ON((c(user_regs.eflags) & EF_IOPL) != 0); + c(user_regs.eflags |= v->arch.iopl << 12); } - c->flags = 0; + flags = 0; if ( test_bit(_VCPUF_fpu_initialised, &v->vcpu_flags) ) - c->flags |= VGCF_i387_valid; + flags |= VGCF_i387_valid; if ( guest_kernel_mode(v, &v->arch.guest_context.user_regs) ) - c->flags |= VGCF_in_kernel; + flags |= VGCF_in_kernel; + c(flags = flags); if ( !IS_COMPAT(v->domain) ) - c->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); + c.nat->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); #ifdef CONFIG_COMPAT else - c->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); + c.cmp->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); #endif - c->vm_assist = v->domain->vm_assist; + c(vm_assist = v->domain->vm_assist); +#undef c } +#endif /* * Local variables: diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index baa57351c8..318f867ee9 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -3260,7 +3260,7 @@ void shadow_mark_dirty(struct domain *d, mfn_t gmfn) int shadow_domctl(struct domain *d, xen_domctl_shadow_op_t *sc, - XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) + XEN_GUEST_HANDLE(void) u_domctl) { int rc, preempted = 0; diff --git a/xen/arch/x86/x86_32/traps.c b/xen/arch/x86/x86_32/traps.c index 3e8c82aba3..e6cd085962 100644 --- a/xen/arch/x86/x86_32/traps.c +++ b/xen/arch/x86/x86_32/traps.c @@ -193,7 +193,7 @@ unsigned long do_iret(void) /* * Pop, fix up and restore EFLAGS. We fix up in a local staging area - * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt. + * to avoid firing the BUG_ON(IOPL) check in arch_get_info_guest. */ if ( unlikely(__copy_from_user(&eflags, (void __user *)regs->esp, 4)) ) goto exit_and_crash; diff --git a/xen/arch/x86/x86_64/Makefile b/xen/arch/x86/x86_64/Makefile index fad1ca83f2..a2985ff0d3 100644 --- a/xen/arch/x86/x86_64/Makefile +++ b/xen/arch/x86/x86_64/Makefile @@ -5,6 +5,7 @@ obj-y += traps.o obj-$(CONFIG_COMPAT) += compat.o obj-$(CONFIG_COMPAT) += domain.o +obj-$(CONFIG_COMPAT) += domctl.o obj-$(CONFIG_COMPAT) += physdev.o obj-$(CONFIG_COMPAT) += platform_hypercall.o obj-$(CONFIG_COMPAT) += sysctl.o @@ -12,6 +13,7 @@ obj-$(CONFIG_COMPAT) += sysctl.o ifeq ($(CONFIG_COMPAT),y) # extra dependencies compat.o: ../compat.c +domctl.o: ../domctl.c entry.o: compat/entry.S mm.o: compat/mm.c physdev.o: ../physdev.c diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 0a532d2ced..0684d951bc 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -278,8 +278,6 @@ CFIX14: .section .rodata, "a", @progbits -#define compat_domctl domain_crash_synchronous - ENTRY(compat_hypercall_table) .quad compat_set_trap_table /* 0 */ .quad do_mmu_update diff --git a/xen/arch/x86/x86_64/compat/traps.c b/xen/arch/x86/x86_64/compat/traps.c index 938732ba9f..a7f24cecf8 100644 --- a/xen/arch/x86/x86_64/compat/traps.c +++ b/xen/arch/x86/x86_64/compat/traps.c @@ -49,7 +49,7 @@ unsigned int compat_iret(void) /* * Fix up and restore EFLAGS. We fix up in a local staging area - * to avoid firing the BUG_ON(IOPL) check in arch_getdomaininfo_ctxt. + * to avoid firing the BUG_ON(IOPL) check in arch_get_info_guest. */ if ( unlikely(__get_user(eflags, (u32 __user *)regs->rsp + 3)) ) goto exit_and_crash; diff --git a/xen/arch/x86/x86_64/domctl.c b/xen/arch/x86/x86_64/domctl.c new file mode 100644 index 0000000000..4af72ff193 --- /dev/null +++ b/xen/arch/x86/x86_64/domctl.c @@ -0,0 +1,111 @@ +/****************************************************************************** + * Arch-specific compatibility domctl.c + */ + +#include +#include +#include +#include + +DEFINE_XEN_GUEST_HANDLE(compat_domctl_t); +#define xen_domctl compat_domctl +#define xen_domctl_t compat_domctl_t +#define arch_do_domctl(x, h) arch_compat_domctl(x, _##h) + +static int compat_shadow_domctl(struct domain *d, + compat_domctl_shadow_op_t *csc, + XEN_GUEST_HANDLE(void) u_domctl) +{ + xen_domctl_shadow_op_t nsc; + int rc, mode; + +#define XLAT_domctl_shadow_op_HNDL_dirty_bitmap(_d_, _s_) \ + do \ + { \ + if ( (_s_)->op != XEN_DOMCTL_SHADOW_OP_CLEAN \ + && (_s_)->op != XEN_DOMCTL_SHADOW_OP_PEEK ) \ + { \ + set_xen_guest_handle((_d_)->dirty_bitmap, NULL); \ + mode = -1; \ + } \ + else if ( compat_handle_is_null((_s_)->dirty_bitmap) \ + || (((_s_)->pages - 1) \ + & (BITS_PER_LONG - COMPAT_BITS_PER_LONG)) \ + == BITS_PER_LONG - COMPAT_BITS_PER_LONG ) \ + { \ + XEN_GUEST_HANDLE(void) tmp; \ + guest_from_compat_handle(tmp, (_s_)->dirty_bitmap); \ + (_d_)->dirty_bitmap = guest_handle_cast(tmp, ulong); \ + mode = 0; \ + } \ + else if ( (_s_)->pages > COMPAT_ARG_XLAT_SIZE * 8 ) \ + { \ + printk("Cannot translate compatibility mode XEN_DOMCTL_SHADOW_OP_{CLEAN,PEEK} (0x%lX)\n", \ + (_s_)->pages); \ + return -E2BIG; \ + } \ + else \ + { \ + set_xen_guest_handle((_d_)->dirty_bitmap, \ + (void *)COMPAT_ARG_XLAT_VIRT_START(current->vcpu_id)); \ + mode = 1; \ + } \ + } while (0) + XLAT_domctl_shadow_op(&nsc, csc); +#undef XLAT_domctl_shadow_op_HNDL_dirty_bitmap + rc = shadow_domctl(d, &nsc, u_domctl); + if ( rc != __HYPERVISOR_domctl ) + { + BUG_ON(rc > 0); +#define XLAT_domctl_shadow_op_HNDL_dirty_bitmap(_d_, _s_) \ + do \ + { \ + if ( rc == 0 \ + && mode > 0 \ + && copy_to_compat((_d_)->dirty_bitmap, \ + (unsigned int *)(_s_)->dirty_bitmap.p, \ + ((_s_)->pages + COMPAT_BITS_PER_LONG - 1) / COMPAT_BITS_PER_LONG) ) \ + rc = -EFAULT; \ + } while (0) + XLAT_domctl_shadow_op(csc, &nsc); +#undef XLAT_domctl_shadow_op_HNDL_dirty_bitmap + } + return rc; +} +#define xen_domctl_shadow_op compat_domctl_shadow_op +#define xen_domctl_shadow_op_t compat_domctl_shadow_op_t +#define shadow_domctl(d, sc, u) compat_shadow_domctl(d, sc, u) + +#define xen_domctl_ioport_permission compat_domctl_ioport_permission +#define xen_domctl_ioport_permission_t compat_domctl_ioport_permission_t + +#define xen_domctl_getpageframeinfo compat_domctl_getpageframeinfo +#define xen_domctl_getpageframeinfo_t compat_domctl_getpageframeinfo_t + +#define xen_domctl_getpageframeinfo2 compat_domctl_getpageframeinfo2 +#define xen_domctl_getpageframeinfo2_t compat_domctl_getpageframeinfo2_t + +#define xen_domctl_getmemlist compat_domctl_getmemlist +#define xen_domctl_getmemlist_t compat_domctl_getmemlist_t +#define xen_pfn_t compat_pfn_t + +#define xen_domctl_hypercall_init compat_domctl_hypercall_init +#define xen_domctl_hypercall_init_t compat_domctl_hypercall_init_t + +#define COMPAT +#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) +#define _long int +#define copy_from_xxx_offset copy_from_compat_offset +#define copy_to_xxx_offset copy_to_compat_offset + +#include "../domctl.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/compat/Makefile b/xen/common/compat/Makefile index 2210dd05f9..ad5ec1b174 100644 --- a/xen/common/compat/Makefile +++ b/xen/common/compat/Makefile @@ -1,4 +1,5 @@ obj-y += domain.o +obj-y += domctl.o obj-y += kernel.o obj-y += memory.o obj-y += multicall.o @@ -6,6 +7,7 @@ obj-y += sysctl.o obj-y += xlat.o # extra dependencies +domctl.o: ../domctl.c kernel.o: ../kernel.c multicall.o: ../multicall.c sysctl.o: ../sysctl.c diff --git a/xen/common/compat/domain.c b/xen/common/compat/domain.c index fbe7602e8d..3f54260316 100644 --- a/xen/common/compat/domain.c +++ b/xen/common/compat/domain.c @@ -28,7 +28,6 @@ int compat_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg) case VCPUOP_initialise: { struct compat_vcpu_guest_context *cmp_ctxt; - struct vcpu_guest_context *nat_ctxt; if ( (cmp_ctxt = xmalloc(struct compat_vcpu_guest_context)) == NULL ) { @@ -43,23 +42,13 @@ int compat_vcpu_op(int cmd, int vcpuid, XEN_GUEST_HANDLE(void) arg) break; } - if ( (nat_ctxt = xmalloc(struct vcpu_guest_context)) == NULL ) - { - rc = -ENOMEM; - break; - } - - memset(nat_ctxt, 0, sizeof(*nat_ctxt)); - XLAT_vcpu_guest_context(nat_ctxt, cmp_ctxt); - xfree(cmp_ctxt); - LOCK_BIGLOCK(d); rc = -EEXIST; if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) - rc = boot_vcpu(d, vcpuid, nat_ctxt); + rc = boot_vcpu(d, vcpuid, cmp_ctxt); UNLOCK_BIGLOCK(d); - xfree(nat_ctxt); + xfree(cmp_ctxt); break; } diff --git a/xen/common/compat/domctl.c b/xen/common/compat/domctl.c new file mode 100644 index 0000000000..e04e3aae04 --- /dev/null +++ b/xen/common/compat/domctl.c @@ -0,0 +1,137 @@ +/****************************************************************************** + * compat/domctl.c + */ + +#include +#include +#include +#include +#include + +DEFINE_XEN_GUEST_HANDLE(compat_domctl_t); +#define xen_domctl compat_domctl +#define xen_domctl_t compat_domctl_t +#define do_domctl(h) compat_domctl(_##h) +#define arch_do_domctl(x, h) arch_compat_domctl(x, _##h) + +#define xen_domain_handle_t compat_domain_handle_t + +#define xen_domctl_vcpucontext compat_domctl_vcpucontext +#define xen_domctl_vcpucontext_t compat_domctl_vcpucontext_t + +#define xen_domctl_createdomain compat_domctl_createdomain +#define xen_domctl_createdomain_t compat_domctl_createdomain_t + +#define xen_domctl_max_vcpus compat_domctl_max_vcpus +#define xen_domctl_max_vcpus_t compat_domctl_max_vcpus_t + +static void cpumask_to_compat_ctl_cpumap( + struct compat_ctl_cpumap *cmpctl_cpumap, cpumask_t *cpumask) +{ + unsigned int guest_bytes, copy_bytes, i; + /*static const*/ uint8_t zero = 0; + + if ( compat_handle_is_null(cmpctl_cpumap->bitmap) ) + return; + + guest_bytes = (cmpctl_cpumap->nr_cpus + 7) / 8; + copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8); + + copy_to_compat(cmpctl_cpumap->bitmap, + (uint8_t *)cpus_addr(*cpumask), + copy_bytes); + + for ( i = copy_bytes; i < guest_bytes; i++ ) + copy_to_compat_offset(cmpctl_cpumap->bitmap, i, &zero, 1); +} +#define cpumask_to_xenctl_cpumap cpumask_to_compat_ctl_cpumap + +void compat_ctl_cpumap_to_cpumask( + cpumask_t *cpumask, struct compat_ctl_cpumap *cmpctl_cpumap) +{ + unsigned int guest_bytes, copy_bytes; + + guest_bytes = (cmpctl_cpumap->nr_cpus + 7) / 8; + copy_bytes = min_t(unsigned int, guest_bytes, (NR_CPUS + 7) / 8); + + cpus_clear(*cpumask); + + if ( compat_handle_is_null(cmpctl_cpumap->bitmap) ) + return; + + copy_from_compat((uint8_t *)cpus_addr(*cpumask), + cmpctl_cpumap->bitmap, + copy_bytes); +} +#define xenctl_cpumap_to_cpumask compat_ctl_cpumap_to_cpumask + +#define xen_domctl_vcpuaffinity compat_domctl_vcpuaffinity +#define xen_domctl_vcpuaffinity_t compat_domctl_vcpuaffinity_t + +static int compat_sched_adjust(struct domain *d, + struct compat_domctl_scheduler_op *cop) +{ + struct xen_domctl_scheduler_op nop; + int ret; + enum XLAT_domctl_scheduler_op_u u; + + switch ( cop->sched_id ) + { + case XEN_SCHEDULER_SEDF: u = XLAT_domctl_scheduler_op_u_sedf; break; + case XEN_SCHEDULER_CREDIT: u = XLAT_domctl_scheduler_op_u_credit; break; + default: return -EINVAL; + } + XLAT_domctl_scheduler_op(&nop, cop); + ret = sched_adjust(d, &nop); + XLAT_domctl_scheduler_op(cop, &nop); + + return ret; +} +#define sched_adjust(d, op) compat_sched_adjust(d, op) +#define xen_domctl_scheduler_op compat_domctl_scheduler_op +#define xen_domctl_scheduler_op_t compat_domctl_scheduler_op_t + +#define xen_domctl_getdomaininfo compat_domctl_getdomaininfo +#define xen_domctl_getdomaininfo_t compat_domctl_getdomaininfo_t +#define getdomaininfo(d, i) compat_getdomaininfo(d, i) + +#define xen_domctl_getvcpuinfo compat_domctl_getvcpuinfo +#define xen_domctl_getvcpuinfo_t compat_domctl_getvcpuinfo_t + +#define xen_domctl_max_mem compat_domctl_max_mem +#define xen_domctl_max_mem_t compat_domctl_max_mem_t + +#define xen_domctl_setdomainhandle compat_domctl_setdomainhandle +#define xen_domctl_setdomainhandle_t compat_domctl_setdomainhandle_t + +#define xen_domctl_setdebugging compat_domctl_setdebugging +#define xen_domctl_setdebugging_t compat_domctl_setdebugging_t + +#define xen_domctl_irq_permission compat_domctl_irq_permission +#define xen_domctl_irq_permission_t compat_domctl_irq_permission_t + +#define xen_domctl_iomem_permission compat_domctl_iomem_permission +#define xen_domctl_iomem_permission_t compat_domctl_iomem_permission_t + +#define xen_domctl_settimeoffset compat_domctl_settimeoffset +#define xen_domctl_settimeoffset_t compat_domctl_settimeoffset_t + +#define COMPAT +#define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t) +#define _u_domctl u_domctl +//#undef guest_handle_cast +//#define guest_handle_cast compat_handle_cast +//#define copy_to_xxx_offset copy_to_compat_offset +typedef int ret_t; + +#include "../domctl.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/compat/sysctl.c b/xen/common/compat/sysctl.c index 9aa5fba783..6072443566 100644 --- a/xen/common/compat/sysctl.c +++ b/xen/common/compat/sysctl.c @@ -40,13 +40,6 @@ static int compat_tb_control(struct compat_sysctl_tbuf_op *cmp_tbc) #define xen_sysctl_sched_id compat_sysctl_sched_id #define xen_sysctl_sched_id_t compat_sysctl_sched_id_t -static void compat_getdomaininfo(struct domain *d, struct compat_domctl_getdomaininfo *ci) -{ - struct xen_domctl_getdomaininfo ni; - - getdomaininfo(d, &ni); - XLAT_domctl_getdomaininfo(ci, &ni); -} #define xen_sysctl_getdomaininfolist compat_sysctl_getdomaininfolist #define xen_sysctl_getdomaininfolist_t compat_sysctl_getdomaininfolist_t #define xen_domctl_getdomaininfo compat_domctl_getdomaininfo diff --git a/xen/common/domain.c b/xen/common/domain.c index 8afab95a31..28530c40d5 100644 --- a/xen/common/domain.c +++ b/xen/common/domain.c @@ -26,6 +26,9 @@ #include #include #include +#ifdef CONFIG_COMPAT +#include +#endif /* Both these structures are protected by the domlist_lock. */ DEFINE_RWLOCK(domlist_lock); @@ -451,32 +454,64 @@ void domain_unpause_by_systemcontroller(struct domain *d) * the userspace dom0 domain builder. */ int set_info_guest(struct domain *d, - xen_domctl_vcpucontext_t *vcpucontext) + xen_domctl_vcpucontext_u vcpucontext) { int rc = 0; - struct vcpu_guest_context *c = NULL; - unsigned long vcpu = vcpucontext->vcpu; + vcpu_guest_context_u c; +#ifdef CONFIG_COMPAT + CHECK_FIELD(domctl_vcpucontext, vcpu); +#endif + unsigned long vcpu = vcpucontext.nat->vcpu; struct vcpu *v; if ( (vcpu >= MAX_VIRT_CPUS) || ((v = d->vcpu[vcpu]) == NULL) ) return -EINVAL; - if ( (c = xmalloc(struct vcpu_guest_context)) == NULL ) +#ifdef CONFIG_COMPAT + BUILD_BUG_ON(sizeof(struct vcpu_guest_context) + < sizeof(struct compat_vcpu_guest_context)); +#endif + if ( (c.nat = xmalloc(struct vcpu_guest_context)) == NULL ) return -ENOMEM; domain_pause(d); - rc = -EFAULT; - if ( copy_from_guest(c, vcpucontext->ctxt, 1) == 0 ) + if ( !IS_COMPAT(v->domain) ) + { + if ( !IS_COMPAT(current->domain) + ? copy_from_guest(c.nat, vcpucontext.nat->ctxt, 1) +#ifndef CONFIG_COMPAT + : 0 ) +#else + : copy_from_guest(c.nat, + compat_handle_cast(vcpucontext.cmp->ctxt, + void), + 1) ) +#endif + rc = -EFAULT; + } +#ifdef CONFIG_COMPAT + else + { + if ( !IS_COMPAT(current->domain) + ? copy_from_guest(c.cmp, + guest_handle_cast(vcpucontext.nat->ctxt, void), + 1) + : copy_from_compat(c.cmp, vcpucontext.cmp->ctxt, 1) ) + rc = -EFAULT; + } +#endif + + if ( rc == 0 ) rc = arch_set_info_guest(v, c); domain_unpause(d); - xfree(c); + xfree(c.nat); return rc; } -int boot_vcpu(struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt) +int boot_vcpu(struct domain *d, int vcpuid, vcpu_guest_context_u ctxt) { struct vcpu *v = d->vcpu[vcpuid]; diff --git a/xen/common/domctl.c b/xen/common/domctl.c index b05ecd1099..b9cd57e949 100644 --- a/xen/common/domctl.c +++ b/xen/common/domctl.c @@ -18,14 +18,22 @@ #include #include #include +#ifdef CONFIG_COMPAT +#include +#endif #include #include #include -extern long arch_do_domctl( +#ifndef COMPAT +typedef long ret_t; +#define copy_to_xxx_offset copy_to_guest_offset +#endif + +extern ret_t arch_do_domctl( struct xen_domctl *op, XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); -extern void arch_getdomaininfo_ctxt( - struct vcpu *, struct vcpu_guest_context *); + +#ifndef COMPAT void cpumask_to_xenctl_cpumap( struct xenctl_cpumap *xenctl_cpumap, cpumask_t *cpumask) @@ -65,6 +73,8 @@ void xenctl_cpumap_to_cpumask( copy_bytes); } +#endif /* COMPAT */ + static inline int is_free_domid(domid_t dom) { struct domain *d; @@ -169,9 +179,9 @@ static unsigned int default_vcpu0_location(void) return cpu; } -long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) +ret_t do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) { - long ret = 0; + ret_t ret = 0; struct xen_domctl curop, *op = &curop; void *ssid = NULL; /* save security ptr between pre and post/fail hooks */ static DEFINE_SPINLOCK(domctl_lock); @@ -283,11 +293,36 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) if ( (d = domain_create(dom, domcr_flags)) == NULL ) break; + ret = 0; + switch ( (op->u.createdomain.flags >> XEN_DOMCTL_CDF_WORDSIZE_SHIFT) + & XEN_DOMCTL_CDF_WORDSIZE_MASK ) + { + case 0: + if ( !IS_COMPAT(current->domain) ) + op->u.createdomain.flags |= BITS_PER_LONG + << XEN_DOMCTL_CDF_WORDSIZE_SHIFT; +#ifdef CONFIG_COMPAT + else + { + op->u.createdomain.flags |= COMPAT_BITS_PER_LONG + << XEN_DOMCTL_CDF_WORDSIZE_SHIFT; + case COMPAT_BITS_PER_LONG: + ret = switch_compat(d); + } +#endif + break; + case BITS_PER_LONG: + break; + default: + ret = -EINVAL; + break; + } + if ( ret ) + break; + memcpy(d->handle, op->u.createdomain.handle, sizeof(xen_domain_handle_t)); - ret = 0; - op->domain = d->domain_id; if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; @@ -446,7 +481,7 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) case XEN_DOMCTL_getvcpucontext: { - struct vcpu_guest_context *c; + vcpu_guest_context_u c; struct domain *d; struct vcpu *v; @@ -466,23 +501,48 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) if ( !test_bit(_VCPUF_initialised, &v->vcpu_flags) ) goto getvcpucontext_out; +#ifdef CONFIG_COMPAT + BUILD_BUG_ON(sizeof(struct vcpu_guest_context) + < sizeof(struct compat_vcpu_guest_context)); +#endif ret = -ENOMEM; - if ( (c = xmalloc(struct vcpu_guest_context)) == NULL ) + if ( (c.nat = xmalloc(struct vcpu_guest_context)) == NULL ) goto getvcpucontext_out; if ( v != current ) vcpu_pause(v); - arch_getdomaininfo_ctxt(v,c); + arch_get_info_guest(v, c); ret = 0; if ( v != current ) vcpu_unpause(v); - if ( copy_to_guest(op->u.vcpucontext.ctxt, c, 1) ) - ret = -EFAULT; + if ( !IS_COMPAT(v->domain) ) + { +#ifndef COMPAT + if ( copy_to_guest(op->u.vcpucontext.ctxt, c.nat, 1) ) +#else + if ( copy_to_guest(compat_handle_cast(op->u.vcpucontext.ctxt, + void), + c.nat, 1) ) +#endif + ret = -EFAULT; + } +#ifdef CONFIG_COMPAT + else + { +#ifndef COMPAT + if ( copy_to_guest(guest_handle_cast(op->u.vcpucontext.ctxt, void), + c.cmp, 1) ) +#else + if ( copy_to_compat(op->u.vcpucontext.ctxt, c.cmp, 1) ) +#endif + ret = -EFAULT; + } +#endif - xfree(c); + xfree(c.nat); if ( copy_to_guest(u_domctl, op, 1) ) ret = -EFAULT; @@ -646,6 +706,16 @@ long do_domctl(XEN_GUEST_HANDLE(xen_domctl_t) u_domctl) } break; +#ifdef CONFIG_COMPAT + case XEN_DOMCTL_set_compat: + ret = switch_compat(find_domain_by_id(op->domain)); + break; + + case XEN_DOMCTL_set_native: + ret = switch_native(find_domain_by_id(op->domain)); + break; +#endif + default: ret = arch_do_domctl(op, u_domctl); break; diff --git a/xen/common/schedule.c b/xen/common/schedule.c index 69fbb02634..55abd5f5ca 100644 --- a/xen/common/schedule.c +++ b/xen/common/schedule.c @@ -33,8 +33,6 @@ #include #include -extern void arch_getdomaininfo_ctxt(struct vcpu *, - struct vcpu_guest_context *); /* opt_sched: scheduler - default to credit */ static char opt_sched[10] = "credit"; string_param("sched", opt_sched); diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index d9c94010c0..68ae3cb011 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -192,7 +192,7 @@ int shadow_enable(struct domain *d, u32 mode); * manipulate the log-dirty bitmap. */ int shadow_domctl(struct domain *d, xen_domctl_shadow_op_t *sc, - XEN_GUEST_HANDLE(xen_domctl_t) u_domctl); + XEN_GUEST_HANDLE(void) u_domctl); /* Call when destroying a domain */ void shadow_teardown(struct domain *d); diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 588d430511..d9b23d5b75 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -53,6 +53,8 @@ struct xen_domctl_createdomain { /* Is this an HVM guest (as opposed to a PV guest)? */ #define _XEN_DOMCTL_CDF_hvm_guest 0 #define XEN_DOMCTL_CDF_hvm_guest (1U<<_XEN_DOMCTL_CDF_hvm_guest) +#define XEN_DOMCTL_CDF_WORDSIZE_MASK 255 +#define XEN_DOMCTL_CDF_WORDSIZE_SHIFT 24 uint32_t flags; }; typedef struct xen_domctl_createdomain xen_domctl_createdomain_t; @@ -392,6 +394,9 @@ struct xen_domctl_real_mode_area { typedef struct xen_domctl_real_mode_area xen_domctl_real_mode_area_t; DEFINE_XEN_GUEST_HANDLE(xen_domctl_real_mode_area_t); +#define XEN_DOMCTL_set_compat 42 +#define XEN_DOMCTL_set_native 43 + struct xen_domctl { uint32_t cmd; uint32_t interface_version; /* XEN_DOMCTL_INTERFACE_VERSION */ diff --git a/xen/include/xen/compat.h b/xen/include/xen/compat.h index d5b733ec58..06771a1c23 100644 --- a/xen/include/xen/compat.h +++ b/xen/include/xen/compat.h @@ -166,6 +166,9 @@ void xlat_start_info(struct start_info *, enum XLAT_start_info_console); struct vcpu_runstate_info; void xlat_vcpu_runstate_info(struct vcpu_runstate_info *); +int switch_compat(struct domain *); +int switch_native(struct domain *); + #define BITS_PER_GUEST_LONG(d) (!IS_COMPAT(d) ? BITS_PER_LONG : COMPAT_BITS_PER_LONG) #else diff --git a/xen/include/xen/domain.h b/xen/include/xen/domain.h index fd0b3ab0ff..26b2047f5a 100644 --- a/xen/include/xen/domain.h +++ b/xen/include/xen/domain.h @@ -2,10 +2,15 @@ #ifndef __XEN_DOMAIN_H__ #define __XEN_DOMAIN_H__ +typedef union { + struct vcpu_guest_context *nat; + struct compat_vcpu_guest_context *cmp; +} vcpu_guest_context_u __attribute__((__transparent_union__)); + struct vcpu *alloc_vcpu( struct domain *d, unsigned int vcpu_id, unsigned int cpu_id); int boot_vcpu( - struct domain *d, int vcpuid, struct vcpu_guest_context *ctxt); + struct domain *d, int vcpuid, vcpu_guest_context_u ctxt); struct vcpu *alloc_idle_vcpu(unsigned int cpu_id); struct domain *alloc_domain(domid_t domid); @@ -14,6 +19,9 @@ void free_domain(struct domain *d); struct xen_domctl_getdomaininfo; void getdomaininfo( struct domain *d, struct xen_domctl_getdomaininfo *info); +struct compat_domctl_getdomaininfo; +void compat_getdomaininfo( + struct domain *d, struct compat_domctl_getdomaininfo *info); /* * Arch-specifics. @@ -37,7 +45,8 @@ int arch_domain_create(struct domain *d); void arch_domain_destroy(struct domain *d); -int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c); +int arch_set_info_guest(struct vcpu *, vcpu_guest_context_u); +void arch_get_info_guest(struct vcpu *, vcpu_guest_context_u); void domain_relinquish_resources(struct domain *d); diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h index 81bb634f20..3e72ea9b31 100644 --- a/xen/include/xen/sched.h +++ b/xen/include/xen/sched.h @@ -275,7 +275,13 @@ int construct_dom0( unsigned long image_start, unsigned long image_len, unsigned long initrd_start, unsigned long initrd_len, char *cmdline); -int set_info_guest(struct domain *d, xen_domctl_vcpucontext_t *); + +typedef union { + struct xen_domctl_vcpucontext *nat; + struct compat_domctl_vcpucontext *cmp; +} xen_domctl_vcpucontext_u __attribute__((__transparent_union__)); + +int set_info_guest(struct domain *d, xen_domctl_vcpucontext_u); struct domain *find_domain_by_id(domid_t dom); void domain_destroy(struct domain *d); diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 18e0d0c21b..566dcc277f 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -11,7 +11,9 @@ ! vcpu_guest_context arch-x86/xen.h ? acm_getdecision acm_ops.h ! ctl_cpumap domctl.h -! domctl_getdomaininfo domctl.h +! domctl_scheduler_op domctl.h +! domctl_shadow_op domctl.h +! domctl_shadow_op_stats domctl.h ? evtchn_alloc_unbound event_channel.h ? evtchn_bind_interdomain event_channel.h ? evtchn_bind_ipi event_channel.h From 70a6f21e0ffd2f369a175ce966d40dd517ba6354 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:40 +0000 Subject: [PATCH 095/570] Enable compatibility mode operation for trace buffer access. Signed-off-by: Jan Beulich --- xen/common/trace.c | 78 ++++++++++++++++++++++++++++++++++---------- xen/include/xlat.lst | 1 + 2 files changed, 61 insertions(+), 18 deletions(-) diff --git a/xen/common/trace.c b/xen/common/trace.c index a5cec8e69a..eb791c1f8f 100644 --- a/xen/common/trace.c +++ b/xen/common/trace.c @@ -32,13 +32,29 @@ #include #include +#ifdef CONFIG_COMPAT +#include +#define xen_t_buf t_buf +CHECK_t_buf; +#undef xen_t_buf +#define TB_COMPAT IS_COMPAT(dom0) +#else +#define compat_t_rec t_rec +#define TB_COMPAT 0 +#endif + +typedef union { + struct t_rec *nat; + struct compat_t_rec *cmp; +} t_rec_u; + /* opt_tbuf_size: trace buffer size (in pages) */ static unsigned int opt_tbuf_size = 0; integer_param("tbuf_size", opt_tbuf_size); /* Pointers to the meta-data objects for all system trace buffers */ static DEFINE_PER_CPU(struct t_buf *, t_bufs); -static DEFINE_PER_CPU(struct t_rec *, t_recs); +static DEFINE_PER_CPU(t_rec_u, t_recs); static int nr_recs; /* High water mark for trace buffers; */ @@ -87,7 +103,7 @@ static int alloc_trace_bufs(void) nr_pages = num_online_cpus() * opt_tbuf_size; order = get_order_from_pages(nr_pages); nr_recs = (opt_tbuf_size * PAGE_SIZE - sizeof(struct t_buf)) / - sizeof(struct t_rec); + (!TB_COMPAT ? sizeof(struct t_rec) : sizeof(struct compat_t_rec)); if ( (rawbuf = alloc_xenheap_pages(order)) == NULL ) { @@ -106,7 +122,7 @@ static int alloc_trace_bufs(void) buf = per_cpu(t_bufs, i) = (struct t_buf *) &rawbuf[i*opt_tbuf_size*PAGE_SIZE]; buf->cons = buf->prod = 0; - per_cpu(t_recs, i) = (struct t_rec *)(buf + 1); + per_cpu(t_recs, i).nat = (struct t_rec *)(buf + 1); } t_buf_highwater = nr_recs >> 1; /* 50% high water */ @@ -232,7 +248,7 @@ void trace(u32 event, unsigned long d1, unsigned long d2, unsigned long d3, unsigned long d4, unsigned long d5) { struct t_buf *buf; - struct t_rec *rec; + t_rec_u rec; unsigned long flags; BUG_ON(!tb_init_done); @@ -269,25 +285,51 @@ void trace(u32 event, unsigned long d1, unsigned long d2, if ( unlikely(this_cpu(lost_records) != 0) ) { - rec = &this_cpu(t_recs)[buf->prod % nr_recs]; - memset(rec, 0, sizeof(*rec)); - rec->cycles = (u64)get_cycles(); - rec->event = TRC_LOST_RECORDS; - rec->data[0] = this_cpu(lost_records); - this_cpu(lost_records) = 0; + if ( !TB_COMPAT ) + { + rec.nat = &this_cpu(t_recs).nat[buf->prod % nr_recs]; + memset(rec.nat, 0, sizeof(*rec.nat)); + rec.nat->cycles = (u64)get_cycles(); + rec.nat->event = TRC_LOST_RECORDS; + rec.nat->data[0] = this_cpu(lost_records); + this_cpu(lost_records) = 0; + } + else + { + rec.cmp = &this_cpu(t_recs).cmp[buf->prod % nr_recs]; + memset(rec.cmp, 0, sizeof(*rec.cmp)); + rec.cmp->cycles = (u64)get_cycles(); + rec.cmp->event = TRC_LOST_RECORDS; + rec.cmp->data[0] = this_cpu(lost_records); + this_cpu(lost_records) = 0; + } wmb(); buf->prod++; } - rec = &this_cpu(t_recs)[buf->prod % nr_recs]; - rec->cycles = (u64)get_cycles(); - rec->event = event; - rec->data[0] = d1; - rec->data[1] = d2; - rec->data[2] = d3; - rec->data[3] = d4; - rec->data[4] = d5; + if ( !TB_COMPAT ) + { + rec.nat = &this_cpu(t_recs).nat[buf->prod % nr_recs]; + rec.nat->cycles = (u64)get_cycles(); + rec.nat->event = event; + rec.nat->data[0] = d1; + rec.nat->data[1] = d2; + rec.nat->data[2] = d3; + rec.nat->data[3] = d4; + rec.nat->data[4] = d5; + } + else + { + rec.cmp = &this_cpu(t_recs).cmp[buf->prod % nr_recs]; + rec.cmp->cycles = (u64)get_cycles(); + rec.cmp->event = event; + rec.cmp->data[0] = d1; + rec.cmp->data[1] = d2; + rec.cmp->data[2] = d3; + rec.cmp->data[3] = d4; + rec.cmp->data[4] = d5; + } wmb(); buf->prod++; diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 566dcc277f..89af2d3fb1 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -44,6 +44,7 @@ ? sysctl_perfc_desc sysctl.h ! sysctl_perfc_op sysctl.h ! sysctl_tbuf_op sysctl.h +? t_buf trace.h ! vcpu_runstate_info vcpu.h ? xenoprof_init xenoprof.h ? xenoprof_passive xenoprof.h From 8c7577f2c3bacb8b49205c6d4afb11d61be852db Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:41 +0000 Subject: [PATCH 096/570] Enable compatibility mode operation for kexec. Signed-off-by: Jan Beulich --- xen/arch/x86/x86_64/compat/entry.S | 2 ++ xen/common/Makefile | 1 + xen/common/compat/kexec.c | 33 +++++++++++++++++++++++ xen/common/kexec.c | 42 +++++++++++++++++++++++------- xen/include/xlat.lst | 2 ++ 5 files changed, 71 insertions(+), 9 deletions(-) create mode 100644 xen/common/compat/kexec.c diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index 0684d951bc..bc47636d25 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -316,6 +316,7 @@ ENTRY(compat_hypercall_table) .quad compat_ni_hypercall .quad compat_sysctl /* 35 */ .quad compat_domctl + .quad compat_kexec_op .rept NR_hypercalls-((.-compat_hypercall_table)/8) .quad compat_ni_hypercall .endr @@ -358,6 +359,7 @@ ENTRY(compat_hypercall_args_table) .byte 0 /* compat_ni_hypercall */ .byte 1 /* compat_sysctl */ /* 35 */ .byte 1 /* compat_domctl */ + .byte 2 /* compat_kexec_op */ .rept NR_hypercalls-(.-compat_hypercall_args_table) .byte 0 /* compat_ni_hypercall */ .endr diff --git a/xen/common/Makefile b/xen/common/Makefile index 1997f461c2..0c9b9b2333 100644 --- a/xen/common/Makefile +++ b/xen/common/Makefile @@ -44,6 +44,7 @@ ifeq ($(CONFIG_COMPAT),y) # extra dependencies acm_ops.o: compat/acm_ops.c grant_table.o: compat/grant_table.c +kexec.o: compat/kexec.c schedule.o: compat/schedule.c xenoprof.o: compat/xenoprof.c endif diff --git a/xen/common/compat/kexec.c b/xen/common/compat/kexec.c new file mode 100644 index 0000000000..b167d8a4ff --- /dev/null +++ b/xen/common/compat/kexec.c @@ -0,0 +1,33 @@ +/* + * compat/kexec.c + */ + +#include + +#define COMPAT +#define ret_t int + +#define do_kexec_op compat_kexec_op + +#undef kexec_get +#define kexec_get(x) compat_kexec_get_##x +#define xen_kexec_range compat_kexec_range +#define xen_kexec_range_t compat_kexec_range_t + +#define kexec_load_unload compat_kexec_load_unload +#define xen_kexec_load compat_kexec_load +#define xen_kexec_load_t compat_kexec_load_t + +CHECK_kexec_exec; + +#include "../kexec.c" + +/* + * Local variables: + * mode: C + * c-set-style: "BSD" + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + */ diff --git a/xen/common/kexec.c b/xen/common/kexec.c index 8f511608f5..1b470a5e50 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -22,6 +22,10 @@ #include #include +#ifndef COMPAT + +typedef long ret_t; + DEFINE_PER_CPU (crash_note_t, crash_notes); cpumask_t crash_saved_cpus; @@ -143,21 +147,25 @@ static __init int register_crashdump_trigger(void) } __initcall(register_crashdump_trigger); -static int kexec_get_reserve(xen_kexec_range_t *range) +#define kexec_get(x) kexec_get_##x + +#endif + +static int kexec_get(reserve)(xen_kexec_range_t *range) { range->start = kexec_crash_area.start; range->size = kexec_crash_area.size; return 0; } -static int kexec_get_xen(xen_kexec_range_t *range) +static int kexec_get(xen)(xen_kexec_range_t *range) { range->start = virt_to_maddr(_start); range->size = (unsigned long)_end - (unsigned long)_start; return 0; } -static int kexec_get_cpu(xen_kexec_range_t *range) +static int kexec_get(cpu)(xen_kexec_range_t *range) { if ( range->nr < 0 || range->nr >= num_present_cpus() ) return -EINVAL; @@ -167,7 +175,7 @@ static int kexec_get_cpu(xen_kexec_range_t *range) return 0; } -static int kexec_get_range(XEN_GUEST_HANDLE(void) uarg) +static int kexec_get(range)(XEN_GUEST_HANDLE(void) uarg) { xen_kexec_range_t range; int ret = -EINVAL; @@ -178,13 +186,13 @@ static int kexec_get_range(XEN_GUEST_HANDLE(void) uarg) switch ( range.range ) { case KEXEC_RANGE_MA_CRASH: - ret = kexec_get_reserve(&range); + ret = kexec_get(reserve)(&range); break; case KEXEC_RANGE_MA_XEN: - ret = kexec_get_xen(&range); + ret = kexec_get(xen)(&range); break; case KEXEC_RANGE_MA_CPU: - ret = kexec_get_cpu(&range); + ret = kexec_get(cpu)(&range); break; } @@ -194,6 +202,8 @@ static int kexec_get_range(XEN_GUEST_HANDLE(void) uarg) return ret; } +#ifndef COMPAT + static int kexec_load_get_bits(int type, int *base, int *bit) { switch ( type ) @@ -212,6 +222,8 @@ static int kexec_load_get_bits(int type, int *base, int *bit) return 0; } +#endif + static int kexec_load_unload(unsigned long op, XEN_GUEST_HANDLE(void) uarg) { xen_kexec_load_t load; @@ -234,7 +246,11 @@ static int kexec_load_unload(unsigned long op, XEN_GUEST_HANDLE(void) uarg) BUG_ON(test_bit((base + !pos), &kexec_flags)); /* must be free */ +#ifndef COMPAT memcpy(image, &load.image, sizeof(*image)); +#else + XLAT_kexec_image(image, &load.image); +#endif if ( !(ret = machine_kexec_load(load.type, base + !pos, image)) ) { @@ -259,6 +275,8 @@ static int kexec_load_unload(unsigned long op, XEN_GUEST_HANDLE(void) uarg) return ret; } +#ifndef COMPAT + static int kexec_exec(XEN_GUEST_HANDLE(void) uarg) { xen_kexec_exec_t exec; @@ -292,7 +310,9 @@ static int kexec_exec(XEN_GUEST_HANDLE(void) uarg) return -EINVAL; /* never reached */ } -long do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg) +#endif + +ret_t do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg) { unsigned long flags; int ret = -EINVAL; @@ -303,7 +323,7 @@ long do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg) switch ( op ) { case KEXEC_CMD_kexec_get_range: - ret = kexec_get_range(uarg); + ret = kexec_get(range)(uarg); break; case KEXEC_CMD_kexec_load: case KEXEC_CMD_kexec_unload: @@ -322,6 +342,10 @@ long do_kexec_op(unsigned long op, XEN_GUEST_HANDLE(void) uarg) return ret; } +#if defined(CONFIG_COMPAT) && !defined(COMPAT) +#include "compat/kexec.c" +#endif + /* * Local variables: * mode: C diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 89af2d3fb1..950f60b2f4 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -32,6 +32,8 @@ ! gnttab_transfer grant_table.h ? gnttab_unmap_grant_ref grant_table.h ? grant_entry grant_table.h +? kexec_exec kexec.h +! kexec_image kexec.h ! add_to_physmap memory.h ! foreign_memory_map memory.h ! memory_exchange memory.h From f4c856df98b0797eab75e9c73f925a0aa101a06d Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:41 +0000 Subject: [PATCH 097/570] Preliminary, likely incomplete and/or wrong, adjustments to shadow code. Signed-off-by: Jan Beulich --- xen/arch/x86/mm/shadow/common.c | 7 ++-- xen/arch/x86/mm/shadow/multi.c | 62 ++++++++++++++++++++++++++++----- xen/include/asm-x86/shadow.h | 8 +++++ 3 files changed, 65 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index 318f867ee9..ac543baba1 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -2443,9 +2443,10 @@ static void sh_update_paging_modes(struct vcpu *v) /// PV guest /// #if CONFIG_PAGING_LEVELS == 4 - /* When 32-on-64 PV guests are supported, they must choose - * a different mode here */ - v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,4); + if ( pv_32bit_guest(v) ) + v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3); + else + v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,4,4); #elif CONFIG_PAGING_LEVELS == 3 v->arch.shadow.mode = &SHADOW_INTERNAL_NAME(sh_paging_mode,3,3); #elif CONFIG_PAGING_LEVELS == 2 diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 72b1b847ed..56bd93d428 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -1422,7 +1422,7 @@ void sh_install_xen_entries_in_l4(struct vcpu *v, mfn_t gl4mfn, mfn_t sl4mfn) } #endif -#if CONFIG_PAGING_LEVELS == 3 && GUEST_PAGING_LEVELS == 3 +#if (CONFIG_PAGING_LEVELS == 3 || defined(CONFIG_COMPAT)) && GUEST_PAGING_LEVELS == 3 // For 3-on-3 PV guests, we need to make sure the xen mappings are in // place, which means that we need to populate the l2h entry in the l3 // table. @@ -1432,12 +1432,20 @@ void sh_install_xen_entries_in_l2h(struct vcpu *v, { struct domain *d = v->domain; shadow_l2e_t *sl2e; +#if CONFIG_PAGING_LEVELS == 3 int i; +#else + + if ( !pv_32bit_guest(v) ) + return; +#endif sl2e = sh_map_domain_page(sl2hmfn); ASSERT(sl2e != NULL); ASSERT(sizeof (l2_pgentry_t) == sizeof (shadow_l2e_t)); +#if CONFIG_PAGING_LEVELS == 3 + /* Copy the common Xen mappings from the idle domain */ memcpy(&sl2e[L2_PAGETABLE_FIRST_XEN_SLOT & (L2_PAGETABLE_ENTRIES-1)], &idle_pg_table_l2[L2_PAGETABLE_FIRST_XEN_SLOT], @@ -1478,6 +1486,15 @@ void sh_install_xen_entries_in_l2h(struct vcpu *v, } sh_unmap_domain_page(p2m); } + +#else + + /* Copy the common Xen mappings from the idle domain */ + memcpy(&sl2e[COMPAT_L2_PAGETABLE_FIRST_XEN_SLOT(d)], + &compat_idle_pg_table_l2[l2_table_offset(HIRO_COMPAT_MPT_VIRT_START)], + COMPAT_L2_PAGETABLE_XEN_SLOTS(d) * sizeof(*sl2e)); + +#endif sh_unmap_domain_page(sl2e); } @@ -1660,6 +1677,19 @@ sh_make_monitor_table(struct vcpu *v) l4e = sh_map_domain_page(m4mfn); l4e[0] = l4e_from_pfn(mfn_x(m3mfn), __PAGE_HYPERVISOR); sh_unmap_domain_page(l4e); + if ( pv_32bit_guest(v) ) + { + // Install a monitor l2 table in slot 3 of the l3 table. + // This is used for all Xen entries. + mfn_t m2mfn; + l3_pgentry_t *l3e; + m2mfn = shadow_alloc(d, SH_type_monitor_table, 0); + mfn_to_page(m2mfn)->shadow_flags = 2; + l3e = sh_map_domain_page(m3mfn); + l3e[3] = l3e_from_pfn(mfn_x(m2mfn), _PAGE_PRESENT); + sh_install_xen_entries_in_l2h(v, m2mfn); + sh_unmap_domain_page(l3e); + } } #endif /* SHADOW_PAGING_LEVELS < 4 */ return m4mfn; @@ -2067,7 +2097,16 @@ void sh_destroy_monitor_table(struct vcpu *v, mfn_t mmfn) { l4_pgentry_t *l4e = sh_map_domain_page(mmfn); ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT); - shadow_free(d, _mfn(l4e_get_pfn(l4e[0]))); + mmfn = _mfn(l4e_get_pfn(l4e[0])); + if ( pv_32bit_guest(v) ) + { + /* Need to destroy the l2 monitor page in slot 3 too */ + l3_pgentry_t *l3e = sh_map_domain_page(mmfn); + ASSERT(l3e_get_flags(l3e[3]) & _PAGE_PRESENT); + shadow_free(d, _mfn(l3e_get_pfn(l3e[3]))); + sh_unmap_domain_page(l3e); + } + shadow_free(d, mmfn); sh_unmap_domain_page(l4e); } #elif CONFIG_PAGING_LEVELS == 3 @@ -3044,12 +3083,15 @@ sh_update_linear_entries(struct vcpu *v) #elif (CONFIG_PAGING_LEVELS == 4) && (SHADOW_PAGING_LEVELS == 3) - /* This case only exists in HVM. To give ourselves a linear map of the - * shadows, we need to extend a PAE shadow to 4 levels. We do this by - * having a monitor l3 in slot 0 of the monitor l4 table, and - * copying the PAE l3 entries into it. Then, by having the monitor l4e - * for shadow pagetables also point to the monitor l4, we can use it - * to access the shadows. */ + /* PV: XXX + * + * HVM: To give ourselves a linear map of the shadows, we need to + * extend a PAE shadow to 4 levels. We do this by having a monitor + * l3 in slot 0 of the monitor l4 table, and copying the PAE l3 + * entries into it. Then, by having the monitor l4e for shadow + * pagetables also point to the monitor l4, we can use it to access + * the shadows. + */ if ( shadow_mode_external(d) ) { @@ -3092,6 +3134,8 @@ sh_update_linear_entries(struct vcpu *v) if ( v != current ) sh_unmap_domain_page(ml3e); } + else + domain_crash(d); /* XXX */ #elif CONFIG_PAGING_LEVELS == 3 @@ -3404,7 +3448,7 @@ sh_update_cr3(struct vcpu *v, int do_locking) (unsigned long)pagetable_get_pfn(v->arch.guest_table)); #if GUEST_PAGING_LEVELS == 4 - if ( !(v->arch.flags & TF_kernel_mode) ) + if ( !(v->arch.flags & TF_kernel_mode) && !IS_COMPAT(v->domain) ) gmfn = pagetable_get_mfn(v->arch.guest_table_user); else #endif diff --git a/xen/include/asm-x86/shadow.h b/xen/include/asm-x86/shadow.h index 68ae3cb011..2afc0b0562 100644 --- a/xen/include/asm-x86/shadow.h +++ b/xen/include/asm-x86/shadow.h @@ -67,6 +67,14 @@ * It is also true for all vcpus of translated PV domains. */ #define shadow_vcpu_mode_translate(_v) ((_v)->arch.shadow.translate_enabled) +/* + * 32on64 support + */ +#ifdef __x86_64__ +#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v) && IS_COMPAT((_v)->domain)) +#else +#define pv_32bit_guest(_v) (!is_hvm_vcpu(_v)) +#endif /****************************************************************************** * With shadow pagetables, the different kinds of address start From b1cf3deb811b8d4cb9c36146f0f5ea046d8f4062 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:34:43 +0000 Subject: [PATCH 098/570] Support for save and restore of compatibility guests Signed-off-by: Emmanuel Ackaouy --- tools/libxc/xc_linux_save.c | 23 ++++++++++++++++++----- tools/libxc/xg_save_restore.h | 9 +++++++++ xen/arch/x86/domctl.c | 5 ++++- xen/include/asm-x86/x86_64/page.h | 2 +- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/tools/libxc/xc_linux_save.c b/tools/libxc/xc_linux_save.c index 44dba99cd5..7ca8453848 100644 --- a/tools/libxc/xc_linux_save.c +++ b/tools/libxc/xc_linux_save.c @@ -44,6 +44,7 @@ static xen_pfn_t *live_p2m = NULL; /* Live mapping of system MFN to PFN table. */ static xen_pfn_t *live_m2p = NULL; +static unsigned long m2p_mfn0; /* grep fodder: machine_to_phys */ @@ -440,13 +441,23 @@ static int canonicalize_pagetable(unsigned long type, unsigned long pfn, ** that this check will fail for other L2s. */ if (pt_levels == 3 && type == XEN_DOMCTL_PFINFO_L2TAB) { + int hstart; + unsigned long he; -/* XXX index of the L2 entry in PAE mode which holds the guest LPT */ -#define PAE_GLPT_L2ENTRY (495) - pte = ((const uint64_t*)spage)[PAE_GLPT_L2ENTRY]; + hstart = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; + he = ((const uint64_t *) spage)[hstart]; - if(((pte >> PAGE_SHIFT) & 0x0fffffff) == live_p2m[pfn]) - xen_start = (hvirt_start >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; + if ( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) { + /* hvirt starts with xen stuff... */ + xen_start = hstart; + } else if ( hvirt_start != 0xf5800000 ) { + /* old L2s from before hole was shrunk... */ + hstart = (0xf5800000 >> L2_PAGETABLE_SHIFT_PAE) & 0x1ff; + he = ((const uint64_t *) spage)[hstart]; + + if( ((he >> PAGE_SHIFT) & 0x0fffffff) == m2p_mfn0 ) + xen_start = hstart; + } } if (pt_levels == 4 && type == XEN_DOMCTL_PFINFO_L4TAB) { @@ -550,6 +561,8 @@ static xen_pfn_t *xc_map_m2p(int xc_handle, return NULL; } + m2p_mfn0 = entries[0].mfn; + free(extent_start); free(entries); diff --git a/tools/libxc/xg_save_restore.h b/tools/libxc/xg_save_restore.h index 00d0753def..6275b37ef0 100644 --- a/tools/libxc/xg_save_restore.h +++ b/tools/libxc/xg_save_restore.h @@ -53,8 +53,17 @@ static int get_platform_info(int xc_handle, uint32_t dom, *hvirt_start = xen_params.virt_start; + /* + * XXX For now, 32bit dom0's can only save/restore 32bit domUs + * on 64bit hypervisors, so no need to check which type of domain + * we're dealing with. + */ if (strstr(xen_caps, "xen-3.0-x86_64")) +#if defined(__i386__) + *pt_levels = 3; +#else *pt_levels = 4; +#endif else if (strstr(xen_caps, "xen-3.0-x86_32p")) *pt_levels = 3; else if (strstr(xen_caps, "xen-3.0-x86_32")) diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index f1b63ffb66..fdc102c1a5 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -356,7 +356,10 @@ void arch_get_info_guest(struct vcpu *v, vcpu_guest_context_u c) c.nat->ctrlreg[3] = xen_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); #ifdef CONFIG_COMPAT else - c.cmp->ctrlreg[3] = compat_pfn_to_cr3(pagetable_get_pfn(v->arch.guest_table)); + { + l4_pgentry_t *l4e = __va(pagetable_get_paddr(v->arch.guest_table)); + c.cmp->ctrlreg[3] = compat_pfn_to_cr3(l4e_get_pfn(*l4e)); + } #endif c(vm_assist = v->domain->vm_assist); diff --git a/xen/include/asm-x86/x86_64/page.h b/xen/include/asm-x86/x86_64/page.h index b1f59b8f13..ecda3a7bf5 100644 --- a/xen/include/asm-x86/x86_64/page.h +++ b/xen/include/asm-x86/x86_64/page.h @@ -96,7 +96,7 @@ typedef l4_pgentry_t root_pgentry_t; #define L3_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) #define L4_DISALLOW_MASK (BASE_DISALLOW_MASK | 0x180U /* must-be-zero */) -#define COMPAT_L3_DISALLOW_MASK 0xFFFFF1E6U /* must-be-zero */ +#define COMPAT_L3_DISALLOW_MASK L3_DISALLOW_MASK #define PAGE_HYPERVISOR (__PAGE_HYPERVISOR | _PAGE_GLOBAL) #define PAGE_HYPERVISOR_NOCACHE (__PAGE_HYPERVISOR_NOCACHE | _PAGE_GLOBAL) From a9e6f2b5310a2e0072e66675691c0590d129aa99 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 5 Jan 2007 17:39:34 +0000 Subject: [PATCH 099/570] [BALLOON] Ifdef some x86-specific balloon init code. Signed-off-by: Keir Fraser --- linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c index b621d76383..d6d3f7640a 100644 --- a/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c +++ b/linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c @@ -446,8 +446,10 @@ static struct notifier_block xenstore_notifier; static int __init balloon_init(void) { +#ifdef CONFIG_X86 unsigned long pfn; struct page *page; +#endif if (!is_running_on_xen()) return -ENODEV; @@ -476,13 +478,15 @@ static int __init balloon_init(void) balloon_pde->write_proc = balloon_write; #endif balloon_sysfs_init(); - + +#ifdef CONFIG_X86 /* Initialise the balloon with excess memory space. */ for (pfn = xen_start_info->nr_pages; pfn < max_pfn; pfn++) { page = pfn_to_page(pfn); if (!PageReserved(page)) balloon_append(page); } +#endif target_watch.callback = watch_target; xenstore_notifier.notifier_call = balloon_init_watcher; From 4b0e8fb306f0ae5eda49f60758880663a897d763 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Fri, 5 Jan 2007 17:51:07 +0000 Subject: [PATCH 100/570] Initial support for HVM compat guests Signed-off-by: Emmanuel Ackaouy --- xen/arch/x86/domain.c | 6 +++++- xen/arch/x86/hvm/intercept.c | 2 +- xen/arch/x86/mm/shadow/multi.c | 1 - xen/arch/x86/x86_64/compat/entry.S | 4 ++-- xen/include/public/hvm/ioreq.h | 5 +++-- 5 files changed, 11 insertions(+), 7 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index acff71b90f..b03824f5ca 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1395,7 +1395,11 @@ void domain_relinquish_resources(struct domain *d) #ifdef CONFIG_COMPAT if ( IS_COMPAT(d) ) { - pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table))); + if ( is_hvm_vcpu(v) ) + pfn = pagetable_get_pfn(v->arch.guest_table); + else + pfn = l4e_get_pfn(*(l4_pgentry_t *)__va(pagetable_get_paddr(v->arch.guest_table))); + if ( pfn != 0 ) { if ( shadow_mode_refcounts(d) ) diff --git a/xen/arch/x86/hvm/intercept.c b/xen/arch/x86/hvm/intercept.c index 4a1e682b5d..3de58812c3 100644 --- a/xen/arch/x86/hvm/intercept.c +++ b/xen/arch/x86/hvm/intercept.c @@ -182,7 +182,7 @@ int hvm_buffered_io_intercept(ioreq_t *p) spin_lock(buffered_io_lock); if ( buffered_iopage->write_pointer - buffered_iopage->read_pointer == - (unsigned long)IOREQ_BUFFER_SLOT_NUM ) { + (unsigned int)IOREQ_BUFFER_SLOT_NUM ) { /* the queue is full. * send the iopacket through the normal path. * NOTE: The arithimetic operation could handle the situation for diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index 56bd93d428..b86b55b085 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -2106,7 +2106,6 @@ void sh_destroy_monitor_table(struct vcpu *v, mfn_t mmfn) shadow_free(d, _mfn(l3e_get_pfn(l3e[3]))); sh_unmap_domain_page(l3e); } - shadow_free(d, mmfn); sh_unmap_domain_page(l4e); } #elif CONFIG_PAGING_LEVELS == 3 diff --git a/xen/arch/x86/x86_64/compat/entry.S b/xen/arch/x86/x86_64/compat/entry.S index bc47636d25..25ea08bacf 100644 --- a/xen/arch/x86/x86_64/compat/entry.S +++ b/xen/arch/x86/x86_64/compat/entry.S @@ -313,7 +313,7 @@ ENTRY(compat_hypercall_table) .quad compat_xenoprof_op .quad do_event_channel_op .quad compat_physdev_op - .quad compat_ni_hypercall + .quad do_hvm_op .quad compat_sysctl /* 35 */ .quad compat_domctl .quad compat_kexec_op @@ -356,7 +356,7 @@ ENTRY(compat_hypercall_args_table) .byte 2 /* compat_xenoprof_op */ .byte 2 /* compat_event_channel_op */ .byte 2 /* compat_physdev_op */ - .byte 0 /* compat_ni_hypercall */ + .byte 2 /* do_hvm_op */ .byte 1 /* compat_sysctl */ /* 35 */ .byte 1 /* compat_domctl */ .byte 2 /* compat_kexec_op */ diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h index 0d3dc3277a..351801a9b2 100644 --- a/xen/include/public/hvm/ioreq.h +++ b/xen/include/public/hvm/ioreq.h @@ -56,6 +56,7 @@ struct ioreq { uint8_t dir:1; /* 1=read, 0=write */ uint8_t df:1; uint8_t type; /* I/O type */ + uint8_t _pad0[6]; uint64_t io_count; /* How many IO done on a vcpu */ }; typedef struct ioreq ioreq_t; @@ -74,8 +75,8 @@ typedef struct shared_iopage shared_iopage_t; #define IOREQ_BUFFER_SLOT_NUM 80 struct buffered_iopage { - unsigned long read_pointer; - unsigned long write_pointer; + unsigned int read_pointer; + unsigned int write_pointer; ioreq_t ioreq[IOREQ_BUFFER_SLOT_NUM]; }; /* sizeof this structure must be in one page */ typedef struct buffered_iopage buffered_iopage_t; From b4270971d58c86f81ff6595c427116bdc258180a Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 5 Jan 2007 18:01:20 +0000 Subject: [PATCH 101/570] [XEN] Fix new XCHG emulation. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 0df20bd961..c0d128cd5e 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -1084,10 +1084,10 @@ x86_emulate( if ( !(rex_prefix & 1) ) break; /* nop */ case 0x91 ... 0x97: /* xchg reg,%%rax */ - src.type = OP_REG; + src.type = dst.type = OP_REG; + src.bytes = dst.bytes = op_bytes; src.reg = (unsigned long *)&_regs.eax; src.val = *src.reg; - dst.type = OP_REG; dst.reg = decode_register( (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); dst.val = dst.orig_val = *dst.reg; From 4d5aa6c3452e14976347c6b821756120a3f37d61 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Fri, 5 Jan 2007 18:17:36 +0000 Subject: [PATCH 102/570] [XEN] Skip over the unit in parse_size_and_unit() when returning the remainder of the string. Signed-off-by: Ian Campbell --- xen/common/lib.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/common/lib.c b/xen/common/lib.c index c8a90b99a7..661f76420d 100644 --- a/xen/common/lib.c +++ b/xen/common/lib.c @@ -454,7 +454,7 @@ unsigned long long parse_size_and_unit(const char *s, const char **ps) case 'K': case 'k': ret <<= 10; case 'B': case 'b': - s++; + s1++; break; default: ret <<= 10; /* default to kB */ From e975e81c9b5dd56d6746cbc395fe93f383eecfd4 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Sat, 6 Jan 2007 11:17:52 +0000 Subject: [PATCH 103/570] [TOOLS] Improve information displayed by the xm sched-credit command. The improvement is as follows. 1. The display form is changed like the xm sched-sedf command. 2. When -d option is omitted, information on all domains is displayed. Examples: # xm sched-credit -d vm1 Name ID Weight Cap vm1 1 512 100 # xm sched-credit Name ID Weight Cap Domain-0 0 256 0 vm1 1 512 100 vm2 2 512 50 Signed-off-by: Masaki Kanno --- tools/python/xen/xm/main.py | 42 +++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/tools/python/xen/xm/main.py b/tools/python/xen/xm/main.py index 3feb864f16..87a0602e2d 100644 --- a/tools/python/xen/xm/main.py +++ b/tools/python/xen/xm/main.py @@ -130,7 +130,7 @@ SUBCOMMAND_HELP = { 'log' : ('', 'Print Xend log'), 'rename' : (' ', 'Rename a domain.'), 'sched-sedf' : (' [options]', 'Get/set EDF parameters.'), - 'sched-credit': ('-d [-w[=WEIGHT]|-c[=CAP]]', + 'sched-credit': ('[-d [-w[=WEIGHT]|-c[=CAP]]]', 'Get/set credit scheduler parameters.'), 'sysrq' : (' ', 'Send a sysrq to a domain.'), 'vcpu-list' : ('[]', @@ -717,6 +717,10 @@ def parse_sedf_info(info): 'weight' : get_info('weight', int, -1), } +def domid_match(domid, info): + return domid is None or domid == info['name'] or \ + domid == str(info['domid']) + def xm_brief_list(doms): print '%-40s %3s %5s %5s %10s %9s' % \ ('Name', 'ID', 'Mem', 'VCPUs', 'State', 'Time(s)') @@ -1091,10 +1095,6 @@ def xm_sched_sedf(args): print( ("%(name)-32s %(domid)3d %(period)9.1f %(slice)9.1f" + " %(latency)7.1f %(extratime)6d %(weight)6d") % info) - def domid_match(domid, info): - return domid is None or domid == info['name'] or \ - domid == str(info['domid']) - # we want to just display current info if no parameters are passed if len(args) == 0: domid = None @@ -1174,27 +1174,43 @@ def xm_sched_credit(args): err(opterr) usage('sched-credit') - domain = None + domid = None weight = None cap = None for o, a in opts: if o == "-d": - domain = a + domid = a elif o == "-w": weight = int(a) elif o == "-c": cap = int(a); - if domain is None: - # place holder for system-wide scheduler parameters - err("No domain given.") - usage('sched-credit') + doms = filter(lambda x : domid_match(domid, x), + [parse_doms_info(dom) + for dom in getDomains(None, 'running')]) if weight is None and cap is None: - print server.xend.domain.sched_credit_get(domain) + # print header if we aren't setting any parameters + print '%-33s %-2s %-6s %-4s' % ('Name','ID','Weight','Cap') + + for d in doms: + try: + info = server.xend.domain.sched_credit_get(d['domid']) + except xmlrpclib.Fault: + # domain does not support sched-credit? + info = {'weight': -1, 'cap': -1} + + info['name'] = d['name'] + info['domid'] = int(d['domid']) + print( ("%(name)-32s %(domid)3d %(weight)6d %(cap)4d") % info) else: - result = server.xend.domain.sched_credit_set(domain, weight, cap) + if domid is None: + # place holder for system-wide scheduler parameters + err("No domain given.") + usage('sched-credit') + + result = server.xend.domain.sched_credit_set(domid, weight, cap) if result != 0: err(str(result)) From 018858d496d869cd227be107c72d38bf2724b119 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Sat, 6 Jan 2007 12:56:58 +0000 Subject: [PATCH 104/570] [PV-on-HVM] Add definition of irq_to_evtchn_port(). Signed-off-by: Keir Fraser --- unmodified_drivers/linux-2.6/platform-pci/evtchn.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c index 7ad340074a..9cf5972f0d 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/evtchn.c +++ b/unmodified_drivers/linux-2.6/platform-pci/evtchn.c @@ -49,6 +49,12 @@ static struct { int close; /* close on unbind_from_irqhandler()? */ } evtchns[MAX_EVTCHN]; +int irq_to_evtchn_port(int irq) +{ + return irq; +} +EXPORT_SYMBOL(irq_to_evtchn_port); + void mask_evtchn(int port) { shared_info_t *s = shared_info_area; From 5abeb42c62a3bcc9fe32955f3a01f069e32d1d69 Mon Sep 17 00:00:00 2001 From: "kaf24@localhost.localdomain" Date: Sat, 6 Jan 2007 15:56:52 +0000 Subject: [PATCH 105/570] [XEN] Emulate MOV imm->reg. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index c0d128cd5e..45ff34bf73 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -111,8 +111,14 @@ static uint8_t opcode_table[256] = { /* 0xA8 - 0xAF */ 0, 0, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 0, 0, - /* 0xB0 - 0xBF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xB0 - 0xB7 */ + ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov, + ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov, + ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov, + ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov, + /* 0xB8 - 0xBF */ + DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, + DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, /* 0xC0 - 0xC7 */ ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0, 0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov, @@ -906,6 +912,19 @@ x86_emulate( goto done; register_address_increment(_regs.esp, dst.bytes); break; + case 0xb0 ... 0xb7: /* mov imm8,r8 */ + dst.reg = decode_register( + (b & 7) | ((rex_prefix & 1) << 3), &_regs, (rex_prefix == 0)); + dst.val = src.val; + break; + case 0xb8 ... 0xbf: /* mov imm{16,32,64},r{16,32,64} */ + if ( dst.bytes == 8 ) /* Fetch more bytes to obtain imm64 */ + src.val = ((uint32_t)src.val | + ((uint64_t)insn_fetch_type(uint32_t) << 32)); + dst.reg = decode_register( + (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); + dst.val = src.val; + break; case 0xc0 ... 0xc1: grp2: /* Grp2 */ switch ( modrm_reg & 7 ) { From 1c86aafefb99e43786e1e88c428507c803519c2a Mon Sep 17 00:00:00 2001 From: Christian Limpach Date: Mon, 8 Jan 2007 11:33:45 +0000 Subject: [PATCH 106/570] [linux build] Build Linux kernels with output files in a separate directory. Use a single source tree (linux-2.6-xen) and use Linux' O= option to make the build put output files in a build-linux-$(LINUX_VER)-$(EXTRAVERSION)_$(XEN_TARGET_ARCH) directory, making it possible to build both x86_32 and x86_64 kernels in the same tree. Signed-off-by: Christian Limpach --- .hgignore | 1 + buildconfigs/mk.linux-2.6-xen | 30 +++++++++++++++++++----------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/.hgignore b/.hgignore index d4127b6d1f..d89639242d 100644 --- a/.hgignore +++ b/.hgignore @@ -20,6 +20,7 @@ ^\.config$ ^TAGS$ ^tags$ +^build.*$ ^dist/.*$ ^docs/.*\.aux$ ^docs/.*\.dvi$ diff --git a/buildconfigs/mk.linux-2.6-xen b/buildconfigs/mk.linux-2.6-xen index 9a1e47a332..d1ec6afe12 100644 --- a/buildconfigs/mk.linux-2.6-xen +++ b/buildconfigs/mk.linux-2.6-xen @@ -3,7 +3,8 @@ LINUX_VER = 2.6.16.33 EXTRAVERSION ?= xen -LINUX_DIR = linux-$(LINUX_VER)-$(EXTRAVERSION) +LINUX_SRCDIR = linux-$(LINUX_VER)-xen +LINUX_DIR = build-linux-$(LINUX_VER)-$(EXTRAVERSION)_$(XEN_TARGET_ARCH) IMAGE_TARGET ?= vmlinuz INSTALL_BOOT_PATH ?= $(DESTDIR) @@ -23,24 +24,30 @@ build: $(LINUX_DIR)/include/linux/autoconf.h mkdir -p $(INSTALL_BOOT_PATH) $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) INSTALL_PATH=$(INSTALL_BOOT_PATH) install -$(LINUX_DIR)/include/linux/autoconf.h: ref-linux-$(LINUX_VER)/.valid-ref - rm -rf $(LINUX_DIR) - cp -al $(Mk.tmp ; \ + rm -f Makefile ; mv Mk.tmp Makefile ) + touch $@ + +$(LINUX_DIR)/include/linux/autoconf.h: $(LINUX_SRCDIR)/.valid-src + rm -rf $(LINUX_DIR) + mkdir -p $(LINUX_DIR) # Re-use config from install dir if one exits else use default config - CONFIG_VERSION=$$(sed -ne 's/^EXTRAVERSION = //p' $(LINUX_DIR)/Makefile); \ + CONFIG_VERSION=$$(sed -ne 's/$$(XENGUEST)//; s/^EXTRAVERSION = //p' $(LINUX_SRCDIR)/Makefile); \ [ -r $(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION-$(EXTRAVERSION) ] && \ cp $(DESTDIR)/boot/config-$(LINUX_VER3)$$CONFIG_VERSION-$(EXTRAVERSION) $(LINUX_DIR)/.config \ || sh buildconfigs/create_config.sh $(LINUX_DIR)/.config $(EXTRAVERSION) $(XEN_TARGET_ARCH) $(XEN_SYSTYPE) # See if we need to munge config to enable PAE $(MAKE) CONFIG_FILE=$(LINUX_DIR)/.config -f buildconfigs/Rules.mk config-update-pae - # Patch kernel Makefile to set EXTRAVERSION - ( cd $(LINUX_DIR) ; \ - sed -e 's/^EXTRAVERSION.*/&$$(XENGUEST)\nXENGUEST = -$(EXTRAVERSION)/' Makefile >Mk.tmp ; \ - rm -f Makefile ; mv Mk.tmp Makefile ) - $(MAKE) -C $(LINUX_DIR) ARCH=$(LINUX_ARCH) oldconfig + echo "-$(EXTRAVERSION)" >$(LINUX_DIR)/.xenguest + $(MAKE) -C $(LINUX_SRCDIR) ARCH=$(LINUX_ARCH) oldconfig O=$$(/bin/pwd)/$(LINUX_DIR) .PHONY: prep prep: $(LINUX_DIR)/include/linux/autoconf.h @@ -62,4 +69,5 @@ delete: .PHONY: mrpropper mrpropper: + rm -rf $(LINUX_SRCDIR) rm -f linux-$(LINUX_VER).tar.bz2 From ba0f039582de3f7556b2c75f5f022084a75dc238 Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Mon, 8 Jan 2007 14:24:30 +0000 Subject: [PATCH 107/570] [HVM] Add expansion-ROM boot support again. Boot info now stored at 0x9ff00; registers saved in HDD load code. Signed-off-by: Tim Deegan --- tools/firmware/rombios/rombios.c | 457 ++++++++++++++++++++----------- tools/ioemu/hw/pc.c | 2 + tools/ioemu/vl.c | 2 +- 3 files changed, 297 insertions(+), 164 deletions(-) diff --git a/tools/firmware/rombios/rombios.c b/tools/firmware/rombios/rombios.c index edbc0cc528..34f7d78062 100644 --- a/tools/firmware/rombios/rombios.c +++ b/tools/firmware/rombios/rombios.c @@ -278,7 +278,6 @@ typedef unsigned short Bit16u; typedef unsigned short bx_bool; typedef unsigned long Bit32u; -#if BX_USE_ATADRV void memsetb(seg,offset,value,count); void memcpyb(dseg,doffset,sseg,soffset,count); @@ -418,7 +417,6 @@ typedef unsigned long Bit32u; ASM_END } #endif -#endif //BX_USE_ATADRV // read_dword and write_dword functions static Bit32u read_dword(); @@ -728,6 +726,8 @@ typedef struct { // The EBDA structure should conform to // http://www.cybertrails.com/~fys/rombios.htm document // I made the ata and cdemu structs begin at 0x121 in the EBDA seg + // EBDA must be at most 768 bytes; it lives at 0x9fc00, and the boot + // device tables are at 0x9ff00 -- 0x9ffff typedef struct { unsigned char filler1[0x3D]; @@ -885,7 +885,7 @@ static void int14_function(); static void int15_function(); static void int16_function(); static void int17_function(); -static Bit32u int19_function(); +static void int19_function(); static void int1a_function(); static void int70_function(); static void int74_function(); @@ -1854,28 +1854,100 @@ print_bios_banner() printf("\n"); } + +//-------------------------------------------------------------------------- +// BIOS Boot Specification 1.0.1 compatibility +// +// Very basic support for the BIOS Boot Specification, which allows expansion +// ROMs to register themselves as boot devices, instead of just stealing the +// INT 19h boot vector. +// +// This is a hack: to do it properly requires a proper PnP BIOS and we aren't +// one; we just lie to the option ROMs to make them behave correctly. +// We also don't support letting option ROMs register as bootable disk +// drives (BCVs), only as bootable devices (BEVs). +// +// http://www.phoenix.com/en/Customer+Services/White+Papers-Specs/pc+industry+specifications.htm +//-------------------------------------------------------------------------- + +/* 256 bytes at 0x9ff00 -- 0x9ffff is used for the IPL boot table. */ +#define IPL_SEG 0x9ff0 +#define IPL_TABLE_OFFSET 0x0000 +#define IPL_TABLE_ENTRIES 8 +#define IPL_COUNT_OFFSET 0x0080 /* u16: number of valid table entries */ +#define IPL_SEQUENCE_OFFSET 0x0082 /* u16: next boot device */ + +struct ipl_entry { + Bit16u type; + Bit16u flags; + Bit32u vector; + Bit32u description; + Bit32u reserved; +}; + +static void +init_boot_vectors() +{ + struct ipl_entry e; + Bit16u count = 0; + Bit16u ss = get_SS(); + + /* Clear out the IPL table. */ + memsetb(IPL_SEG, IPL_TABLE_OFFSET, 0, 0xff); + + /* Floppy drive */ + e.type = 1; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; + memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); + count++; + + /* First HDD */ + e.type = 2; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; + memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); + count++; + +#if BX_ELTORITO_BOOT + /* CDROM */ + e.type = 3; e.flags = 0; e.vector = 0; e.description = 0; e.reserved = 0; + memcpyb(IPL_SEG, IPL_TABLE_OFFSET + count * sizeof (e), ss, &e, sizeof (e)); + count++; +#endif + + /* Remember how many devices we have */ + write_word(IPL_SEG, IPL_COUNT_OFFSET, count); + /* Not tried booting anything yet */ + write_word(IPL_SEG, IPL_SEQUENCE_OFFSET, 0xffff); +} + +static Bit8u +get_boot_vector(i, e) +Bit16u i; struct ipl_entry *e; +{ + Bit16u count; + Bit16u ss = get_SS(); + /* Get the count of boot devices, and refuse to overrun the array */ + count = read_word(IPL_SEG, IPL_COUNT_OFFSET); + if (i >= count) return 0; + /* OK to read this device */ + memcpyb(ss, e, IPL_SEG, IPL_TABLE_OFFSET + i * sizeof (*e), sizeof (*e)); + return 1; +} + + //-------------------------------------------------------------------------- // print_boot_device // displays the boot device //-------------------------------------------------------------------------- -static char drivetypes[][10]={"Floppy","Hard Disk","CD-Rom"}; +static char drivetypes[][10]={"", "Floppy","Hard Disk","CD-Rom", "Network"}; void -print_boot_device(cdboot, drive) - Bit8u cdboot; Bit16u drive; +print_boot_device(type) + Bit16u type; { - Bit8u i; - - // cdboot contains 0 if floppy/harddisk, 1 otherwise - // drive contains real/emulated boot drive - - if(cdboot)i=2; // CD-Rom - else if((drive&0x0080)==0x00)i=0; // Floppy - else if((drive&0x0080)==0x80)i=1; // Hard drive - else return; - - printf("Booting from %s...\n",drivetypes[i]); + /* NIC appears as type 0x80 */ + if (type == 0x80 ) type = 0x4; + if (type == 0 || type > 0x4) BX_PANIC("Bad drive type\n"); + printf("Booting from %s...\n", drivetypes[type]); } //-------------------------------------------------------------------------- @@ -1883,29 +1955,20 @@ print_boot_device(cdboot, drive) // displays the reason why boot failed //-------------------------------------------------------------------------- void -print_boot_failure(cdboot, drive, reason, lastdrive) - Bit8u cdboot; Bit8u drive; Bit8u lastdrive; +print_boot_failure(type, reason) + Bit16u type; Bit8u reason; { - Bit16u drivenum = drive&0x7f; + if (type == 0 || type > 0x3) BX_PANIC("Bad drive type\n"); - // cdboot: 1 if boot from cd, 0 otherwise - // drive : drive number - // reason: 0 signature check failed, 1 read error - // lastdrive: 1 boot drive is the last one in boot sequence - - if (cdboot) - bios_printf(BIOS_PRINTF_INFO | BIOS_PRINTF_SCREEN, "Boot from %s failed\n",drivetypes[2]); - else if (drive & 0x80) - bios_printf(BIOS_PRINTF_INFO | BIOS_PRINTF_SCREEN, "Boot from %s %d failed\n", drivetypes[1],drivenum); + printf("Boot from %s failed", drivetypes[type]); + if (type < 4) { + /* Report the reason too */ + if (reason==0) + printf(": not a bootable disk"); else - bios_printf(BIOS_PRINTF_INFO | BIOS_PRINTF_SCREEN, "Boot from %s %d failed\n", drivetypes[0],drivenum); - - if (lastdrive==1) { - if (reason==0) - BX_PANIC("Not a bootable disk\n"); - else - BX_PANIC("Could not read the boot disk\n"); + printf(": could not read the boot disk"); } + printf("\n"); } //-------------------------------------------------------------------------- @@ -7553,19 +7616,19 @@ int17_function(regs, ds, iret_addr) } } -// returns bootsegment in ax, drive in bl - Bit32u -int19_function(bseqnr) -Bit8u bseqnr; +void +int19_function(seq_nr) +Bit16u seq_nr; { Bit16u ebda_seg=read_word(0x0040,0x000E); - Bit16u bootseq; + Bit16u bootdev; Bit8u bootdrv; - Bit8u bootcd; Bit8u bootchk; Bit16u bootseg; + Bit16u bootip; Bit16u status; - Bit8u lastdrive=0; + + struct ipl_entry e; // if BX_ELTORITO_BOOT is not defined, old behavior // check bit 5 in CMOS reg 0x2d. load either 0x00 or 0x80 into DL @@ -7582,62 +7645,54 @@ Bit8u bseqnr; // 0x01 : first floppy // 0x02 : first harddrive // 0x03 : first cdrom + // 0x04 - 0x0f : PnP expansion ROMs (e.g. Etherboot) // else : boot failure // Get the boot sequence #if BX_ELTORITO_BOOT - bootseq=inb_cmos(0x3d); - bootseq|=((inb_cmos(0x38) & 0xf0) << 4); + bootdev = inb_cmos(0x3d); + bootdev |= ((inb_cmos(0x38) & 0xf0) << 4); + bootdev >>= 4 * seq_nr; + bootdev &= 0xf; + if (bootdev == 0) BX_PANIC("No bootable device.\n"); + + /* Translate from CMOS runes to an IPL table offset by subtracting 1 */ + bootdev -= 1; +#else + if (seq_nr ==2) BX_PANIC("No more boot devices."); + if (!!(inb_cmos(0x2d) & 0x20) ^ (seq_nr == 1)) + /* Boot from floppy if the bit is set or it's the second boot */ + bootdev = 0x00; + else + bootdev = 0x01; +#endif - if (bseqnr==2) bootseq >>= 4; - if (bseqnr==3) bootseq >>= 8; - if (bootseq<0x10) lastdrive = 1; - bootdrv=0x00; bootcd=0; - switch(bootseq & 0x0f) { - case 0x01: bootdrv=0x00; bootcd=0; break; - case 0x02: bootdrv=0x80; bootcd=0; break; - case 0x03: bootdrv=0x00; bootcd=1; break; - default: return 0x00000000; - } -#else - bootseq=inb_cmos(0x2d); - - if (bseqnr==2) { - bootseq ^= 0x20; - lastdrive = 1; + /* Read the boot device from the IPL table */ + if (get_boot_vector(bootdev, &e) == 0) { + BX_INFO("Invalid boot device (0x%x)\n", bootdev); + return; } - bootdrv=0x00; bootcd=0; - if((bootseq&0x20)==0) bootdrv=0x80; -#endif // BX_ELTORITO_BOOT -#if BX_ELTORITO_BOOT - // We have to boot from cd - if (bootcd != 0) { - status = cdrom_boot(); + /* Do the loading, and set up vector as a far pointer to the boot + * address, and bootdrv as the boot drive */ + print_boot_device(e.type); - // If failure - if ( (status & 0x00ff) !=0 ) { - print_cdromboot_failure(status); - print_boot_failure(bootcd, bootdrv, 1, lastdrive); - return 0x00000000; - } + switch(e.type) { + case 0x01: /* FDD */ + case 0x02: /* HDD */ - bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment); - bootdrv = (Bit8u)(status>>8); - } - -#endif // BX_ELTORITO_BOOT - - // We have to boot from harddisk or floppy - if (bootcd == 0) { - bootseg=0x07c0; + bootdrv = (e.type == 0x02) ? 0x80 : 0x00; + bootseg = 0x07c0; + status = 0; ASM_START push bp mov bp, sp + push ax + push bx + push cx + push dx - mov ax, #0x0000 - mov _int19_function.status + 2[bp], ax mov dl, _int19_function.bootdrv + 2[bp] mov ax, _int19_function.bootseg + 2[bp] mov es, ax ;; segment @@ -7653,43 +7708,83 @@ ASM_START mov _int19_function.status + 2[bp], ax int19_load_done: + pop dx + pop cx + pop bx + pop ax pop bp ASM_END if (status != 0) { - print_boot_failure(bootcd, bootdrv, 1, lastdrive); - return 0x00000000; + print_boot_failure(e.type, 1); + return; + } + + /* Always check the signature on a HDD boot sector; on FDD, only do + * the check if the CMOS doesn't tell us to skip it */ + if (e.type != 0x00 || !((inb_cmos(0x38) & 0x01))) { + if (read_word(bootseg,0x1fe) != 0xaa55) { + print_boot_failure(e.type, 0); + return; } } - // check signature if instructed by cmos reg 0x38, only for floppy - // bootchk = 1 : signature check disabled - // bootchk = 0 : signature check enabled - if (bootdrv != 0) bootchk = 0; - else bootchk = inb_cmos(0x38) & 0x01; + /* Canonicalize bootseg:bootip */ + bootip = (bootseg & 0x0fff) << 4; + bootseg &= 0xf000; + break; #if BX_ELTORITO_BOOT - // if boot from cd, no signature check - if (bootcd != 0) - bootchk = 1; -#endif // BX_ELTORITO_BOOT + case 0x03: /* CD-ROM */ + status = cdrom_boot(); - if (bootchk == 0) { - if (read_word(bootseg,0x1fe) != 0xaa55) { - print_boot_failure(bootcd, bootdrv, 0, lastdrive); - return 0x00000000; - } + // If failure + if ( (status & 0x00ff) !=0 ) { + print_cdromboot_failure(status); + print_boot_failure(e.type, 1); + return; } + + bootdrv = (Bit8u)(status>>8); + bootseg = read_word(ebda_seg,&EbdaData->cdemu.load_segment); + /* Canonicalize bootseg:bootip */ + bootip = (bootseg & 0x0fff) << 4; + bootseg &= 0xf000; + break; +#endif + + case 0x80: /* Expansion ROM with a Bootstrap Entry Vector (a far pointer) */ + bootseg = e.vector >> 16; + bootip = e.vector & 0xffff; + break; + + default: return; + } + + /* Debugging info */ + printf("Booting from %x:%x\n", bootseg, bootip); -#if BX_ELTORITO_BOOT - // Print out the boot string - print_boot_device(bootcd, bootdrv); -#else // BX_ELTORITO_BOOT - print_boot_device(0, bootdrv); -#endif // BX_ELTORITO_BOOT - - // return the boot segment - return (((Bit32u)bootdrv) << 16) + bootseg; + /* Jump to the boot vector */ +ASM_START + mov bp, sp + ;; Build an iret stack frame that will take us to the boot vector. + ;; iret pops ip, then cs, then flags, so push them in the opposite order. + pushf + mov ax, _int19_function.bootseg + 0[bp] + push ax + mov ax, _int19_function.bootip + 0[bp] + push ax + ;; Set the magic number in ax and the boot drive in dl. + mov ax, #0xaa55 + mov dl, _int19_function.bootdrv + 0[bp] + ;; Zero some of the other registers. + xor bx, bx + mov ds, bx + mov es, bx + mov bp, bx + ;; Go! + iret +ASM_END } void @@ -8146,14 +8241,29 @@ int13_out: popa iret - ;---------- ;- INT18h - ;---------- -int18_handler: ;; Boot Failure routing - call _int18_panic_msg - hlt - iret +int18_handler: ;; Boot Failure recovery: try the next device. + + ;; Reset SP and SS + mov ax, #0xfffe + mov sp, ax + xor ax, ax + mov ss, ax + + ;; Get the boot sequence number out of the IPL memory + mov bx, #IPL_SEG + mov ds, bx ;; Set segment + mov bx, IPL_SEQUENCE_OFFSET ;; BX is now the sequence number + inc bx ;; ++ + mov IPL_SEQUENCE_OFFSET, bx ;; Write it back + mov ds, ax ;; and reset the segment to zero. + + ;; Carry on in the INT 19h handler, using the new sequence number + push bx + + jmp int19_next_boot ;---------- ;- INT19h - @@ -8161,62 +8271,32 @@ int18_handler: ;; Boot Failure routing int19_relocated: ;; Boot function, relocated ;; int19 was beginning to be really complex, so now it - ;; just calls an C function, that does the work - ;; it returns in BL the boot drive, and in AX the boot segment - ;; the boot segment will be 0x0000 if something has failed + ;; just calls a C function that does the work push bp mov bp, sp - - ;; drop ds + + ;; Reset SS and SP + mov ax, #0xfffe + mov sp, ax xor ax, ax - mov ds, ax + mov ss, ax + + ;; Start from the first boot device (0, in AX) + mov bx, #IPL_SEG + mov ds, bx ;; Set segment to write to the IPL memory + mov IPL_SEQUENCE_OFFSET, ax ;; Save the sequence number + mov ds, ax ;; and reset the segment. - ;; 1st boot device - mov ax, #0x0001 push ax + +int19_next_boot: + + ;; Call the C code for the next boot device call _int19_function - inc sp - inc sp - ;; bl contains the boot drive - ;; ax contains the boot segment or 0 if failure - test ax, ax ;; if ax is 0 try next boot device - jnz boot_setup - - ;; 2nd boot device - mov ax, #0x0002 - push ax - call _int19_function - inc sp - inc sp - test ax, ax ;; if ax is 0 try next boot device - jnz boot_setup - - ;; 3rd boot device - mov ax, #0x0003 - push ax - call _int19_function - inc sp - inc sp - test ax, ax ;; if ax is 0 call int18 - jz int18_handler - -boot_setup: - mov dl, bl ;; set drive so guest os find it - shl eax, #0x04 ;; convert seg to ip - mov 2[bp], ax ;; set ip - - shr eax, #0x04 ;; get cs back - and ax, #0xF000 ;; remove what went in ip - mov 4[bp], ax ;; set cs - xor ax, ax - mov es, ax ;; set es to zero fixes [ 549815 ] - mov [bp], ax ;; set bp to zero - mov ax, #0xaa55 ;; set ok flag - - pop bp - iret ;; Beam me up Scotty + ;; Boot failed: invoke the boot recovery function + int #0x18 ;---------- ;- INT1Ch - @@ -9394,6 +9474,15 @@ checksum_loop: pop ax ret + +;; We need a copy of this string, but we are not actually a PnP BIOS, +;; so make sure it is *not* aligned, so OSes will not see it if they scan. +.align 16 + db 0 +pnp_string: + .ascii "$PnP" + + rom_scan: ;; Scan for existence of valid expansion ROMS. ;; Video ROM: from 0xC0000..0xC7FFF in 2k increments @@ -9428,9 +9517,17 @@ block_count_rounded: xor bx, bx ;; Restore DS back to 0000: mov ds, bx push ax ;; Save AX + push di ;; Save DI ;; Push addr of ROM entry point push cx ;; Push seg push #0x0003 ;; Push offset + + ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS. + ;; That should stop it grabbing INT 19h; we will use its BEV instead. + mov ax, #0xf000 + mov es, ax + lea di, pnp_string + mov bp, sp ;; Call ROM init routine using seg:off on stack db 0xff ;; call_far ss:[bp+0] db 0x5e @@ -9438,6 +9535,38 @@ block_count_rounded: cli ;; In case expansion ROM BIOS turns IF on add sp, #2 ;; Pop offset value pop cx ;; Pop seg value (restore CX) + + ;; Look at the ROM's PnP Expansion header. Properly, we're supposed + ;; to init all the ROMs and then go back and build an IPL table of + ;; all the bootable devices, but we can get away with one pass. + mov ds, cx ;; ROM base + mov bx, 0x001a ;; 0x1A is the offset into ROM header that contains... + mov ax, [bx] ;; the offset of PnP expansion header, where... + cmp ax, #0x5024 ;; we look for signature "$PnP" + jne no_bev + mov ax, 2[bx] + cmp ax, #0x506e + jne no_bev + mov ax, 0x1a[bx] ;; 0x1A is also the offset into the expansion header of... + cmp ax, #0x0000 ;; the Bootstrap Entry Vector, or zero if there is none. + je no_bev + + ;; Found a device that thinks it can boot the system. Record its BEV. + mov bx, #IPL_SEG ;; Go to the segment where the IPL table lives + mov ds, bx + mov bx, IPL_COUNT_OFFSET ;; Read the number of entries so far + cmp bx, #IPL_TABLE_ENTRIES + je no_bev ;; Get out if the table is full + shl bx, #0x4 ;; Turn count into offset (entries are 16 bytes) + mov 0[bx], #0x80 ;; This entry is a BEV device + mov 6[bx], cx ;; Build a far pointer from the segment... + mov 4[bx], ax ;; and the offset + shr bx, #0x4 ;; Turn the offset back into a count + inc bx ;; We have one more entry now + mov IPL_COUNT_OFFSET, bx ;; Remember that. + +no_bev: + pop di ;; Restore DI pop ax ;; Restore AX rom_scan_increment: shl ax, #5 ;; convert 512-bytes blocks to 16-byte increments @@ -9771,6 +9900,8 @@ post_default_ints: call smbios_init #endif + call _init_boot_vectors + call rom_scan call _print_bios_banner diff --git a/tools/ioemu/hw/pc.c b/tools/ioemu/hw/pc.c index 234c4722bb..1a686515a7 100644 --- a/tools/ioemu/hw/pc.c +++ b/tools/ioemu/hw/pc.c @@ -168,6 +168,8 @@ static int get_bios_disk(char *boot_device, int index) { return 0x02; /* hard drive */ case 'd': return 0x03; /* cdrom */ + case 'n': + return 0x04; /* network */ } } return 0x00; /* no device */ diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c index 6fc10c8187..573687a08d 100644 --- a/tools/ioemu/vl.c +++ b/tools/ioemu/vl.c @@ -6153,7 +6153,7 @@ int main(int argc, char **argv) case QEMU_OPTION_boot: boot_device = strdup(optarg); if (strspn(boot_device, "acd" -#ifdef TARGET_SPARC +#if defined(TARGET_SPARC) || defined(TARGET_I386) "n" #endif ) != strlen(boot_device)) { From ad7e6bfecb191c267c57c719c3bfdfe2a3a4ffdf Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Mon, 8 Jan 2007 14:24:42 +0000 Subject: [PATCH 108/570] Update .hgignore --- .hgignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.hgignore b/.hgignore index d89639242d..0e77280f96 100644 --- a/.hgignore +++ b/.hgignore @@ -206,6 +206,7 @@ ^xen/ddb/.*$ ^xen/include/asm$ ^xen/include/asm-.*/asm-offsets\.h$ +^xen/include/compat/.*$ ^xen/include/hypervisor-ifs/arch$ ^xen/include/public/public$ ^xen/include/xen/.*\.new$ From a6004eb295d3856d6c729f482c760884d50bfbbe Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Mon, 8 Jan 2007 14:25:28 +0000 Subject: [PATCH 109/570] Fix signedness issue in private implementation of memmem(). Signed-off-by: Alex Williamson --- xen/tools/symbols.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xen/tools/symbols.c b/xen/tools/symbols.c index 00f1a43037..c21e012206 100644 --- a/xen/tools/symbols.c +++ b/xen/tools/symbols.c @@ -353,7 +353,7 @@ static void build_initial_tok_table(void) static void *memmem_pvt(void *h, size_t hlen, void *n, size_t nlen) { char *p; - for (p = h; (p - (char *)h) <= (hlen - nlen); p++) + for (p = h; (p - (char *)h) <= (long)(hlen - nlen); p++) if (!memcmp(p, n, nlen)) return p; return NULL; } From e1e72012670b331fbc522c3fe3ff7765f5deaae1 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Mon, 8 Jan 2007 15:52:53 +0000 Subject: [PATCH 110/570] [XEN] Emulate relative near/short jumps, including Jcc. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 219 ++++++++++++++++++++++++++++--------- 1 file changed, 167 insertions(+), 52 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 45ff34bf73..5c85b9ff13 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -88,8 +88,12 @@ static uint8_t opcode_table[256] = { /* 0x60 - 0x6F */ 0, 0, 0, DstReg|SrcMem32|ModRM|Mov /* movsxd (x86/64) */, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x70 - 0x7F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x70 - 0x77 */ + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + /* 0x78 - 0x7F */ + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0x80 - 0x87 */ ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImm|ModRM, ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, @@ -130,8 +134,10 @@ static uint8_t opcode_table[256] = { 0, 0, 0, 0, /* 0xD8 - 0xDF */ 0, 0, 0, 0, 0, 0, 0, 0, - /* 0xE0 - 0xEF */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0xE0 - 0xE7 */ + 0, 0, 0, ImplicitOps, 0, 0, 0, 0, + /* 0xE8 - 0xEF */ + 0, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, /* 0xF0 - 0xF7 */ 0, 0, 0, 0, 0, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM, @@ -165,8 +171,12 @@ static uint8_t twobyte_table[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x7F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - /* 0x80 - 0x8F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x80 - 0x87 */ + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + /* 0x88 - 0x8F */ + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0x90 - 0x9F */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xA0 - 0xA7 */ @@ -380,31 +390,82 @@ do{ __asm__ __volatile__ ( \ /* Fetch next part of the instruction being emulated. */ #define insn_fetch_bytes(_size) \ -({ unsigned long _x; \ - rc = ops->insn_fetch(x86_seg_cs, _regs.eip, &_x, (_size), ctxt); \ +({ unsigned long _x, _eip = _truncate_ea(_regs.eip, def_ad_bytes); \ + rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt); \ if ( rc != 0 ) \ goto done; \ - _regs.eip += (_size); \ + _register_address_increment(_regs.eip, (_size), def_ad_bytes); \ _x; \ }) #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type))) -#define truncate_ea(ea) \ +#define _truncate_ea(ea, byte_width) \ ({ unsigned long __ea = (ea); \ - ((ad_bytes == sizeof(unsigned long)) ? __ea : \ - (__ea & ((1UL << (ad_bytes << 3)) - 1))); \ + (((byte_width) == sizeof(unsigned long)) ? __ea : \ + (__ea & ((1UL << ((byte_width) << 3)) - 1))); \ }) +#define truncate_ea(ea) _truncate_ea((ea), ad_bytes) /* Update address held in a register, based on addressing mode. */ -#define register_address_increment(reg, inc) \ +#define _register_address_increment(reg, inc, byte_width) \ do { \ int _inc = (inc); /* signed type ensures sign extension to long */ \ - if ( ad_bytes == sizeof(unsigned long) ) \ + if ( (byte_width) == sizeof(unsigned long) ) \ (reg) += _inc; \ + else if ( mode == X86EMUL_MODE_PROT64 ) \ + (reg) = ((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1); \ else \ - (reg) = ((reg) & ~((1UL << (ad_bytes << 3)) - 1)) | \ - (((reg) + _inc) & ((1UL << (ad_bytes << 3)) - 1)); \ + (reg) = ((reg) & ~((1UL << ((byte_width) << 3)) - 1)) | \ + (((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1)); \ } while (0) +#define register_address_increment(reg, inc) \ + _register_address_increment((reg), (inc), ad_bytes) + +#define jmp_rel(rel) \ +do { \ + _regs.eip += (int)(rel); \ + if ( mode != X86EMUL_MODE_PROT64 ) \ + _regs.eip = ((op_bytes == 2) \ + ? (uint16_t)_regs.eip : (uint32_t)_regs.eip); \ +} while (0) + +static int +test_cc( + unsigned int condition, unsigned int flags) +{ + int rc = 0; + + switch ( (condition & 15) >> 1 ) + { + case 0: /* o */ + rc |= (flags & EFLG_OF); + break; + case 1: /* b/c/nae */ + rc |= (flags & EFLG_CF); + break; + case 2: /* z/e */ + rc |= (flags & EFLG_ZF); + break; + case 3: /* be/na */ + rc |= (flags & (EFLG_CF|EFLG_ZF)); + break; + case 4: /* s */ + rc |= (flags & EFLG_SF); + break; + case 5: /* p/pe */ + rc |= (flags & EFLG_PF); + break; + case 7: /* le/ng */ + rc |= (flags & EFLG_ZF); + /* fall through */ + case 6: /* l/nge */ + rc |= (!(flags & EFLG_SF) != !(flags & EFLG_OF)); + break; + } + + /* Odd condition identifiers (lsb == 1) have inverted sense. */ + return (!!rc ^ (condition & 1)); +} void * decode_register( @@ -456,7 +517,8 @@ x86_emulate( uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0; uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; - unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; + unsigned int op_bytes, ad_bytes, def_ad_bytes; + unsigned int lock_prefix = 0, rep_prefix = 0, i; int rc = 0; struct operand src, dst; int mode = ctxt->mode; @@ -473,21 +535,23 @@ x86_emulate( { case X86EMUL_MODE_REAL: case X86EMUL_MODE_PROT16: - op_bytes = ad_bytes = 2; + op_bytes = def_ad_bytes = 2; break; case X86EMUL_MODE_PROT32: - op_bytes = ad_bytes = 4; + op_bytes = def_ad_bytes = 4; break; #ifdef __x86_64__ case X86EMUL_MODE_PROT64: op_bytes = 4; - ad_bytes = 8; + def_ad_bytes = 8; break; #endif default: return -1; } + ad_bytes = def_ad_bytes; + /* Prefix bytes. */ for ( i = 0; i < 8; i++ ) { @@ -820,53 +884,62 @@ x86_emulate( case 0x00 ... 0x03: add: /* add */ emulate_2op_SrcV("add", src, dst, _regs.eflags); break; + case 0x0c ... 0x0d: /* or imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; dst.val = dst.orig_val = _regs.eax; case 0x08 ... 0x0b: or: /* or */ emulate_2op_SrcV("or", src, dst, _regs.eflags); break; + case 0x14 ... 0x15: /* adc imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; dst.val = dst.orig_val = _regs.eax; case 0x10 ... 0x13: adc: /* adc */ emulate_2op_SrcV("adc", src, dst, _regs.eflags); break; + case 0x1c ... 0x1d: /* sbb imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; dst.val = dst.orig_val = _regs.eax; case 0x18 ... 0x1b: sbb: /* sbb */ emulate_2op_SrcV("sbb", src, dst, _regs.eflags); break; + case 0x24 ... 0x25: /* and imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; dst.val = dst.orig_val = _regs.eax; case 0x20 ... 0x23: and: /* and */ emulate_2op_SrcV("and", src, dst, _regs.eflags); break; + case 0x2c ... 0x2d: /* sub imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; dst.val = dst.orig_val = _regs.eax; case 0x28 ... 0x2b: sub: /* sub */ emulate_2op_SrcV("sub", src, dst, _regs.eflags); break; + case 0x34 ... 0x35: /* xor imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; dst.val = dst.orig_val = _regs.eax; case 0x30 ... 0x33: xor: /* xor */ emulate_2op_SrcV("xor", src, dst, _regs.eflags); break; + case 0x3c ... 0x3d: /* cmp imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; dst.val = dst.orig_val = _regs.eax; case 0x38 ... 0x3b: cmp: /* cmp */ emulate_2op_SrcV("cmp", src, dst, _regs.eflags); break; + case 0x63: /* movsxd */ if ( mode != X86EMUL_MODE_PROT64 ) goto cannot_emulate; dst.val = (int32_t)src.val; break; + case 0x80 ... 0x83: /* Grp1 */ switch ( modrm_reg & 7 ) { @@ -880,9 +953,11 @@ x86_emulate( case 7: goto cmp; } break; + case 0x84 ... 0x85: test: /* test */ emulate_2op_SrcV("test", src, dst, _regs.eflags); break; + case 0x86 ... 0x87: xchg: /* xchg */ /* Write back the register source. */ switch ( dst.bytes ) @@ -896,13 +971,16 @@ x86_emulate( dst.val = src.val; lock_prefix = 1; break; + case 0x88 ... 0x8b: /* mov */ case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ dst.val = src.val; break; + case 0x8d: /* lea */ dst.val = ea.mem.off; break; + case 0x8f: /* pop (sole member of Grp1a) */ /* 64-bit mode: POP defaults to a 64-bit operand. */ if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) @@ -912,11 +990,13 @@ x86_emulate( goto done; register_address_increment(_regs.esp, dst.bytes); break; + case 0xb0 ... 0xb7: /* mov imm8,r8 */ dst.reg = decode_register( (b & 7) | ((rex_prefix & 1) << 3), &_regs, (rex_prefix == 0)); dst.val = src.val; break; + case 0xb8 ... 0xbf: /* mov imm{16,32,64},r{16,32,64} */ if ( dst.bytes == 8 ) /* Fetch more bytes to obtain imm64 */ src.val = ((uint32_t)src.val | @@ -925,6 +1005,7 @@ x86_emulate( (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); dst.val = src.val; break; + case 0xc0 ... 0xc1: grp2: /* Grp2 */ switch ( modrm_reg & 7 ) { @@ -952,12 +1033,15 @@ x86_emulate( break; } break; + case 0xd0 ... 0xd1: /* Grp2 */ src.val = 1; goto grp2; + case 0xd2 ... 0xd3: /* Grp2 */ src.val = _regs.ecx; goto grp2; + case 0xf6 ... 0xf7: /* Grp3 */ switch ( modrm_reg & 7 ) { @@ -983,6 +1067,7 @@ x86_emulate( goto cannot_emulate; } break; + case 0xfe ... 0xff: /* Grp4/Grp5 */ switch ( modrm_reg & 7 ) { @@ -1052,8 +1137,10 @@ x86_emulate( special_insn: /* Default action: disable writeback. There may be no dest operand. */ dst.orig_val = dst.val; + if ( twobyte ) goto twobyte_special_insn; + if ( rep_prefix ) { if ( _regs.ecx == 0 ) @@ -1064,6 +1151,7 @@ x86_emulate( _regs.ecx--; _regs.eip = ctxt->regs->eip; } + switch ( b ) { case 0x40 ... 0x4f: /* inc/dec reg */ @@ -1076,6 +1164,7 @@ x86_emulate( else emulate_1op("inc", dst, _regs.eflags); break; + case 0x50 ... 0x57: /* push reg */ dst.type = OP_MEM; dst.bytes = op_bytes; @@ -1087,6 +1176,7 @@ x86_emulate( dst.mem.seg = x86_seg_ss; dst.mem.off = truncate_ea(_regs.esp); break; + case 0x58 ... 0x5f: /* pop reg */ dst.type = OP_REG; dst.reg = decode_register( @@ -1099,9 +1189,18 @@ x86_emulate( goto done; register_address_increment(_regs.esp, dst.bytes); break; + + case 0x70 ... 0x7f: /* jcc (short) */ { + int rel = insn_fetch_type(int8_t); + if ( test_cc(b, _regs.eflags) ) + jmp_rel(rel); + break; + } + case 0x90: /* nop / xchg %%r8,%%rax */ if ( !(rex_prefix & 1) ) break; /* nop */ + case 0x91 ... 0x97: /* xchg reg,%%rax */ src.type = dst.type = OP_REG; src.bytes = dst.bytes = op_bytes; @@ -1111,6 +1210,7 @@ x86_emulate( (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); dst.val = dst.orig_val = *dst.reg; goto xchg; + case 0xa0 ... 0xa1: /* mov mem.offs,{%al,%ax,%eax,%rax} */ /* Source EA is not encoded via ModRM. */ dst.type = OP_REG; @@ -1120,6 +1220,7 @@ x86_emulate( &dst.val, dst.bytes, ctxt)) != 0 ) goto done; break; + case 0xa2 ... 0xa3: /* mov {%al,%ax,%eax,%rax},mem.offs */ /* Destination EA is not encoded via ModRM. */ dst.type = OP_MEM; @@ -1128,6 +1229,7 @@ x86_emulate( dst.bytes = (d & ByteOp) ? 1 : op_bytes; dst.val = (unsigned long)_regs.eax; break; + case 0xa4 ... 0xa5: /* movs */ dst.type = OP_MEM; dst.bytes = (d & ByteOp) ? 1 : op_bytes; @@ -1141,6 +1243,7 @@ x86_emulate( register_address_increment( _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); break; + case 0xaa ... 0xab: /* stos */ dst.type = OP_MEM; dst.bytes = (d & ByteOp) ? 1 : op_bytes; @@ -1150,6 +1253,7 @@ x86_emulate( register_address_increment( _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); break; + case 0xac ... 0xad: /* lods */ dst.type = OP_REG; dst.bytes = (d & ByteOp) ? 1 : op_bytes; @@ -1160,18 +1264,40 @@ x86_emulate( register_address_increment( _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); break; + + case 0xe3: /* jcxz/jecxz (short) */ { + int rel = insn_fetch_type(int8_t); + if ( (ad_bytes == 2) ? !(uint16_t)_regs.ecx : + (ad_bytes == 4) ? !(uint32_t)_regs.ecx : !_regs.ecx ) + jmp_rel(rel); + break; + } + + case 0xe9: /* jmp (short) */ + jmp_rel(insn_fetch_type(int8_t)); + break; + + case 0xeb: /* jmp (near) */ + jmp_rel(insn_fetch_bytes( + (mode == X86EMUL_MODE_PROT64) ? 4 : op_bytes)); + break; + case 0xf5: /* cmc */ _regs.eflags ^= EFLG_CF; break; + case 0xf8: /* clc */ _regs.eflags &= ~EFLG_CF; break; + case 0xf9: /* stc */ _regs.eflags |= EFLG_CF; break; + case 0xfc: /* cld */ _regs.eflags &= ~EFLG_DF; break; + case 0xfd: /* std */ _regs.eflags |= EFLG_DF; break; @@ -1183,39 +1309,9 @@ x86_emulate( { case 0x40 ... 0x4f: /* cmov */ dst.val = dst.orig_val = src.val; - d &= ~Mov; /* default to no move */ - /* First, assume we're decoding an even cmov opcode (lsb == 0). */ - switch ( (b & 15) >> 1 ) - { - case 0: /* cmovo */ - d |= (_regs.eflags & EFLG_OF) ? Mov : 0; - break; - case 1: /* cmovb/cmovc/cmovnae */ - d |= (_regs.eflags & EFLG_CF) ? Mov : 0; - break; - case 2: /* cmovz/cmove */ - d |= (_regs.eflags & EFLG_ZF) ? Mov : 0; - break; - case 3: /* cmovbe/cmovna */ - d |= (_regs.eflags & (EFLG_CF|EFLG_ZF)) ? Mov : 0; - break; - case 4: /* cmovs */ - d |= (_regs.eflags & EFLG_SF) ? Mov : 0; - break; - case 5: /* cmovp/cmovpe */ - d |= (_regs.eflags & EFLG_PF) ? Mov : 0; - break; - case 7: /* cmovle/cmovng */ - d |= (_regs.eflags & EFLG_ZF) ? Mov : 0; - /* fall through */ - case 6: /* cmovl/cmovnge */ - d |= (!(_regs.eflags & EFLG_SF) != !(_regs.eflags & EFLG_OF)) ? - Mov : 0; - break; - } - /* Odd cmov opcodes (lsb == 1) have inverted sense. */ - d ^= (b & 1) ? Mov : 0; + d = (d & ~Mov) | (test_cc(b, _regs.eflags) ? Mov : 0); break; + case 0xb0 ... 0xb1: /* cmpxchg */ /* Save real source value, then compare EAX against destination. */ src.orig_val = src.val; @@ -1235,27 +1331,34 @@ x86_emulate( dst.reg = (unsigned long *)&_regs.eax; } break; + case 0xa3: bt: /* bt */ emulate_2op_SrcV_nobyte("bt", src, dst, _regs.eflags); break; + case 0xb3: btr: /* btr */ emulate_2op_SrcV_nobyte("btr", src, dst, _regs.eflags); break; + case 0xab: bts: /* bts */ emulate_2op_SrcV_nobyte("bts", src, dst, _regs.eflags); break; + case 0xb6: /* movzx rm8,r{16,32,64} */ /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */ dst.reg = decode_register(modrm_reg, &_regs, 0); dst.bytes = op_bytes; dst.val = (uint8_t)src.val; break; + case 0xb7: /* movzx rm16,r{16,32,64} */ dst.val = (uint16_t)src.val; break; + case 0xbb: btc: /* btc */ emulate_2op_SrcV_nobyte("btc", src, dst, _regs.eflags); break; + case 0xba: /* Grp8 */ switch ( modrm_reg & 3 ) { @@ -1265,15 +1368,18 @@ x86_emulate( case 3: goto btc; } break; + case 0xbe: /* movsx rm8,r{16,32,64} */ /* Recompute DstReg as we may have decoded AH/BH/CH/DH. */ dst.reg = decode_register(modrm_reg, &_regs, 0); dst.bytes = op_bytes; dst.val = (int8_t)src.val; break; + case 0xbf: /* movsx rm16,r{16,32,64} */ dst.val = (int16_t)src.val; break; + case 0xc0 ... 0xc1: /* xadd */ /* Write back the register source. */ switch ( dst.bytes ) @@ -1293,6 +1399,15 @@ x86_emulate( case 0x0d: /* GrpP (prefetch) */ case 0x18: /* Grp16 (prefetch/nop) */ break; + + case 0x80 ... 0x8f: /* jcc (near) */ { + int rel = insn_fetch_bytes( + (mode == X86EMUL_MODE_PROT64) ? 4 : op_bytes); + if ( test_cc(b, _regs.eflags) ) + jmp_rel(rel); + break; + } + case 0xc7: /* Grp9 (cmpxchg8b) */ #if defined(__i386__) { From 82048fc4416cb69fd9eedd75893cee621bc0b298 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Mon, 8 Jan 2007 16:27:35 +0000 Subject: [PATCH 111/570] [XEN] Fix MAP target. Signed-off-by: Ian Campbell --- xen/Makefile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/xen/Makefile b/xen/Makefile index b391513ccc..85472d0596 100644 --- a/xen/Makefile +++ b/xen/Makefile @@ -14,8 +14,8 @@ default: build .PHONY: dist dist: install -.PHONY: build install clean distclean cscope TAGS tags -build install debug clean distclean cscope TAGS tags:: +.PHONY: build install clean distclean cscope TAGS tags MAP +build install debug clean distclean cscope TAGS tags MAP:: $(MAKE) -f Rules.mk _$@ .PHONY: _build @@ -160,9 +160,9 @@ _cscope: $(all_sources) > cscope.files cscope -k -b -q -.PHONY: MAP -MAP: - $(NM) -n $(TARGET) | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' > System.map +.PHONY: _MAP +_MAP: + $(NM) -n $(TARGET)-syms | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' > System.map .PHONY: FORCE FORCE: From 58a6d83e7d8f4548005e9d4b7a42b05623d41b20 Mon Sep 17 00:00:00 2001 From: Christian Limpach Date: Mon, 8 Jan 2007 17:38:47 +0000 Subject: [PATCH 112/570] [linux build] Append $XENGUEST to kernel version. This was lost in changeset 13286:c89384734c19. Signed-off-by: Christian Limpach --- buildconfigs/mk.linux-2.6-xen | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/buildconfigs/mk.linux-2.6-xen b/buildconfigs/mk.linux-2.6-xen index d1ec6afe12..272a58479d 100644 --- a/buildconfigs/mk.linux-2.6-xen +++ b/buildconfigs/mk.linux-2.6-xen @@ -32,7 +32,8 @@ $(LINUX_SRCDIR)/.valid-src: ref-linux-$(LINUX_VER)/.valid-ref LINUX_ARCH=$(LINUX_ARCH) bash ./mkbuildtree ../$(LINUX_SRCDIR) ) # Patch kernel Makefile to set EXTRAVERSION ( cd $(LINUX_SRCDIR) ; \ - sed -e 's,^EXTRAVERSION.*,&$$(XENGUEST)\nXENGUEST := $$(shell [ -r $$(objtree)/.xenguest ] \&\& cat $$(objtree)/.xenguest),' Makefile >Mk.tmp ; \ + sed -e 's,^EXTRAVERSION.*,&$$(XENGUEST),' \ + -e 's,^KERNELRELEASE,XENGUEST := $$(shell [ -r $$(objtree)/.xenguest ] \&\& cat $$(objtree)/.xenguest)\n&,' Makefile >Mk.tmp ; \ rm -f Makefile ; mv Mk.tmp Makefile ) touch $@ From ddef8e1678e51d9a3eb5b10ba5b659dd0269e452 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Mon, 8 Jan 2007 18:39:29 +0000 Subject: [PATCH 113/570] [XEN] Tweak x86 emulator interface. Signed-off-by: Keir Fraser --- tools/tests/test_x86_emulator.c | 2 +- xen/arch/x86/hvm/instrlen.c | 30 ++++++---------- xen/arch/x86/hvm/platform.c | 22 ++++++------ xen/arch/x86/hvm/svm/svm.c | 8 ++--- xen/arch/x86/hvm/vmx/vmx.c | 8 ++--- xen/arch/x86/mm.c | 6 ++-- xen/arch/x86/mm/shadow/common.c | 12 +++---- xen/arch/x86/x86_emulate.c | 58 ++++++++++++------------------- xen/include/asm-x86/hvm/hvm.h | 2 +- xen/include/asm-x86/x86_emulate.h | 19 ++-------- 10 files changed, 62 insertions(+), 105 deletions(-) diff --git a/tools/tests/test_x86_emulator.c b/tools/tests/test_x86_emulator.c index ea8cf54f63..8bbfa3af28 100644 --- a/tools/tests/test_x86_emulator.c +++ b/tools/tests/test_x86_emulator.c @@ -102,7 +102,7 @@ int main(int argc, char **argv) int rc; ctxt.regs = ®s; - ctxt.mode = X86EMUL_MODE_PROT32; + ctxt.address_bytes = 4; res = mmap((void *)0x100000, 0x1000, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); diff --git a/xen/arch/x86/hvm/instrlen.c b/xen/arch/x86/hvm/instrlen.c index 85ee70c9de..0255d1f7c9 100644 --- a/xen/arch/x86/hvm/instrlen.c +++ b/xen/arch/x86/hvm/instrlen.c @@ -201,7 +201,7 @@ static uint8_t twobyte_table[256] = { if ( inst_copy_from_guest(&_x, pc, 1) != 1 ) { \ gdprintk(XENLOG_WARNING, \ "Cannot read from address %lx (eip %lx, mode %d)\n", \ - pc, org_pc, mode); \ + pc, org_pc, address_bytes); \ return -1; \ } \ pc += 1; \ @@ -218,30 +218,20 @@ static uint8_t twobyte_table[256] = { * EXTERNAL this routine calculates the length of the current instruction * pointed to by org_pc. The guest state is _not_ changed by this routine. */ -int hvm_instruction_length(unsigned long org_pc, int mode) +int hvm_instruction_length(unsigned long org_pc, int address_bytes) { uint8_t b, d, twobyte = 0, rex_prefix = 0, modrm_reg = 0; unsigned int op_default, op_bytes, ad_default, ad_bytes, tmp; int length = 0; unsigned long pc = org_pc; - switch ( mode ) + op_bytes = op_default = ad_bytes = ad_default = address_bytes; + if ( op_bytes == 8 ) { - case X86EMUL_MODE_REAL: - case X86EMUL_MODE_PROT16: - op_bytes = op_default = ad_bytes = ad_default = 2; - break; - case X86EMUL_MODE_PROT32: - op_bytes = op_default = ad_bytes = ad_default = 4; - break; -#ifdef __x86_64__ - case X86EMUL_MODE_PROT64: op_bytes = op_default = 4; - ad_bytes = ad_default = 8; - break; -#endif - default: +#ifndef __x86_64__ return -1; +#endif } /* Legacy prefixes. */ @@ -253,7 +243,7 @@ int hvm_instruction_length(unsigned long org_pc, int mode) op_bytes = op_default ^ 6; /* switch between 2/4 bytes */ break; case 0x67: /* address-size override */ - if ( mode == X86EMUL_MODE_PROT64 ) + if ( ad_default == 8 ) ad_bytes = ad_default ^ 12; /* switch between 4/8 bytes */ else ad_bytes = ad_default ^ 6; /* switch between 2/4 bytes */ @@ -270,7 +260,7 @@ int hvm_instruction_length(unsigned long org_pc, int mode) break; #ifdef __x86_64__ case 0x40 ... 0x4f: - if ( mode == X86EMUL_MODE_PROT64 ) + if ( ad_default == 8 ) { rex_prefix = b; continue; @@ -434,7 +424,7 @@ done: cannot_emulate: gdprintk(XENLOG_WARNING, - "Cannot emulate %02x at address %lx (%lx, mode %d)\n", - b, pc - 1, org_pc, mode); + "Cannot emulate %02x at address %lx (%lx, addr_bytes %d)\n", + b, pc - 1, org_pc, address_bytes); return -1; } diff --git a/xen/arch/x86/hvm/platform.c b/xen/arch/x86/hvm/platform.c index daab79f178..1c8e4c11c4 100644 --- a/xen/arch/x86/hvm/platform.c +++ b/xen/arch/x86/hvm/platform.c @@ -352,7 +352,7 @@ static int reg_mem(unsigned char size, unsigned char *opcode, return DECODE_success; } -static int mmio_decode(int mode, unsigned char *opcode, +static int mmio_decode(int address_bytes, unsigned char *opcode, struct hvm_io_op *mmio_op, unsigned char *ad_size, unsigned char *op_size, unsigned char *seg_sel) @@ -368,9 +368,9 @@ static int mmio_decode(int mode, unsigned char *opcode, opcode = check_prefix(opcode, mmio_op, ad_size, op_size, seg_sel, &rex); - switch ( mode ) { - case X86EMUL_MODE_REAL: /* meaning is reversed */ - case X86EMUL_MODE_PROT16: + switch ( address_bytes ) + { + case 2: if ( *op_size == WORD ) *op_size = LONG; else if ( *op_size == LONG ) @@ -384,14 +384,14 @@ static int mmio_decode(int mode, unsigned char *opcode, else if ( *ad_size == 0 ) *ad_size = WORD; break; - case X86EMUL_MODE_PROT32: + case 4: if ( *op_size == 0 ) *op_size = LONG; if ( *ad_size == 0 ) *ad_size = LONG; break; #ifdef __x86_64__ - case X86EMUL_MODE_PROT64: + case 8: if ( *op_size == 0 ) *op_size = rex & 0x8 ? QUAD : LONG; if ( *ad_size == 0 ) @@ -907,7 +907,7 @@ void handle_mmio(unsigned long gpa) struct hvm_io_op *mmio_op; struct cpu_user_regs *regs; unsigned char inst[MAX_INST_LEN], ad_size, op_size, seg_sel; - int i, mode, df, inst_len; + int i, address_bytes, df, inst_len; struct vcpu *v = current; mmio_op = &v->arch.hvm_vcpu.io_op; @@ -919,9 +919,9 @@ void handle_mmio(unsigned long gpa) df = regs->eflags & X86_EFLAGS_DF ? 1 : 0; - mode = hvm_guest_x86_mode(v); + address_bytes = hvm_guest_x86_mode(v); inst_addr = hvm_get_segment_base(v, x86_seg_cs) + regs->eip; - inst_len = hvm_instruction_length(inst_addr, mode); + inst_len = hvm_instruction_length(inst_addr, address_bytes); if ( inst_len <= 0 ) { printk("handle_mmio: failed to get instruction length\n"); @@ -934,8 +934,8 @@ void handle_mmio(unsigned long gpa) domain_crash_synchronous(); } - if ( mmio_decode(mode, inst, mmio_op, &ad_size, &op_size, &seg_sel) - == DECODE_failure ) { + if ( mmio_decode(address_bytes, inst, mmio_op, &ad_size, + &op_size, &seg_sel) == DECODE_failure ) { printk("handle_mmio: failed to decode instruction\n"); printk("mmio opcode: gpa 0x%lx, len %d:", gpa, inst_len); for ( i = 0; i < inst_len; i++ ) diff --git a/xen/arch/x86/hvm/svm/svm.c b/xen/arch/x86/hvm/svm/svm.c index 2a8bdaa5f5..2a3e6370d6 100644 --- a/xen/arch/x86/hvm/svm/svm.c +++ b/xen/arch/x86/hvm/svm/svm.c @@ -483,14 +483,12 @@ static int svm_guest_x86_mode(struct vcpu *v) struct vmcb_struct *vmcb = v->arch.hvm_svm.vmcb; if ( vmcb->efer & EFER_LMA ) - return (vmcb->cs.attr.fields.l ? - X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32); + return (vmcb->cs.attr.fields.l ? 8 : 4); if ( svm_realmode(v) ) - return X86EMUL_MODE_REAL; + return 2; - return (vmcb->cs.attr.fields.db ? - X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16); + return (vmcb->cs.attr.fields.db ? 4 : 2); } void svm_update_host_cr3(struct vcpu *v) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index 473b2eee06..c8782ef8a2 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -695,14 +695,12 @@ static int vmx_guest_x86_mode(struct vcpu *v) cs_ar_bytes = __vmread(GUEST_CS_AR_BYTES); if ( vmx_long_mode_enabled(v) ) - return ((cs_ar_bytes & (1u<<13)) ? - X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32); + return ((cs_ar_bytes & (1u<<13)) ? 8 : 4); if ( vmx_realmode(v) ) - return X86EMUL_MODE_REAL; + return 2; - return ((cs_ar_bytes & (1u<<14)) ? - X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16); + return ((cs_ar_bytes & (1u<<14)) ? 4 : 2); } static int vmx_pae_enabled(struct vcpu *v) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index bad639f692..026180c11a 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3379,9 +3379,9 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, goto bail; ptwr_ctxt.ctxt.regs = guest_cpu_user_regs(); - ptwr_ctxt.ctxt.mode = !IS_COMPAT(d) ? X86EMUL_MODE_HOST : X86EMUL_MODE_PROT32; - ptwr_ctxt.cr2 = addr; - ptwr_ctxt.pte = pte; + ptwr_ctxt.ctxt.address_bytes = IS_COMPAT(d) ? 4 : sizeof(long); + ptwr_ctxt.cr2 = addr; + ptwr_ctxt.pte = pte; if ( x86_emulate(&ptwr_ctxt.ctxt, &ptwr_emulate_ops) ) goto bail; diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index ac543baba1..e1a2e44447 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -110,7 +110,7 @@ static int hvm_translate_linear_addr( unsigned long limit, addr = offset; uint32_t last_byte; - if ( sh_ctxt->ctxt.mode != X86EMUL_MODE_PROT64 ) + if ( sh_ctxt->ctxt.address_bytes != 8 ) { /* * COMPATIBILITY MODE: Apply segment checks and add base. @@ -407,7 +407,7 @@ struct x86_emulate_ops *shadow_init_emulation( if ( !is_hvm_vcpu(v) ) { - sh_ctxt->ctxt.mode = X86EMUL_MODE_HOST; + sh_ctxt->ctxt.address_bytes = sizeof(long); return &pv_shadow_emulator_ops; } @@ -417,13 +417,11 @@ struct x86_emulate_ops *shadow_init_emulation( /* Work out the emulation mode. */ if ( hvm_long_mode_enabled(v) ) - sh_ctxt->ctxt.mode = creg->attr.fields.l ? - X86EMUL_MODE_PROT64 : X86EMUL_MODE_PROT32; + sh_ctxt->ctxt.address_bytes = creg->attr.fields.l ? 8 : 4; else if ( regs->eflags & X86_EFLAGS_VM ) - sh_ctxt->ctxt.mode = X86EMUL_MODE_REAL; + sh_ctxt->ctxt.address_bytes = 2; else - sh_ctxt->ctxt.mode = creg->attr.fields.db ? - X86EMUL_MODE_PROT32 : X86EMUL_MODE_PROT16; + sh_ctxt->ctxt.address_bytes = creg->attr.fields.db ? 4 : 2; /* Attempt to prefetch whole instruction. */ sh_ctxt->insn_buf_bytes = diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 5c85b9ff13..b4118c4318 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -391,10 +391,10 @@ do{ __asm__ __volatile__ ( \ /* Fetch next part of the instruction being emulated. */ #define insn_fetch_bytes(_size) \ ({ unsigned long _x, _eip = _truncate_ea(_regs.eip, def_ad_bytes); \ + if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \ rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt); \ - if ( rc != 0 ) \ - goto done; \ - _register_address_increment(_regs.eip, (_size), def_ad_bytes); \ + if ( rc ) goto done; \ + _regs.eip += (_size); /* real hardware doesn't truncate */ \ _x; \ }) #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type))) @@ -406,13 +406,15 @@ do{ __asm__ __volatile__ ( \ }) #define truncate_ea(ea) _truncate_ea((ea), ad_bytes) +#define mode_64bit() (def_ad_bytes == 8) + /* Update address held in a register, based on addressing mode. */ #define _register_address_increment(reg, inc, byte_width) \ do { \ int _inc = (inc); /* signed type ensures sign extension to long */ \ if ( (byte_width) == sizeof(unsigned long) ) \ (reg) += _inc; \ - else if ( mode == X86EMUL_MODE_PROT64 ) \ + else if ( mode_64bit() ) \ (reg) = ((reg) + _inc) & ((1UL << ((byte_width) << 3)) - 1); \ else \ (reg) = ((reg) & ~((1UL << ((byte_width) << 3)) - 1)) | \ @@ -424,7 +426,7 @@ do { \ #define jmp_rel(rel) \ do { \ _regs.eip += (int)(rel); \ - if ( mode != X86EMUL_MODE_PROT64 ) \ + if ( !mode_64bit() ) \ _regs.eip = ((op_bytes == 2) \ ? (uint16_t)_regs.eip : (uint32_t)_regs.eip); \ } while (0) @@ -521,7 +523,6 @@ x86_emulate( unsigned int lock_prefix = 0, rep_prefix = 0, i; int rc = 0; struct operand src, dst; - int mode = ctxt->mode; /* Data operand effective address (usually computed from ModRM). */ struct operand ea; @@ -531,27 +532,15 @@ x86_emulate( ea.mem.seg = x86_seg_ds; ea.mem.off = 0; - switch ( mode ) + op_bytes = ad_bytes = def_ad_bytes = ctxt->address_bytes; + if ( op_bytes == 8 ) { - case X86EMUL_MODE_REAL: - case X86EMUL_MODE_PROT16: - op_bytes = def_ad_bytes = 2; - break; - case X86EMUL_MODE_PROT32: - op_bytes = def_ad_bytes = 4; - break; -#ifdef __x86_64__ - case X86EMUL_MODE_PROT64: op_bytes = 4; - def_ad_bytes = 8; - break; -#endif - default: +#ifndef __x86_64__ return -1; +#endif } - ad_bytes = def_ad_bytes; - /* Prefix bytes. */ for ( i = 0; i < 8; i++ ) { @@ -561,7 +550,7 @@ x86_emulate( op_bytes ^= 6; /* switch between 2/4 bytes */ break; case 0x67: /* address-size override */ - if ( mode == X86EMUL_MODE_PROT64 ) + if ( mode_64bit() ) ad_bytes ^= 12; /* switch between 4/8 bytes */ else ad_bytes ^= 6; /* switch between 2/4 bytes */ @@ -592,7 +581,7 @@ x86_emulate( rep_prefix = 1; break; case 0x40 ... 0x4f: /* REX */ - if ( mode != X86EMUL_MODE_PROT64 ) + if ( !mode_64bit() ) goto done_prefixes; rex_prefix = b; continue; @@ -685,8 +674,7 @@ x86_emulate( else if ( (sib_base == 4) && !twobyte && (b == 0x8f) ) /* POP must have its EA calculated post increment. */ ea.mem.off += _regs.esp + - (((mode == X86EMUL_MODE_PROT64) && (op_bytes == 4)) - ? 8 : op_bytes); + ((mode_64bit() && (op_bytes == 4)) ? 8 : op_bytes); else ea.mem.off += *(long*)decode_register(sib_base, &_regs, 0); } @@ -701,7 +689,7 @@ x86_emulate( if ( (modrm_rm & 7) != 5 ) break; ea.mem.off = insn_fetch_type(int32_t); - if ( mode != X86EMUL_MODE_PROT64 ) + if ( !mode_64bit() ) break; /* Relative to RIP of next instruction. Argh! */ ea.mem.off += _regs.eip; @@ -935,7 +923,7 @@ x86_emulate( break; case 0x63: /* movsxd */ - if ( mode != X86EMUL_MODE_PROT64 ) + if ( !mode_64bit() ) goto cannot_emulate; dst.val = (int32_t)src.val; break; @@ -983,7 +971,7 @@ x86_emulate( case 0x8f: /* pop (sole member of Grp1a) */ /* 64-bit mode: POP defaults to a 64-bit operand. */ - if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) + if ( mode_64bit() && (dst.bytes == 4) ) dst.bytes = 8; if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp), &dst.val, dst.bytes, ctxt)) != 0 ) @@ -1079,7 +1067,7 @@ x86_emulate( break; case 6: /* push */ /* 64-bit mode: PUSH defaults to a 64-bit operand. */ - if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) + if ( mode_64bit() && (dst.bytes == 4) ) { dst.bytes = 8; if ( (rc = ops->read(dst.mem.seg, dst.mem.off, @@ -1168,7 +1156,7 @@ x86_emulate( case 0x50 ... 0x57: /* push reg */ dst.type = OP_MEM; dst.bytes = op_bytes; - if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) + if ( mode_64bit() && (dst.bytes == 4) ) dst.bytes = 8; dst.val = *(unsigned long *)decode_register( (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); @@ -1182,7 +1170,7 @@ x86_emulate( dst.reg = decode_register( (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); dst.bytes = op_bytes; - if ( (mode == X86EMUL_MODE_PROT64) && (dst.bytes == 4) ) + if ( mode_64bit() && (dst.bytes == 4) ) dst.bytes = 8; if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp), &dst.val, dst.bytes, ctxt)) != 0 ) @@ -1278,8 +1266,7 @@ x86_emulate( break; case 0xeb: /* jmp (near) */ - jmp_rel(insn_fetch_bytes( - (mode == X86EMUL_MODE_PROT64) ? 4 : op_bytes)); + jmp_rel(insn_fetch_bytes(mode_64bit() ? 4 : op_bytes)); break; case 0xf5: /* cmc */ @@ -1401,8 +1388,7 @@ x86_emulate( break; case 0x80 ... 0x8f: /* jcc (near) */ { - int rel = insn_fetch_bytes( - (mode == X86EMUL_MODE_PROT64) ? 4 : op_bytes); + int rel = insn_fetch_bytes(mode_64bit() ? 4 : op_bytes); if ( test_cc(b, _regs.eflags) ) jmp_rel(rel); break; diff --git a/xen/include/asm-x86/hvm/hvm.h b/xen/include/asm-x86/hvm/hvm.h index f97c00ec89..5051ab276b 100644 --- a/xen/include/asm-x86/hvm/hvm.h +++ b/xen/include/asm-x86/hvm/hvm.h @@ -185,7 +185,7 @@ hvm_guest_x86_mode(struct vcpu *v) return hvm_funcs.guest_x86_mode(v); } -int hvm_instruction_length(unsigned long pc, int mode); +int hvm_instruction_length(unsigned long pc, int address_bytes); static inline void hvm_update_host_cr3(struct vcpu *v) diff --git a/xen/include/asm-x86/x86_emulate.h b/xen/include/asm-x86/x86_emulate.h index 6e234cb22b..e1d6f1d50d 100644 --- a/xen/include/asm-x86/x86_emulate.h +++ b/xen/include/asm-x86/x86_emulate.h @@ -134,25 +134,12 @@ struct cpu_user_regs; struct x86_emulate_ctxt { /* Register state before/after emulation. */ - struct cpu_user_regs *regs; + struct cpu_user_regs *regs; - /* Emulated execution mode, represented by an X86EMUL_MODE value. */ - int mode; + /* Default address size in current execution mode (2, 4, or 8). */ + int address_bytes; }; -/* Execution mode, passed to the emulator. */ -#define X86EMUL_MODE_REAL 0 /* Real mode. */ -#define X86EMUL_MODE_PROT16 2 /* 16-bit protected mode. */ -#define X86EMUL_MODE_PROT32 4 /* 32-bit protected mode. */ -#define X86EMUL_MODE_PROT64 8 /* 64-bit (long) mode. */ - -/* Host execution mode. */ -#if defined(__i386__) -#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT32 -#elif defined(__x86_64__) -#define X86EMUL_MODE_HOST X86EMUL_MODE_PROT64 -#endif - /* * x86_emulate: Emulate an instruction. * Returns -1 on failure, 0 on success. From c5a9d11fa86650e847d20b9649114b01a5ef3e71 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 10 Jan 2007 14:14:30 +0000 Subject: [PATCH 114/570] [HVM] Remove unneeded vcpu_kick() from HPET device model. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/hpet.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/xen/arch/x86/hvm/hpet.c b/xen/arch/x86/hvm/hpet.c index e835382eac..5d8ec92150 100644 --- a/xen/arch/x86/hvm/hpet.c +++ b/xen/arch/x86/hvm/hpet.c @@ -356,8 +356,6 @@ static void hpet_timer_fn(void *opaque) } set_timer(&h->timers[tn], NOW() + hpet_tick_to_ns(h, h->period[tn])); } - - vcpu_kick(h->vcpu); } void hpet_migrate_timers(struct vcpu *v) From 647c467fd9651d3fb4c7fbdccad4273497a8380a Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 10 Jan 2007 15:05:00 +0000 Subject: [PATCH 115/570] [HVM] Allow PV-on-HVM callback irq to be identified by PCI device. Signed-off-by: Keir Fraser --- .../linux-2.6/platform-pci/platform-pci.c | 22 ++- .../linux-2.6/platform-pci/platform-pci.h | 4 +- xen/arch/x86/hvm/hvm.c | 2 +- xen/arch/x86/hvm/irq.c | 153 ++++++++++++------ xen/include/asm-x86/hvm/irq.h | 16 +- xen/include/public/hvm/params.h | 22 ++- 6 files changed, 157 insertions(+), 62 deletions(-) diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c index 3a2453a25c..24159f2bab 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.c @@ -179,7 +179,7 @@ static int get_hypercall_stubs(void) #define get_hypercall_stubs() (0) #endif -static int get_callback_irq(struct pci_dev *pdev) +static uint64_t get_callback_via(struct pci_dev *pdev) { #ifdef __ia64__ int irq; @@ -189,16 +189,24 @@ static int get_callback_irq(struct pci_dev *pdev) } return 0; #else /* !__ia64__ */ - return pdev->irq; + if (pdev->irq < 16) + return pdev->irq; /* ISA IRQ */ + /* We don't know the GSI. Specify the PCI INTx line instead. */ + return (((uint64_t)0x01 << 56) | /* PCI INTx identifier */ + ((uint64_t)pci_domain_nr(pdev->bus) << 32) | + ((uint64_t)pdev->bus->number << 16) | + ((uint64_t)(pdev->devfn & 0xff) << 8) | + ((uint64_t)(pdev->pin - 1) & 3)); #endif } static int __devinit platform_pci_init(struct pci_dev *pdev, const struct pci_device_id *ent) { - int i, ret, callback_irq; + int i, ret; long ioaddr, iolen; long mmio_addr, mmio_len; + uint64_t callback_via; i = pci_enable_device(pdev); if (i) @@ -210,9 +218,9 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, mmio_addr = pci_resource_start(pdev, 1); mmio_len = pci_resource_len(pdev, 1); - callback_irq = get_callback_irq(pdev); + callback_via = get_callback_via(pdev); - if (mmio_addr == 0 || ioaddr == 0 || callback_irq == 0) { + if (mmio_addr == 0 || ioaddr == 0 || callback_via == 0) { printk(KERN_WARNING DRV_NAME ":no resources found\n"); return -ENOENT; } @@ -247,7 +255,7 @@ static int __devinit platform_pci_init(struct pci_dev *pdev, goto out; } - if ((ret = set_callback_irq(callback_irq))) + if ((ret = set_callback_via(callback_via))) goto out; out: @@ -297,7 +305,7 @@ static void __exit platform_pci_module_cleanup(void) { printk(KERN_INFO DRV_NAME ":Do platform module cleanup\n"); /* disable hypervisor for callback irq */ - set_callback_irq(0); + set_callback_via(0); if (pci_device_registered) pci_unregister_driver(&platform_driver); } diff --git a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h index 5e10413b13..ca65358599 100644 --- a/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h +++ b/unmodified_drivers/linux-2.6/platform-pci/platform-pci.h @@ -24,13 +24,13 @@ #include #include -static inline int set_callback_irq(int irq) +static inline int set_callback_via(uint64_t via) { struct xen_hvm_param a; a.domid = DOMID_SELF; a.index = HVM_PARAM_CALLBACK_IRQ; - a.value = irq; + a.value = via; return HYPERVISOR_hvm_op(HVMOP_set_param, &a); } diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c index 8d8de4c513..febc278c23 100644 --- a/xen/arch/x86/hvm/hvm.c +++ b/xen/arch/x86/hvm/hvm.c @@ -800,7 +800,7 @@ long do_hvm_op(unsigned long op, XEN_GUEST_HANDLE(void) arg) d->arch.hvm_domain.buffered_io_va = (unsigned long)p; break; case HVM_PARAM_CALLBACK_IRQ: - hvm_set_callback_gsi(d, a.value); + hvm_set_callback_via(d, a.value); break; } d->arch.hvm_domain.params[a.index] = a.value; diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index 45d4f97042..72f8419d46 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -25,7 +25,7 @@ #include #include -void hvm_pci_intx_assert( +static void __hvm_pci_intx_assert( struct domain *d, unsigned int device, unsigned int intx) { struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; @@ -33,10 +33,8 @@ void hvm_pci_intx_assert( ASSERT((device <= 31) && (intx <= 3)); - spin_lock(&hvm_irq->lock); - if ( __test_and_set_bit(device*4 + intx, &hvm_irq->pci_intx) ) - goto out; + return; gsi = hvm_pci_intx_gsi(device, intx); if ( hvm_irq->gsi_assert_count[gsi]++ == 0 ) @@ -50,12 +48,19 @@ void hvm_pci_intx_assert( vioapic_irq_positive_edge(d, isa_irq); vpic_irq_positive_edge(d, isa_irq); } +} - out: +void hvm_pci_intx_assert( + struct domain *d, unsigned int device, unsigned int intx) +{ + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; + + spin_lock(&hvm_irq->lock); + __hvm_pci_intx_assert(d, device, intx); spin_unlock(&hvm_irq->lock); } -void hvm_pci_intx_deassert( +static void __hvm_pci_intx_deassert( struct domain *d, unsigned int device, unsigned int intx) { struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; @@ -63,10 +68,8 @@ void hvm_pci_intx_deassert( ASSERT((device <= 31) && (intx <= 3)); - spin_lock(&hvm_irq->lock); - if ( !__test_and_clear_bit(device*4 + intx, &hvm_irq->pci_intx) ) - goto out; + return; gsi = hvm_pci_intx_gsi(device, intx); --hvm_irq->gsi_assert_count[gsi]; @@ -76,8 +79,15 @@ void hvm_pci_intx_deassert( if ( (--hvm_irq->pci_link_assert_count[link] == 0) && isa_irq && (--hvm_irq->gsi_assert_count[isa_irq] == 0) ) vpic_irq_negative_edge(d, isa_irq); +} - out: +void hvm_pci_intx_deassert( + struct domain *d, unsigned int device, unsigned int intx) +{ + struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; + + spin_lock(&hvm_irq->lock); + __hvm_pci_intx_deassert(d, device, intx); spin_unlock(&hvm_irq->lock); } @@ -123,37 +133,47 @@ void hvm_set_callback_irq_level(void) struct vcpu *v = current; struct domain *d = v->domain; struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; - unsigned int gsi = hvm_irq->callback_gsi; + unsigned int gsi, pdev, pintx, asserted; /* Fast lock-free tests. */ - if ( (v->vcpu_id != 0) || (gsi == 0) ) + if ( (v->vcpu_id != 0) || + (hvm_irq->callback_via_type == HVMIRQ_callback_none) ) return; spin_lock(&hvm_irq->lock); - gsi = hvm_irq->callback_gsi; - if ( gsi == 0 ) - goto out; - /* NB. Do not check the evtchn_upcall_mask. It is not used in HVM mode. */ - if ( vcpu_info(v, evtchn_upcall_pending) ) + asserted = !!vcpu_info(v, evtchn_upcall_pending); + if ( hvm_irq->callback_via_asserted == asserted ) + goto out; + hvm_irq->callback_via_asserted = asserted; + + /* Callback status has changed. Update the callback via. */ + switch ( hvm_irq->callback_via_type ) { - if ( !__test_and_set_bit(0, &hvm_irq->callback_irq_wire) && - (hvm_irq->gsi_assert_count[gsi]++ == 0) ) + case HVMIRQ_callback_gsi: + gsi = hvm_irq->callback_via.gsi; + if ( asserted && (hvm_irq->gsi_assert_count[gsi]++ == 0) ) { vioapic_irq_positive_edge(d, gsi); if ( gsi <= 15 ) vpic_irq_positive_edge(d, gsi); } - } - else - { - if ( __test_and_clear_bit(0, &hvm_irq->callback_irq_wire) && - (--hvm_irq->gsi_assert_count[gsi] == 0) ) + else if ( !asserted && (--hvm_irq->gsi_assert_count[gsi] == 0) ) { if ( gsi <= 15 ) vpic_irq_negative_edge(d, gsi); } + break; + case HVMIRQ_callback_pci_intx: + pdev = hvm_irq->callback_via.pci.dev; + pintx = hvm_irq->callback_via.pci.intx; + if ( asserted ) + __hvm_pci_intx_assert(d, pdev, pintx); + else + __hvm_pci_intx_deassert(d, pdev, pintx); + default: + break; } out: @@ -193,40 +213,79 @@ void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq) d->domain_id, link, old_isa_irq, isa_irq); } -void hvm_set_callback_gsi(struct domain *d, unsigned int gsi) +void hvm_set_callback_via(struct domain *d, uint64_t via) { struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; - unsigned int old_gsi; + unsigned int gsi=0, pdev=0, pintx=0; + uint8_t via_type; - if ( gsi >= ARRAY_SIZE(hvm_irq->gsi_assert_count) ) - gsi = 0; + via_type = (uint8_t)(via >> 56) + 1; + if ( ((via_type == HVMIRQ_callback_gsi) && (via == 0)) || + (via_type > HVMIRQ_callback_pci_intx) ) + via_type = HVMIRQ_callback_none; spin_lock(&hvm_irq->lock); - old_gsi = hvm_irq->callback_gsi; - if ( old_gsi == gsi ) - goto out; - hvm_irq->callback_gsi = gsi; - - if ( !test_bit(0, &hvm_irq->callback_irq_wire) ) - goto out; - - if ( old_gsi && (--hvm_irq->gsi_assert_count[old_gsi] == 0) ) - if ( old_gsi <= 15 ) - vpic_irq_negative_edge(d, old_gsi); - - if ( gsi && (hvm_irq->gsi_assert_count[gsi]++ == 0) ) + /* Tear down old callback via. */ + if ( hvm_irq->callback_via_asserted ) { - vioapic_irq_positive_edge(d, gsi); - if ( gsi <= 15 ) - vpic_irq_positive_edge(d, gsi); + switch ( hvm_irq->callback_via_type ) + { + case HVMIRQ_callback_gsi: + gsi = hvm_irq->callback_via.gsi; + if ( (--hvm_irq->gsi_assert_count[gsi] == 0) && (gsi <= 15) ) + vpic_irq_negative_edge(d, gsi); + break; + case HVMIRQ_callback_pci_intx: + pdev = hvm_irq->callback_via.pci.dev; + pintx = hvm_irq->callback_via.pci.intx; + __hvm_pci_intx_deassert(d, pdev, pintx); + break; + default: + break; + } + } + + /* Set up new callback via. */ + switch ( hvm_irq->callback_via_type = via_type ) + { + case HVMIRQ_callback_gsi: + gsi = hvm_irq->callback_via.gsi = (uint8_t)via; + if ( (gsi == 0) || (gsi >= ARRAY_SIZE(hvm_irq->gsi_assert_count)) ) + hvm_irq->callback_via_type = HVMIRQ_callback_none; + else if ( hvm_irq->callback_via_asserted && + (hvm_irq->gsi_assert_count[gsi]++ == 0) ) + { + vioapic_irq_positive_edge(d, gsi); + if ( gsi <= 15 ) + vpic_irq_positive_edge(d, gsi); + } + break; + case HVMIRQ_callback_pci_intx: + pdev = hvm_irq->callback_via.pci.dev = (uint8_t)(via >> 11) & 31; + pintx = hvm_irq->callback_via.pci.intx = (uint8_t)via & 3; + if ( hvm_irq->callback_via_asserted ) + __hvm_pci_intx_assert(d, pdev, pintx); + break; + default: + break; } - out: spin_unlock(&hvm_irq->lock); - dprintk(XENLOG_G_INFO, "Dom%u callback GSI changed %u -> %u\n", - d->domain_id, old_gsi, gsi); + dprintk(XENLOG_G_INFO, "Dom%u callback via changed to ", d->domain_id); + switch ( via_type ) + { + case HVMIRQ_callback_gsi: + printk("GSI %u\n", gsi); + break; + case HVMIRQ_callback_pci_intx: + printk("PCI INTx Dev 0x%02x Int%c\n", pdev, 'A' + pintx); + break; + default: + printk("None\n"); + break; + } } int cpu_has_pending_irq(struct vcpu *v) diff --git a/xen/include/asm-x86/hvm/irq.h b/xen/include/asm-x86/hvm/irq.h index af66d67f2c..44e9ab1cf5 100644 --- a/xen/include/asm-x86/hvm/irq.h +++ b/xen/include/asm-x86/hvm/irq.h @@ -43,9 +43,17 @@ struct hvm_irq { */ DECLARE_BITMAP(isa_irq, 16); - /* Virtual interrupt wire and GSI link for paravirtual platform driver. */ - DECLARE_BITMAP(callback_irq_wire, 1); - unsigned int callback_gsi; + /* Virtual interrupt and via-link for paravirtual platform driver. */ + unsigned int callback_via_asserted; + enum { + HVMIRQ_callback_none, + HVMIRQ_callback_gsi, + HVMIRQ_callback_pci_intx + } callback_via_type; + union { + unsigned int gsi; + struct { uint8_t dev, intx; } pci; + } callback_via; /* * PCI-ISA interrupt router. @@ -105,7 +113,7 @@ void hvm_isa_irq_deassert( void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq); void hvm_set_callback_irq_level(void); -void hvm_set_callback_gsi(struct domain *d, unsigned int gsi); +void hvm_set_callback_via(struct domain *d, uint64_t via); int cpu_get_interrupt(struct vcpu *v, int *type); int cpu_has_pending_irq(struct vcpu *v); diff --git a/xen/include/public/hvm/params.h b/xen/include/public/hvm/params.h index caa1f1f545..c3a87163e4 100644 --- a/xen/include/public/hvm/params.h +++ b/xen/include/public/hvm/params.h @@ -24,13 +24,33 @@ #include "hvm_op.h" -/* Parameter space for HVMOP_{set,get}_param. */ +/* + * Parameter space for HVMOP_{set,get}_param. + */ + +/* + * How should CPU0 event-channel notifications be delivered? + * val[63:56] == 0: val[55:0] is a delivery GSI (Global System Interrupt). + * val[63:56] == 1: val[55:0] is a delivery PCI INTx line, as follows: + * Domain = val[47:32], Bus = val[31:16], + * DevFn = val[15: 8], IntX = val[ 1: 0] + * If val == 0 then CPU0 event-channel notifications are not delivered. + */ #define HVM_PARAM_CALLBACK_IRQ 0 + +/* + * These are not used by Xen. They are here for convenience of HVM-guest + * xenbus implementations. + */ #define HVM_PARAM_STORE_PFN 1 #define HVM_PARAM_STORE_EVTCHN 2 + #define HVM_PARAM_PAE_ENABLED 4 + #define HVM_PARAM_IOREQ_PFN 5 + #define HVM_PARAM_BUFIOREQ_PFN 6 + #define HVM_NR_PARAMS 7 #endif /* __XEN_PUBLIC_HVM_PARAMS_H__ */ From d49020eed746315183168f58e9fa6b8059231e8e Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 10 Jan 2007 16:17:35 +0000 Subject: [PATCH 116/570] [HVM][VMX] Fix problem taking an NMI on entry/exit to/from VMX mode. Also cleans up code a bit. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/vmx/vmcs.c | 9 ++++++++- xen/arch/x86/hvm/vmx/x86_32/exits.S | 31 +---------------------------- xen/arch/x86/hvm/vmx/x86_64/exits.S | 27 +------------------------ xen/arch/x86/oprofile/nmi_int.c | 2 +- xen/arch/x86/traps.c | 2 +- 5 files changed, 12 insertions(+), 59 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmcs.c b/xen/arch/x86/hvm/vmx/vmcs.c index 8355c6e54d..dde3a4c201 100644 --- a/xen/arch/x86/hvm/vmx/vmcs.c +++ b/xen/arch/x86/hvm/vmx/vmcs.c @@ -278,7 +278,14 @@ static void vmx_set_host_env(struct vcpu *v) host_env.tr_base = (unsigned long) &init_tss[cpu]; __vmwrite(HOST_TR_SELECTOR, host_env.tr_selector); __vmwrite(HOST_TR_BASE, host_env.tr_base); - __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom()); + + /* + * Skip end of cpu_user_regs when entering the hypervisor because the + * CPU does not save context onto the stack. SS,RSP,CS,RIP,RFLAGS,etc + * all get saved into the VMCS instead. + */ + __vmwrite(HOST_RSP, + (unsigned long)&get_cpu_info()->guest_cpu_user_regs.error_code); } static void construct_vmcs(struct vcpu *v) diff --git a/xen/arch/x86/hvm/vmx/x86_32/exits.S b/xen/arch/x86/hvm/vmx/x86_32/exits.S index 144dd174d4..35b67d3c48 100644 --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S @@ -29,35 +29,7 @@ andl $~3,reg; \ movl (reg),reg; -/* - * At VMExit time the processor saves the guest selectors, esp, eip, - * and eflags. Therefore we don't save them, but simply decrement - * the kernel stack pointer to make it consistent with the stack frame - * at usual interruption time. The eflags of the host is not saved by VMX, - * and we set it to the fixed value. - * - * We also need the room, especially because orig_eax field is used - * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following: - * (10) u32 gs; - * (9) u32 fs; - * (8) u32 ds; - * (7) u32 es; - * <- get_stack_bottom() (= HOST_ESP) - * (6) u32 ss; - * (5) u32 esp; - * (4) u32 eflags; - * (3) u32 cs; - * (2) u32 eip; - * (2/1) u16 entry_vector; - * (1/1) u16 error_code; - * However, get_stack_bottom() actually returns 20 bytes before the real - * bottom of the stack to allow space for: - * domain pointer, DS, ES, FS, GS. Therefore, we effectively skip 6 registers. - */ - -#define NR_SKIPPED_REGS 6 /* See the above explanation */ #define HVM_SAVE_ALL_NOSEGREGS \ - subl $(NR_SKIPPED_REGS*4), %esp; \ movl $0, 0xc(%esp); /* XXX why do we need to force eflags==0 ?? */ \ pushl %eax; \ pushl %ebp; \ @@ -74,8 +46,7 @@ popl %esi; \ popl %edi; \ popl %ebp; \ - popl %eax; \ - addl $(NR_SKIPPED_REGS*4), %esp + popl %eax ALIGN ENTRY(vmx_asm_vmexit_handler) diff --git a/xen/arch/x86/hvm/vmx/x86_64/exits.S b/xen/arch/x86/hvm/vmx/x86_64/exits.S index d427ac2cd5..cbe9902391 100644 --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S @@ -29,31 +29,7 @@ andq $~7,reg; \ movq (reg),reg; -/* - * At VMExit time the processor saves the guest selectors, rsp, rip, - * and rflags. Therefore we don't save them, but simply decrement - * the kernel stack pointer to make it consistent with the stack frame - * at usual interruption time. The rflags of the host is not saved by VMX, - * and we set it to the fixed value. - * - * We also need the room, especially because orig_eax field is used - * by do_IRQ(). Compared the cpu_user_regs, we skip pushing for the following: - * (10) u64 gs; - * (9) u64 fs; - * (8) u64 ds; - * (7) u64 es; - * <- get_stack_bottom() (= HOST_ESP) - * (6) u64 ss; - * (5) u64 rsp; - * (4) u64 rflags; - * (3) u64 cs; - * (2) u64 rip; - * (2/1) u32 entry_vector; - * (1/1) u32 error_code; - */ -#define NR_SKIPPED_REGS 6 /* See the above explanation */ #define HVM_SAVE_ALL_NOSEGREGS \ - subq $(NR_SKIPPED_REGS*8), %rsp; \ pushq %rdi; \ pushq %rsi; \ pushq %rdx; \ @@ -85,8 +61,7 @@ popq %rcx; \ popq %rdx; \ popq %rsi; \ - popq %rdi; \ - addq $(NR_SKIPPED_REGS*8), %rsp; + popq %rdi ALIGN ENTRY(vmx_asm_vmexit_handler) diff --git a/xen/arch/x86/oprofile/nmi_int.c b/xen/arch/x86/oprofile/nmi_int.c index 15e2818edb..ffefe3bf2d 100644 --- a/xen/arch/x86/oprofile/nmi_int.c +++ b/xen/arch/x86/oprofile/nmi_int.c @@ -42,7 +42,7 @@ extern int is_profiled(struct domain *d); extern size_t strlcpy(char *dest, const char *src, size_t size); -int nmi_callback(struct cpu_user_regs *regs, int cpu) +static int nmi_callback(struct cpu_user_regs *regs, int cpu) { int xen_mode, ovf; diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c index cf1defeae3..e8ff825ea7 100644 --- a/xen/arch/x86/traps.c +++ b/xen/arch/x86/traps.c @@ -1854,7 +1854,7 @@ static int dummy_nmi_callback(struct cpu_user_regs *regs, int cpu) } static nmi_callback_t nmi_callback = dummy_nmi_callback; - + asmlinkage void do_nmi(struct cpu_user_regs *regs) { unsigned int cpu = smp_processor_id(); From 7220350010061dfd1c354397d7a25ec6829ae88a Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Wed, 10 Jan 2007 17:26:58 +0000 Subject: [PATCH 117/570] [XEN] 32on64: need to take multicall context into consideration when determining the continuation arguments for mmuext ops. Signed-off-by: Jan Beulich --- xen/arch/x86/x86_64/compat/mm.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/x86_64/compat/mm.c b/xen/arch/x86/x86_64/compat/mm.c index ae833ff4a6..a9c136323f 100644 --- a/xen/arch/x86/x86_64/compat/mm.c +++ b/xen/arch/x86/x86_64/compat/mm.c @@ -1,6 +1,7 @@ #ifdef CONFIG_COMPAT #include +#include #include #include @@ -289,20 +290,27 @@ int compat_mmuext_op(XEN_GUEST_HANDLE(mmuext_op_compat_t) cmp_uops, if ( err == __HYPERVISOR_mmuext_op ) { struct cpu_user_regs *regs = guest_cpu_user_regs(); - unsigned int left = regs->ecx & ~MMU_UPDATE_PREEMPTED; + struct mc_state *mcs = &this_cpu(mc_state); + unsigned int arg1 = !test_bit(_MCSF_in_multicall, &mcs->flags) + ? regs->ecx + : mcs->call.args[1]; + unsigned int left = arg1 & ~MMU_UPDATE_PREEMPTED; - BUG_ON(!(regs->ecx & MMU_UPDATE_PREEMPTED)); + BUG_ON(left == arg1); BUG_ON(left > count); guest_handle_add_offset(nat_ops, count - left); BUG_ON(left + i < count); guest_handle_add_offset(cmp_uops, (signed int)(count - left - i)); left = 1; BUG_ON(!hypercall_xlat_continuation(&left, 0x01, nat_ops, cmp_uops)); - BUG_ON(left != regs->ecx); - regs->ecx += count - i; + BUG_ON(left != arg1); + if (!test_bit(_MCSF_in_multicall, &mcs->flags)) + regs->_ecx += count - i; + else + mcs->compat_call.args[1] += count - i; } else - BUG_ON(rc > 0); + BUG_ON(err > 0); rc = err; } From 2736a406e4eac36a6de7a3b5e08b7f30da038f35 Mon Sep 17 00:00:00 2001 From: Emmanuel Ackaouy Date: Wed, 10 Jan 2007 17:56:54 +0000 Subject: [PATCH 118/570] [XEN] Partial fix for compat build non-portability. Signed-off-by: John Levon --- xen/include/Makefile | 50 +++++++++++++++++--------------- xen/tools/compat-build-header.py | 21 ++++++++++++++ xen/tools/compat-build-source.py | 27 +++++++++++++++++ xen/tools/get-fields.sh | 37 +++++++++++++---------- 4 files changed, 97 insertions(+), 38 deletions(-) create mode 100755 xen/tools/compat-build-header.py create mode 100755 xen/tools/compat-build-source.py diff --git a/xen/include/Makefile b/xen/include/Makefile index d2efb237c3..15b347ca11 100644 --- a/xen/include/Makefile +++ b/xen/include/Makefile @@ -2,8 +2,28 @@ ifneq ($(CONFIG_COMPAT),) compat-arch-$(CONFIG_X86) := x86_32 -headers-y := $(shell echo public/*.h | sed -e 's,[^[:space:]]*-[^[:space:]]*,,g' -e 's,public/,compat/,g') -headers-y := $(filter-out %/dom0_ops.h,$(headers-y)) +headers-y := \ + compat/acm.h \ + compat/acm_ops.h \ + compat/callback.h \ + compat/domctl.h \ + compat/elfnote.h \ + compat/event_channel.h \ + compat/features.h \ + compat/grant_table.h \ + compat/kexec.h \ + compat/memory.h \ + compat/nmi.h \ + compat/physdev.h \ + compat/platform.h \ + compat/sched.h \ + compat/sysctl.h \ + compat/trace.h \ + compat/vcpu.h \ + compat/version.h \ + compat/xen.h \ + compat/xencomm.h \ + compat/xenoprof.h headers-$(CONFIG_X86) += compat/arch-x86/xen.h headers-$(CONFIG_X86) += compat/arch-x86/xen-$(compat-arch-y).h headers-y += compat/arch-$(compat-arch-y).h compat/xlat.h @@ -21,24 +41,14 @@ endif all: $(headers-y) compat/%.h: compat/%.i Makefile - id=_$$(echo $@ | sed 'y,abcdefghijklmnopqrstuvwxyz-/.,ABCDEFGHIJKLMNOPQRSTUVWXYZ___,'); \ + id=_$$(echo $@ | tr '[:lower:]-/.' '[:upper:]___'); \ echo "#ifndef $$id" >$@.new; \ echo "#define $$id" >>$@.new; \ echo "#include " >>$@.new; \ $(if $(filter-out compat/arch-%.h,$@),echo "#include <$(patsubst compat/%,public/%,$@)>" >>$@.new;) \ $(if $(prefix-y),echo "$(prefix-y)" >>$@.new;) \ - grep -v '^# [[:digit:]]' $< | \ - sed -e 's,__InClUdE__,#include,' \ - -e 's,"xen-compat.h",,' \ - -e 's,\(struct\|union\|enum\)[[:space:]]\+\(xen_\?\)\?\([[:alpha:]_]\),\1 compat_\3,g' \ - -e 's,@KeeP@,,g' \ - -e 's,_t\([^[:alnum:]_]\|$$\),_compat_t\1,g' \ - -e 's,\(8\|16\|32\|64\)_compat_t\([^[:alnum:]_]\|$$\),\1_t\2,g' \ - -e 's,\(^\|[^[:alnum:]_]\)xen_\?\([[:alnum:]_]*\)_compat_t\([^[:alnum:]_]\|$$\),\1compat_\2_t\3,g' \ - -e 's,\(^\|[^[:alnum:]_]\)XEN_\?,\1COMPAT_,' \ - -e 's,\(^\|[^[:alnum:]_]\)Xen_\?,\1Compat_,' \ - -e 's,\(^\|[^[:alnum:]]\)long\([^[:alnum:]]\|$$\),\1int\2,g' | \ - uniq >>$@.new; \ + grep -v '^# [0-9]' $< | \ + $(BASEDIR)/tools/compat-build-header.py | uniq >>$@.new; \ $(if $(suffix-y),echo "$(suffix-y)" >>$@.new;) \ echo "#endif /* $$id */" >>$@.new mv -f $@.new $@ @@ -49,17 +59,11 @@ compat/%.i: compat/%.c Makefile compat/%.c: public/%.h xlat.lst Makefile mkdir -p $(@D) grep -v 'DEFINE_XEN_GUEST_HANDLE(long)' $< | \ - sed -e 's,^[[:space:]]*#[[:space:]]*include[[:space:]]\+,__InClUdE__ ,' \ - -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:upper:]_]*_GUEST_HANDLE\),#define HIDE_\1,' \ - -e 's,^[[:space:]]*#[[:space:]]*define[[:space:]]\+\([[:lower:]_]*_guest_handle\),#define hide_\1,' \ - -e 's,XEN_GUEST_HANDLE\(_[[:xdigit:]]\+\)\?,COMPAT_HANDLE,g' \ - $(foreach n,$(shell sed -n 's,^[[:space:]]*?[[:space:]]\+\([[:alnum:]_]*\)[[:space:]].*,\1,p' xlat.lst), \ - -e 's,\(struct\|union\)[[:space:]]\+\(xen_\?\)\?$n[[:space:]]\+\([[:alpha:]_]\),\1 @KeeP@\2$n \3,g') \ - >$@.new + $(BASEDIR)/tools/compat-build-source.py >$@.new mv -f $@.new $@ compat/xlat.h: xlat.lst $(filter-out compat/xlat.h,$(headers-y)) $(BASEDIR)/tools/get-fields.sh Makefile - grep -v '^[[:space:]]*#' xlat.lst | \ + grep -v '^[ ]*#' xlat.lst | \ while read what name hdr; do \ $(SHELL) $(BASEDIR)/tools/get-fields.sh "$$what" compat_$$name $$(echo compat/$$hdr | sed 's,@arch@,$(compat-arch-y),g') || exit $$?; \ done >$@.new diff --git a/xen/tools/compat-build-header.py b/xen/tools/compat-build-header.py new file mode 100755 index 0000000000..6fb795eaaa --- /dev/null +++ b/xen/tools/compat-build-header.py @@ -0,0 +1,21 @@ +#!/usr/bin/python + +import re,sys + +pats = [ + [ r"__InClUdE__", r"#include" ], + [ r"\"xen-compat.h\"", r"" ], + [ r"(struct|union|enum)\s+(xen_?)?(\w)", r"\1 compat_\3" ], + [ r"@KeeP@", r"" ], + [ r"_t([^\w]|$)", r"_compat_t\1" ], + [ r"(8|16|32|64)_compat_t([^\w]|$)", r"\1_t\2" ], + [ r"(^|[^\w])xen_?(\w*)_compat_t([^\w]|$$)", r"\1compat_\2_t\3" ], + [ r"(^|[^\w])XEN_?", r"\1COMPAT_" ], + [ r"(^|[^\w])Xen_?", r"\1Compat_" ], + [ r"(^|[^\w])long([^\w]|$$)", r"\1int\2" ] +]; + +for line in sys.stdin.readlines(): + for pat in pats: + line = re.subn(pat[0], pat[1], line)[0] + print line.rstrip() diff --git a/xen/tools/compat-build-source.py b/xen/tools/compat-build-source.py new file mode 100755 index 0000000000..449e738188 --- /dev/null +++ b/xen/tools/compat-build-source.py @@ -0,0 +1,27 @@ +#!/usr/bin/python + +import re,sys + +pats = [ + [ r"^\s*#\s*include\s+", r"__InClUdE__ " ], + [ r"^\s*#\s*define\s+([A-Z_]*_GUEST_HANDLE)", r"#define HIDE_\1" ], + [ r"^\s*#\s*define\s+([a-z_]*_guest_handle)", r"#define hide_\1" ], + [ r"XEN_GUEST_HANDLE(_[0-9A-Fa-f]+)?", r"COMPAT_HANDLE" ], +]; + +xlats = [] + +xlatf = open('xlat.lst', 'r') +for line in xlatf.readlines(): + match = re.subn(r"^\s*\?\s+(\w*)\s.*", r"\1", line.rstrip()) + if match[1]: + xlats.append(match[0]) +xlatf.close() + +for line in sys.stdin.readlines(): + for pat in pats: + line = re.subn(pat[0], pat[1], line)[0] + for xlat in xlats: + line = re.subn(r"(struct|union)\s+(%s|xen_%s)\s+(\w)" % (xlat, xlat), + r"\1 @KeeP@\2 \3", line.rstrip())[0] + print line.rstrip() diff --git a/xen/tools/get-fields.sh b/xen/tools/get-fields.sh index 01af5eaaf3..d272c84e0b 100644 --- a/xen/tools/get-fields.sh +++ b/xen/tools/get-fields.sh @@ -1,7 +1,10 @@ -#!/bin/sh +#!/bin/bash test -n "$1" -a -n "$2" -a -n "$3" set -ef +SED=sed +[ -x /usr/xpg4/bin/sed ] && SED=/usr/xpg4/bin/sed + get_fields() { local level=1 aggr=0 name= fields= for token in $2 @@ -90,11 +93,15 @@ handle_field() { then echo -n "$1(_d_)->$3 = (_s_)->$3;" else - echo -n "$1XLAT_${2}_HNDL_$(echo $3 | sed 's,\.,_,g')(_d_, _s_);" + echo -n "$1XLAT_${2}_HNDL_$(echo $3 | $SED 's,\.,_,g')(_d_, _s_);" fi - elif [ -z "$(echo "$5" | sed 's,[^{}],,g')" ] + elif [ -z "$(echo "$5" | $SED 's,[^{}],,g')" ] then - local tag=$(echo "$5" | sed 's,[[:space:]]*\(struct\|union\)[[:space:]]\+\(compat_\)\?\([[:alnum:]_]\+\)[[:space:]].*,\3,') + local tag=$(echo "$5" | python -c ' +import re,sys +for line in sys.stdin.readlines(): + print re.subn(r"\s*(struct|union)\s+(compat_)?(\w+)\s.*", r"\3", line)[0].rstrip() +') echo " \\" echo -n "${1}XLAT_$tag(&(_d_)->$3, &(_s_)->$3);" else @@ -110,7 +117,7 @@ handle_field() { if [ $kind = union ] then echo " \\" - echo -n "${1}switch ($(echo $3 | sed 's,\.,_,g')) {" + echo -n "${1}switch ($(echo $3 | $SED 's,\.,_,g')) {" fi fi ;; @@ -158,12 +165,12 @@ handle_field() { id=$token ;; [\,\;]) - if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] + if [ $level == 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ] then if [ $kind = union ] then echo " \\" - echo -n "${1}case XLAT_${2}_$(echo $3.$id | sed 's,\.,_,g'):" + echo -n "${1}case XLAT_${2}_$(echo $3.$id | $SED 's,\.,_,g'):" handle_field "$1 " $2 $3.$id "$type" "$fields" elif [ -z "$array" -a -z "$array_type" ] then @@ -202,7 +209,7 @@ copy_array() { } handle_array() { - local i="i$(echo $4 | sed 's,[^;], ,g' | wc -w)" + local i="i$(echo $4 | $SED 's,[^;], ,g' | wc -w | $SED 's,[[:space:]]*,,g')" echo " \\" echo "$1{ \\" echo "$1 unsigned int $i; \\" @@ -272,7 +279,7 @@ build_body() { fi ;; [\,\;]) - if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] + if [ $level == 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ] then if [ -z "$array" -a -z "$array_type" ] then @@ -300,10 +307,10 @@ build_body() { } check_field() { - if [ -z "$(echo "$4" | sed 's,[^{}],,g')" ] + if [ -z "$(echo "$4" | $SED 's,[^{}],,g')" ] then echo "; \\" - local n=$(echo $3 | sed 's,[^.], ,g' | wc -w) + local n=$(echo $3 | $SED 's,[^.], ,g' | wc -w | $SED 's,[[:space:]]*,,g') if [ -n "$4" ] then for n in $4 @@ -325,7 +332,7 @@ check_field() { then echo -n " CHECK_FIELD_($1, $2, $3)" else - echo -n " CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | sed 's!\.!, !g'))" + echo -n " CHECK_SUBFIELD_${n}_($1, $2, $(echo $3 | $SED 's!\.!, !g'))" fi else local level=1 fields= id= token @@ -345,7 +352,7 @@ check_field() { id=$token ;; [\,\;]) - if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] + if [ $level == 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ] then check_field $1 $2 $3.$id "$fields" test "$token" != ";" || fields= id= @@ -390,7 +397,7 @@ build_check() { test $level != 2 -o $arrlvl != 1 || id=$token ;; [\,\;]) - if [ $level == 2 -a -n "$(echo $id | sed 's,^_pad[[:digit:]]*,,')" ] + if [ $level == 2 -a -n "$(echo $id | $SED 's,^_pad[[:digit:]]*,,')" ] then check_field $kind $1 $id "$fields" test "$token" != ";" || fields= id= @@ -402,7 +409,7 @@ build_check() { echo "" } -fields="$(get_fields $(echo $2 | sed 's,^compat_xen,compat_,') "$(sed -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")" +fields="$(get_fields $(echo $2 | $SED 's,^compat_xen,compat_,') "$($SED -e 's,^[[:space:]]#.*,,' -e 's!\([]\[,;:{}]\)! \1 !g' $3)")" if [ -z "$fields" ] then echo "Fields of '$2' not found in '$3'" >&2 From 409d47638a9b8070ac18ecb7a318935f7e8bbc9c Mon Sep 17 00:00:00 2001 From: Jake Wires Date: Tue, 9 Jan 2007 18:56:44 -0800 Subject: [PATCH 119/570] [BLKTAP/BLKBACK] name blktap/blkback kernel threads as "domid.virtual_devname" Signed-off-by: Jake Wires --- .../drivers/xen/blkback/xenbus.c | 32 ++++++++++++++++--- .../drivers/xen/blktap/xenbus.c | 30 +++++++++++++++-- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c index 349ae64d0f..b22712e80c 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/xenbus.c @@ -42,9 +42,30 @@ static int connect_ring(struct backend_info *); static void backend_changed(struct xenbus_watch *, const char **, unsigned int); +static int blkback_name(blkif_t *blkif, char *buf) +{ + char *devpath, *devname; + struct xenbus_device *dev = blkif->be->dev; + + devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL); + if (IS_ERR(devpath)) + return PTR_ERR(devpath); + + if ((devname = strstr(devpath, "/dev/")) != NULL) + devname += strlen("/dev/"); + else + devname = devpath; + + snprintf(buf, TASK_COMM_LEN, "blkback.%d.%s", blkif->domid, devname); + kfree(devpath); + + return 0; +} + static void update_blkif_status(blkif_t *blkif) { int err; + char name[TASK_COMM_LEN]; /* Not ready to connect? */ if (!blkif->irq || !blkif->vbd.bdev) @@ -59,10 +80,13 @@ static void update_blkif_status(blkif_t *blkif) if (blkif->be->dev->state != XenbusStateConnected) return; - blkif->xenblkd = kthread_run(blkif_schedule, blkif, - "xvd %d %02x:%02x", - blkif->domid, - blkif->be->major, blkif->be->minor); + err = blkback_name(blkif, name); + if (err) { + xenbus_dev_error(blkif->be->dev, err, "get blkback dev name"); + return; + } + + blkif->xenblkd = kthread_run(blkif_schedule, blkif, name); if (IS_ERR(blkif->xenblkd)) { err = PTR_ERR(blkif->xenblkd); blkif->xenblkd = NULL; diff --git a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c index 553ad45c48..fb2979b70b 100644 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/xenbus.c @@ -92,9 +92,30 @@ static long get_id(const char *str) return simple_strtol(num, NULL, 10); } +static int blktap_name(blkif_t *blkif, char *buf) +{ + char *devpath, *devname; + struct xenbus_device *dev = blkif->be->dev; + + devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL); + if (IS_ERR(devpath)) + return PTR_ERR(devpath); + + if ((devname = strstr(devpath, "/dev/")) != NULL) + devname += strlen("/dev/"); + else + devname = devpath; + + snprintf(buf, TASK_COMM_LEN, "blktap.%d.%s", blkif->domid, devname); + kfree(devpath); + + return 0; +} + static void tap_update_blkif_status(blkif_t *blkif) { int err; + char name[TASK_COMM_LEN]; /* Not ready to connect? */ if(!blkif->irq || !blkif->sectors) { @@ -110,10 +131,13 @@ static void tap_update_blkif_status(blkif_t *blkif) if (blkif->be->dev->state != XenbusStateConnected) return; - blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif, - "xvd %d", - blkif->domid); + err = blktap_name(blkif, name); + if (err) { + xenbus_dev_error(blkif->be->dev, err, "get blktap dev name"); + return; + } + blkif->xenblkd = kthread_run(tap_blkif_schedule, blkif, name); if (IS_ERR(blkif->xenblkd)) { err = PTR_ERR(blkif->xenblkd); blkif->xenblkd = NULL; From dc5bf8aa504e69ce3d0b0eabc6a15364a205f473 Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Thu, 11 Jan 2007 10:08:14 +0000 Subject: [PATCH 120/570] [HVM] Allow a dom to have nonsense m2p entries when building the p2m Signed-off-by: Tim Deegan --- xen/arch/x86/mm/shadow/common.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/xen/arch/x86/mm/shadow/common.c b/xen/arch/x86/mm/shadow/common.c index e1a2e44447..8cee158842 100644 --- a/xen/arch/x86/mm/shadow/common.c +++ b/xen/arch/x86/mm/shadow/common.c @@ -1303,6 +1303,9 @@ shadow_alloc_p2m_table(struct domain *d) if ( !shadow_set_p2m_entry(d, gfn, mfn) ) goto error; + /* Build a p2m map that matches the m2p entries for this domain's + * allocated pages. Skip any pages that have an explicitly invalid + * or obviously bogus m2p entry. */ for ( entry = d->page_list.next; entry != &d->page_list; entry = entry->next ) @@ -1318,6 +1321,8 @@ shadow_alloc_p2m_table(struct domain *d) (gfn != 0x55555555L) #endif && gfn != INVALID_M2P_ENTRY + && (gfn < + (RO_MPT_VIRT_END - RO_MPT_VIRT_START) / sizeof (l1_pgentry_t)) && !shadow_set_p2m_entry(d, gfn, mfn) ) goto error; } From 68a749f1782d8639264fd9ef924db97c3b8048be Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 11 Jan 2007 10:10:16 +0000 Subject: [PATCH 121/570] [XEN] More emulator fixes: 1. Emulate LAHF/SAHF instructions 2. #GP if instruction is longer than 15 bytes 3. Accept any number of prefix bytes (up to 15-byte total instruction length) 4. Repeated addr/data-size overrides are sticky rather than toggling. 2,3,4 are based on a patch from Jan Beulich. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 57650986f1..ec174595e3 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -107,7 +107,7 @@ static uint8_t opcode_table[256] = { ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0x98 - 0x9F */ - 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, ImplicitOps, ImplicitOps, /* 0xA0 - 0xA7 */ ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, @@ -230,7 +230,8 @@ struct operand { #define EFLG_CF (1<<0) /* Exception definitions. */ -#define EXC_DE 0 +#define EXC_DE 0 +#define EXC_GP 13 /* * Instruction emulation: @@ -394,11 +395,13 @@ do{ __asm__ __volatile__ ( \ /* Fetch next part of the instruction being emulated. */ #define insn_fetch_bytes(_size) \ -({ unsigned long _x, _eip = _truncate_ea(_regs.eip, def_ad_bytes); \ +({ unsigned long _x, _eip = _regs.eip; \ if ( !mode_64bit() ) _eip = (uint32_t)_eip; /* ignore upper dword */ \ + _regs.eip += (_size); /* real hardware doesn't truncate */ \ + generate_exception_if((uint8_t)(_regs.eip - ctxt->regs->eip) > 15, \ + EXC_GP); \ rc = ops->insn_fetch(x86_seg_cs, _eip, &_x, (_size), ctxt); \ if ( rc ) goto done; \ - _regs.eip += (_size); /* real hardware doesn't truncate */ \ _x; \ }) #define insn_fetch_type(_type) ((_type)insn_fetch_bytes(sizeof(_type))) @@ -540,8 +543,8 @@ x86_emulate( uint8_t b, d, sib, sib_index, sib_base, twobyte = 0, rex_prefix = 0; uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; - unsigned int op_bytes, ad_bytes, def_ad_bytes; - unsigned int lock_prefix = 0, rep_prefix = 0, i; + unsigned int op_bytes, def_op_bytes, ad_bytes, def_ad_bytes; + unsigned int lock_prefix = 0, rep_prefix = 0; int rc = 0; struct operand src, dst; @@ -553,28 +556,25 @@ x86_emulate( ea.mem.seg = x86_seg_ds; ea.mem.off = 0; - op_bytes = ad_bytes = def_ad_bytes = ctxt->address_bytes; + op_bytes = def_op_bytes = ad_bytes = def_ad_bytes = ctxt->address_bytes; if ( op_bytes == 8 ) { - op_bytes = 4; + op_bytes = def_op_bytes = 4; #ifndef __x86_64__ return -1; #endif } /* Prefix bytes. */ - for ( i = 0; i < 8; i++ ) + for ( ; ; ) { switch ( b = insn_fetch_type(uint8_t) ) { case 0x66: /* operand-size override */ - op_bytes ^= 6; /* switch between 2/4 bytes */ + op_bytes = def_op_bytes ^ 6; break; case 0x67: /* address-size override */ - if ( mode_64bit() ) - ad_bytes ^= 12; /* switch between 4/8 bytes */ - else - ad_bytes ^= 6; /* switch between 2/4 bytes */ + ad_bytes = def_ad_bytes ^ (mode_64bit() ? 12 : 6); break; case 0x2e: /* CS override */ ea.mem.seg = x86_seg_cs; @@ -1288,6 +1288,14 @@ x86_emulate( dst.val = dst.orig_val = *dst.reg; goto xchg; + case 0x9e: /* sahf */ + *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02; + break; + + case 0x9f: /* lahf */ + ((uint8_t *)&_regs.eax)[1] = (_regs.eflags & 0xd7) | 0x02; + break; + case 0xa0 ... 0xa1: /* mov mem.offs,{%al,%ax,%eax,%rax} */ /* Source EA is not encoded via ModRM. */ dst.type = OP_REG; From 5c8a39cf80c48d7048f03ed77d7a552d0c1dcc0e Mon Sep 17 00:00:00 2001 From: "john.levon@sun.com" Date: Mon, 8 Jan 2007 12:54:41 -0800 Subject: [PATCH 122/570] Use strstr() to look for "bimodal" string in ELF notes, to allow guests to use "yes,bimodal", so they are correctly identified as PAE on older hypervisors. Signed-off-by: John Levon --- tools/libxc/xc_load_elf.c | 14 ++++++++------ xen/common/elf.c | 2 +- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/tools/libxc/xc_load_elf.c b/tools/libxc/xc_load_elf.c index cabc164cca..4d7d9823a5 100644 --- a/tools/libxc/xc_load_elf.c +++ b/tools/libxc/xc_load_elf.c @@ -406,17 +406,19 @@ static int parseelfimage(const char *image, } /* - * A "bimodal" ELF note indicates the kernel will adjust to the - * current paging mode, including handling extended cr3 syntax. - * If we have ELF notes then PAE=yes implies that we must support - * the extended cr3 syntax. Otherwise we need to find the - * [extended-cr3] syntax in the __xen_guest string. + * A "bimodal" ELF note indicates the kernel will adjust to the current + * paging mode, including handling extended cr3 syntax. If we have ELF + * notes then PAE=yes implies that we must support the extended cr3 syntax. + * Otherwise we need to find the [extended-cr3] syntax in the __xen_guest + * string. We use strstr() to look for "bimodal" to allow guests to use + * "yes,bimodal" or "no,bimodal" for compatibility reasons. */ + dsi->pae_kernel = PAEKERN_no; if ( dsi->__elfnote_section ) { p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE); - if ( p != NULL && strncmp(p, "bimodal", 7) == 0 ) + if ( p != NULL && strstr(p, "bimodal") != NULL ) dsi->pae_kernel = PAEKERN_bimodal; else if ( p != NULL && strncmp(p, "yes", 3) == 0 ) dsi->pae_kernel = PAEKERN_extended_cr3; diff --git a/xen/common/elf.c b/xen/common/elf.c index 6a55053e74..8414f5e933 100644 --- a/xen/common/elf.c +++ b/xen/common/elf.c @@ -300,7 +300,7 @@ int parseelfimage(struct domain_setup_info *dsi) if ( dsi->__elfnote_section ) { p = xen_elfnote_string(dsi, XEN_ELFNOTE_PAE_MODE); - if ( p != NULL && strncmp(p, "bimodal", 7) == 0 ) + if ( p != NULL && strstr(p, "bimodal") != NULL ) dsi->pae_kernel = PAEKERN_bimodal; else if ( p != NULL && strncmp(p, "yes", 3) == 0 ) dsi->pae_kernel = PAEKERN_extended_cr3; From a25c73ef380731b0ab4347b854e81827cb6a6131 Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Tue, 9 Jan 2007 10:50:46 +0000 Subject: [PATCH 123/570] [HVM] Fix shadow memory tracking Fixes a missing free from cset 13275, and a missing prealloc. Signed-off-by: Tim Deegan --- xen/arch/x86/mm/shadow/multi.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index b86b55b085..ba4659d325 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -1655,12 +1655,15 @@ make_fl1_shadow(struct vcpu *v, gfn_t gfn) mfn_t sh_make_monitor_table(struct vcpu *v) { + struct domain *d = v->domain; ASSERT(pagetable_get_pfn(v->arch.monitor_table) == 0); + /* Guarantee we can get the memory we need */ + shadow_prealloc(d, SHADOW_MAX_ORDER); + #if CONFIG_PAGING_LEVELS == 4 { - struct domain *d = v->domain; mfn_t m4mfn; m4mfn = shadow_alloc(d, SH_type_monitor_table, 0); sh_install_xen_entries_in_l4(v, m4mfn, m4mfn); @@ -1698,7 +1701,6 @@ sh_make_monitor_table(struct vcpu *v) #elif CONFIG_PAGING_LEVELS == 3 { - struct domain *d = v->domain; mfn_t m3mfn, m2mfn; l3_pgentry_t *l3e; l2_pgentry_t *l2e; @@ -1732,7 +1734,6 @@ sh_make_monitor_table(struct vcpu *v) #elif CONFIG_PAGING_LEVELS == 2 { - struct domain *d = v->domain; mfn_t m2mfn; m2mfn = shadow_alloc(d, SH_type_monitor_table, 0); sh_install_xen_entries_in_l2(v, m2mfn, m2mfn); @@ -2095,17 +2096,19 @@ void sh_destroy_monitor_table(struct vcpu *v, mfn_t mmfn) #if (CONFIG_PAGING_LEVELS == 4) && (SHADOW_PAGING_LEVELS != 4) /* Need to destroy the l3 monitor page in slot 0 too */ { + mfn_t m3mfn; l4_pgentry_t *l4e = sh_map_domain_page(mmfn); ASSERT(l4e_get_flags(l4e[0]) & _PAGE_PRESENT); - mmfn = _mfn(l4e_get_pfn(l4e[0])); + m3mfn = _mfn(l4e_get_pfn(l4e[0])); if ( pv_32bit_guest(v) ) { /* Need to destroy the l2 monitor page in slot 3 too */ - l3_pgentry_t *l3e = sh_map_domain_page(mmfn); + l3_pgentry_t *l3e = sh_map_domain_page(m3mfn); ASSERT(l3e_get_flags(l3e[3]) & _PAGE_PRESENT); shadow_free(d, _mfn(l3e_get_pfn(l3e[3]))); sh_unmap_domain_page(l3e); } + shadow_free(d, m3mfn); sh_unmap_domain_page(l4e); } #elif CONFIG_PAGING_LEVELS == 3 From 2166b8b539fdc1b23d8da9a51028cd16fdbf28fe Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Tue, 9 Jan 2007 11:52:15 +0000 Subject: [PATCH 124/570] Do not call refreshShutdown in XendDomain for VM-list operations, as this is unnecessary and expensive. Signed-off-by: Ewan Mellor --- tools/python/xen/xend/XendDomain.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/python/xen/xend/XendDomain.py b/tools/python/xen/xend/XendDomain.py index 6ea6ae075b..4257057398 100644 --- a/tools/python/xen/xend/XendDomain.py +++ b/tools/python/xen/xend/XendDomain.py @@ -377,7 +377,7 @@ class XendDomain: dom0.setVCpuCount(target) - def _refresh(self): + def _refresh(self, refresh_shutdown = True): """Refresh the domain list. Needs to be called when either xenstore has changed or when a method requires up to date information (like uptime, cputime stats). @@ -393,7 +393,7 @@ class XendDomain: for dom in running: domid = dom['domid'] if domid in self.domains: - self.domains[domid].update(dom) + self.domains[domid].update(dom, refresh_shutdown) elif domid not in self.domains and dom['dying'] != 1: try: new_dom = XendDomainInfo.recreate(dom, False) @@ -495,7 +495,7 @@ class XendDomain: """ self.domains_lock.acquire() try: - self._refresh() + self._refresh(refresh_shutdown = False) dom = self.domain_lookup_nr(domid) if not dom: raise XendError("No domain named '%s'." % str(domid)) @@ -731,7 +731,7 @@ class XendDomain: self.domains_lock.acquire() try: - self._refresh() + self._refresh(refresh_shutdown = False) # active domains active_domains = self.domains.values() From 3b59eb2941a4f85758d369dca81592b34396f893 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 9 Jan 2007 12:04:41 +0000 Subject: [PATCH 125/570] [XEN] Fill in some more opcode space in the emulator. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 122 ++++++++++++++++++++++++++++++++++--- 1 file changed, 114 insertions(+), 8 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index b4118c4318..0b32e48213 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -62,19 +62,19 @@ static uint8_t opcode_table[256] = { /* 0x20 - 0x27 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, /* 0x28 - 0x2F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, /* 0x30 - 0x37 */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, /* 0x38 - 0x3F */ ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, ByteOp|DstReg|SrcMem|ModRM, DstReg|SrcMem|ModRM, - ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, 0, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, 0, ImplicitOps, /* 0x40 - 0x4F */ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, @@ -113,7 +113,8 @@ static uint8_t opcode_table[256] = { ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 0, 0, /* 0xA8 - 0xAF */ - 0, 0, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, + ByteOp|DstReg|SrcImm, DstReg|SrcImm, + ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, 0, 0, /* 0xB0 - 0xB7 */ ByteOp|DstReg|SrcImm|Mov, ByteOp|DstReg|SrcImm|Mov, @@ -131,7 +132,7 @@ static uint8_t opcode_table[256] = { /* 0xD0 - 0xD7 */ ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, ByteOp|DstMem|SrcImplicit|ModRM, DstMem|SrcImplicit|ModRM, - 0, 0, 0, 0, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0xD8 - 0xDF */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0 - 0xE7 */ @@ -228,6 +229,9 @@ struct operand { #define EFLG_PF (1<<2) #define EFLG_CF (1<<0) +/* Exception definitions. */ +#define EXC_DE 0 + /* * Instruction emulation: * Most instructions are emulated directly via a fragment of inline assembly @@ -408,6 +412,23 @@ do{ __asm__ __volatile__ ( \ #define mode_64bit() (def_ad_bytes == 8) +#define fail_if(p) \ +do { \ + rc = (p) ? X86EMUL_UNHANDLEABLE : 0; \ + if ( rc ) goto done; \ +} while (0) + +/* In future we will be able to generate arbitrary exceptions. */ +#define generate_exception_if(p, e) fail_if(p) + +/* Given byte has even parity (even number of 1s)? */ +static int even_parity(uint8_t v) +{ + __asm__ ( "test %%al,%%al; setp %%al" + : "=a" (v) : "0" (v) ); + return v; +} + /* Update address held in a register, based on addressing mode. */ #define _register_address_increment(reg, inc, byte_width) \ do { \ @@ -942,6 +963,9 @@ x86_emulate( } break; + case 0xa8 ... 0xa9: /* test imm,%%eax */ + dst.reg = (unsigned long *)&_regs.eax; + dst.val = dst.orig_val = _regs.eax; case 0x84 ... 0x85: test: /* test */ emulate_2op_SrcV("test", src, dst, _regs.eflags); break; @@ -960,8 +984,9 @@ x86_emulate( lock_prefix = 1; break; - case 0x88 ... 0x8b: /* mov */ case 0xc6 ... 0xc7: /* mov (sole member of Grp11) */ + fail_if((modrm_reg & 7) != 0); + case 0x88 ... 0x8b: /* mov */ dst.val = src.val; break; @@ -970,6 +995,7 @@ x86_emulate( break; case 0x8f: /* pop (sole member of Grp1a) */ + fail_if((modrm_reg & 7) != 0); /* 64-bit mode: POP defaults to a 64-bit operand. */ if ( mode_64bit() && (dst.bytes == 4) ) dst.bytes = 8; @@ -1056,7 +1082,9 @@ x86_emulate( } break; - case 0xfe ... 0xff: /* Grp4/Grp5 */ + case 0xfe: /* Grp4 */ + fail_if((modrm_reg & 7) >= 2); + case 0xff: /* Grp5 */ switch ( modrm_reg & 7 ) { case 0: /* inc */ @@ -1080,6 +1108,8 @@ x86_emulate( goto done; dst.val = dst.orig_val; /* skanky: disable writeback */ break; + case 7: + fail_if(1); default: goto cannot_emulate; } @@ -1142,6 +1172,43 @@ x86_emulate( switch ( b ) { + case 0x27: /* daa */ { + uint8_t al = _regs.eax; + unsigned long tmp; + fail_if(mode_64bit()); + __asm__ __volatile__ ( + _PRE_EFLAGS("0","4","2") "daa; " _POST_EFLAGS("0","4","2") + : "=m" (_regs.eflags), "=a" (al), "=&r" (tmp) + : "a" (al), "i" (EFLAGS_MASK) ); + *(uint8_t *)_regs.eax = al; + break; + } + + case 0x2f: /* das */ { + uint8_t al = _regs.eax; + unsigned long tmp; + fail_if(mode_64bit()); + __asm__ __volatile__ ( + _PRE_EFLAGS("0","4","2") "das; " _POST_EFLAGS("0","4","2") + : "=m" (_regs.eflags), "=a" (al), "=&r" (tmp) + : "a" (al), "i" (EFLAGS_MASK) ); + *(uint8_t *)_regs.eax = al; + break; + } + + case 0x37: /* aaa */ + case 0x3f: /* aas */ + fail_if(mode_64bit()); + _regs.eflags &= ~EFLG_CF; + if ( ((uint8_t)_regs.eax > 9) || (_regs.eflags & EFLG_AF) ) + { + ((uint8_t *)&_regs.eax)[0] += (b == 0x37) ? 6 : -6; + ((uint8_t *)&_regs.eax)[1] += (b == 0x37) ? 1 : -1; + _regs.eflags |= EFLG_CF | EFLG_AF; + } + ((uint8_t *)&_regs.eax)[0] &= 0x0f; + break; + case 0x40 ... 0x4f: /* inc/dec reg */ dst.type = OP_REG; dst.reg = decode_register(b & 7, &_regs, 0); @@ -1253,6 +1320,45 @@ x86_emulate( _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); break; + case 0xd4: /* aam */ { + unsigned int base = insn_fetch_type(uint8_t); + uint8_t al = _regs.eax; + fail_if(mode_64bit()); + generate_exception_if(base == 0, EXC_DE); + *(uint16_t *)&_regs.eax = ((al / base) << 8) | (al % base); + _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); + _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; + _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0; + _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0; + break; + } + + case 0xd5: /* aad */ { + unsigned int base = insn_fetch_type(uint8_t); + uint16_t ax = _regs.eax; + fail_if(mode_64bit()); + *(uint16_t *)&_regs.eax = (uint8_t)(ax + ((ax >> 8) * base)); + _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); + _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; + _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0; + _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0; + break; + } + + case 0xd6: /* salc */ + fail_if(mode_64bit()); + *(uint8_t *)&_regs.eax = (_regs.eflags & EFLG_CF) ? 0xff : 0x00; + break; + + case 0xd7: /* xlat */ { + unsigned long al = (uint8_t)_regs.eax; + if ( (rc = ops->read(ea.mem.seg, truncate_ea(_regs.ebx + al), + &al, 1, ctxt)) != 0 ) + goto done; + *(uint8_t *)&_regs.eax = al; + break; + } + case 0xe3: /* jcxz/jecxz (short) */ { int rel = insn_fetch_type(int8_t); if ( (ad_bytes == 2) ? !(uint16_t)_regs.ecx : From b624e752bd6783279c353509b7434d42ed35150f Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Tue, 9 Jan 2007 13:24:40 +0000 Subject: [PATCH 126/570] Fix for pygrub path on Solaris. Signed-off-by: John Levon --- tools/python/xen/xend/XendDomainInfo.py | 4 ++-- tools/python/xen/xend/osdep.py | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 3a2fa3ef4f..099302f573 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -37,7 +37,7 @@ from xen.util import asserts from xen.util.blkif import blkdev_uname_to_file from xen.util import security -from xen.xend import balloon, sxp, uuid, image, arch +from xen.xend import balloon, sxp, uuid, image, arch, osdep from xen.xend import XendRoot, XendNode, XendConfig from xen.xend.XendConfig import scrub_password @@ -1575,7 +1575,7 @@ class XendDomainInfo: else: # Boot using bootloader if not blexec or blexec == 'pygrub': - blexec = '/usr/bin/pygrub' + blexec = osdep.pygrub_path blcfg = None for (devtype, devinfo) in self.info.all_devices_sxpr(): diff --git a/tools/python/xen/xend/osdep.py b/tools/python/xen/xend/osdep.py index 35af7c55af..1dd3c7c1dd 100644 --- a/tools/python/xen/xend/osdep.py +++ b/tools/python/xen/xend/osdep.py @@ -29,8 +29,13 @@ _xend_autorestart = { "SunOS": False, } +_pygrub_path = { + "SunOS": "/usr/lib/xen/bin/pygrub" +} + def _get(var, default=None): return var.get(os.uname()[0], default) scripts_dir = _get(_scripts_dir, "/etc/xen/scripts") xend_autorestart = _get(_xend_autorestart) +pygrub_path = _get(_pygrub_path, "/usr/bin/pygrub") From 8c119d2ee4f79c20f9aeb7759d76a458f14902c1 Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Tue, 9 Jan 2007 13:24:40 +0000 Subject: [PATCH 127/570] Pass in kernel/ramdisk settings to pygrub; if specified, don't try to use grub.conf; this allows hands-off bootloading in the absence of a grub.conf. It's also useful for specifying temporary changes etc. Signed-off-by: John Levon --- tools/pygrub/src/pygrub | 116 +++++++++++++++--------- tools/python/xen/xend/XendBootloader.py | 6 ++ 2 files changed, 81 insertions(+), 41 deletions(-) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index 8fb43ca680..8b2f85bc69 100644 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -431,19 +431,56 @@ def get_entry_idx(cf, entry): return None +def run_grub(file, isconfig, entry): + global g + + def run_main(scr, *args): + global sel + global g + sel = g.run() + + g = Grub(file, isconfig) + if interactive: + curses.wrapper(run_main) + else: + sel = g.cf.default + + # set the entry to boot as requested + if entry is not None: + idx = get_entry_idx(g.cf, entry) + if idx is not None and idx > 0 and idx < len(g.cf.images): + sel = idx + + if sel == -1: + print "No kernel image selected!" + sys.exit(1) + + img = g.cf.images[sel] + + grubcfg["kernel"] = img.kernel[1] + grubcfg["ramdisk"] = img.initrd[1] + grubcfg["args"] = img.args[1] + + print "Going to boot %s" %(img.title) + print " kernel: %s" % grubcfg["kernel"] + if img.initrd: + print " initrd: %s" % grubcfg["ramdisk"] + + if isconfig: + print " args: %s" % grubcfg["args"] + sys.exit(0) + + return grubcfg + if __name__ == "__main__": sel = None - def run_main(scr, *args): - global sel - sel = g.run() - def usage(): - print >> sys.stderr, "Usage: %s [-q|--quiet] [--output=] [--entry=] " %(sys.argv[0],) + print >> sys.stderr, "Usage: %s [-q|--quiet] [--output=] [--kernel=] [--ramdisk=] [--args=] [--entry=] " %(sys.argv[0],) try: opts, args = getopt.gnu_getopt(sys.argv[1:], 'qh::', - ["quiet", "help", "output=", "entry=", + ["quiet", "help", "output=", "entry=", "kernel=", "ramdisk=", "args=", "isconfig"]) except getopt.GetoptError: usage() @@ -458,6 +495,14 @@ if __name__ == "__main__": entry = None interactive = True isconfig = False + + # what was passed in + incfg = { "kernel": None, "ramdisk": None, "args": None }; + # what grub chose + chosencfg = { "kernel": None, "ramdisk": None, "args": None }; + # what to boot + bootcfg = { "kernel": None, "ramdisk": None, "args": None }; + for o, a in opts: if o in ("-q", "--quiet"): interactive = False @@ -466,6 +511,12 @@ if __name__ == "__main__": sys.exit() elif o in ("--output",): output = a + elif o in ("--kernel",): + incfg["kernel"] = a + elif o in ("--ramdisk",): + incfg["ramdisk"] = a + elif o in ("--args",): + incfg["args"] = a elif o in ("--entry",): entry = a # specifying the entry to boot implies non-interactive @@ -473,37 +524,17 @@ if __name__ == "__main__": elif o in ("--isconfig",): isconfig = True + if output is None or output == "-": fd = sys.stdout.fileno() else: fd = os.open(output, os.O_WRONLY) - g = Grub(file, isconfig) - if interactive: - curses.wrapper(run_main) + if not incfg["kernel"]: + chosencfg = run_grub(file, isconfig, entry) else: - sel = g.cf.default - - # set the entry to boot as requested - if entry is not None: - idx = get_entry_idx(g.cf, entry) - if idx is not None and idx > 0 and idx < len(g.cf.images): - sel = idx - - if sel == -1: - print "No kernel image selected!" - sys.exit(1) - - img = g.cf.images[sel] - print "Going to boot %s" %(img.title) - print " kernel: %s" %(img.kernel[1],) - if img.initrd: - print " initrd: %s" %(img.initrd[1],) - - if isconfig: - print " args: %s" %(img.args,) - sys.exit(0) - + chosencfg = incfg + offset = 0 if is_disk_image(file): offset = get_active_offset(file) @@ -513,23 +544,26 @@ if __name__ == "__main__": # read the kernel and initrd onto the hostfs fs = fsimage.open(file, offset) - kernel = fs.open_file(img.kernel[1],).read() - (tfd, fn) = tempfile.mkstemp(prefix="boot_kernel.", + data = fs.open_file(chosencfg["kernel"]).read() + (tfd, bootcfg["kernel"]) = tempfile.mkstemp(prefix="boot_kernel.", dir="/var/run/xend/boot") - os.write(tfd, kernel) + os.write(tfd, data) os.close(tfd) - sxp = "linux (kernel %s)" %(fn,) - if img.initrd: - initrd = fs.open_file(img.initrd[1],).read() - (tfd, fn) = tempfile.mkstemp(prefix="boot_ramdisk.", + if chosencfg["ramdisk"]: + data = fs.open_file(chosencfg["ramdisk"],).read() + (tfd, bootcfg["ramdisk"]) = tempfile.mkstemp(prefix="boot_ramdisk.", dir="/var/run/xend/boot") - os.write(tfd, initrd) + os.write(tfd, data) os.close(tfd) - sxp += "(ramdisk %s)" %(fn,) else: initrd = None - sxp += "(args '%s')" %(img.args,) + + sxp = "linux (kernel %s)" % bootcfg["kernel"] + if bootcfg["ramdisk"]: + sxp += "(ramdisk %s)" % bootcfg["ramdisk"] + if chosencfg["args"]: + sxp += "(args \"%s\")" % chosencfg["args"] sys.stdout.flush() os.write(fd, sxp) diff --git a/tools/python/xen/xend/XendBootloader.py b/tools/python/xen/xend/XendBootloader.py index 170b637222..66d8427bff 100644 --- a/tools/python/xen/xend/XendBootloader.py +++ b/tools/python/xen/xend/XendBootloader.py @@ -53,6 +53,12 @@ def bootloader(blexec, disk, quiet = False, blargs = '', kernel = '', child = os.fork() if (not child): args = [ blexec ] + if kernel: + args.append("--kernel=%s" % kernel) + if ramdisk: + args.append("--ramdisk=%s" % ramdisk) + if kernel_args: + args.append("--args=%s" % kernel_args) if quiet: args.append("-q") args.append("--output=%s" % fifo) From 9c9e43e5f0185fc635334217bedad71c7304930f Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Tue, 9 Jan 2007 13:24:41 +0000 Subject: [PATCH 128/570] Sniff for Solaris if not specified. This allows Solaris domU's to automatically boot correctly without fiddling with domain configs. Signed-off-by: John Levon --- tools/pygrub/src/pygrub | 156 ++++++++++++++++++++++++---------------- 1 file changed, 95 insertions(+), 61 deletions(-) diff --git a/tools/pygrub/src/pygrub b/tools/pygrub/src/pygrub index 8b2f85bc69..ab8a20f31b 100644 --- a/tools/pygrub/src/pygrub +++ b/tools/pygrub/src/pygrub @@ -13,7 +13,7 @@ # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -import os, sys, string, struct, tempfile +import os, sys, string, struct, tempfile, re import copy import logging @@ -66,6 +66,15 @@ def get_active_offset(file): P1 = 446 return struct.unpack(" ") @@ -143,12 +152,12 @@ class GrubLineEditor(curses.textpad.Textbox): class Grub: - def __init__(self, file, isconfig = False): + def __init__(self, file, fs = None): self.screen = None self.entry_win = None self.text_win = None if file: - self.read_config(file, isconfig) + self.read_config(file, fs) def draw_main_windows(self): if self.screen is None: #only init stuff once @@ -295,8 +304,8 @@ class Grub: # else, we cancelled and should just go back break - def read_config(self, fn, isConfig = False): - """Read the given file to parse the config. If isconfig, then + def read_config(self, fn, fs = None): + """Read the given file to parse the config. If fs = None, then we're being given a raw config file rather than a disk image.""" if not os.access(fn, os.R_OK): @@ -304,38 +313,25 @@ class Grub: self.cf = grub.GrubConf.GrubConfigFile() - if isConfig: + if not fs: # set the config file and parse it self.cf.filename = fn self.cf.parse() return - offset = 0 - if is_disk_image(fn): - offset = get_active_offset(fn) - if offset == -1: - raise RuntimeError, "Unable to find active partition on disk" - - # open the image and read the grub config - fs = fsimage.open(fn, offset) - - if fs is not None: - grubfile = None - for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf", - "/grub/menu.lst", "/grub/grub.conf"): - if fs.file_exists(f): - grubfile = f - break - if grubfile is None: - raise RuntimeError, "we couldn't find grub config file in the image provided." - f = fs.open_file(grubfile) - buf = f.read() - del f - del fs - # then parse the grub config - self.cf.parse(buf) - else: - raise RuntimeError, "Unable to read filesystem" + grubfile = None + for f in ("/boot/grub/menu.lst", "/boot/grub/grub.conf", + "/grub/menu.lst", "/grub/grub.conf"): + if fs.file_exists(f): + grubfile = f + break + if grubfile is None: + raise RuntimeError, "we couldn't find grub config file in the image provided." + f = fs.open_file(grubfile) + buf = f.read() + del f + # then parse the grub config + self.cf.parse(buf) def run(self): timeout = int(self.cf.timeout) @@ -431,15 +427,16 @@ def get_entry_idx(cf, entry): return None -def run_grub(file, isconfig, entry): +def run_grub(file, entry, fs): global g + global sel def run_main(scr, *args): global sel global g sel = g.run() - g = Grub(file, isconfig) + g = Grub(file, fs) if interactive: curses.wrapper(run_main) else: @@ -457,21 +454,57 @@ def run_grub(file, isconfig, entry): img = g.cf.images[sel] + grubcfg = { "kernel": None, "ramdisk": None, "args": None } + grubcfg["kernel"] = img.kernel[1] - grubcfg["ramdisk"] = img.initrd[1] - grubcfg["args"] = img.args[1] - - print "Going to boot %s" %(img.title) - print " kernel: %s" % grubcfg["kernel"] if img.initrd: - print " initrd: %s" % grubcfg["ramdisk"] + grubcfg["ramdisk"] = img.initrd[1] + if img.args: + grubcfg["args"] = img.args - if isconfig: - print " args: %s" % grubcfg["args"] - sys.exit(0) - return grubcfg +# If nothing has been specified, look for a Solaris domU. If found, perform the +# necessary tweaks. +def sniff_solaris(fs, cfg): + if not fs.file_exists("/platform/i86xen/kernel/unix"): + return cfg + + # darned python + longmode = (sys.maxint != 2147483647L) + if not longmode: + longmode = os.uname()[4] == "x86_64" + if not longmode: + if (os.access("/usr/bin/isainfo", os.R_OK) and + os.popen("/usr/bin/isainfo -b").read() == "64\n"): + longmode = True + + if not cfg["kernel"]: + cfg["kernel"] = "/platform/i86xen/kernel/unix" + cfg["ramdisk"] = "/platform/i86pc/boot_archive" + if longmode: + cfg["kernel"] = "/platform/i86xen/kernel/amd64/unix" + cfg["ramdisk"] = "/platform/i86pc/amd64/boot_archive" + + # Unpleasant. Typically we'll have 'root=foo -k' or 'root=foo /kernel -k', + # and we need to maintain Xen properties (root= and ip=) and the kernel + # before any user args. + + xenargs = "" + userargs = "" + + if not cfg["args"]: + cfg["args"] = cfg["kernel"] + else: + for arg in cfg["args"].split(): + if re.match("^root=", arg) or re.match("^ip=", arg): + xenargs += arg + " " + elif arg != cfg["kernel"]: + userargs += arg + " " + cfg["args"] = xenargs + " " + cfg["kernel"] + " " + userargs + + return cfg + if __name__ == "__main__": sel = None @@ -497,11 +530,11 @@ if __name__ == "__main__": isconfig = False # what was passed in - incfg = { "kernel": None, "ramdisk": None, "args": None }; - # what grub chose - chosencfg = { "kernel": None, "ramdisk": None, "args": None }; + incfg = { "kernel": None, "ramdisk": None, "args": None } + # what grub or sniffing chose + chosencfg = { "kernel": None, "ramdisk": None, "args": None } # what to boot - bootcfg = { "kernel": None, "ramdisk": None, "args": None }; + bootcfg = { "kernel": None, "ramdisk": None, "args": None } for o, a in opts: if o in ("-q", "--quiet"): @@ -524,25 +557,26 @@ if __name__ == "__main__": elif o in ("--isconfig",): isconfig = True - if output is None or output == "-": fd = sys.stdout.fileno() else: fd = os.open(output, os.O_WRONLY) - if not incfg["kernel"]: - chosencfg = run_grub(file, isconfig, entry) - else: - chosencfg = incfg - - offset = 0 - if is_disk_image(file): - offset = get_active_offset(file) - if offset == -1: - raise RuntimeError, "Unable to find active partition on disk" + # debug + if isconfig: + chosencfg = run_grub(file, entry) + print " kernel: %s" % chosencfg["kernel"] + if img.initrd: + print " initrd: %s" % chosencfg["ramdisk"] + print " args: %s" % chosencfg["args"] + sys.exit(0) - # read the kernel and initrd onto the hostfs - fs = fsimage.open(file, offset) + fs = open_fs(file) + + chosencfg = sniff_solaris(fs, incfg) + + if not chosencfg["kernel"]: + chosencfg = run_grub(file, entry, fs) data = fs.open_file(chosencfg["kernel"]).read() (tfd, bootcfg["kernel"]) = tempfile.mkstemp(prefix="boot_kernel.", From 662e32f5cc5eae12c8bcc870d3f1b85a7fccf95a Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Tue, 9 Jan 2007 13:24:42 +0000 Subject: [PATCH 129/570] Fix auto-bootloading via 'xm create'. Signed-off-by: John Levon --- tools/python/xen/xm/create.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 1726979aaa..1250dae5f4 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -990,8 +990,6 @@ def preprocess_vnc(vals): vals.extra = vnc + ' ' + vals.extra def preprocess(vals): - if not vals.kernel and not vals.bootloader: - err("No kernel specified") preprocess_disk(vals) preprocess_pci(vals) preprocess_ioports(vals) From eb568d662406284527bf0de19420378b0125e89f Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Tue, 9 Jan 2007 13:24:43 +0000 Subject: [PATCH 130/570] Fix bootloader = "pygrub" via 'xm create'. Signed-off-by: John Levon --- tools/python/xen/xm/create.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 1250dae5f4..4bc94932b8 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -28,6 +28,7 @@ import xmlrpclib from xen.xend import sxp from xen.xend import PrettyPrint +from xen.xend import osdep import xen.xend.XendClient from xen.xend.XendBootloader import bootloader from xen.util import blkif @@ -759,6 +760,8 @@ def make_config(vals): config_image = configure_image(vals) if vals.bootloader: + if vals.bootloader == "pygrub": + vals.bootloader = osdep.pygrub_path config_image = run_bootloader(vals, config_image) config.append(['bootloader', vals.bootloader]) if vals.bootargs: From 38d6397a83af62e5036a09815552d12c416e803b Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Tue, 9 Jan 2007 13:24:44 +0000 Subject: [PATCH 131/570] Fix xm create direct call to XendBootloader Signed-off-by: John Levon --- tools/python/xen/xm/create.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 4bc94932b8..175e0fffc7 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -719,8 +719,11 @@ def run_bootloader(vals, config_image): "--entry= directly.") vals.bootargs = "--entry=%s" %(vals.bootentry,) + kernel = sxp.child_value(config_image, 'kernel') + ramdisk = sxp.child_value(config_image, 'ramdisk') + args = sxp.child_value(config_image, 'args') return bootloader(vals.bootloader, file, not vals.console_autoconnect, - vals.bootargs, config_image) + vals.bootargs, kernel, ramdisk, args) def make_config(vals): """Create the domain configuration. From db442369b3747f1d4be9b31d9ff459536e2a0a4b Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Tue, 9 Jan 2007 13:24:45 +0000 Subject: [PATCH 132/570] When booting via xm, only run the bootloader if it's in non-interactive mode: otherwise we lose the user's named kernel and try to bootload the temporary file pygrub returned. Signed-off-by: John Levon --- tools/python/xen/xm/create.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/python/xen/xm/create.py b/tools/python/xen/xm/create.py index 175e0fffc7..094b583d57 100644 --- a/tools/python/xen/xm/create.py +++ b/tools/python/xen/xm/create.py @@ -765,7 +765,12 @@ def make_config(vals): if vals.bootloader: if vals.bootloader == "pygrub": vals.bootloader = osdep.pygrub_path - config_image = run_bootloader(vals, config_image) + + # if a kernel is specified, we're using the bootloader + # non-interactively, and need to let xend run it so we preserve the + # real kernel choice. + if not vals.kernel: + config_image = run_bootloader(vals, config_image) config.append(['bootloader', vals.bootloader]) if vals.bootargs: config.append(['bootloader_args', vals.bootargs]) From 0137f2b67b55aef4f8939d31740c49471172614f Mon Sep 17 00:00:00 2001 From: Tim Deegan Date: Tue, 9 Jan 2007 16:49:16 +0000 Subject: [PATCH 133/570] [HVM] Remove unnecessary write barriers Using a volatile pointer saves us from the compier reordering these writes, and the processor won't let them appear out of order. Signed-off-by: Tim Deegan --- xen/arch/x86/mm/shadow/multi.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/xen/arch/x86/mm/shadow/multi.c b/xen/arch/x86/mm/shadow/multi.c index ba4659d325..e040e60e71 100644 --- a/xen/arch/x86/mm/shadow/multi.c +++ b/xen/arch/x86/mm/shadow/multi.c @@ -851,9 +851,7 @@ static inline void safe_write_entry(void *dst, void *src) * then writing the high word before the low word. */ BUILD_BUG_ON(sizeof (shadow_l1e_t) != 2 * sizeof (unsigned long)); d[0] = 0; - wmb(); d[1] = s[1]; - wmb(); d[0] = s[0]; #else /* In 32-bit and 64-bit, sizeof(pte) == sizeof(ulong) == 1 word, From c9d971bec6fb2584ee469dbbfc30a6dc76d65204 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 9 Jan 2007 16:59:52 +0000 Subject: [PATCH 134/570] [XEN] Emulate DAA/DAS the hard way. We cannot execute the instruction directly within the emulator as it is unavailable if the emulator runs in x86/64 mode. Signed-off-by: Keir Fraser --- tools/tests/test_x86_emulator.c | 67 ++++++++++++++++++++++++++++++++- xen/arch/x86/x86_emulate.c | 46 ++++++++++++++++------ 2 files changed, 99 insertions(+), 14 deletions(-) diff --git a/tools/tests/test_x86_emulator.c b/tools/tests/test_x86_emulator.c index 8bbfa3af28..89687e0d6e 100644 --- a/tools/tests/test_x86_emulator.c +++ b/tools/tests/test_x86_emulator.c @@ -15,6 +15,15 @@ typedef int64_t s64; #include #include +/* EFLAGS bit definitions. */ +#define EFLG_OF (1<<11) +#define EFLG_DF (1<<10) +#define EFLG_SF (1<<7) +#define EFLG_ZF (1<<6) +#define EFLG_AF (1<<4) +#define EFLG_PF (1<<2) +#define EFLG_CF (1<<0) + static int read( unsigned int seg, unsigned long offset, @@ -98,8 +107,8 @@ int main(int argc, char **argv) struct x86_emulate_ctxt ctxt; struct cpu_user_regs regs; char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */ - unsigned int *res; - int rc; + unsigned int *res, bcdres_native, bcdres_emul; + int rc, i; ctxt.regs = ®s; ctxt.address_bytes = 4; @@ -399,6 +408,60 @@ int main(int argc, char **argv) goto fail; printf("okay\n"); + printf("%-40s", "Testing daa/das (all inputs)..."); + /* Bits 0-7: AL; Bit 8: EFLG_AF; Bit 9: EFLG_CF; Bit 10: DAA vs. DAS. */ + for ( i = 0; i < 0x800; i++ ) + { + regs.eflags = (i & 0x200) ? EFLG_CF : 0; + regs.eflags |= (i & 0x100) ? EFLG_AF : 0; + if ( i & 0x400 ) + __asm__ ( + "pushf; and $0xffffffee,(%%esp); or %1,(%%esp); popf; das; " + "pushf; popl %1" + : "=a" (bcdres_native), "=r" (regs.eflags) + : "0" (i & 0xff), "1" (regs.eflags) ); + else + __asm__ ( + "pushf; and $0xffffffee,(%%esp); or %1,(%%esp); popf; daa; " + "pushf; popl %1" + : "=a" (bcdres_native), "=r" (regs.eflags) + : "0" (i & 0xff), "1" (regs.eflags) ); + bcdres_native |= (regs.eflags & EFLG_CF) ? 0x200 : 0; + bcdres_native |= (regs.eflags & EFLG_AF) ? 0x100 : 0; + + instr[0] = (i & 0x400) ? 0x2f: 0x27; /* daa/das */ + regs.eflags = (i & 0x200) ? EFLG_CF : 0; + regs.eflags |= (i & 0x100) ? EFLG_AF : 0; + regs.eip = (unsigned long)&instr[0]; + regs.eax = (unsigned char)i; + rc = x86_emulate(&ctxt, &emulops); + bcdres_emul = regs.eax; + bcdres_emul |= (regs.eflags & EFLG_CF) ? 0x200 : 0; + bcdres_emul |= (regs.eflags & EFLG_AF) ? 0x100 : 0; + if ( (rc != 0) || (regs.eax > 255) || + (regs.eip != (unsigned long)&instr[1]) ) + goto fail; + + if ( bcdres_emul != bcdres_native ) + { + printf("%s: AL=%02x %s %s\n" + "Output: AL=%02x %s %s\n" + "Emul.: AL=%02x %s %s\n", + (i & 0x400) ? "DAS" : "DAA", + (unsigned char)i, + (i & 0x200) ? "CF" : " ", + (i & 0x100) ? "AF" : " ", + (unsigned char)bcdres_native, + (bcdres_native & 0x200) ? "CF" : " ", + (bcdres_native & 0x100) ? "AF" : " ", + (unsigned char)bcdres_emul, + (bcdres_emul & 0x200) ? "CF" : " ", + (bcdres_emul & 0x100) ? "AF" : " "); + goto fail; + } + } + printf("okay\n"); + return 0; fail: diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 0b32e48213..57650986f1 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -1174,25 +1174,47 @@ x86_emulate( { case 0x27: /* daa */ { uint8_t al = _regs.eax; - unsigned long tmp; + unsigned long eflags = _regs.eflags; fail_if(mode_64bit()); - __asm__ __volatile__ ( - _PRE_EFLAGS("0","4","2") "daa; " _POST_EFLAGS("0","4","2") - : "=m" (_regs.eflags), "=a" (al), "=&r" (tmp) - : "a" (al), "i" (EFLAGS_MASK) ); - *(uint8_t *)_regs.eax = al; + _regs.eflags &= ~(EFLG_CF|EFLG_AF); + if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) ) + { + *(uint8_t *)&_regs.eax += 6; + _regs.eflags |= EFLG_AF; + } + if ( (al > 0x99) || (eflags & EFLG_CF) ) + { + *(uint8_t *)&_regs.eax += 0x60; + _regs.eflags |= EFLG_CF; + } + _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); + _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; + _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0; + _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0; break; } case 0x2f: /* das */ { uint8_t al = _regs.eax; - unsigned long tmp; + unsigned long eflags = _regs.eflags; fail_if(mode_64bit()); - __asm__ __volatile__ ( - _PRE_EFLAGS("0","4","2") "das; " _POST_EFLAGS("0","4","2") - : "=m" (_regs.eflags), "=a" (al), "=&r" (tmp) - : "a" (al), "i" (EFLAGS_MASK) ); - *(uint8_t *)_regs.eax = al; + _regs.eflags &= ~(EFLG_CF|EFLG_AF); + if ( ((al & 0x0f) > 9) || (eflags & EFLG_AF) ) + { + _regs.eflags |= EFLG_AF; + if ( (al < 6) || (eflags & EFLG_CF) ) + _regs.eflags |= EFLG_CF; + *(uint8_t *)&_regs.eax -= 6; + } + if ( (al > 0x99) || (eflags & EFLG_CF) ) + { + *(uint8_t *)&_regs.eax -= 0x60; + _regs.eflags |= EFLG_CF; + } + _regs.eflags &= ~(EFLG_SF|EFLG_ZF|EFLG_PF); + _regs.eflags |= ((uint8_t)_regs.eax == 0) ? EFLG_ZF : 0; + _regs.eflags |= (( int8_t)_regs.eax < 0) ? EFLG_SF : 0; + _regs.eflags |= even_parity(_regs.eax) ? EFLG_PF : 0; break; } From e0fd6020bc0bd71083db8786c60605f1df013452 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 9 Jan 2007 17:11:46 +0000 Subject: [PATCH 135/570] [TEST] Fix x86_emulate tests on x86/64 host. Signed-off-by: Keir Fraser --- tools/tests/test_x86_emulator.c | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/tools/tests/test_x86_emulator.c b/tools/tests/test_x86_emulator.c index 89687e0d6e..2753795d5c 100644 --- a/tools/tests/test_x86_emulator.c +++ b/tools/tests/test_x86_emulator.c @@ -106,9 +106,12 @@ int main(int argc, char **argv) { struct x86_emulate_ctxt ctxt; struct cpu_user_regs regs; - char instr[20] = { 0x01, 0x08 }; /* add %ecx,(%eax) */ - unsigned int *res, bcdres_native, bcdres_emul; - int rc, i; + char *instr; + unsigned int *res; + int rc; +#ifndef __x86_64__ + unsigned int i, bcdres_native, bcdres_emul; +#endif ctxt.regs = ®s; ctxt.address_bytes = 4; @@ -120,6 +123,7 @@ int main(int argc, char **argv) fprintf(stderr, "mmap to low address failed\n"); exit(1); } + instr = (char *)res + 0x100; printf("%-40s", "Testing addl %%ecx,(%%eax)..."); instr[0] = 0x01; instr[1] = 0x08; @@ -409,6 +413,7 @@ int main(int argc, char **argv) printf("okay\n"); printf("%-40s", "Testing daa/das (all inputs)..."); +#ifndef __x86_64__ /* Bits 0-7: AL; Bit 8: EFLG_AF; Bit 9: EFLG_CF; Bit 10: DAA vs. DAS. */ for ( i = 0; i < 0x800; i++ ) { @@ -426,6 +431,9 @@ int main(int argc, char **argv) "pushf; popl %1" : "=a" (bcdres_native), "=r" (regs.eflags) : "0" (i & 0xff), "1" (regs.eflags) ); + bcdres_native |= (regs.eflags & EFLG_PF) ? 0x1000 : 0; + bcdres_native |= (regs.eflags & EFLG_ZF) ? 0x800 : 0; + bcdres_native |= (regs.eflags & EFLG_SF) ? 0x400 : 0; bcdres_native |= (regs.eflags & EFLG_CF) ? 0x200 : 0; bcdres_native |= (regs.eflags & EFLG_AF) ? 0x100 : 0; @@ -436,6 +444,9 @@ int main(int argc, char **argv) regs.eax = (unsigned char)i; rc = x86_emulate(&ctxt, &emulops); bcdres_emul = regs.eax; + bcdres_emul |= (regs.eflags & EFLG_PF) ? 0x1000 : 0; + bcdres_emul |= (regs.eflags & EFLG_ZF) ? 0x800 : 0; + bcdres_emul |= (regs.eflags & EFLG_SF) ? 0x400 : 0; bcdres_emul |= (regs.eflags & EFLG_CF) ? 0x200 : 0; bcdres_emul |= (regs.eflags & EFLG_AF) ? 0x100 : 0; if ( (rc != 0) || (regs.eax > 255) || @@ -445,8 +456,8 @@ int main(int argc, char **argv) if ( bcdres_emul != bcdres_native ) { printf("%s: AL=%02x %s %s\n" - "Output: AL=%02x %s %s\n" - "Emul.: AL=%02x %s %s\n", + "Output: AL=%02x %s %s %s %s %s\n" + "Emul.: AL=%02x %s %s %s %s %s\n", (i & 0x400) ? "DAS" : "DAA", (unsigned char)i, (i & 0x200) ? "CF" : " ", @@ -454,13 +465,22 @@ int main(int argc, char **argv) (unsigned char)bcdres_native, (bcdres_native & 0x200) ? "CF" : " ", (bcdres_native & 0x100) ? "AF" : " ", + (bcdres_native & 0x1000) ? "PF" : " ", + (bcdres_native & 0x800) ? "ZF" : " ", + (bcdres_native & 0x400) ? "SF" : " ", (unsigned char)bcdres_emul, (bcdres_emul & 0x200) ? "CF" : " ", - (bcdres_emul & 0x100) ? "AF" : " "); + (bcdres_emul & 0x100) ? "AF" : " ", + (bcdres_emul & 0x1000) ? "PF" : " ", + (bcdres_emul & 0x800) ? "ZF" : " ", + (bcdres_emul & 0x400) ? "SF" : " "); goto fail; } } printf("okay\n"); +#else + printf("skipped\n"); +#endif return 0; From b0a47bd080d9c9d78cbc054d04db609d0d085d2d Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 9 Jan 2007 17:14:28 +0000 Subject: [PATCH 136/570] [LINUX] Kexec: Don't try to load an NULL image. This can occur when unloading. Signed-off-by: Ian Campbell --- linux-2.6-xen-sparse/kernel/kexec.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/linux-2.6-xen-sparse/kernel/kexec.c b/linux-2.6-xen-sparse/kernel/kexec.c index 9a1dbb6ae3..bb19157362 100644 --- a/linux-2.6-xen-sparse/kernel/kexec.c +++ b/linux-2.6-xen-sparse/kernel/kexec.c @@ -1012,9 +1012,11 @@ asmlinkage long sys_kexec_load(unsigned long entry, unsigned long nr_segments, goto out; } #ifdef CONFIG_XEN - result = xen_machine_kexec_load(image); - if (result) - goto out; + if (image) { + result = xen_machine_kexec_load(image); + if (result) + goto out; + } #endif /* Install the new kernel, and Uninstall the old */ image = xchg(dest_image, image); From 123e738ef2e8111fdb21972766f9f209ef21cf46 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 9 Jan 2007 17:15:28 +0000 Subject: [PATCH 137/570] [XEN] Kexec: Clean up ELF note construction to avoid multiply nested struct/unions and the packed keyword. Signed-off-by: Ian Campbell --- xen/common/kexec.c | 84 ++++++++++++++++++++++++++++----------- xen/include/xen/elfcore.h | 57 -------------------------- 2 files changed, 61 insertions(+), 80 deletions(-) diff --git a/xen/common/kexec.c b/xen/common/kexec.c index 1b470a5e50..8271aa56f7 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -26,7 +26,15 @@ typedef long ret_t; -DEFINE_PER_CPU (crash_note_t, crash_notes); +#define ELFNOTE_ALIGN(_n_) (((_n_)+3)&~3) +#define ELFNOTE_NAME(_n_) ((void*)(_n_) + sizeof(*(_n_))) +#define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + ELFNOTE_ALIGN((_n_)->namesz)) +#define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + ELFNOTE_ALIGN((_n_)->descsz)) + +DEFINE_PER_CPU(void *, crash_notes); + +Elf_Note *xen_crash_note; + cpumask_t crash_saved_cpus; xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR]; @@ -70,40 +78,29 @@ static void one_cpu_only(void) void kexec_crash_save_cpu(void) { int cpu = smp_processor_id(); - crash_note_t *cntp; + Elf_Note *note = per_cpu(crash_notes, cpu); + ELF_Prstatus *prstatus; + crash_xen_core_t *xencore; if ( cpu_test_and_set(cpu, crash_saved_cpus) ) return; - cntp = &per_cpu(crash_notes, cpu); - elf_core_save_regs(&cntp->core.desc.desc.pr_reg, - &cntp->xen_regs.desc.desc); + prstatus = ELFNOTE_DESC(note); - /* Set up crash "CORE" note. */ - setup_crash_note(cntp, core, CORE_STR, CORE_STR_LEN, NT_PRSTATUS); + note = ELFNOTE_NEXT(note); + xencore = ELFNOTE_DESC(note); - /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_REGS. */ - setup_crash_note(cntp, xen_regs, XEN_STR, XEN_STR_LEN, - XEN_ELFNOTE_CRASH_REGS); + elf_core_save_regs(&prstatus->pr_reg, xencore); } /* Set up the single Xen-specific-info crash note. */ crash_xen_info_t *kexec_crash_save_info(void) { int cpu = smp_processor_id(); - crash_note_t *cntp; - crash_xen_info_t *info; + crash_xen_info_t *info = ELFNOTE_DESC(xen_crash_note); BUG_ON(!cpu_test_and_set(cpu, crash_saved_cpus)); - cntp = &per_cpu(crash_notes, cpu); - - /* Set up crash note "Xen", XEN_ELFNOTE_CRASH_INFO. */ - setup_crash_note(cntp, xen_info, XEN_STR, XEN_STR_LEN, - XEN_ELFNOTE_CRASH_INFO); - - info = &cntp->xen_info.desc.desc; - info->xen_major_version = xen_major_version(); info->xen_minor_version = xen_minor_version(); info->xen_extra_version = __pa(xen_extra_version()); @@ -147,6 +144,14 @@ static __init int register_crashdump_trigger(void) } __initcall(register_crashdump_trigger); +static void setup_note(Elf_Note *n, const char *name, int type, int descsz) +{ + strcpy(ELFNOTE_NAME(n), name); + n->namesz = strlen(name); + n->descsz = descsz; + n->type = type; +} + #define kexec_get(x) kexec_get_##x #endif @@ -167,11 +172,44 @@ static int kexec_get(xen)(xen_kexec_range_t *range) static int kexec_get(cpu)(xen_kexec_range_t *range) { - if ( range->nr < 0 || range->nr >= num_present_cpus() ) + int nr = range->nr; + int nr_bytes = sizeof(Elf_Note) * 2 + + ELFNOTE_ALIGN(sizeof(ELF_Prstatus)) + + ELFNOTE_ALIGN(sizeof(crash_xen_core_t)); + + if ( nr < 0 || nr >= num_present_cpus() ) return -EINVAL; - range->start = __pa((unsigned long)&per_cpu(crash_notes, range->nr)); - range->size = sizeof(crash_note_t); + /* The Xen info note is included in CPU0's range. */ + if ( nr == 0 ) + nr_bytes += sizeof(Elf_Note) + ELFNOTE_ALIGN(sizeof(crash_xen_info_t)); + + if ( per_cpu(crash_notes, nr) == NULL ) + { + Elf_Note *note; + + note = per_cpu(crash_notes, nr) = xmalloc_bytes(nr_bytes); + + if ( note == NULL ) + return -ENOMEM; + + /* Setup CORE note. */ + setup_note(note, "CORE", NT_PRSTATUS, sizeof(ELF_Prstatus)); + + /* Setup Xen CORE note. */ + note = ELFNOTE_NEXT(note); + setup_note(note, "Xen", XEN_ELFNOTE_CRASH_REGS, sizeof(crash_xen_core_t)); + + if (nr == 0) + { + /* Setup system wide Xen info note. */ + xen_crash_note = note = ELFNOTE_NEXT(note); + setup_note(note, "Xen", XEN_ELFNOTE_CRASH_INFO, sizeof(crash_xen_info_t)); + } + } + + range->start = __pa((unsigned long)per_cpu(crash_notes, nr)); + range->size = nr_bytes; return 0; } diff --git a/xen/include/xen/elfcore.h b/xen/include/xen/elfcore.h index 75ce7c49ef..fbe8ed1a6a 100644 --- a/xen/include/xen/elfcore.h +++ b/xen/include/xen/elfcore.h @@ -56,49 +56,6 @@ typedef struct int pr_fpvalid; /* True if math co-processor being used. */ } ELF_Prstatus; -/* - * The following data structures provide 64-bit ELF notes. In theory it should - * be possible to support both 64-bit and 32-bit ELF files, but to keep it - * simple we only do 64-bit. - * - * Please note that the current code aligns the 64-bit notes in the same - * way as Linux does. We are not following the 64-bit ELF spec, no one does. - * - * We are avoiding two problems by restricting us to 64-bit notes only: - * - Alignment of notes change with the word size. Ick. - * - We would need to tell kexec-tools which format we are using in the - * hypervisor to make sure the right ELF format is generated. - * That requires infrastructure. Let's not. - */ - -#define NOTE_ALIGN(x, n) ((x + ((1 << n) - 1)) / (1 << n)) -#define PAD32(x) u32 pad_data[NOTE_ALIGN(x, 2)] - -#define TYPEDEF_NOTE(type, strlen, desctype) \ - typedef struct { \ - union { \ - struct { \ - Elf_Note note; \ - unsigned char name[strlen]; \ - } note; \ - PAD32(sizeof(Elf_Note) + strlen); \ - } note; \ - union { \ - desctype desc; \ - PAD32(sizeof(desctype)); \ - } desc; \ - } __attribute__ ((packed)) type - -#define CORE_STR "CORE" -#define CORE_STR_LEN 5 /* including terminating zero */ - -TYPEDEF_NOTE(crash_note_core_t, CORE_STR_LEN, ELF_Prstatus); - -#define XEN_STR "Xen" -#define XEN_STR_LEN 4 /* including terminating zero */ - -TYPEDEF_NOTE(crash_note_xen_core_t, XEN_STR_LEN, crash_xen_core_t); - typedef struct { unsigned long xen_major_version; unsigned long xen_minor_version; @@ -113,20 +70,6 @@ typedef struct { #endif } crash_xen_info_t; -TYPEDEF_NOTE(crash_note_xen_info_t, XEN_STR_LEN, crash_xen_info_t); - -typedef struct { - crash_note_core_t core; - crash_note_xen_core_t xen_regs; - crash_note_xen_info_t xen_info; -} __attribute__ ((packed)) crash_note_t; - -#define setup_crash_note(np, member, str, str_len, id) \ - np->member.note.note.note.namesz = str_len; \ - np->member.note.note.note.descsz = sizeof(np->member.desc.desc); \ - np->member.note.note.note.type = id; \ - memcpy(np->member.note.note.name, str, str_len) - #endif /* __ELFCOREC_H__ */ /* From 0ae7229c6664f19f27b83e66d8fd3e4c63eb187c Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Tue, 9 Jan 2007 17:15:29 +0000 Subject: [PATCH 138/570] [XEN] Kexec: Make some variables static. Signed-off-by: Ian Campbell --- xen/common/kexec.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/xen/common/kexec.c b/xen/common/kexec.c index 8271aa56f7..294e57b353 100644 --- a/xen/common/kexec.c +++ b/xen/common/kexec.c @@ -31,21 +31,21 @@ typedef long ret_t; #define ELFNOTE_DESC(_n_) (ELFNOTE_NAME(_n_) + ELFNOTE_ALIGN((_n_)->namesz)) #define ELFNOTE_NEXT(_n_) (ELFNOTE_DESC(_n_) + ELFNOTE_ALIGN((_n_)->descsz)) -DEFINE_PER_CPU(void *, crash_notes); +static DEFINE_PER_CPU(void *, crash_notes); -Elf_Note *xen_crash_note; +static Elf_Note *xen_crash_note; -cpumask_t crash_saved_cpus; +static cpumask_t crash_saved_cpus; -xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR]; +static xen_kexec_image_t kexec_image[KEXEC_IMAGE_NR]; #define KEXEC_FLAG_DEFAULT_POS (KEXEC_IMAGE_NR + 0) #define KEXEC_FLAG_CRASH_POS (KEXEC_IMAGE_NR + 1) #define KEXEC_FLAG_IN_PROGRESS (KEXEC_IMAGE_NR + 2) -unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */ +static unsigned long kexec_flags = 0; /* the lowest bits are for KEXEC_IMAGE... */ -spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED; +static spinlock_t kexec_lock = SPIN_LOCK_UNLOCKED; xen_kexec_reserve_t kexec_crash_area; From e4658203b4ce1947e81e606d72ac9b1cfd2109fc Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Tue, 9 Jan 2007 17:23:22 +0000 Subject: [PATCH 139/570] Add needed modules to the ramdisk if the modules exist on the current system. (i.e. the current system contains a modularized kernel) Signed-off-by: Lynn Bendixsen --- tools/xm-test/ramdisk/Makefile.am | 13 +++++++++++-- tools/xm-test/ramdisk/skel/etc/init.d/rcS | 11 +++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/tools/xm-test/ramdisk/Makefile.am b/tools/xm-test/ramdisk/Makefile.am index b6c59d60e5..1de0d1423d 100644 --- a/tools/xm-test/ramdisk/Makefile.am +++ b/tools/xm-test/ramdisk/Makefile.am @@ -36,7 +36,12 @@ XMTEST_MAJ_VER = $(shell echo @PACKAGE_VERSION@ | perl -pe 's/(\d+)\.(\d+)\.\d+/ XMTEST_VER_IMG = initrd-$(XMTEST_MAJ_VER)-$(BR_ARCH).img XMTEST_DL_IMG = $(shell echo $(XMTEST_VER_IMG) | sed -e 's/x86_64/i386/g') -EXTRA_ROOT_DIRS = sys +EXTRA_ROOT_DIRS = sys modules + +BLKDRV = /lib/modules/$(shell uname -r)/kernel/drivers/xen/blkfront/xenblk.ko +NETDRV = /lib/modules/$(shell uname -r)/kernel/drivers/xen/netfront/xennet.ko +PKTDRV = /lib/modules/$(shell uname -r)/kernel/net/packet/af_packet.ko + if HVM all: initrd.img disk.img @@ -60,7 +65,11 @@ $(BR_IMG): $(BR_SRC) $(XMTEST_VER_IMG): $(BR_IMG) chmod a+x skel/etc/init.d/rcS - (cd skel; mkdir -p $(EXTRA_ROOT_DIRS); tar cf - .) \ + cd skel && mkdir -p $(EXTRA_ROOT_DIRS) + -[ -e "$(BLKDRV)" ] && cp $(BLKDRV) skel/modules + -[ -e "$(NETDRV)" ] && cp $(NETDRV) skel/modules + -[ -e "$(PKTDRV)" ] && cp $(PKTDRV) skel/modules + (cd skel; tar cf - .) \ | (cd $(BR_SRC)/$(BR_ROOT); tar xvf -) cd $(BR_SRC) && make cp $(BR_IMG) $(XMTEST_VER_IMG) diff --git a/tools/xm-test/ramdisk/skel/etc/init.d/rcS b/tools/xm-test/ramdisk/skel/etc/init.d/rcS index b3a92109e9..4c294f3dff 100644 --- a/tools/xm-test/ramdisk/skel/etc/init.d/rcS +++ b/tools/xm-test/ramdisk/skel/etc/init.d/rcS @@ -6,3 +6,14 @@ mount -a if uname -r | grep -q '^2.6'; then mount -t sysfs none /sys fi + +# If the block, net, and packet drivers are modules, we need to load them +if test -e /modules/xenblk.ko; then + insmod /modules/xenblk.ko > /dev/null 2>&1 +fi +if test -e /modules/xennet.ko; then + insmod /modules/xennet.ko > /dev/null 2>&1 +fi +if test -e /modules/af_packet.ko; then + insmod /modules/af_packet.ko > /dev/null 2>&1 +fi From 00e52488131f7190f005c65a64169752a5b9b9a8 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Tue, 9 Jan 2007 17:25:28 +0000 Subject: [PATCH 140/570] This simple patch allows domains created in the xm-test suite to be created as managed domains using either a parameter to the XenTestDomain() constructor or by setting the environment variable XM_MANAGED_DOMAINS and running the tests with it. Signed-off-by: Stefan Berger --- tools/xm-test/lib/XmTestLib/DomainTracking.py | 43 +++++++++++++++++++ tools/xm-test/lib/XmTestLib/XenDomain.py | 28 ++++++++++-- 2 files changed, 67 insertions(+), 4 deletions(-) create mode 100644 tools/xm-test/lib/XmTestLib/DomainTracking.py diff --git a/tools/xm-test/lib/XmTestLib/DomainTracking.py b/tools/xm-test/lib/XmTestLib/DomainTracking.py new file mode 100644 index 0000000000..cbd25146f5 --- /dev/null +++ b/tools/xm-test/lib/XmTestLib/DomainTracking.py @@ -0,0 +1,43 @@ +#!/usr/bin/python +""" + Copyright (C) International Business Machines Corp., 2005 + Author: Dan Smith + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; under version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +""" + +import atexit +import Test + +# Tracking of managed domains +_managedDomains = [] +registered = 0 + +def addManagedDomain(name): + global registered + _managedDomains.append(name) + if not registered: + atexit.register(destroyManagedDomains) + registered = 1 + +def delManagedDomain(name): + if name in _managedDomains: + del _managedDomains[_managedDomains.index(name)] + +def destroyManagedDomains(): + if len(_managedDomains) > 0: + for m in _managedDomains: + Test.traceCommand("xm destroy %s" % m) + Test.traceCommand("xm delete %s" % m) diff --git a/tools/xm-test/lib/XmTestLib/XenDomain.py b/tools/xm-test/lib/XmTestLib/XenDomain.py index 40aaebf9b4..3fcfcea4f1 100644 --- a/tools/xm-test/lib/XmTestLib/XenDomain.py +++ b/tools/xm-test/lib/XmTestLib/XenDomain.py @@ -29,6 +29,7 @@ from Test import * from config import * from Console import * from XenDevice import * +from DomainTracking import * from acm import * @@ -147,7 +148,7 @@ class DomainError(Exception): class XenDomain: - def __init__(self, name=None, config=None): + def __init__(self, name=None, config=None, isManaged=False): """Create a domain object. @param config: String filename of config file """ @@ -162,6 +163,10 @@ class XenDomain: self.devices = {} self.netEnv = "bridge" + if os.getenv("XM_MANAGED_DOMAINS"): + isManaged = True + self.isManaged = isManaged + # Set domain type, either PV for ParaVirt domU or HVM for # FullVirt domain if ENABLE_HVM_SUPPORT: @@ -171,7 +176,17 @@ class XenDomain: def start(self, noConsole=False): - ret, output = traceCommand("xm create %s" % self.config) + if not self.isManaged: + ret, output = traceCommand("xm create %s" % self.config) + else: + ret, output = traceCommand("xm new %s" % self.config) + if ret != 0: + _ret, output = traceCommand("xm delete " + + self.config.getOpt("name")) + else: + ret, output = traceCommand("xm start " + + self.config.getOpt("name")) + addManagedDomain(self.config.getOpt("name")) if ret != 0: raise DomainError("Failed to create domain", @@ -218,6 +233,10 @@ class XenDomain: self.closeConsole() ret, output = traceCommand(prog + cmd + self.config.getOpt("name")) + if self.isManaged: + ret, output = traceCommand(prog + " delete " + + self.config.getOpt("name")) + delManagedDomain(self.config.getOpt("name")) return ret @@ -296,7 +315,7 @@ class XenDomain: class XmTestDomain(XenDomain): def __init__(self, name=None, extraConfig=None, - baseConfig=arch.configDefaults): + baseConfig=arch.configDefaults, isManaged=False): """Create a new xm-test domain @param name: The requested domain name @param extraConfig: Additional configuration options @@ -312,7 +331,8 @@ class XmTestDomain(XenDomain): elif not config.getOpt("name"): config.setOpt("name", getUniqueName()) - XenDomain.__init__(self, config.getOpt("name"), config=config) + XenDomain.__init__(self, config.getOpt("name"), config=config, + isManaged=isManaged) def minSafeMem(self): return arch.minSafeMem From e3e7d81e413560eaeca19f7ec613e63ea0f02e8c Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Tue, 9 Jan 2007 17:38:48 +0000 Subject: [PATCH 141/570] Update sched-credit test to match new format from xm sched-credit. Signed-off-by: Ewan Mellor --- .../01_sched_credit_weight_cap_pos.py | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/tools/xm-test/tests/sched-credit/01_sched_credit_weight_cap_pos.py b/tools/xm-test/tests/sched-credit/01_sched_credit_weight_cap_pos.py index e0b1fe5846..cdbca0f757 100644 --- a/tools/xm-test/tests/sched-credit/01_sched_credit_weight_cap_pos.py +++ b/tools/xm-test/tests/sched-credit/01_sched_credit_weight_cap_pos.py @@ -2,14 +2,27 @@ # # Sched-credit tests modified from SEDF tests # + +import re + from XmTestLib import * +paramsRE = re.compile(r'^[^ ]* *[^ ]* *([^ ]*) *([^ ]*)$') + def get_sched_credit_params(domain): - status, output = traceCommand("xm sched-credit -d %s" %(domain.getName())) - params = output.strip('{}').split(', ') - cap = int(params[0].split(':')[1].strip(' ')) - weight = int(params[1].split(':')[1].strip(' ')) - return (status, (weight, cap)) + status, output = traceCommand("xm sched-credit -d %s | tail -1" % + domain.getName()) + + if status != 0: + FAIL("Getting sched-credit parameters return non-zero rv (%d)", + status) + + m = paramsRE.match(output) + if not m: + FAIL("xm sched-credit gave bad output") + weight = int(m.group(1)) + cap = int(m.group(2)) + return (weight, cap) def set_sched_credit_weight(domain, weight): status, output = traceCommand("xm sched-credit -d %s -w %d" %(domain.getName(), weight)) @@ -31,11 +44,8 @@ except DomainError, e: FAIL(str(e)) # check default param values -(status, params) = get_sched_credit_params(domain) -if status != 0: - FAIL("Getting sched-credit parameters return non-zero rv (%d)", status) +(weight, cap) = get_sched_credit_params(domain) -(weight, cap) = params if weight != 256: FAIL("default weight is 256 (got %d)", weight) if cap != 0: @@ -51,11 +61,8 @@ if status != 0: FAIL("Setting sched-credit cap return non-zero rv (%d)", status) # check new param values -(status, params) = get_sched_credit_params(domain) -if status != 0: - FAIL("Getting sched-credit parameters return non-zero rv (%d)", status) +(weight, cap) = get_sched_credit_params(domain) -(weight, cap) = params if weight != 512: FAIL("expected weight of 512 (got %d)", weight) if cap != 100: From 9bec2359e659b6a5e0d49df9e5723d837e1ca8df Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Tue, 9 Jan 2007 17:43:13 +0000 Subject: [PATCH 142/570] [HVM] Ignore evtchn_upcall_mask and initialise to zero. Signed-off-by: Keir Fraser --- tools/libxc/xc_hvm_build.c | 3 +-- xen/arch/x86/hvm/irq.c | 3 ++- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/libxc/xc_hvm_build.c b/tools/libxc/xc_hvm_build.c index 21e20ffaf9..8c0c52238b 100644 --- a/tools/libxc/xc_hvm_build.c +++ b/tools/libxc/xc_hvm_build.c @@ -233,8 +233,7 @@ static int setup_guest(int xc_handle, SCRATCH_PFN)) == NULL) ) goto error_out; memset(shared_info, 0, PAGE_SIZE); - for ( i = 0; i < MAX_VIRT_CPUS; i++ ) - shared_info->vcpu_info[i].evtchn_upcall_mask = 1; + /* NB. evtchn_upcall_mask is unused: leave as zero. */ memset(&shared_info->evtchn_mask[0], 0xff, sizeof(shared_info->evtchn_mask)); munmap(shared_info, PAGE_SIZE); diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index 1b51f5905c..45d4f97042 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -135,7 +135,8 @@ void hvm_set_callback_irq_level(void) if ( gsi == 0 ) goto out; - if ( local_events_need_delivery() ) + /* NB. Do not check the evtchn_upcall_mask. It is not used in HVM mode. */ + if ( vcpu_info(v, evtchn_upcall_pending) ) { if ( !__test_and_set_bit(0, &hvm_irq->callback_irq_wire) && (hvm_irq->gsi_assert_count[gsi]++ == 0) ) From 0257938d1107165c9857a28b7c51991d0873b72b Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 10 Jan 2007 09:39:24 +0000 Subject: [PATCH 143/570] [LINUX] Clarify comment in xen_machine_kexec_setup_resources(). Noticed by Horms. Signed-off-by: Ian Campbell --- linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c b/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c index a16e9d9a22..41b1405ff7 100644 --- a/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c +++ b/linux-2.6-xen-sparse/drivers/xen/core/machine_kexec.c @@ -98,8 +98,8 @@ void xen_machine_kexec_setup_resources(void) err: /* * It isn't possible to free xen_phys_cpus this early in the - * boot. Since failure at this stage is unexpected and the - * amount is small we leak the memory. + * boot. Failure at this stage is unexpected and the amount of + * memory is small therefore we tolerate the potential leak. */ xen_max_nr_phys_cpus = 0; return; From ca00403ecee10e337e3693600fd0508bada2b8c7 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Wed, 10 Jan 2007 09:39:24 +0000 Subject: [PATCH 144/570] [PATCH] kexec/kdump: remove unnecessary incusion of asm/fixmap.h I think this a legacy of an older revision of this code, but asm/fixmap.h does not seem to be needed in asm-x86/x86_32/kexec.h or asm-x86/x86_64/kexec.h That is, neither of these incarntations of kexec.h seem to do anything related to fixmap directly or indirectly. Signed-off-by: Simon Horman --- xen/include/asm-x86/x86_32/kexec.h | 1 - xen/include/asm-x86/x86_64/kexec.h | 1 - 2 files changed, 2 deletions(-) diff --git a/xen/include/asm-x86/x86_32/kexec.h b/xen/include/asm-x86/x86_32/kexec.h index aa6db02088..cb4ada715e 100644 --- a/xen/include/asm-x86/x86_32/kexec.h +++ b/xen/include/asm-x86/x86_32/kexec.h @@ -10,7 +10,6 @@ #include #include -#include typedef asmlinkage void (*relocate_new_kernel_t)( unsigned long indirection_page, diff --git a/xen/include/asm-x86/x86_64/kexec.h b/xen/include/asm-x86/x86_64/kexec.h index b9779aa9d7..c54dbb9ba6 100644 --- a/xen/include/asm-x86/x86_64/kexec.h +++ b/xen/include/asm-x86/x86_64/kexec.h @@ -10,7 +10,6 @@ #include #include -#include typedef void (*relocate_new_kernel_t)( unsigned long indirection_page, From 5fc32d22f2975d14e23fdbdab6db2e6297a47869 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Wed, 10 Jan 2007 11:09:21 +0000 Subject: [PATCH 145/570] [XEN] Remove bogus BUG_ON() which breaks the build with gcc 4.2.0. Signed-off-by: Keir Fraser --- xen/common/symbols.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/xen/common/symbols.c b/xen/common/symbols.c index 496f231f8b..fba6cf0867 100644 --- a/xen/common/symbols.c +++ b/xen/common/symbols.c @@ -94,9 +94,6 @@ const char *symbols_lookup(unsigned long addr, unsigned long i, low, high, mid; unsigned long symbol_end = 0; - /* This kernel should never had been booted. */ - BUG_ON(!symbols_addresses); - namebuf[KSYM_NAME_LEN] = 0; namebuf[0] = 0; From 6ed3af384fe8be0982eaf8ab841b41ed578761a7 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 10 Jan 2007 08:00:50 -0700 Subject: [PATCH 146/570] [IA64] Clean up VTi memory initialization logic This patch makes the logic in setup_guest() more clear. domain_translate_gpfn_list() is now gone, so we can make memory initializtion code simple. Xend passes memory size which is a sum of normal memory size and GFW memory to QEMU and Libxc. This patch fixes this issue. Signed-off-by: Zhang Xin --- tools/ioemu/vl.c | 4 --- tools/libxc/ia64/xc_ia64_hvm_build.c | 44 ++++++++++++---------------- tools/python/xen/xend/image.py | 3 ++ 3 files changed, 21 insertions(+), 30 deletions(-) diff --git a/tools/ioemu/vl.c b/tools/ioemu/vl.c index 6fc10c8187..ffce41d173 100644 --- a/tools/ioemu/vl.c +++ b/tools/ioemu/vl.c @@ -6464,10 +6464,6 @@ int main(int argc, char **argv) } #if defined (__ia64__) - /* ram_size passed from xend has added on GFW memory, - so we must subtract it here */ - ram_size -= 16 * MEM_M; - if (ram_size > MMIO_START) ram_size += 1 * MEM_G; /* skip 3G-4G MMIO, LEGACY_IO_SPACE etc. */ #endif diff --git a/tools/libxc/ia64/xc_ia64_hvm_build.c b/tools/libxc/ia64/xc_ia64_hvm_build.c index 3bfa274293..270a6f67a2 100644 --- a/tools/libxc/ia64/xc_ia64_hvm_build.c +++ b/tools/libxc/ia64/xc_ia64_hvm_build.c @@ -569,18 +569,13 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize, xen_pfn_t *pfn_list; shared_iopage_t *sp; void *ioreq_buffer_page; - // memsize equal to normal memory size(in configure file) + 16M - // dom_memsize will pass to xc_ia64_build_hob(), so must be subbed 16M - unsigned long dom_memsize = ((memsize - 16) << 20); - unsigned long nr_pages = (unsigned long)memsize << (20 - PAGE_SHIFT); - unsigned long normal_pages = nr_pages - GFW_PAGES; + unsigned long dom_memsize = memsize << 20; + unsigned long nr_pages = memsize << (20 - PAGE_SHIFT); unsigned long vcpus; int rc; - long i, j; + long i; DECLARE_DOMCTL; - // ROM size for guest firmware, ioreq page and xenstore page - nr_pages += 3; if ((image_size > 12 * MEM_M) || (image_size & (PAGE_SIZE - 1))) { PERROR("Guest firmware size is incorrect [%ld]?", image_size); @@ -598,20 +593,20 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize, pfn_list[i] = i; // If normal memory > 3G. Reserve 3G ~ 4G for MMIO, GFW and others. - for (j = (MMIO_START >> PAGE_SHIFT); j < (dom_memsize >> PAGE_SHIFT); j++) - pfn_list[j] += ((1 * MEM_G) >> PAGE_SHIFT); + for (i = (MMIO_START >> PAGE_SHIFT); i < (dom_memsize >> PAGE_SHIFT); i++) + pfn_list[i] += ((1 * MEM_G) >> PAGE_SHIFT); // Allocate memory for VTI guest, up to VGA hole from 0xA0000-0xC0000. rc = xc_domain_memory_populate_physmap(xc_handle, dom, - (normal_pages > VGA_START_PAGE) ? - VGA_START_PAGE : normal_pages, + (nr_pages > VGA_START_PAGE) ? + VGA_START_PAGE : nr_pages, 0, 0, &pfn_list[0]); // We're not likely to attempt to create a domain with less than // 640k of memory, but test for completeness if (rc == 0 && nr_pages > VGA_END_PAGE) rc = xc_domain_memory_populate_physmap(xc_handle, dom, - normal_pages - VGA_END_PAGE, + nr_pages - VGA_END_PAGE, 0, 0, &pfn_list[VGA_END_PAGE]); if (rc != 0) { PERROR("Could not allocate normal memory for Vti guest.\n"); @@ -621,24 +616,22 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize, // We allocate additional pfn for GFW and other three pages, so // the pfn_list is not contiguous. Due to this we must support // old interface xc_ia64_get_pfn_list(). - // Here i = (dom_memsize >> PAGE_SHIFT) - for (j = 0; i < nr_pages - 3; i++, j++) - pfn_list[i] = (GFW_START >> PAGE_SHIFT) + j; + for (i = 0; i < GFW_PAGES; i++) + pfn_list[i] = (GFW_START >> PAGE_SHIFT) + i; rc = xc_domain_memory_populate_physmap(xc_handle, dom, GFW_PAGES, - 0, 0, &pfn_list[normal_pages]); + 0, 0, &pfn_list[0]); if (rc != 0) { PERROR("Could not allocate GFW memory for Vti guest.\n"); goto error_out; } - // Here i = (dom_memsize >> PAGE_SHIFT) + GFW_PAGES - pfn_list[i] = IO_PAGE_START >> PAGE_SHIFT; - pfn_list[i+1] = STORE_PAGE_START >> PAGE_SHIFT; - pfn_list[i+2] = BUFFER_IO_PAGE_START >> PAGE_SHIFT; + pfn_list[0] = IO_PAGE_START >> PAGE_SHIFT; + pfn_list[1] = STORE_PAGE_START >> PAGE_SHIFT; + pfn_list[2] = BUFFER_IO_PAGE_START >> PAGE_SHIFT; rc = xc_domain_memory_populate_physmap(xc_handle, dom, 3, - 0, 0, &pfn_list[nr_pages - 3]); + 0, 0, &pfn_list[0]); if (rc != 0) { PERROR("Could not allocate IO page or store page or buffer io page.\n"); goto error_out; @@ -675,13 +668,12 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize, goto error_out; } - xc_set_hvm_param(xc_handle, dom, - HVM_PARAM_STORE_PFN, pfn_list[nr_pages - 2]); + xc_set_hvm_param(xc_handle, dom, HVM_PARAM_STORE_PFN, pfn_list[1]); // Retrieve special pages like io, xenstore, etc. sp = (shared_iopage_t *)xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, - pfn_list[nr_pages - 3]); + pfn_list[0]); if (sp == 0) goto error_out; @@ -689,7 +681,7 @@ setup_guest(int xc_handle, uint32_t dom, unsigned long memsize, munmap(sp, PAGE_SIZE); ioreq_buffer_page = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, PROT_READ | PROT_WRITE, - pfn_list[nr_pages - 1]); + pfn_list[2]); memset(ioreq_buffer_page,0,PAGE_SIZE); munmap(ioreq_buffer_page, PAGE_SIZE); free(pfn_list); diff --git a/tools/python/xen/xend/image.py b/tools/python/xen/xend/image.py index d3876e2749..982feea114 100644 --- a/tools/python/xen/xend/image.py +++ b/tools/python/xen/xend/image.py @@ -591,6 +591,9 @@ class IA64_HVM_ImageHandler(HVMImageHandler): extra_pages = 1024 + 3 return mem_kb + extra_pages * page_kb + def getRequiredInitialReservation(self): + return self.vm.getMemoryTarget() + def getRequiredShadowMemory(self, shadow_mem_kb, maxmem_kb): # Explicit shadow memory is not a concept return 0 From 175ff0db6498db6a1235a73ff376e24f96027263 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 10 Jan 2007 08:47:36 -0700 Subject: [PATCH 147/570] [IA64] Remove bogus linux/kernel.h include This seems to be an extraneous include and causes problems when pulled into asm files. Signed-off-by: Alex Williamson --- xen/include/asm-ia64/xensystem.h | 1 - 1 file changed, 1 deletion(-) diff --git a/xen/include/asm-ia64/xensystem.h b/xen/include/asm-ia64/xensystem.h index d966d1917b..95a1991e1a 100644 --- a/xen/include/asm-ia64/xensystem.h +++ b/xen/include/asm-ia64/xensystem.h @@ -11,7 +11,6 @@ * */ #include -#include /* Define HV space hierarchy. VMM memory space is protected by CPL for paravirtualized domains and From 1fb39fdef3d0c052ce2316173560b09eaf86481f Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 10 Jan 2007 08:48:50 -0700 Subject: [PATCH 148/570] [IA64] Add empty nmi.h Necessary to build Signed-off-by: Alex Williamson --- xen/include/asm-ia64/linux-null/asm/nmi.h | 1 + 1 file changed, 1 insertion(+) create mode 100644 xen/include/asm-ia64/linux-null/asm/nmi.h diff --git a/xen/include/asm-ia64/linux-null/asm/nmi.h b/xen/include/asm-ia64/linux-null/asm/nmi.h new file mode 100644 index 0000000000..29f4f4cd69 --- /dev/null +++ b/xen/include/asm-ia64/linux-null/asm/nmi.h @@ -0,0 +1 @@ +/* This file is intentionally left empty. */ From b6ddced3214c8d8e46955df598ae903230ebbe69 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 10 Jan 2007 10:35:24 -0700 Subject: [PATCH 149/570] [IA64] Move cmdline.c to linux-xen Need to clean up some build warnings. Probably should have been moved last time it was modified. Signed-off-by: Alex Williamson --- xen/arch/ia64/linux-xen/Makefile | 1 + xen/arch/ia64/linux-xen/README.origin | 1 + xen/arch/ia64/{linux => linux-xen}/cmdline.c | 0 xen/arch/ia64/linux/Makefile | 1 - xen/arch/ia64/linux/README.origin | 1 - 5 files changed, 2 insertions(+), 2 deletions(-) rename xen/arch/ia64/{linux => linux-xen}/cmdline.c (100%) diff --git a/xen/arch/ia64/linux-xen/Makefile b/xen/arch/ia64/linux-xen/Makefile index 182cc8ebbf..f4ee8c396b 100644 --- a/xen/arch/ia64/linux-xen/Makefile +++ b/xen/arch/ia64/linux-xen/Makefile @@ -1,5 +1,6 @@ subdir-y += sn +obj-y += cmdline.o obj-y += efi.o obj-y += entry.o obj-y += irq_ia64.o diff --git a/xen/arch/ia64/linux-xen/README.origin b/xen/arch/ia64/linux-xen/README.origin index e667b05603..bfc3981e15 100644 --- a/xen/arch/ia64/linux-xen/README.origin +++ b/xen/arch/ia64/linux-xen/README.origin @@ -5,6 +5,7 @@ # (e.g. with #ifdef XEN or XEN in a comment) so that they can be # easily updated to future versions of the corresponding Linux files. +cmdline.c -> linux/lib/cmdline.c efi.c -> linux/arch/ia64/kernel/efi.c entry.h -> linux/arch/ia64/kernel/entry.h entry.S -> linux/arch/ia64/kernel/entry.S diff --git a/xen/arch/ia64/linux/cmdline.c b/xen/arch/ia64/linux-xen/cmdline.c similarity index 100% rename from xen/arch/ia64/linux/cmdline.c rename to xen/arch/ia64/linux-xen/cmdline.c diff --git a/xen/arch/ia64/linux/Makefile b/xen/arch/ia64/linux/Makefile index 843c849fb9..4e55bcb3a4 100644 --- a/xen/arch/ia64/linux/Makefile +++ b/xen/arch/ia64/linux/Makefile @@ -4,7 +4,6 @@ subdir-y += sn obj-y += bitop.o obj-y += clear_page.o -obj-y += cmdline.o obj-y += copy_page_mck.o obj-y += efi_stub.o obj-y += extable.o diff --git a/xen/arch/ia64/linux/README.origin b/xen/arch/ia64/linux/README.origin index 9706a53502..f5f4677115 100644 --- a/xen/arch/ia64/linux/README.origin +++ b/xen/arch/ia64/linux/README.origin @@ -4,7 +4,6 @@ NOTE: DO NOT commit changes to these files! If a file needs to be changed, move it to ../linux-xen and follow the instructions in the README there. -cmdline.c -> linux/lib/cmdline.c efi_stub.S -> linux/arch/ia64/kernel/efi_stub.S extable.c -> linux/arch/ia64/mm/extable.c hpsim.S -> linux/arch/ia64/hp/sim/hpsim.S From 14ab6103b51bfb030cc2202b9c51e22c7991b19a Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Wed, 10 Jan 2007 10:37:41 -0700 Subject: [PATCH 150/570] [IA64] Clean up build warnings Signed-off-by: Alex Williamson --- xen/arch/ia64/linux-xen/cmdline.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/xen/arch/ia64/linux-xen/cmdline.c b/xen/arch/ia64/linux-xen/cmdline.c index b6dddcd808..48e6de1ccf 100644 --- a/xen/arch/ia64/linux-xen/cmdline.c +++ b/xen/arch/ia64/linux-xen/cmdline.c @@ -15,7 +15,9 @@ #include #include #include +#ifdef XEN #include +#endif /** @@ -38,7 +40,11 @@ int get_option (char **str, int *pint) if (!cur || !(*cur)) return 0; +#ifndef XEN *pint = simple_strtol (cur, str, 0); +#else + *pint = simple_strtol (cur, (const char**)str, 0); +#endif if (cur == *str) return 0; if (**str == ',') { @@ -96,7 +102,11 @@ char *get_options(const char *str, int nints, int *ints) unsigned long long memparse (char *ptr, char **retptr) { +#ifndef XEN unsigned long long ret = simple_strtoull (ptr, retptr, 0); +#else + unsigned long long ret = simple_strtoull (ptr, (const char**)retptr, 0); +#endif switch (**retptr) { case 'G': From 5dd4f8ccd1b77aca6909e7a4a9393744ad2ecd79 Mon Sep 17 00:00:00 2001 From: Ian Campbell Date: Thu, 11 Jan 2007 10:36:41 +0000 Subject: [PATCH 151/570] [XEN] Update comments in elfnote.h interface header. Signed-off-by: Ian Campbell --- xen/include/public/elfnote.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/xen/include/public/elfnote.h b/xen/include/public/elfnote.h index 4924767d30..3d9b988dca 100644 --- a/xen/include/public/elfnote.h +++ b/xen/include/public/elfnote.h @@ -40,8 +40,6 @@ /* * NAME=VALUE pair (string). - * - * LEGACY: FEATURES and PAE */ #define XEN_ELFNOTE_INFO 0 @@ -108,7 +106,12 @@ #define XEN_ELFNOTE_LOADER 8 /* - * The kernel supports PAE (x86/32 only, string = "yes" or "no"). + * The kernel supports PAE (x86/32 only, string = "yes", "no" or + * "bimodal"). + * + * For compatibility with Xen 3.0.3 and earlier the "bimodal" setting + * may be given as "yes,bimodal" which will cause older Xen to treat + * this kernel as PAE. * * LEGACY: PAE (n.b. The legacy interface included a provision to * indicate 'extended-cr3' support allowing L3 page tables to be From 5b6bf5798a81ec3c82009755e9222061e8d450c1 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 11 Jan 2007 11:41:44 +0000 Subject: [PATCH 152/570] [XEN] More emulator fixes and emulate BSWAP. Better handling of LOCK prefix. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 157 +++++++++++++++++++++++++------------ 1 file changed, 107 insertions(+), 50 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index ec174595e3..568864ed81 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -178,8 +178,16 @@ static uint8_t twobyte_table[256] = { /* 0x88 - 0x8F */ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, - /* 0x90 - 0x9F */ - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + /* 0x90 - 0x97 */ + ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, + ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, + ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, + ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, + /* 0x98 - 0x9F */ + ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, + ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, + ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, + ByteOp|DstMem|SrcNone|ModRM|Mov, ByteOp|DstMem|SrcNone|ModRM|Mov, /* 0xA0 - 0xA7 */ 0, 0, 0, DstBitBase|SrcReg|ModRM, 0, 0, 0, 0, /* 0xA8 - 0xAF */ @@ -195,7 +203,8 @@ static uint8_t twobyte_table[256] = { ByteOp|DstMem|SrcReg|ModRM, DstMem|SrcReg|ModRM, 0, 0, 0, 0, 0, ImplicitOps|ModRM, /* 0xC8 - 0xCF */ - 0, 0, 0, 0, 0, 0, 0, 0, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0xD0 - 0xDF */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0 - 0xEF */ @@ -206,7 +215,7 @@ static uint8_t twobyte_table[256] = { /* Type, address-of, and value of an instruction's operand. */ struct operand { - enum { OP_REG, OP_MEM, OP_IMM } type; + enum { OP_REG, OP_MEM, OP_IMM, OP_NONE } type; unsigned int bytes; unsigned long val, orig_val; union { @@ -635,6 +644,9 @@ x86_emulate( goto cannot_emulate; } + /* Lock prefix is allowed only on RMW instructions. */ + generate_exception_if((d & Mov) && lock_prefix, EXC_GP); + /* ModRM and SIB bytes. */ if ( d & ModRM ) { @@ -874,13 +886,18 @@ x86_emulate( case 8: dst.val = *(uint64_t *)dst.reg; break; } } - else if ( !(d & Mov) && /* optimisation - avoid slow emulated read */ - (rc = ops->read(dst.mem.seg, dst.mem.off, - &dst.val, dst.bytes, ctxt)) ) - goto done; + else if ( !(d & Mov) ) /* optimisation - avoid slow emulated read */ + { + if ( (rc = ops->read(dst.mem.seg, dst.mem.off, + &dst.val, dst.bytes, ctxt)) ) + goto done; + dst.orig_val = dst.val; + } break; } - dst.orig_val = dst.val; + + /* LOCK prefix allowed only on instructions with memory destination. */ + generate_exception_if(lock_prefix && (dst.type != OP_MEM), EXC_GP); if ( twobyte ) goto twobyte_insn; @@ -889,56 +906,56 @@ x86_emulate( { case 0x04 ... 0x05: /* add imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; - dst.val = dst.orig_val = _regs.eax; + dst.val = _regs.eax; case 0x00 ... 0x03: add: /* add */ emulate_2op_SrcV("add", src, dst, _regs.eflags); break; case 0x0c ... 0x0d: /* or imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; - dst.val = dst.orig_val = _regs.eax; + dst.val = _regs.eax; case 0x08 ... 0x0b: or: /* or */ emulate_2op_SrcV("or", src, dst, _regs.eflags); break; case 0x14 ... 0x15: /* adc imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; - dst.val = dst.orig_val = _regs.eax; + dst.val = _regs.eax; case 0x10 ... 0x13: adc: /* adc */ emulate_2op_SrcV("adc", src, dst, _regs.eflags); break; case 0x1c ... 0x1d: /* sbb imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; - dst.val = dst.orig_val = _regs.eax; + dst.val = _regs.eax; case 0x18 ... 0x1b: sbb: /* sbb */ emulate_2op_SrcV("sbb", src, dst, _regs.eflags); break; case 0x24 ... 0x25: /* and imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; - dst.val = dst.orig_val = _regs.eax; + dst.val = _regs.eax; case 0x20 ... 0x23: and: /* and */ emulate_2op_SrcV("and", src, dst, _regs.eflags); break; case 0x2c ... 0x2d: /* sub imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; - dst.val = dst.orig_val = _regs.eax; + dst.val = _regs.eax; case 0x28 ... 0x2b: sub: /* sub */ emulate_2op_SrcV("sub", src, dst, _regs.eflags); break; case 0x34 ... 0x35: /* xor imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; - dst.val = dst.orig_val = _regs.eax; + dst.val = _regs.eax; case 0x30 ... 0x33: xor: /* xor */ emulate_2op_SrcV("xor", src, dst, _regs.eflags); break; case 0x3c ... 0x3d: /* cmp imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; - dst.val = dst.orig_val = _regs.eax; + dst.val = _regs.eax; case 0x38 ... 0x3b: cmp: /* cmp */ emulate_2op_SrcV("cmp", src, dst, _regs.eflags); break; @@ -965,7 +982,7 @@ x86_emulate( case 0xa8 ... 0xa9: /* test imm,%%eax */ dst.reg = (unsigned long *)&_regs.eax; - dst.val = dst.orig_val = _regs.eax; + dst.val = _regs.eax; case 0x84 ... 0x85: test: /* test */ emulate_2op_SrcV("test", src, dst, _regs.eflags); break; @@ -1106,7 +1123,7 @@ x86_emulate( if ( (rc = ops->write(x86_seg_ss, truncate_ea(_regs.esp), dst.val, dst.bytes, ctxt)) != 0 ) goto done; - dst.val = dst.orig_val; /* skanky: disable writeback */ + dst.type = OP_NONE; break; case 7: fail_if(1); @@ -1117,33 +1134,32 @@ x86_emulate( } writeback: - if ( (d & Mov) || (dst.orig_val != dst.val) ) + switch ( dst.type ) { - switch ( dst.type ) + case OP_REG: + /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ + switch ( dst.bytes ) { - case OP_REG: - /* The 4-byte case *is* correct: in 64-bit mode we zero-extend. */ - switch ( dst.bytes ) - { - case 1: *(uint8_t *)dst.reg = (uint8_t)dst.val; break; - case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break; - case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */ - case 8: *dst.reg = dst.val; break; - } - break; - case OP_MEM: - if ( lock_prefix ) - rc = ops->cmpxchg( - dst.mem.seg, dst.mem.off, dst.orig_val, - dst.val, dst.bytes, ctxt); - else - rc = ops->write( - dst.mem.seg, dst.mem.off, dst.val, dst.bytes, ctxt); - if ( rc != 0 ) - goto done; - default: - break; + case 1: *(uint8_t *)dst.reg = (uint8_t)dst.val; break; + case 2: *(uint16_t *)dst.reg = (uint16_t)dst.val; break; + case 4: *dst.reg = (uint32_t)dst.val; break; /* 64b: zero-ext */ + case 8: *dst.reg = dst.val; break; } + break; + case OP_MEM: + if ( !(d & Mov) && (dst.orig_val == dst.val) ) + /* nothing to do */; + else if ( lock_prefix ) + rc = ops->cmpxchg( + dst.mem.seg, dst.mem.off, dst.orig_val, + dst.val, dst.bytes, ctxt); + else + rc = ops->write( + dst.mem.seg, dst.mem.off, dst.val, dst.bytes, ctxt); + if ( rc != 0 ) + goto done; + default: + break; } /* Commit shadow register state. */ @@ -1153,8 +1169,13 @@ x86_emulate( return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; special_insn: - /* Default action: disable writeback. There may be no dest operand. */ - dst.orig_val = dst.val; + dst.type = OP_NONE; + + /* + * The only implicit-operands instruction allowed a LOCK prefix is + * CMPXCHG{8,16}B. + */ + generate_exception_if(lock_prefix && (b != 0xc7), EXC_GP); if ( twobyte ) goto twobyte_special_insn; @@ -1235,7 +1256,7 @@ x86_emulate( dst.type = OP_REG; dst.reg = decode_register(b & 7, &_regs, 0); dst.bytes = op_bytes; - dst.orig_val = dst.val = *dst.reg; + dst.val = *dst.reg; if ( b & 8 ) emulate_1op("dec", dst, _regs.eflags); else @@ -1285,7 +1306,7 @@ x86_emulate( src.val = *src.reg; dst.reg = decode_register( (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); - dst.val = dst.orig_val = *dst.reg; + dst.val = *dst.reg; goto xchg; case 0x9e: /* sahf */ @@ -1430,9 +1451,14 @@ x86_emulate( twobyte_insn: switch ( b ) { - case 0x40 ... 0x4f: /* cmov */ - dst.val = dst.orig_val = src.val; - d = (d & ~Mov) | (test_cc(b, _regs.eflags) ? Mov : 0); + case 0x40 ... 0x4f: /* cmovcc */ + dst.val = src.val; + if ( !test_cc(b, _regs.eflags) ) + dst.type = OP_NONE; + break; + + case 0x90 ... 0x9f: /* setcc */ + dst.val = test_cc(b, _regs.eflags); break; case 0xb0 ... 0xb1: /* cmpxchg */ @@ -1580,6 +1606,37 @@ x86_emulate( break; } #endif + + case 0xc8 ... 0xcf: /* bswap */ + dst.type = OP_REG; + dst.reg = decode_register(b & 7, &_regs, 0); + dst.val = *dst.reg; + switch ( dst.bytes = op_bytes ) + { + case 2: + dst.val = (((dst.val & 0x00FFUL) << 8) | + ((dst.val & 0xFF00UL) >> 8)); + break; + case 4: + dst.val = (((dst.val & 0x000000FFUL) << 24) | + ((dst.val & 0x0000FF00UL) << 8) | + ((dst.val & 0x00FF0000UL) >> 8) | + ((dst.val & 0xFF000000UL) >> 24)); + break; +#ifdef __x86_64__ + case 8: + dst.val = (((dst.val & 0x00000000000000FFUL) << 56) | + ((dst.val & 0x000000000000FF00UL) << 40) | + ((dst.val & 0x0000000000FF0000UL) << 24) | + ((dst.val & 0x00000000FF000000UL) << 8) | + ((dst.val & 0x000000FF00000000UL) >> 8) | + ((dst.val & 0x0000FF0000000000UL) >> 24) | + ((dst.val & 0x00FF000000000000UL) >> 40) | + ((dst.val & 0xFF00000000000000UL) >> 56)); + break; +#endif + } + break; } goto writeback; From fbe70926969f71dbf149f38c9bc2449ec932c902 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 11 Jan 2007 15:43:38 +0000 Subject: [PATCH 153/570] [HVM][VMX] Some simplifications, particularly to vmx_load/save_cpu_regs. Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/vmx/vmx.c | 133 +++++++++++----------------- xen/arch/x86/hvm/vmx/x86_32/exits.S | 2 - xen/arch/x86/hvm/vmx/x86_64/exits.S | 2 - 3 files changed, 54 insertions(+), 83 deletions(-) diff --git a/xen/arch/x86/hvm/vmx/vmx.c b/xen/arch/x86/hvm/vmx/vmx.c index c8782ef8a2..74e0776016 100644 --- a/xen/arch/x86/hvm/vmx/vmx.c +++ b/xen/arch/x86/hvm/vmx/vmx.c @@ -410,10 +410,6 @@ static void vmx_store_cpu_guest_regs( regs->eflags = __vmread(GUEST_RFLAGS); regs->ss = __vmread(GUEST_SS_SELECTOR); regs->cs = __vmread(GUEST_CS_SELECTOR); - regs->ds = __vmread(GUEST_DS_SELECTOR); - regs->es = __vmread(GUEST_ES_SELECTOR); - regs->gs = __vmread(GUEST_GS_SELECTOR); - regs->fs = __vmread(GUEST_FS_SELECTOR); regs->eip = __vmread(GUEST_RIP); regs->esp = __vmread(GUEST_RSP); } @@ -429,62 +425,39 @@ static void vmx_store_cpu_guest_regs( vmx_vmcs_exit(v); } -/* - * The VMX spec (section 4.3.1.2, Checks on Guest Segment - * Registers) says that virtual-8086 mode guests' segment - * base-address fields in the VMCS must be equal to their - * corresponding segment selector field shifted right by - * four bits upon vmentry. - * - * This function (called only for VM86-mode guests) fixes - * the bases to be consistent with the selectors in regs - * if they're not already. Without this, we can fail the - * vmentry check mentioned above. - */ -static void fixup_vm86_seg_bases(struct cpu_user_regs *regs) +static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs) { unsigned long base; - base = __vmread(GUEST_ES_BASE); - if (regs->es << 4 != base) - __vmwrite(GUEST_ES_BASE, regs->es << 4); - base = __vmread(GUEST_CS_BASE); - if (regs->cs << 4 != base) - __vmwrite(GUEST_CS_BASE, regs->cs << 4); - base = __vmread(GUEST_SS_BASE); - if (regs->ss << 4 != base) - __vmwrite(GUEST_SS_BASE, regs->ss << 4); - base = __vmread(GUEST_DS_BASE); - if (regs->ds << 4 != base) - __vmwrite(GUEST_DS_BASE, regs->ds << 4); - base = __vmread(GUEST_FS_BASE); - if (regs->fs << 4 != base) - __vmwrite(GUEST_FS_BASE, regs->fs << 4); - base = __vmread(GUEST_GS_BASE); - if (regs->gs << 4 != base) - __vmwrite(GUEST_GS_BASE, regs->gs << 4); -} - -static void vmx_load_cpu_guest_regs(struct vcpu *v, struct cpu_user_regs *regs) -{ vmx_vmcs_enter(v); __vmwrite(GUEST_SS_SELECTOR, regs->ss); - __vmwrite(GUEST_DS_SELECTOR, regs->ds); - __vmwrite(GUEST_ES_SELECTOR, regs->es); - __vmwrite(GUEST_GS_SELECTOR, regs->gs); - __vmwrite(GUEST_FS_SELECTOR, regs->fs); - __vmwrite(GUEST_RSP, regs->esp); /* NB. Bit 1 of RFLAGS must be set for VMENTRY to succeed. */ __vmwrite(GUEST_RFLAGS, regs->eflags | 2UL); - if (regs->eflags & EF_TF) + + if ( regs->eflags & EF_TF ) __vm_set_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); else __vm_clear_bit(EXCEPTION_BITMAP, EXCEPTION_BITMAP_DB); - if (regs->eflags & EF_VM) - fixup_vm86_seg_bases(regs); + + if ( regs->eflags & EF_VM ) + { + /* + * The VMX spec (section 4.3.1.2, Checks on Guest Segment + * Registers) says that virtual-8086 mode guests' segment + * base-address fields in the VMCS must be equal to their + * corresponding segment selector field shifted right by + * four bits upon vmentry. + */ + base = __vmread(GUEST_CS_BASE); + if ( (regs->cs << 4) != base ) + __vmwrite(GUEST_CS_BASE, regs->cs << 4); + base = __vmread(GUEST_SS_BASE); + if ( (regs->ss << 4) != base ) + __vmwrite(GUEST_SS_BASE, regs->ss << 4); + } __vmwrite(GUEST_CS_SELECTOR, regs->cs); __vmwrite(GUEST_RIP, regs->eip); @@ -2251,47 +2224,54 @@ static void vmx_reflect_exception(struct vcpu *v) } } +static void vmx_failed_vmentry(unsigned int exit_reason) +{ + unsigned int failed_vmentry_reason = (uint16_t)exit_reason; + unsigned long exit_qualification; + + exit_qualification = __vmread(EXIT_QUALIFICATION); + printk("Failed vm entry (exit reason 0x%x) ", exit_reason); + switch ( failed_vmentry_reason ) + { + case EXIT_REASON_INVALID_GUEST_STATE: + printk("caused by invalid guest state (%ld).\n", exit_qualification); + break; + case EXIT_REASON_MSR_LOADING: + printk("caused by MSR entry %ld loading.\n", exit_qualification); + break; + case EXIT_REASON_MACHINE_CHECK: + printk("caused by machine check.\n"); + break; + default: + printk("reason not known yet!"); + break; + } + + printk("************* VMCS Area **************\n"); + vmcs_dump_vcpu(); + printk("**************************************\n"); + + domain_crash(current->domain); +} + asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs) { unsigned int exit_reason; unsigned long exit_qualification, inst_len = 0; struct vcpu *v = current; + TRACE_3D(TRC_VMX_VMEXIT + v->vcpu_id, 0, 0, 0); + exit_reason = __vmread(VM_EXIT_REASON); perfc_incra(vmexits, exit_reason); + TRACE_VMEXIT(0, exit_reason); if ( exit_reason != EXIT_REASON_EXTERNAL_INTERRUPT ) local_irq_enable(); if ( unlikely(exit_reason & VMX_EXIT_REASONS_FAILED_VMENTRY) ) - { - unsigned int failed_vmentry_reason = exit_reason & 0xFFFF; - - exit_qualification = __vmread(EXIT_QUALIFICATION); - printk("Failed vm entry (exit reason 0x%x) ", exit_reason); - switch ( failed_vmentry_reason ) { - case EXIT_REASON_INVALID_GUEST_STATE: - printk("caused by invalid guest state (%ld).\n", exit_qualification); - break; - case EXIT_REASON_MSR_LOADING: - printk("caused by MSR entry %ld loading.\n", exit_qualification); - break; - case EXIT_REASON_MACHINE_CHECK: - printk("caused by machine check.\n"); - break; - default: - printk("reason not known yet!"); - break; - } - - printk("************* VMCS Area **************\n"); - vmcs_dump_vcpu(); - printk("**************************************\n"); - goto exit_and_crash; - } - - TRACE_VMEXIT(0, exit_reason); + return vmx_failed_vmentry(exit_reason); switch ( exit_reason ) { @@ -2519,11 +2499,6 @@ asmlinkage void vmx_trace_vmentry(void) TRACE_VMEXIT(4, 0); } -asmlinkage void vmx_trace_vmexit (void) -{ - TRACE_3D(TRC_VMX_VMEXIT + current->vcpu_id, 0, 0, 0); -} - /* * Local variables: * mode: C diff --git a/xen/arch/x86/hvm/vmx/x86_32/exits.S b/xen/arch/x86/hvm/vmx/x86_32/exits.S index 35b67d3c48..ef24dce0ea 100644 --- a/xen/arch/x86/hvm/vmx/x86_32/exits.S +++ b/xen/arch/x86/hvm/vmx/x86_32/exits.S @@ -50,9 +50,7 @@ ALIGN ENTRY(vmx_asm_vmexit_handler) - /* selectors are restored/saved by VMX */ HVM_SAVE_ALL_NOSEGREGS - call vmx_trace_vmexit movl %esp,%eax push %eax call vmx_vmexit_handler diff --git a/xen/arch/x86/hvm/vmx/x86_64/exits.S b/xen/arch/x86/hvm/vmx/x86_64/exits.S index cbe9902391..0bebeb6ec3 100644 --- a/xen/arch/x86/hvm/vmx/x86_64/exits.S +++ b/xen/arch/x86/hvm/vmx/x86_64/exits.S @@ -65,9 +65,7 @@ ALIGN ENTRY(vmx_asm_vmexit_handler) - /* selectors are restored/saved by VMX */ HVM_SAVE_ALL_NOSEGREGS - call vmx_trace_vmexit movq %rsp,%rdi call vmx_vmexit_handler jmp vmx_asm_do_vmentry From 02ae5b357febec7270cc0f407b1d3a8eddb86838 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 11 Jan 2007 15:50:28 +0000 Subject: [PATCH 154/570] [XEN] Use local var instead of current->domain in two places. Signed-off-by: Jan Beulich --- xen/arch/x86/mm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 026180c11a..78e9e151fc 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -1376,7 +1376,7 @@ static int mod_l2_entry(l2_pgentry_t *pl2e, if ( !l2e_has_changed(ol2e, nl2e, _PAGE_PRESENT)) return UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, current); - if ( unlikely(!get_page_from_l2e(nl2e, pfn, current->domain)) ) + if ( unlikely(!get_page_from_l2e(nl2e, pfn, d)) ) return 0; if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, current)) ) @@ -1439,7 +1439,7 @@ static int mod_l3_entry(l3_pgentry_t *pl3e, if (!l3e_has_changed(ol3e, nl3e, _PAGE_PRESENT)) return UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, current); - if ( unlikely(!get_page_from_l3e(nl3e, pfn, current->domain)) ) + if ( unlikely(!get_page_from_l3e(nl3e, pfn, d)) ) return 0; if ( unlikely(!UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, current)) ) From 85bc6f4326e93f022d2eddee03c7ee007fc92766 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 11 Jan 2007 16:36:46 +0000 Subject: [PATCH 155/570] [XEND] Fix broken block-configure. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendDomainInfo.py | 31 ++++++++++++++----------- tools/python/xen/xend/server/blkif.py | 1 + 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/tools/python/xen/xend/XendDomainInfo.py b/tools/python/xen/xend/XendDomainInfo.py index 099302f573..f80c3f5be7 100644 --- a/tools/python/xen/xend/XendDomainInfo.py +++ b/tools/python/xen/xend/XendDomainInfo.py @@ -496,7 +496,7 @@ class XendDomainInfo: self._waitForDevice(dev_type, devid) return self.getDeviceController(dev_type).sxpr(devid) - def device_configure(self, dev_config, devid = None): + def device_configure(self, dev_sxp, devid = None): """Configure an existing device. @param dev_config: device configuration @@ -506,19 +506,24 @@ class XendDomainInfo: @return: Returns True if successfully updated device @rtype: boolean """ - deviceClass = sxp.name(dev_config) - - # look up uuid of the device - dev_control = self.getDeviceController(deviceClass) - dev_sxpr = dev_control.sxpr(devid) - dev_uuid = sxp.child_value(dev_sxpr, 'uuid') - if not dev_uuid: - return False - self.info.device_update(dev_uuid, dev_config) - dev_config_dict = self.info['devices'].get(dev_uuid) - if dev_config_dict: - dev_control.reconfigureDevice(devid, dev_config_dict[1]) + # convert device sxp to a dict + dev_class = sxp.name(dev_sxp) + dev_config = {} + for opt_val in dev_sxp[1:]: + try: + dev_config[opt_val[0]] = opt_val[1] + except IndexError: + pass + + # use DevController.reconfigureDevice to change device config + dev_control = self.getDeviceController(dev_class) + dev_uuid = dev_control.reconfigureDevice(devid, dev_config) + + # update XendConfig with new device info + if dev_uuid: + self.info.device_update(dev_uuid, dev_sxp) + return True def waitForDevices(self): diff --git a/tools/python/xen/xend/server/blkif.py b/tools/python/xen/xend/server/blkif.py index 44d1a1e1ff..72a0787d93 100644 --- a/tools/python/xen/xend/server/blkif.py +++ b/tools/python/xen/xend/server/blkif.py @@ -101,6 +101,7 @@ class BlkifController(DevController): self.writeBackend(devid, 'type', new_back['type'], 'params', new_back['params']) + return new_back.get('uuid') else: raise VmError('Refusing to reconfigure device %s:%d to %s' % (self.deviceClass, devid, config)) From b1567297790fd21968af033f9766f38c56f7d6a1 Mon Sep 17 00:00:00 2001 From: Alastair Tse Date: Thu, 11 Jan 2007 17:03:11 +0000 Subject: [PATCH 156/570] [XEND] Device update should handle SXP without 'device' as first param. Signed-off-by: Alastair Tse --- tools/python/xen/xend/XendConfig.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tools/python/xen/xend/XendConfig.py b/tools/python/xen/xend/XendConfig.py index cfd2c20e6e..b264b79f32 100644 --- a/tools/python/xen/xend/XendConfig.py +++ b/tools/python/xen/xend/XendConfig.py @@ -1020,10 +1020,11 @@ class XendConfig(dict): @return: Returns True if succesfully found and updated a device conf """ if dev_uuid in self['devices']: - config = sxp.child0(cfg_sxp) - dev_type = sxp.name(config) - dev_info = {} - + if sxp.child0(cfg_sxp) == 'device': + config = sxp.child0(cfg_sxp) + else: + config = cfg_sxp + for opt_val in config[1:]: try: opt, val = opt_val From 50dd6f58e0d6896623a0d4803929eb543a9b759b Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 11 Jan 2007 17:47:13 +0000 Subject: [PATCH 157/570] [XEN] Fix/implement JMP/CALL/RET emulation. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 96 ++++++++++++++++++++++++++++++-------- 1 file changed, 77 insertions(+), 19 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index 568864ed81..e96e981b21 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -85,9 +85,11 @@ static uint8_t opcode_table[256] = { ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, ImplicitOps|Mov, - /* 0x60 - 0x6F */ + /* 0x60 - 0x67 */ 0, 0, 0, DstReg|SrcMem32|ModRM|Mov /* movsxd (x86/64) */, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, + /* 0x68 - 0x6F */ + ImplicitOps|Mov, 0, ImplicitOps|Mov, 0, 0, 0, 0, 0, /* 0x70 - 0x77 */ ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, @@ -125,7 +127,8 @@ static uint8_t opcode_table[256] = { DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, DstReg|SrcImm|Mov, /* 0xC0 - 0xC7 */ - ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, 0, 0, + ByteOp|DstMem|SrcImm|ModRM, DstMem|SrcImmByte|ModRM, + ImplicitOps, ImplicitOps, 0, 0, ByteOp|DstMem|SrcImm|ModRM|Mov, DstMem|SrcImm|ModRM|Mov, /* 0xC8 - 0xCF */ 0, 0, 0, 0, 0, 0, 0, 0, @@ -138,7 +141,7 @@ static uint8_t opcode_table[256] = { /* 0xE0 - 0xE7 */ 0, 0, 0, ImplicitOps, 0, 0, 0, 0, /* 0xE8 - 0xEF */ - 0, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, + ImplicitOps, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, /* 0xF0 - 0xF7 */ 0, 0, 0, 0, 0, ImplicitOps, ByteOp|DstMem|SrcNone|ModRM, DstMem|SrcNone|ModRM, @@ -1110,6 +1113,20 @@ x86_emulate( case 1: /* dec */ emulate_1op("dec", dst, _regs.eflags); break; + case 2: /* call (near) */ + case 3: /* jmp (near) */ + if ( ((op_bytes = dst.bytes) != 8) && mode_64bit() ) + { + dst.bytes = op_bytes = 8; + if ( (rc = ops->read(dst.mem.seg, dst.mem.off, + &dst.val, 8, ctxt)) != 0 ) + goto done; + } + src.val = _regs.eip; + _regs.eip = dst.val; + if ( (modrm_reg & 7) == 2 ) + goto push; /* call */ + break; case 6: /* push */ /* 64-bit mode: PUSH defaults to a 64-bit operand. */ if ( mode_64bit() && (dst.bytes == 4) ) @@ -1264,16 +1281,9 @@ x86_emulate( break; case 0x50 ... 0x57: /* push reg */ - dst.type = OP_MEM; - dst.bytes = op_bytes; - if ( mode_64bit() && (dst.bytes == 4) ) - dst.bytes = 8; - dst.val = *(unsigned long *)decode_register( + src.val = *(unsigned long *)decode_register( (b & 7) | ((rex_prefix & 1) << 3), &_regs, 0); - register_address_increment(_regs.esp, -dst.bytes); - dst.mem.seg = x86_seg_ss; - dst.mem.off = truncate_ea(_regs.esp); - break; + goto push; case 0x58 ... 0x5f: /* pop reg */ dst.type = OP_REG; @@ -1288,6 +1298,26 @@ x86_emulate( register_address_increment(_regs.esp, dst.bytes); break; + case 0x68: /* push imm{16,32,64} */ + src.val = ((op_bytes == 2) + ? (int32_t)insn_fetch_type(int16_t) + : insn_fetch_type(int32_t)); + goto push; + + case 0x6a: /* push imm8 */ + src.val = insn_fetch_type(int8_t); + push: + d |= Mov; /* force writeback */ + dst.type = OP_MEM; + dst.bytes = op_bytes; + if ( mode_64bit() && (dst.bytes == 4) ) + dst.bytes = 8; + dst.val = src.val; + register_address_increment(_regs.esp, -dst.bytes); + dst.mem.seg = x86_seg_ss; + dst.mem.off = truncate_ea(_regs.esp); + break; + case 0x70 ... 0x7f: /* jcc (short) */ { int rel = insn_fetch_type(int8_t); if ( test_cc(b, _regs.eflags) ) @@ -1371,6 +1401,18 @@ x86_emulate( _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); break; + case 0xc2: /* ret imm16 (near) */ + case 0xc3: /* ret (near) */ { + int offset = (b == 0xc2) ? insn_fetch_type(uint16_t) : 0; + op_bytes = mode_64bit() ? 8 : op_bytes; + if ( (rc = ops->read(x86_seg_ss, truncate_ea(_regs.esp), + &dst.val, op_bytes, ctxt)) != 0 ) + goto done; + _regs.eip = dst.val; + register_address_increment(_regs.esp, op_bytes + offset); + break; + } + case 0xd4: /* aam */ { unsigned int base = insn_fetch_type(uint8_t); uint8_t al = _regs.eax; @@ -1418,12 +1460,26 @@ x86_emulate( break; } - case 0xe9: /* jmp (short) */ - jmp_rel(insn_fetch_type(int8_t)); - break; + case 0xe8: /* call (near) */ { + int rel = (((op_bytes == 2) && !mode_64bit()) + ? (int32_t)insn_fetch_type(int16_t) + : insn_fetch_type(int32_t)); + op_bytes = mode_64bit() ? 8 : op_bytes; + src.val = _regs.eip; + jmp_rel(rel); + goto push; + } - case 0xeb: /* jmp (near) */ - jmp_rel(insn_fetch_bytes(mode_64bit() ? 4 : op_bytes)); + case 0xe9: /* jmp (near) */ { + int rel = (((op_bytes == 2) && !mode_64bit()) + ? (int32_t)insn_fetch_type(int16_t) + : insn_fetch_type(int32_t)); + jmp_rel(rel); + break; + } + + case 0xeb: /* jmp (short) */ + jmp_rel(insn_fetch_type(int8_t)); break; case 0xf5: /* cmc */ @@ -1550,7 +1606,9 @@ x86_emulate( break; case 0x80 ... 0x8f: /* jcc (near) */ { - int rel = insn_fetch_bytes(mode_64bit() ? 4 : op_bytes); + int rel = (((op_bytes == 2) && !mode_64bit()) + ? (int32_t)insn_fetch_type(int16_t) + : insn_fetch_type(int32_t)); if ( test_cc(b, _regs.eflags) ) jmp_rel(rel); break; From a8ca4c264c2c1420d7b3028672c149662660adff Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 11 Jan 2007 18:54:09 +0000 Subject: [PATCH 158/570] This fixes the xen-api documentation latex-compilation. Signed-off-by: Stefan Berger --- docs/xen-api/wire-protocol.tex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/xen-api/wire-protocol.tex b/docs/xen-api/wire-protocol.tex index bcb228379e..1548f41c9e 100644 --- a/docs/xen-api/wire-protocol.tex +++ b/docs/xen-api/wire-protocol.tex @@ -153,7 +153,7 @@ you must login and initiate a session. For example: \end{verbatim} Where {\tt uname} and {\tt password} refer to your username and password respectively, as defined by the Xen administrator. -The {\tt session\_id} returned by {\tt session.login_with_password} is passed +The {\tt session\_id} returned by {\tt session.login\_with\_password} is passed to subequent RPC calls as an authentication token. A session can be terminated with the {\tt session.logout} function: From 2b1f4094a6bb571855c2a1ca54f5e6ded34913c5 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 11 Jan 2007 18:55:18 +0000 Subject: [PATCH 159/570] Source a file called 'vtpm-impl.alt' if it exists. Signed-off-by: Stefan Berger --- tools/examples/vtpm-common.sh | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tools/examples/vtpm-common.sh b/tools/examples/vtpm-common.sh index bf50f323e3..8af4f321e9 100644 --- a/tools/examples/vtpm-common.sh +++ b/tools/examples/vtpm-common.sh @@ -24,7 +24,9 @@ VTPMDB="/etc/xen/vtpm.db" #In the vtpm-impl file some commands should be defined: # vtpm_create, vtpm_setup, vtpm_start, etc. (see below) -if [ -r "$dir/vtpm-impl" ]; then +if [ -r "$dir/vtpm-impl.alt" ]; then + . "$dir/vtpm-impl.alt" +elif [ -r "$dir/vtpm-impl" ]; then . "$dir/vtpm-impl" else function vtpm_create () { From aeb7c09a6613aae8e39c271283f8db9f7a99d32f Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 11 Jan 2007 18:56:59 +0000 Subject: [PATCH 160/570] I added a parameter '-md' to 'runtest.sh' for running the xm test suite in a mode where all created domains a created as xend-managed domains. This patch also fixes a problem related to calling 'xm domid' on a currently suspended domain if that domain is a managed domain. In that case a 'None' is returned by Xend, which I default to '-1'. Signed-off-by: Stefan Berger --- tools/xm-test/lib/XmTestLib/Xm.py | 2 ++ tools/xm-test/runtest.sh | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/tools/xm-test/lib/XmTestLib/Xm.py b/tools/xm-test/lib/XmTestLib/Xm.py index 43ee90dd7c..6f1e33c153 100644 --- a/tools/xm-test/lib/XmTestLib/Xm.py +++ b/tools/xm-test/lib/XmTestLib/Xm.py @@ -49,6 +49,8 @@ def domid(name): if status != 0 or "Traceback" in output: return -1 + if output == "None": + return -1 try: return int(output) except: diff --git a/tools/xm-test/runtest.sh b/tools/xm-test/runtest.sh index 22c0736bf2..5b102b7f45 100755 --- a/tools/xm-test/runtest.sh +++ b/tools/xm-test/runtest.sh @@ -16,6 +16,7 @@ usage() { echo " -r : url of test results repository to use" echo " -s : just submit report " echo " -u : unsafe -- do not run the sanity checks before starting" + echo " -md : all created domains are xend-'managed' domains" echo " -h | --help : show this help" } @@ -218,11 +219,14 @@ run=yes unsafe=no GROUPENTERED=default +#Prepare for usage with ACM if [ -d /etc/xen/acm-security/policies ]; then cp -f tests/security-acm/xm-test-security_policy.xml \ /etc/xen/acm-security/policies fi +unset XM_MANAGED_DOMAINS + # Resolve options while [ $# -gt 0 ] do @@ -260,6 +264,10 @@ while [ $# -gt 0 ] unsafe=yes report=no ;; + -md) + echo "(use managed domains)" + export XM_MANAGED_DOMAINS=1 + ;; -h|--help) usage exit 0 From baacea8058282908ae5078f8f0373de10d58e150 Mon Sep 17 00:00:00 2001 From: Ewan Mellor Date: Thu, 11 Jan 2007 19:00:35 +0000 Subject: [PATCH 161/570] This patch does the following: - renames the XenManagedDomain.py file to XenAPIDomain.py, since this name better reflects its functionality/purpose - adds domain tracking to the XenAPIDomain class so that xend-managed domains can be deleted in an 'atexit' handler upon test case termination - adds one basic xapi-related test which is part of the grouptests 'xapi' - refactors the vtpm-related test using xen-api and adds it to the grouptest 'xapi' - adds documentation to the README for how to configure xm and xend to use XML-RPC or Xen-API for communication Signed-off-by: Stefan Berger --- tools/xm-test/README | 43 ++++++++ tools/xm-test/configure.ac | 1 + tools/xm-test/grouptest/xapi | 1 + tools/xm-test/lib/XmTestLib/DomainTracking.py | 18 ++++ .../{XenManagedDomain.py => XenAPIDomain.py} | 49 +++++---- tools/xm-test/lib/XmTestLib/xapi.py | 79 ++++++++------- tools/xm-test/tests/vtpm/09_vtpm-xapi.py | 99 +++++++++---------- tools/xm-test/tests/xapi/01_xapi-vm_basic.py | 61 ++++++++++++ tools/xm-test/tests/xapi/Makefile.am | 19 ++++ 9 files changed, 253 insertions(+), 117 deletions(-) rename tools/xm-test/lib/XmTestLib/{XenManagedDomain.py => XenAPIDomain.py} (76%) create mode 100644 tools/xm-test/tests/xapi/01_xapi-vm_basic.py create mode 100644 tools/xm-test/tests/xapi/Makefile.am diff --git a/tools/xm-test/README b/tools/xm-test/README index 9157f7681d..b63a34be32 100644 --- a/tools/xm-test/README +++ b/tools/xm-test/README @@ -207,6 +207,49 @@ dedicated machine. As such, the library automatically destroys any running DomUs on the system to provide each test with a "clean slate". +Testing the XML-RPC and Xen-API interfaces of xend +================================================== + +The xm-test suite can be used to test xm's interface with xend using +either XML-RPC or the Xen-API. In order to use either one of these modes, +xm needs to be configured using its configuration file +'/etc/xen/xm-config.xml'. +Note: The current default configuration after a fresh install of the xen +sources currently is to use the XML-RPC interface for communication with xend. + +Example content for the xm-config.xml for using the Xen-API looks as +follows: + + + + + +This configuration makes xm talk to xend using port 9363. For this to +work, also xend needs to be configured to listen to port 9363. Therefore +The following line must be in /etc/xen/xend-config.sxp. + +(xen-api-server (( 127.0.0.1:9363 none ))) + +To communicate via the legacy XML-RPC interface, the file +'/etc/xen/xm-config.xml' may simply have the following content or +may be complete remove from the /etc/xen directory. + + + + +A few tests have been written for the xm-test suite that test the +Xen-API interface directly without relying on 'xm'. These tests can be +found in the grouptest 'xapi' and for them to work properly, xm must have +been configured to use the Xen-API following the instructions above. To +run these test, the following command line can be invoked: + + # ./runtest.sh -g xapi + + + Extending ========= diff --git a/tools/xm-test/configure.ac b/tools/xm-test/configure.ac index 87df5cd6bd..ffbf146f34 100644 --- a/tools/xm-test/configure.ac +++ b/tools/xm-test/configure.ac @@ -150,6 +150,7 @@ AC_CONFIG_FILES([ tests/vcpu-pin/Makefile tests/vcpu-disable/Makefile tests/vtpm/Makefile + tests/xapi/Makefile tests/enforce_dom0_cpus/Makefile lib/XmTestReport/xmtest.py lib/XmTestLib/config.py diff --git a/tools/xm-test/grouptest/xapi b/tools/xm-test/grouptest/xapi index 407368e6b4..3b049219dd 100644 --- a/tools/xm-test/grouptest/xapi +++ b/tools/xm-test/grouptest/xapi @@ -1 +1,2 @@ +xapi vtpm 09_vtpm-xapi.test diff --git a/tools/xm-test/lib/XmTestLib/DomainTracking.py b/tools/xm-test/lib/XmTestLib/DomainTracking.py index cbd25146f5..7e0bb3013a 100644 --- a/tools/xm-test/lib/XmTestLib/DomainTracking.py +++ b/tools/xm-test/lib/XmTestLib/DomainTracking.py @@ -20,9 +20,11 @@ import atexit import Test +import xapi # Tracking of managed domains _managedDomains = [] +_VMuuids = [] registered = 0 def addManagedDomain(name): @@ -36,8 +38,24 @@ def delManagedDomain(name): if name in _managedDomains: del _managedDomains[_managedDomains.index(name)] +def addXAPIDomain(uuid): + global registered + _VMuuids.append(uuid) + if not registered: + atexit.register(destroyManagedDomains) + registered = 1 + +def delXAPIDomain(uuid): + _VMuuids.remove(uuid) + def destroyManagedDomains(): if len(_managedDomains) > 0: for m in _managedDomains: Test.traceCommand("xm destroy %s" % m) Test.traceCommand("xm delete %s" % m) + if len(_VMuuids) > 0: + for uuid in _VMuuids: + Test.traceCommand("xm destroy %s" % uuid) + Test.traceCommand("xm delete %s" % uuid) + + diff --git a/tools/xm-test/lib/XmTestLib/XenManagedDomain.py b/tools/xm-test/lib/XmTestLib/XenAPIDomain.py similarity index 76% rename from tools/xm-test/lib/XmTestLib/XenManagedDomain.py rename to tools/xm-test/lib/XmTestLib/XenAPIDomain.py index 1b211fe016..cfec7911ee 100644 --- a/tools/xm-test/lib/XmTestLib/XenManagedDomain.py +++ b/tools/xm-test/lib/XmTestLib/XenAPIDomain.py @@ -26,7 +26,7 @@ from xen.util.xmlrpclib2 import ServerProxy from types import DictType -class XenManagedConfig: +class XenAPIConfig: """An object to help create a VM configuration usable via Xen-API""" def __init__(self): self.opts = {} @@ -36,9 +36,9 @@ class XenManagedConfig: 'memory_static_min' , 'memory_dynamic_min', 'memory_dynamic_max' ], - 'kernel' : 'kernel_kernel', - 'ramdisk': 'kernel_initrd', - 'root' : 'kernel_args'} + 'kernel' : 'PV_kernel', + 'ramdisk': 'PV_ramdisk', + 'root' : 'PV_args'} def setOpt(self, name, value): """Set an option in the config""" @@ -69,7 +69,7 @@ class XenManagedConfig: return self.opts -class XenManagedDomain(XenDomain): +class XenAPIDomain(XenDomain): def __init__(self, name=None, config=None): if name: @@ -81,12 +81,11 @@ class XenManagedDomain(XenDomain): self.console = None self.netEnv = "bridge" - self.server, self.session = xapi._connect() - server = self.server + self.session = xapi.connect() + session = self.session try: - self.vm_uuid = xapi.execute(server.VM.create, self.session, - self.config.getOpts()) - xapi._VMuuids.append(self.vm_uuid) + self.vm_uuid = session.xenapi.VM.create(self.config.getOpts()) + addXAPIDomain(self.vm_uuid) except: raise DomainError("Could not create VM config file for " "managed domain.") @@ -96,15 +95,17 @@ class XenManagedDomain(XenDomain): def start(self, noConsole=False, startpaused=False): #start the VM - server = self.server + session = self.session if self.vm_uuid: try: - xapi.execute(server.VM.start, self.session, self.vm_uuid, - startpaused) + session.xenapi.VM.start(self.vm_uuid, startpaused) except: raise DomainError("Could not start domain") else: - raise DomainError("VM has not UUID - VM config does not exist?") + raise DomainError("VM has no UUID - does VM config exist?") + + if startpaused: + return if self.getDomainType() == "HVM": waitForBoot() @@ -120,20 +121,18 @@ class XenManagedDomain(XenDomain): def stop(self): if self.vm_uuid: - server = self.server - xapi.execute(server.VM.hard_shutdown, self.session, self.vm_uuid) + self.session.xenapi.VM.hard_shutdown(self.vm_uuid) else: - raise DomainError("VM has not UUID - VM config does not exist?") + raise DomainError("VM has no UUID - does VM config exist?") def destroy(self): #Stop VM first. self.stop() if self.vm_uuid: - server = self.server - xapi.execute(server.VM.destroy, self.session, self.vm_uuid) - xapi._VMuuids.remove(self.vm_uuid) + self.session.xenapi.VM.destroy(self.vm_uuid) + delXAPIDomain(self.vm_uuid) else: - raise DomainError("VM has not UUID - VM config does not exist?") + raise DomainError("VM has no UUID - does VM config exist?") def get_uuid(self): return self.vm_uuid @@ -154,7 +153,7 @@ class XenManagedDomain(XenDomain): raise DomainError("No support for getDevice().") -class XmTestManagedDomain(XenManagedDomain): +class XmTestAPIDomain(XenAPIDomain): """Create a new managed xm-test domain @param name: The requested domain name @@ -163,7 +162,7 @@ class XmTestManagedDomain(XenManagedDomain): """ def __init__(self, name=None, extraConfig=None, baseConfig=arch.configDefaults): - config = XenManagedConfig() + config = XenAPIConfig() config.setOpts(baseConfig) if extraConfig: config.setOpts(extraConfig) @@ -173,5 +172,5 @@ class XmTestManagedDomain(XenManagedDomain): elif not config.getOpt("name_label"): config.setOpt("name_label", getUniqueName()) - XenManagedDomain.__init__(self, config.getOpt("name_label"), - config=config) + XenAPIDomain.__init__(self, config.getOpt("name_label"), + config=config) diff --git a/tools/xm-test/lib/XmTestLib/xapi.py b/tools/xm-test/lib/XmTestLib/xapi.py index bab0e103d9..773b3c1739 100644 --- a/tools/xm-test/lib/XmTestLib/xapi.py +++ b/tools/xm-test/lib/XmTestLib/xapi.py @@ -17,50 +17,49 @@ # Copyright (C) 2006 IBM Corporation #============================================================================ +import atexit import os import sys from XmTestLib import * -from xen.util.xmlrpclib2 import ServerProxy +from xen.xm import main as xmmain +from xen.xm import XenAPI +from xen.xm.opts import OptionError from types import DictType +import xml.dom.minidom +def get_login_pwd(): + if xmmain.serverType == xmmain.SERVER_XEN_API: + try: + login, password = xmmain.parseAuthentication() + return (login, password) + except: + raise OptionError("Configuration for login/pwd not found. " + "Need to run xapi-setup.py?") + raise OptionError("Xm configuration file not using Xen-API for " + "communication with xend.") -XAPI_DEFAULT_LOGIN = " " -XAPI_DEFAULT_PASSWORD = " " +sessions=[] -class XenAPIError(Exception): - pass - - -#A list of VMs' UUIDs that were created using vm_create -_VMuuids = [] - -#Terminate previously created managed(!) VMs and destroy their configs -def vm_destroy_all(): - server, session = _connect() - for uuid in _VMuuids: - execute(server.VM.hard_shutdown, session, uuid) - execute(server.VM.destroy , session, uuid) - - -def execute(fn, *args): - result = fn(*args) - if type(result) != DictType: - raise TypeError("Function returned object of type: %s" % - str(type(result))) - if 'Value' not in result: - raise XenAPIError(*result['ErrorDescription']) - return result['Value'] - -_initialised = False -_server = None -_session = None -def _connect(*args): - global _server, _session, _initialised - if not _initialised: - _server = ServerProxy('httpu:///var/run/xend/xen-api.sock') - login = XAPI_DEFAULT_LOGIN - password = XAPI_DEFAULT_PASSWORD - creds = (login, password) - _session = execute(_server.session.login_with_password, *creds) - _initialised = True - return (_server, _session) +def connect(*args): + try: + creds = get_login_pwd() + except Exception, e: + FAIL("%s" % str(e)) + try: + session = XenAPI.Session(xmmain.serverURI) + except: + raise OptionError("Could not create XenAPI session with Xend." \ + "URI=%s" % xmmain.serverURI) + try: + session.login_with_password(*creds) + except: + raise OptionError("Could not login to Xend. URI=%s" % xmmain.serverURI) + def logout(): + try: + for s in sessions: + s.xenapi.session.logout() + except: + pass + sessions.append(session) + atexit.register(logout) + return session diff --git a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py index 8547a08b03..89975d077f 100644 --- a/tools/xm-test/tests/vtpm/09_vtpm-xapi.py +++ b/tools/xm-test/tests/vtpm/09_vtpm-xapi.py @@ -6,71 +6,66 @@ # Test to test the vtpm class through the Xen-API from XmTestLib import xapi -from XmTestLib.XenManagedDomain import XmTestManagedDomain +from XmTestLib.XenAPIDomain import XmTestAPIDomain from XmTestLib import * from vtpm_utils import * import commands import os -def do_test(): - domain = XmTestManagedDomain() - vm_uuid = domain.get_uuid() +try: + # XmTestAPIDomain tries to establish a connection to XenD + domain = XmTestAPIDomain() +except Exception, e: + SKIP("Skipping test. Error: %s" % str(e)) +vm_uuid = domain.get_uuid() - vtpmcfg = {} - vtpmcfg['type'] = "paravirtualised" - vtpmcfg['backend'] = "Domain-0" - vtpmcfg['instance'] = 1 - vtpmcfg['VM'] = vm_uuid +vtpmcfg = {} +vtpmcfg['type'] = "paravirtualised" +vtpmcfg['backend'] = "Domain-0" +vtpmcfg['instance'] = 1 +vtpmcfg['VM'] = vm_uuid - server, session = xapi._connect() +session = xapi.connect() - vtpm_uuid = xapi.execute(server.VTPM.create, session, vtpmcfg) +vtpm_uuid = session.xenapi.VTPM.create(vtpmcfg) - vtpm_id = xapi.execute(server.VTPM.get_instance, session, vtpm_uuid) - vtpm_be = xapi.execute(server.VTPM.get_backend , session, vtpm_uuid) - if vtpm_be != vtpmcfg['backend']: - FAIL("vTPM's backend is in '%s', expected: '%s'" % - (vtpm_be, vtpmcfg['backend'])) +vtpm_id = session.xenapi.VTPM.get_instance(vtpm_uuid) +vtpm_be = session.xenapi.VTPM.get_backend(vtpm_uuid) +if vtpm_be != vtpmcfg['backend']: + FAIL("vTPM's backend is in '%s', expected: '%s'" % + (vtpm_be, vtpmcfg['backend'])) - driver = xapi.execute(server.VTPM.get_driver, session, vtpm_uuid) - if driver != vtpmcfg['type']: - FAIL("vTPM has driver type '%s', expected: '%s'" % - (driver, vtpmcfg['type'])) +driver = session.xenapi.VTPM.get_driver(vtpm_uuid) +if driver != vtpmcfg['type']: + FAIL("vTPM has driver type '%s', expected: '%s'" % + (driver, vtpmcfg['type'])) - vtpm_rec = xapi.execute(server.VTPM.get_record, session, vtpm_uuid) +vtpm_rec = session.xenapi.VTPM.get_record(vtpm_uuid) - if vtpm_rec['driver'] != vtpmcfg['type']: - FAIL("vTPM record shows driver type '%s', expected: '%s'" % - (vtpm_rec['driver'], vtpmcfg['type'])) - if vtpm_rec['uuid'] != vtpm_uuid: - FAIL("vTPM record shows vtpm uuid '%s', expected: '%s'" % - (vtpm_rec['uuid'], vtpm_uuid)) - if vtpm_rec['VM'] != vm_uuid: - FAIL("vTPM record shows VM uuid '%s', expected: '%s'" % - (vtpm_rec['VM'], vm_uuid)) - - success = domain.start() - - console = domain.getConsole() - - try: - run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs") - except ConsoleError, e: - saveLog(console.getHistory()) - vtpm_cleanup(domName) - FAIL("No result from dumping the PCRs") - - if re.search("No such file",run["output"]): - vtpm_cleanup(domName) - FAIL("TPM frontend support not compiled into (domU?) kernel") - - domain.stop() - domain.destroy() +if vtpm_rec['driver'] != vtpmcfg['type']: + FAIL("vTPM record shows driver type '%s', expected: '%s'" % + (vtpm_rec['driver'], vtpmcfg['type'])) +if vtpm_rec['uuid'] != vtpm_uuid: + FAIL("vTPM record shows vtpm uuid '%s', expected: '%s'" % + (vtpm_rec['uuid'], vtpm_uuid)) +if vtpm_rec['VM'] != vm_uuid: + FAIL("vTPM record shows VM uuid '%s', expected: '%s'" % + (vtpm_rec['VM'], vm_uuid)) +success = domain.start() +console = domain.getConsole() try: - do_test() -finally: - #Make sure all domains are gone that were created in this test case - xapi.vm_destroy_all() + run = console.runCmd("cat /sys/devices/xen/vtpm-0/pcrs") +except ConsoleError, e: + saveLog(console.getHistory()) + vtpm_cleanup(domName) + FAIL("No result from dumping the PCRs") + +if re.search("No such file",run["output"]): + vtpm_cleanup(domName) + FAIL("TPM frontend support not compiled into (domU?) kernel") + +domain.stop() +domain.destroy() diff --git a/tools/xm-test/tests/xapi/01_xapi-vm_basic.py b/tools/xm-test/tests/xapi/01_xapi-vm_basic.py new file mode 100644 index 0000000000..6f149a0dd9 --- /dev/null +++ b/tools/xm-test/tests/xapi/01_xapi-vm_basic.py @@ -0,0 +1,61 @@ +#!/usr/bin/python + +# Copyright (C) International Business Machines Corp., 2006 +# Author: Stefan Berger + +# Basic VM creation test + +from XmTestLib import xapi +from XmTestLib.XenAPIDomain import XmTestAPIDomain +from XmTestLib import * +from xen.xend import XendAPIConstants +import commands +import os + +try: + # XmTestAPIDomain tries to establish a connection to XenD + domain = XmTestAPIDomain() +except Exception, e: + SKIP("Skipping test. Error: %s" % str(e)) +vm_uuid = domain.get_uuid() + +session = xapi.connect() + +domain.start(startpaused=True) + +res = session.xenapi.VM.get_power_state(vm_uuid) + +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_PAUSED]: + FAIL("VM was not started in 'paused' state") + +res = session.xenapi.VM.unpause(vm_uuid) + +res = session.xenapi.VM.get_power_state(vm_uuid) + +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_RUNNING]: + FAIL("VM could not be put into 'running' state") + +console = domain.getConsole() + +try: + run = console.runCmd("cat /proc/interrupts") +except ConsoleError, e: + saveLog(console.getHistory()) + FAIL("Could not access proc-filesystem") + +res = session.xenapi.VM.pause(vm_uuid) + +res = session.xenapi.VM.get_power_state(vm_uuid) + +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_PAUSED]: + FAIL("VM could not be put into 'paused' state") + +res = session.xenapi.VM.unpause(vm_uuid) + +res = session.xenapi.VM.get_power_state(vm_uuid) + +if res != XendAPIConstants.XEN_API_VM_POWER_STATE[XendAPIConstants.XEN_API_VM_POWER_STATE_RUNNING]: + FAIL("VM could not be 'unpaused'") + +domain.stop() +domain.destroy() diff --git a/tools/xm-test/tests/xapi/Makefile.am b/tools/xm-test/tests/xapi/Makefile.am new file mode 100644 index 0000000000..2a0c44f578 --- /dev/null +++ b/tools/xm-test/tests/xapi/Makefile.am @@ -0,0 +1,19 @@ +SUBDIRS = + +TESTS = 01_xapi-vm_basic.test + +XFAIL_TESTS = + +EXTRA_DIST = $(TESTS) $(XFAIL_TESTS) xapi_utils.py +TESTS_ENVIRONMENT=@TENV@ + +%.test: %.py + cp $< $@ + chmod +x $@ + +clean-local: am_config_clean-local + +am_config_clean-local: + rm -f *test + rm -f *log + rm -f *~ From bfdf10eac543f670c7347ea738bf08f6a9e02934 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Thu, 11 Jan 2007 19:01:28 +0000 Subject: [PATCH 162/570] [XEN] Add LOOP{,Z,NZ} and CBW/CWD/... emulation. Signed-off-by: Keir Fraser --- xen/arch/x86/x86_emulate.c | 53 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/xen/arch/x86/x86_emulate.c b/xen/arch/x86/x86_emulate.c index e96e981b21..200b6c4aac 100644 --- a/xen/arch/x86/x86_emulate.c +++ b/xen/arch/x86/x86_emulate.c @@ -109,7 +109,7 @@ static uint8_t opcode_table[256] = { ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, /* 0x98 - 0x9F */ - 0, 0, 0, 0, 0, 0, ImplicitOps, ImplicitOps, + ImplicitOps, ImplicitOps, 0, 0, 0, 0, ImplicitOps, ImplicitOps, /* 0xA0 - 0xA7 */ ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, ByteOp|ImplicitOps|Mov, ImplicitOps|Mov, @@ -139,7 +139,7 @@ static uint8_t opcode_table[256] = { /* 0xD8 - 0xDF */ 0, 0, 0, 0, 0, 0, 0, 0, /* 0xE0 - 0xE7 */ - 0, 0, 0, ImplicitOps, 0, 0, 0, 0, + ImplicitOps, ImplicitOps, ImplicitOps, ImplicitOps, 0, 0, 0, 0, /* 0xE8 - 0xEF */ ImplicitOps, ImplicitOps, 0, ImplicitOps, 0, 0, 0, 0, /* 0xF0 - 0xF7 */ @@ -1339,6 +1339,30 @@ x86_emulate( dst.val = *dst.reg; goto xchg; + case 0x98: /* cbw/cwde/cdqe */ + switch ( op_bytes ) + { + case 2: *(int16_t *)&_regs.eax = (int8_t)_regs.eax; break; /* cbw */ + case 4: _regs.eax = (uint32_t)(int16_t)_regs.eax; break; /* cwde */ + case 8: _regs.eax = (int32_t)_regs.eax; break; /* cdqe */ + } + break; + + case 0x99: /* cwd/cdq/cqo */ + switch ( op_bytes ) + { + case 2: + *(int16_t *)&_regs.edx = ((int16_t)_regs.eax < 0) ? -1 : 0; + break; + case 4: + _regs.edx = (uint32_t)(((int32_t)_regs.eax < 0) ? -1 : 0); + break; + case 8: + _regs.edx = (_regs.eax < 0) ? -1 : 0; + break; + } + break; + case 0x9e: /* sahf */ *(uint8_t *)_regs.eflags = (((uint8_t *)&_regs.eax)[1] & 0xd7) | 0x02; break; @@ -1452,6 +1476,31 @@ x86_emulate( break; } + case 0xe0 ... 0xe2: /* loop{,z,nz} */ { + int rel = insn_fetch_type(int8_t); + int do_jmp = !(_regs.eflags & EFLG_ZF); /* loopnz */ + if ( b == 0xe1 ) + do_jmp = !do_jmp; /* loopz */ + else if ( b == 0xe2 ) + do_jmp = 1; /* loop */ + switch ( ad_bytes ) + { + case 2: + do_jmp &= --(*(uint16_t *)&_regs.ecx) != 0; + break; + case 4: + do_jmp &= --(*(uint32_t *)&_regs.ecx) != 0; + _regs.ecx = (uint32_t)_regs.ecx; /* zero extend in x86/64 mode */ + break; + default: /* case 8: */ + do_jmp &= --_regs.ecx != 0; + break; + } + if ( do_jmp ) + jmp_rel(rel); + break; + } + case 0xe3: /* jcxz/jecxz (short) */ { int rel = insn_fetch_type(int8_t); if ( (ad_bytes == 2) ? !(uint16_t)_regs.ecx : From 99954e535e5c835c14a592ad18217b293b64b3e7 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 11 Jan 2007 17:03:25 -0700 Subject: [PATCH 163/570] [IA64] fix domain_flush_vtlb_all() It might called by another domain's vcpu. Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/mm.c | 8 ++++---- xen/arch/ia64/xen/vhpt.c | 5 +++-- xen/include/asm-ia64/tlbflush.h | 2 +- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/xen/arch/ia64/xen/mm.c b/xen/arch/ia64/xen/mm.c index b560abf5f8..aec322870c 100644 --- a/xen/arch/ia64/xen/mm.c +++ b/xen/arch/ia64/xen/mm.c @@ -972,7 +972,7 @@ ioports_deny_access(struct domain *d, unsigned long fp, unsigned long lp) // clear pte old_pte = ptep_get_and_clear(mm, mpaddr, pte); } - domain_flush_vtlb_all(); + domain_flush_vtlb_all(d); return 0; } @@ -1730,7 +1730,7 @@ domain_page_flush_and_put(struct domain* d, unsigned long mpaddr, #ifndef CONFIG_XEN_IA64_TLB_TRACK //XXX sledgehammer. // flush finer range. - domain_flush_vtlb_all(); + domain_flush_vtlb_all(d); put_page(page); #else switch (tlb_track_search_and_remove(d->arch.tlb_track, @@ -1749,7 +1749,7 @@ domain_page_flush_and_put(struct domain* d, unsigned long mpaddr, * queue the page and flush vTLB only once. * I.e. The caller must call dfree_flush() explicitly. */ - domain_flush_vtlb_all(); + domain_flush_vtlb_all(d); put_page(page); break; case TLB_TRACK_NOT_FOUND: @@ -1783,7 +1783,7 @@ domain_page_flush_and_put(struct domain* d, unsigned long mpaddr, * So we abondaned to track virtual addresses. * full vTLB flush is necessary. */ - domain_flush_vtlb_all(); + domain_flush_vtlb_all(d); put_page(page); break; case TLB_TRACK_AGAIN: diff --git a/xen/arch/ia64/xen/vhpt.c b/xen/arch/ia64/xen/vhpt.c index 0ba1f93a9b..c8846efc45 100644 --- a/xen/arch/ia64/xen/vhpt.c +++ b/xen/arch/ia64/xen/vhpt.c @@ -258,12 +258,13 @@ static void __vcpu_flush_vtlb_all(void *vcpu) vcpu_flush_vtlb_all((struct vcpu*)vcpu); } -void domain_flush_vtlb_all (void) +// caller must incremented reference count to d somehow. +void domain_flush_vtlb_all(struct domain* d) { int cpu = smp_processor_id (); struct vcpu *v; - for_each_vcpu (current->domain, v) { + for_each_vcpu(d, v) { if (!test_bit(_VCPUF_initialised, &v->vcpu_flags)) continue; diff --git a/xen/include/asm-ia64/tlbflush.h b/xen/include/asm-ia64/tlbflush.h index 49ff463b11..a659f6a0e4 100644 --- a/xen/include/asm-ia64/tlbflush.h +++ b/xen/include/asm-ia64/tlbflush.h @@ -17,7 +17,7 @@ void vcpu_flush_vtlb_all(struct vcpu *v); void vcpu_flush_tlb_vhpt_range (u64 vadr, u64 log_range); /* Global all flush of vTLB */ -void domain_flush_vtlb_all (void); +void domain_flush_vtlb_all(struct domain *d); /* Global range-flush of vTLB. */ void domain_flush_vtlb_range (struct domain *d, u64 vadr, u64 addr_range); From 00fd1992350859a96239c8351e0b7d706d4f0902 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Fri, 12 Jan 2007 12:03:38 -0700 Subject: [PATCH 164/570] [IA64] Resolve a race in tlb_track_search_and_remove() When tlb_track_search_and_remove() is about to remove a found entry, another cpu might update p2m entry and insert the entry right before that. It must be aware of it. Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/tlb_track.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/xen/arch/ia64/xen/tlb_track.c b/xen/arch/ia64/xen/tlb_track.c index 07816a4acb..1cbf6126de 100644 --- a/xen/arch/ia64/xen/tlb_track.c +++ b/xen/arch/ia64/xen/tlb_track.c @@ -454,6 +454,31 @@ tlb_track_search_and_remove(struct tlb_track* tlb_track, continue; if (pte_pfn(entry->pte_val) == mfn) { + /* + * PARANOIA + * We're here after zapping p2m entry. However another pCPU + * may update the same p2m entry entry the same mfn at the + * same time in theory. In such a case, we can't determine + * whether this entry is for us or for the racy p2m update. + * Such a guest domain's racy behaviour doesn't make sense, + * but is allowed. Go the very pessimistic way. Leave this + * entry to be found later and do full flush at this time. + * + * NOTE: Updating tlb tracking hash is protected by spin lock and + * setting _PAGE_TLB_INSERTED and_PAGE_TLB_INSERTED_MANY bits + * is serialized by the same spin lock. + * See tlb_track_insert_or_dirty(). + */ + pte_t current_pte = *ptep; + if (unlikely(pte_pfn(current_pte) == mfn && + pte_tlb_tracking(current_pte) && + pte_tlb_inserted(current_pte))) { + BUG_ON(pte_tlb_inserted_many(current_pte)); + spin_unlock(&tlb_track->hash_lock); + perfc_incrc(tlb_track_sar_many); + return TLB_TRACK_MANY; + } + list_del(&entry->list); spin_unlock(&tlb_track->hash_lock); *entryp = entry; From 5d5be531d0b35b650884063ad4be969d8e18849a Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Fri, 12 Jan 2007 12:14:05 -0700 Subject: [PATCH 165/570] [IA64] Make crash command happy As Dave requested, call unw_init_running() and save ksp before SHUTDOWN_crash. Signed-off-by: Dave Anderson Signed-off-by: Isaku Yamahata --- linux-2.6-xen-sparse/arch/ia64/kernel/setup.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c index 4158332846..ecf770645d 100644 --- a/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c +++ b/linux-2.6-xen-sparse/arch/ia64/kernel/setup.c @@ -77,10 +77,18 @@ EXPORT_SYMBOL(__per_cpu_offset); #endif #ifdef CONFIG_XEN +static void +xen_panic_hypercall(struct unw_frame_info *info, void *arg) +{ + current->thread.ksp = (__u64)info->sw - 16; + HYPERVISOR_shutdown(SHUTDOWN_crash); + /* we're never actually going to get here... */ +} + static int xen_panic_event(struct notifier_block *this, unsigned long event, void *ptr) { - HYPERVISOR_shutdown(SHUTDOWN_crash); + unw_init_running(xen_panic_hypercall, NULL); /* we're never actually going to get here... */ return NOTIFY_DONE; } From 714d43d8e1072eeea1a8ae6b1e442e9b40c62412 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Fri, 12 Jan 2007 12:52:54 -0700 Subject: [PATCH 166/570] [IA64] Use original itir when inserting into the single-entry TLB http://lists.xensource.com/archives/html/xen-ia64-devel/2006-11/msg00349.html The real VHPT insertion is done based on the machine PTE returned from translate_domain_pte, which does the appropriate offset calculations. However, the insertion into the one-entry TLB uses the original PTE, but the page size has been reset to PAGE_SIZE [1]. Thus the entry in the one-entry TLB incorrectly maps the PAGE_SIZE sub-page which was faulted on to the PAGE_SIZE sub-page at the bottom of the superpage. I think it makes most sense to simply use the original itir when inserting into the single-entry TLB, as per attached patch. I've moved the vcpu_set_tr_entry calls up a level into vcpu_itc_d and vcpu_itc_i; the third caller previously used the 4 flag to specify "don't do that". [1] In fact, this is enforced twice, once in translate_domain_pte and again in vcpu_itc_no_srlz. Signed-off-by: Matthew Chapman Signed-off-by: Isaku Yamahata --- xen/arch/ia64/xen/faults.c | 4 ++-- xen/arch/ia64/xen/vcpu.c | 10 ++-------- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c index e2ffb9d72d..8893c7395f 100644 --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -215,8 +215,8 @@ void ia64_do_page_fault(unsigned long address, unsigned long isr, unsigned long m_pteval; m_pteval = translate_domain_pte(pteval, address, itir, &logps, &entry); - vcpu_itc_no_srlz(current, (is_data ? 2 : 1) | 4, - address, m_pteval, pteval, logps, &entry); + vcpu_itc_no_srlz(current, is_data ? 2 : 1, address, + m_pteval, pteval, logps, &entry); if ((fault == IA64_USE_TLB && !current->arch.dtlb.pte.p) || p2m_entry_retry(&entry)) { /* dtlb has been purged in-between. This dtlb was diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index 4b57f2ddb0..8adad97c21 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -2181,14 +2181,6 @@ vcpu_itc_no_srlz(VCPU * vcpu, u64 IorD, u64 vaddr, u64 pte, else vhpt_insert(vaddr, pte, PAGE_SHIFT << 2); #endif - if (IorD & 0x4) /* don't place in 1-entry TLB */ - return; - if (IorD & 0x1) { - vcpu_set_tr_entry(&PSCBX(vcpu, itlb), mp_pte, ps << 2, vaddr); - } - if (IorD & 0x2) { - vcpu_set_tr_entry(&PSCBX(vcpu, dtlb), mp_pte, ps << 2, vaddr); - } } IA64FAULT vcpu_itc_d(VCPU * vcpu, u64 pte, u64 itir, u64 ifa) @@ -2215,6 +2207,7 @@ IA64FAULT vcpu_itc_d(VCPU * vcpu, u64 pte, u64 itir, u64 ifa) vcpu_flush_tlb_vhpt_range(ifa, logps); goto again; } + vcpu_set_tr_entry(&PSCBX(vcpu, dtlb), pte, itir, ifa); return IA64_NO_FAULT; } @@ -2241,6 +2234,7 @@ IA64FAULT vcpu_itc_i(VCPU * vcpu, u64 pte, u64 itir, u64 ifa) vcpu_flush_tlb_vhpt_range(ifa, logps); goto again; } + vcpu_set_tr_entry(&PSCBX(vcpu, itlb), pte, itir, ifa); return IA64_NO_FAULT; } From 2293be461e7fbd877b44c565748b8cc2885117be Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 11 Jan 2007 14:27:39 -0700 Subject: [PATCH 167/570] [IA64] Can't inject event, when guest is executing rfi Can't inject event, when guest is executing rfi, and both both PSCB(v, ifs) and regs->ifs are valid It's very rare case, but I did catch it. It caused domain0 crash Signed-off-by: Anthony Xu --- xen/arch/ia64/xen/faults.c | 5 +++++ xen/arch/ia64/xen/vcpu.c | 29 +++++++++++++++++------------ xen/include/asm-ia64/vcpu.h | 2 ++ 3 files changed, 24 insertions(+), 12 deletions(-) diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c index 8893c7395f..454bdd69a6 100644 --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -134,6 +134,11 @@ void reflect_event(struct pt_regs *regs) if (!event_pending(v)) return; + // can't inject event, when XEN is emulating rfi + // and both PSCB(v, ifs) and regs->ifs are valid + if (regs->cr_iip == *(unsigned long *)dorfirfi) + return; + if (!PSCB(v, interrupt_collection_enabled)) printk("psr.ic off, delivering event, ipsr=%lx,iip=%lx," "isr=%lx,viip=0x%lx\n", diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index 8adad97c21..10a8227ef7 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -1326,7 +1326,6 @@ IA64FAULT vcpu_rfi(VCPU * vcpu) u64 int_enable, regspsr = 0; u64 ifs; REGS *regs = vcpu_regs(vcpu); - extern void dorfirfi(void); psr.i64 = PSCB(vcpu, ipsr); if (psr.ia64_psr.cpl < 3) @@ -1350,18 +1349,24 @@ IA64FAULT vcpu_rfi(VCPU * vcpu) return IA64_ILLOP_FAULT; } PSCB(vcpu, incomplete_regframe) = 0; // is this necessary? + ifs = PSCB(vcpu, ifs); - //if ((ifs & regs->cr_ifs & 0x8000000000000000L) && ifs != regs->cr_ifs) { - //if ((ifs & 0x8000000000000000L) && ifs != regs->cr_ifs) { - if (ifs & regs->cr_ifs & 0x8000000000000000L) { - // TODO: validate PSCB(vcpu,iip) - // TODO: PSCB(vcpu,ipsr) = psr; - PSCB(vcpu, ipsr) = psr.i64; - // now set up the trampoline - regs->cr_iip = *(unsigned long *)dorfirfi; // function pointer!! - __asm__ __volatile("mov %0=psr;;":"=r"(regspsr)::"memory"); - regs->cr_ipsr = - regspsr & ~(IA64_PSR_I | IA64_PSR_IC | IA64_PSR_BN); + if (ifs > 0x8000000000000000UL) { + if (regs->cr_ifs > 0x8000000000000000UL) { + // TODO: validate PSCB(vcpu,iip) + // TODO: PSCB(vcpu,ipsr) = psr; + PSCB(vcpu, ipsr) = psr.i64; + // now set up the trampoline + regs->cr_iip = *(unsigned long *)dorfirfi; // func ptr! + __asm__ __volatile("mov %0=psr;;":"=r"(regspsr) + ::"memory"); + regs->cr_ipsr = regspsr & ~(IA64_PSR_I | IA64_PSR_IC | + IA64_PSR_BN); + } else { + regs->cr_ifs = ifs; + regs->cr_ipsr = psr.i64; + regs->cr_iip = PSCB(vcpu, iip); + } } else { regs->cr_ipsr = psr.i64; regs->cr_iip = PSCB(vcpu, iip); diff --git a/xen/include/asm-ia64/vcpu.h b/xen/include/asm-ia64/vcpu.h index b61915e3b2..e403213d65 100644 --- a/xen/include/asm-ia64/vcpu.h +++ b/xen/include/asm-ia64/vcpu.h @@ -23,6 +23,8 @@ extern u64 cycle_to_ns(u64 cycle); #define SPURIOUS_VECTOR 0xf +extern void dorfirfi(void); + /* general registers */ extern u64 vcpu_get_gr(VCPU * vcpu, unsigned long reg); extern IA64FAULT vcpu_get_gr_nat(VCPU * vcpu, unsigned long reg, u64 * val); From 7fbbbf9e7179375da046414fa0126765049422a0 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 11 Jan 2007 14:42:24 -0700 Subject: [PATCH 168/570] [IA64] merge increment_iip Signed-off-by: Anthony Xu --- xen/arch/ia64/vmx/mmio.c | 8 +++--- xen/arch/ia64/vmx/vmx_process.c | 10 ++++---- xen/arch/ia64/vmx/vmx_vcpu.c | 45 --------------------------------- xen/arch/ia64/vmx/vmx_virt.c | 2 +- xen/arch/ia64/xen/vcpu.c | 14 ++++++++++ xen/include/asm-ia64/vcpu.h | 1 + xen/include/asm-ia64/vmx_vcpu.h | 2 -- 7 files changed, 25 insertions(+), 57 deletions(-) diff --git a/xen/arch/ia64/vmx/mmio.c b/xen/arch/ia64/vmx/mmio.c index 737220df8f..08247e1c14 100644 --- a/xen/arch/ia64/vmx/mmio.c +++ b/xen/arch/ia64/vmx/mmio.c @@ -362,7 +362,7 @@ void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma) temp += post_update; vcpu_set_gr(vcpu,inst.M15.r3,temp,0); - vmx_vcpu_increment_iip(vcpu); + vcpu_increment_iip(vcpu); return; } // Floating-point Load Pair + Imm ldfp8 M12 @@ -382,9 +382,9 @@ void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma) vcpu_set_fpreg(vcpu,inst.M12.f2,&v); padr += 8; vcpu_set_gr(vcpu,inst.M12.r3,padr,0); - vmx_vcpu_increment_iip(vcpu); + vcpu_increment_iip(vcpu); return; - } + } else{ panic_domain (NULL,"This memory access instr can't be emulated: %lx pc=%lx\n ", @@ -420,5 +420,5 @@ void emulate_io_inst(VCPU *vcpu, u64 padr, u64 ma) */ } } - vmx_vcpu_increment_iip(vcpu); + vcpu_increment_iip(vcpu); } diff --git a/xen/arch/ia64/vmx/vmx_process.c b/xen/arch/ia64/vmx/vmx_process.c index f8ff340a78..acce2c0bf9 100644 --- a/xen/arch/ia64/vmx/vmx_process.c +++ b/xen/arch/ia64/vmx/vmx_process.c @@ -93,7 +93,7 @@ void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim, if (vector == IA64_FP_FAULT_VECTOR) { status = handle_fpu_swa(1, regs, isr); if (!status) { - vmx_vcpu_increment_iip(vcpu); + vcpu_increment_iip(vcpu); return; } else if (IA64_RETRY == status) return; @@ -104,7 +104,7 @@ void vmx_reflect_interruption(u64 ifa, u64 isr, u64 iim, if (!status) return; else if (IA64_RETRY == status) { - vmx_vcpu_decrement_iip(vcpu); + vcpu_decrement_iip(vcpu); return; } } @@ -143,16 +143,16 @@ vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long is /* Allow hypercalls only when cpl = 0. */ if (iim == d->arch.breakimm) { ia64_hypercall(regs); - vmx_vcpu_increment_iip(v); + vcpu_increment_iip(v); return IA64_NO_FAULT; } else if(iim == DOMN_PAL_REQUEST){ pal_emul(v); - vmx_vcpu_increment_iip(v); + vcpu_increment_iip(v); return IA64_NO_FAULT; }else if(iim == DOMN_SAL_REQUEST){ sal_emul(v); - vmx_vcpu_increment_iip(v); + vcpu_increment_iip(v); return IA64_NO_FAULT; } } diff --git a/xen/arch/ia64/vmx/vmx_vcpu.c b/xen/arch/ia64/vmx/vmx_vcpu.c index 322afe3542..5c1ab3305f 100644 --- a/xen/arch/ia64/vmx/vmx_vcpu.c +++ b/xen/arch/ia64/vmx/vmx_vcpu.c @@ -145,48 +145,6 @@ vmx_vcpu_set_psr(VCPU *vcpu, unsigned long value) return ; } -/* Adjust slot both in pt_regs and vpd, upon vpsr.ri which - * should have sync with ipsr in entry. - * - * Clear some bits due to successfully emulation. - */ -IA64FAULT vmx_vcpu_increment_iip(VCPU *vcpu) -{ - // TODO: trap_bounce?? Eddie - REGS *regs = vcpu_regs(vcpu); - IA64_PSR *ipsr = (IA64_PSR *)®s->cr_ipsr; - - if (ipsr->ri == 2) { - ipsr->ri = 0; - regs->cr_iip += 16; - } else { - ipsr->ri++; - } - - ipsr->val &= - (~ (IA64_PSR_ID |IA64_PSR_DA | IA64_PSR_DD | - IA64_PSR_SS | IA64_PSR_ED | IA64_PSR_IA - )); - - return (IA64_NO_FAULT); -} - - -IA64FAULT vmx_vcpu_decrement_iip(VCPU *vcpu) -{ - REGS *regs = vcpu_regs(vcpu); - IA64_PSR *ipsr = (IA64_PSR *)®s->cr_ipsr; - - if (ipsr->ri == 0) { - ipsr->ri = 2; - regs->cr_iip -= 16; - } else { - ipsr->ri--; - } - return (IA64_NO_FAULT); -} - - IA64FAULT vmx_vcpu_cover(VCPU *vcpu) { REGS *regs = vcpu_regs(vcpu); @@ -199,15 +157,12 @@ IA64FAULT vmx_vcpu_cover(VCPU *vcpu) return (IA64_NO_FAULT); } - struct virtual_platform_def * vmx_vcpu_get_plat(VCPU *vcpu) { return &(vcpu->domain->arch.vmx_platform); } - - IA64FAULT vmx_vcpu_set_rr(VCPU *vcpu, u64 reg, u64 val) { ia64_rr oldrr,newrr; diff --git a/xen/arch/ia64/vmx/vmx_virt.c b/xen/arch/ia64/vmx/vmx_virt.c index 54c2e67b25..9926c6ed8f 100644 --- a/xen/arch/ia64/vmx/vmx_virt.c +++ b/xen/arch/ia64/vmx/vmx_virt.c @@ -1568,7 +1568,7 @@ if ( (cause == 0xff && opcode == 0x1e000000000) || cause == 0 ) { #endif if ( status == IA64_NO_FAULT && cause !=EVENT_RFI ) { - vmx_vcpu_increment_iip(vcpu); + vcpu_increment_iip(vcpu); } recover_if_physical_mode(vcpu); diff --git a/xen/arch/ia64/xen/vcpu.c b/xen/arch/ia64/xen/vcpu.c index 10a8227ef7..0eceeb38ae 100644 --- a/xen/arch/ia64/xen/vcpu.c +++ b/xen/arch/ia64/xen/vcpu.c @@ -695,6 +695,20 @@ IA64FAULT vcpu_increment_iip(VCPU * vcpu) return IA64_NO_FAULT; } +IA64FAULT vcpu_decrement_iip(VCPU * vcpu) +{ + REGS *regs = vcpu_regs(vcpu); + struct ia64_psr *ipsr = (struct ia64_psr *)®s->cr_ipsr; + + if (ipsr->ri == 0) { + ipsr->ri = 2; + regs->cr_iip -= 16; + } else + ipsr->ri--; + + return IA64_NO_FAULT; +} + IA64FAULT vcpu_set_ifa(VCPU * vcpu, u64 val) { PSCB(vcpu, ifa) = val; diff --git a/xen/include/asm-ia64/vcpu.h b/xen/include/asm-ia64/vcpu.h index e403213d65..248d25dc20 100644 --- a/xen/include/asm-ia64/vcpu.h +++ b/xen/include/asm-ia64/vcpu.h @@ -77,6 +77,7 @@ extern IA64FAULT vcpu_get_ipsr(VCPU * vcpu, u64 * pval); extern IA64FAULT vcpu_get_isr(VCPU * vcpu, u64 * pval); extern IA64FAULT vcpu_get_iip(VCPU * vcpu, u64 * pval); extern IA64FAULT vcpu_increment_iip(VCPU * vcpu); +extern IA64FAULT vcpu_decrement_iip(VCPU * vcpu); extern IA64FAULT vcpu_get_ifa(VCPU * vcpu, u64 * pval); extern IA64FAULT vcpu_get_itir(VCPU * vcpu, u64 * pval); extern unsigned long vcpu_get_itir_on_fault(VCPU * vcpu, u64 ifa); diff --git a/xen/include/asm-ia64/vmx_vcpu.h b/xen/include/asm-ia64/vmx_vcpu.h index 0defc0d4f4..24b3b60578 100644 --- a/xen/include/asm-ia64/vmx_vcpu.h +++ b/xen/include/asm-ia64/vmx_vcpu.h @@ -115,8 +115,6 @@ extern void memwrite_v(VCPU * vcpu, thash_data_t * vtlb, u64 * src, u64 * dest, size_t s); extern void memwrite_p(VCPU * vcpu, u64 * src, u64 * dest, size_t s); extern void vcpu_load_kernel_regs(VCPU * vcpu); -extern IA64FAULT vmx_vcpu_increment_iip(VCPU * vcpu); -extern IA64FAULT vmx_vcpu_decrement_iip(VCPU * vcpu); extern void vmx_switch_rr7(unsigned long, shared_info_t *, void *, void *, void *); From 68fa1896bbe955997bf3e9eaafb357b7e6a46830 Mon Sep 17 00:00:00 2001 From: "awilliam@xenbuild2.aw" Date: Thu, 11 Jan 2007 16:56:58 -0700 Subject: [PATCH 169/570] [IA64] Hypercall optimizations provide hypercall the same path with system most of scrach registers don't need to be saved/restored it is good for performance Signed-off-by: Anthony Xu --- .../arch/ia64/xen/hypercall.S | 7 + .../arch/ia64/xen/hypervisor.c | 2 + .../include/asm-ia64/hypercall.h | 108 ++--- xen/arch/ia64/asm-offsets.c | 1 + xen/arch/ia64/linux-xen/entry.S | 111 ++++- xen/arch/ia64/xen/faults.c | 19 +- xen/arch/ia64/xen/hypercall.c | 170 +++----- xen/arch/ia64/xen/ivt.S | 404 ++++++++++++++---- xen/include/asm-ia64/config.h | 6 +- xen/include/asm-ia64/hypercall.h | 2 + xen/include/public/arch-ia64.h | 2 +- 11 files changed, 525 insertions(+), 307 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S index fd266d0d17..07399d30c8 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypercall.S @@ -306,4 +306,11 @@ GLOBAL_ENTRY(xen_ssm_i_1) brl.cond.sptk .vdso_ssm_i_1_ret ;; END(xen_ssm_i_1) + +GLOBAL_ENTRY(__hypercall) + mov r2=r37 + break 0x1000 + br.ret.sptk.many b0 + ;; +END(__hypercall) #endif diff --git a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c index d0bc3f92ec..f65cf94ee1 100644 --- a/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c +++ b/linux-2.6-xen-sparse/arch/ia64/xen/hypervisor.c @@ -49,6 +49,8 @@ static int p2m_expose_init(void); #define p2m_expose_init() (-ENOSYS) #endif +EXPORT_SYMBOL(__hypercall); + //XXX same as i386, x86_64 contiguous_bitmap_set(), contiguous_bitmap_clear() // move those to lib/contiguous_bitmap? //XXX discontigmem/sparsemem diff --git a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h index 19be0e6ed3..9ae66fe781 100644 --- a/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h +++ b/linux-2.6-xen-sparse/include/asm-ia64/hypercall.h @@ -39,6 +39,9 @@ #include struct xencomm_handle; +extern unsigned long __hypercall(unsigned long a1, unsigned long a2, + unsigned long a3, unsigned long a4, + unsigned long a5, unsigned long cmd); /* * Assembler stubs for hyper-calls. @@ -47,115 +50,58 @@ struct xencomm_handle; #define _hypercall0(type, name) \ ({ \ long __res; \ - __asm__ __volatile__ (";;\n" \ - "mov r2=%1\n" \ - "break 0x1000 ;;\n" \ - "mov %0=r8 ;;\n" \ - : "=r" (__res) \ - : "J" (__HYPERVISOR_##name) \ - : "r2","r8", \ - "memory" ); \ + __res=__hypercall(0, 0, 0, 0, 0, __HYPERVISOR_##name); \ (type)__res; \ }) #define _hypercall1(type, name, a1) \ ({ \ long __res; \ - __asm__ __volatile__ (";;\n" \ - "mov r14=%2\n" \ - "mov r2=%1\n" \ - "break 0x1000 ;;\n" \ - "mov %0=r8 ;;\n" \ - : "=r" (__res) \ - : "J" (__HYPERVISOR_##name), \ - "rI" ((unsigned long)(a1)) \ - : "r14","r2","r8", \ - "memory" ); \ + __res = __hypercall((unsigned long)a1, \ + 0, 0, 0, 0, __HYPERVISOR_##name); \ (type)__res; \ }) #define _hypercall2(type, name, a1, a2) \ ({ \ long __res; \ - __asm__ __volatile__ (";;\n" \ - "mov r14=%2\n" \ - "mov r15=%3\n" \ - "mov r2=%1\n" \ - "break 0x1000 ;;\n" \ - "mov %0=r8 ;;\n" \ - : "=r" (__res) \ - : "J" (__HYPERVISOR_##name), \ - "rI" ((unsigned long)(a1)), \ - "rI" ((unsigned long)(a2)) \ - : "r14","r15","r2","r8", \ - "memory" ); \ + __res = __hypercall((unsigned long)a1, \ + (unsigned long)a2, \ + 0, 0, 0, __HYPERVISOR_##name); \ (type)__res; \ }) #define _hypercall3(type, name, a1, a2, a3) \ ({ \ long __res; \ - __asm__ __volatile__ (";;\n" \ - "mov r14=%2\n" \ - "mov r15=%3\n" \ - "mov r16=%4\n" \ - "mov r2=%1\n" \ - "break 0x1000 ;;\n" \ - "mov %0=r8 ;;\n" \ - : "=r" (__res) \ - : "J" (__HYPERVISOR_##name), \ - "rI" ((unsigned long)(a1)), \ - "rI" ((unsigned long)(a2)), \ - "rI" ((unsigned long)(a3)) \ - : "r14","r15","r16","r2","r8", \ - "memory" ); \ - (type)__res; \ + __res = __hypercall((unsigned long)a1, \ + (unsigned long)a2, \ + (unsigned long)a3, \ + 0, 0, __HYPERVISOR_##name); \ + (type)__res; \ }) #define _hypercall4(type, name, a1, a2, a3, a4) \ ({ \ long __res; \ - __asm__ __volatile__ (";;\n" \ - "mov r14=%2\n" \ - "mov r15=%3\n" \ - "mov r16=%4\n" \ - "mov r17=%5\n" \ - "mov r2=%1\n" \ - "break 0x1000 ;;\n" \ - "mov %0=r8 ;;\n" \ - : "=r" (__res) \ - : "J" (__HYPERVISOR_##name), \ - "rI" ((unsigned long)(a1)), \ - "rI" ((unsigned long)(a2)), \ - "rI" ((unsigned long)(a3)), \ - "rI" ((unsigned long)(a4)) \ - : "r14","r15","r16","r2","r8", \ - "r17","memory" ); \ - (type)__res; \ + __res = __hypercall((unsigned long)a1, \ + (unsigned long)a2, \ + (unsigned long)a3, \ + (unsigned long)a4, \ + 0, __HYPERVISOR_##name); \ + (type)__res; \ }) #define _hypercall5(type, name, a1, a2, a3, a4, a5) \ ({ \ long __res; \ - __asm__ __volatile__ (";;\n" \ - "mov r14=%2\n" \ - "mov r15=%3\n" \ - "mov r16=%4\n" \ - "mov r17=%5\n" \ - "mov r18=%6\n" \ - "mov r2=%1\n" \ - "break 0x1000 ;;\n" \ - "mov %0=r8 ;;\n" \ - : "=r" (__res) \ - : "J" (__HYPERVISOR_##name), \ - "rI" ((unsigned long)(a1)), \ - "rI" ((unsigned long)(a2)), \ - "rI" ((unsigned long)(a3)), \ - "rI" ((unsigned long)(a4)), \ - "rI" ((unsigned long)(a5)) \ - : "r14","r15","r16","r2","r8", \ - "r17","r18","memory" ); \ - (type)__res; \ + __res = __hypercall((unsigned long)a1, \ + (unsigned long)a2, \ + (unsigned long)a3, \ + (unsigned long)a4, \ + (unsigned long)a5, \ + __HYPERVISOR_##name); \ + (type)__res; \ }) diff --git a/xen/arch/ia64/asm-offsets.c b/xen/arch/ia64/asm-offsets.c index efd68306d0..571f396e96 100644 --- a/xen/arch/ia64/asm-offsets.c +++ b/xen/arch/ia64/asm-offsets.c @@ -56,6 +56,7 @@ void foo(void) DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct vcpu, arch._thread.on_ustack)); DEFINE(IA64_VCPU_DOMAIN_OFFSET, offsetof (struct vcpu, domain)); + DEFINE(IA64_VCPU_HYPERCALL_CONTINUATION_OFS, offsetof (struct vcpu, arch.hypercall_continuation)); DEFINE(IA64_VCPU_META_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_rr0)); DEFINE(IA64_VCPU_META_SAVED_RR0_OFFSET, offsetof (struct vcpu, arch.metaphysical_saved_rr0)); DEFINE(IA64_VCPU_BREAKIMM_OFFSET, offsetof (struct vcpu, arch.breakimm)); diff --git a/xen/arch/ia64/linux-xen/entry.S b/xen/arch/ia64/linux-xen/entry.S index 2c73fc5d2b..cb0e89cdd9 100644 --- a/xen/arch/ia64/linux-xen/entry.S +++ b/xen/arch/ia64/linux-xen/entry.S @@ -676,7 +676,9 @@ GLOBAL_ENTRY(ia64_ret_from_syscall) cmp.ge p6,p7=r8,r0 // syscall executed successfully? adds r2=PT(R8)+16,sp // r2 = &pt_regs.r8 mov r10=r0 // clear error indication in r10 +#ifndef XEN (p7) br.cond.spnt handle_syscall_error // handle potential syscall failure +#endif END(ia64_ret_from_syscall) // fall through /* @@ -764,7 +766,9 @@ ENTRY(ia64_leave_syscall) ld8 r19=[r2],PT(B6)-PT(LOADRS) // load ar.rsc value for "loadrs" nop.i 0 ;; +#ifndef XEN mov r16=ar.bsp // M2 get existing backing store pointer +#endif ld8 r18=[r2],PT(R9)-PT(B6) // load b6 #ifndef XEN (p6) and r15=TIF_WORK_MASK,r31 // any work other than TIF_SYSCALL_TRACE? @@ -814,7 +818,11 @@ ENTRY(ia64_leave_syscall) mov f8=f0 // F clear f8 ;; ld8.fill r12=[r2] // M0|1 restore r12 (sp) +#ifdef XEN + ld8.fill r2=[r3] // M0|1 +#else ld8.fill r15=[r3] // M0|1 restore r15 +#endif mov b6=r18 // I0 restore b6 #ifdef XEN @@ -827,7 +835,9 @@ ENTRY(ia64_leave_syscall) srlz.d // M0 ensure interruption collection is off (for cover) shr.u r18=r19,16 // I0|1 get byte size of existing "dirty" partition +#ifndef XEN cover // B add current frame into dirty partition & set cr.ifs +#endif ;; (pUStk) ld4 r17=[r17] // M0|1 r17 = cpu_data->phys_stacked_size_p8 mov r19=ar.bsp // M2 get new backing store pointer @@ -893,24 +903,19 @@ GLOBAL_ENTRY(ia64_leave_kernel) .work_processed_kernel: #ifdef XEN ;; -(pUStk) ssm psr.i -(pUStk) br.call.sptk.many b0=do_softirq -(pUStk) rsm psr.i - ;; - alloc loc0=ar.pfs,0,1,1,0 - adds out0=16,r12 +(pUStk) ssm psr.i +(pUStk) br.call.sptk.many b0=do_softirq +(pUStk) ssm psr.i + ;; +(pUStk) br.call.sptk.many b0=reflect_event + ;; adds r7 = PT(EML_UNAT)+16,r12 ;; ld8 r7 = [r7] ;; -(pUStk) br.call.sptk.many b0=reflect_event -//(pUStk) br.call.sptk.many b0=deliver_pending_interrupt - ;; - mov ar.pfs=loc0 mov ar.unat=r7 /* load eml_unat */ mov r31=r0 - #else adds r17=TI_FLAGS+IA64_TASK_SIZE,r13 ;; @@ -1184,8 +1189,11 @@ skip_rbs_switch: mov cr.ipsr=r29 // M2 mov ar.pfs=r26 // I0 (pLvSys)mov r17=r0 // A clear r17 for leave_syscall, no-op otherwise - +#ifdef XEN + mov cr.ifs=r30 // M2 +#else (p9) mov cr.ifs=r30 // M2 +#endif mov b0=r21 // I0 (pLvSys)mov r18=r0 // A clear r18 for leave_syscall, no-op otherwise @@ -1195,7 +1203,11 @@ skip_rbs_switch: ;; (pUStk) mov ar.rnat=r24 // M2 must happen with RSE in lazy mode nop 0 +#ifdef XEN +(pLvSys)mov r15=r0 +#else (pLvSys)mov r2=r0 +#endif mov ar.rsc=r27 // M2 mov pr=r31,-1 // I0 @@ -1459,7 +1471,80 @@ GLOBAL_ENTRY(unw_init_running) br.ret.sptk.many rp END(unw_init_running) -#ifndef XEN +#ifdef XEN + .rodata + .align 8 + .globl ia64_hypercall_table +ia64_hypercall_table: + data8 do_ni_hypercall /* do_set_trap_table *//* 0 */ + data8 do_ni_hypercall /* do_mmu_update */ + data8 do_ni_hypercall /* do_set_gdt */ + data8 do_ni_hypercall /* do_stack_switch */ + data8 do_ni_hypercall /* do_set_callbacks */ + data8 do_ni_hypercall /* do_fpu_taskswitch *//* 5 */ + data8 do_sched_op_compat + data8 do_ni_hypercall + data8 do_ni_hypercall /* do_set_debugreg */ + data8 do_ni_hypercall /* do_get_debugreg */ + data8 do_ni_hypercall /* do_update_descriptor * 10 */ + data8 do_ni_hypercall /* do_ni_hypercall */ + data8 do_memory_op + data8 do_multicall + data8 do_ni_hypercall /* do_update_va_mapping */ + data8 do_ni_hypercall /* do_set_timer_op */ /* 15 */ + data8 do_ni_hypercall + data8 do_xen_version + data8 do_console_io + data8 do_ni_hypercall + data8 do_grant_table_op /* 20 */ + data8 do_ni_hypercall /* do_vm_assist */ + data8 do_ni_hypercall /* do_update_va_mapping_othe */ + data8 do_ni_hypercall /* (x86 only) */ + data8 do_ni_hypercall /* do_vcpu_op */ + data8 do_ni_hypercall /* (x86_64 only) */ /* 25 */ + data8 do_ni_hypercall /* do_mmuext_op */ + data8 do_ni_hypercall /* do_acm_op */ + data8 do_ni_hypercall /* do_nmi_op */ + data8 do_sched_op + data8 do_callback_op /* */ /* 30 */ + data8 do_xenoprof_op /* */ + data8 do_event_channel_op + data8 do_physdev_op + data8 do_hvm_op /* */ + data8 do_sysctl /* */ /* 35 */ + data8 do_domctl /* */ + data8 do_ni_hypercall /* */ + data8 do_ni_hypercall /* */ + data8 do_ni_hypercall /* */ + data8 do_ni_hypercall /* */ /* 40 */ + data8 do_ni_hypercall /* */ + data8 do_ni_hypercall /* */ + data8 do_ni_hypercall /* */ + data8 do_ni_hypercall /* */ + data8 do_ni_hypercall /* */ /* 45 */ + data8 do_ni_hypercall /* */ + data8 do_ni_hypercall /* */ + data8 do_dom0vp_op /* dom0vp_op */ + data8 do_pirq_guest_eoi /* arch_1 */ + data8 do_ni_hypercall /* arch_2 */ /* 50 */ + data8 do_ni_hypercall /* arch_3 */ + data8 do_ni_hypercall /* arch_4 */ + data8 do_ni_hypercall /* arch_5 */ + data8 do_ni_hypercall /* arch_6 */ + data8 do_ni_hypercall /* arch_7 */ /* 55 */ + data8 do_ni_hypercall + data8 do_ni_hypercall + data8 do_ni_hypercall + data8 do_ni_hypercall + data8 do_ni_hypercall /* 60 */ + data8 do_ni_hypercall + data8 do_ni_hypercall + data8 do_ni_hypercall + + // guard against failures to increase NR_hypercalls + .org ia64_hypercall_table + 8*NR_hypercalls + +#else .rodata .align 8 .globl sys_call_table diff --git a/xen/arch/ia64/xen/faults.c b/xen/arch/ia64/xen/faults.c index 454bdd69a6..7cf641b6fe 100644 --- a/xen/arch/ia64/xen/faults.c +++ b/xen/arch/ia64/xen/faults.c @@ -83,8 +83,8 @@ void reflect_interruption(unsigned long isr, struct pt_regs *regs, check_bad_nested_interruption(isr, regs, vector); PSCB(v, unat) = regs->ar_unat; // not sure if this is really needed? PSCB(v, precover_ifs) = regs->cr_ifs; - vcpu_bsw0(v); PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr); + vcpu_bsw0(v); PSCB(v, isr) = isr; PSCB(v, iip) = regs->cr_iip; PSCB(v, ifs) = 0; @@ -120,33 +120,38 @@ void reflect_extint(struct pt_regs *regs) reflect_interruption(isr, regs, IA64_EXTINT_VECTOR); } -void reflect_event(struct pt_regs *regs) +void reflect_event(void) { - unsigned long isr = regs->cr_ipsr & IA64_PSR_RI; struct vcpu *v = current; + struct pt_regs *regs; + unsigned long isr; + + if (!event_pending(v)) + return; /* Sanity check */ - if (is_idle_vcpu(v) || !user_mode(regs)) { + if (is_idle_vcpu(v)) { //printk("WARN: invocation to reflect_event in nested xen\n"); return; } - if (!event_pending(v)) - return; + regs = vcpu_regs(v); // can't inject event, when XEN is emulating rfi // and both PSCB(v, ifs) and regs->ifs are valid if (regs->cr_iip == *(unsigned long *)dorfirfi) return; + isr = regs->cr_ipsr & IA64_PSR_RI; + if (!PSCB(v, interrupt_collection_enabled)) printk("psr.ic off, delivering event, ipsr=%lx,iip=%lx," "isr=%lx,viip=0x%lx\n", regs->cr_ipsr, regs->cr_iip, isr, PSCB(v, iip)); PSCB(v, unat) = regs->ar_unat; // not sure if this is really needed? PSCB(v, precover_ifs) = regs->cr_ifs; - vcpu_bsw0(v); PSCB(v, ipsr) = vcpu_get_ipsr_int_state(v, regs->cr_ipsr); + vcpu_bsw0(v); PSCB(v, isr) = isr; PSCB(v, iip) = regs->cr_iip; PSCB(v, ifs) = 0; diff --git a/xen/arch/ia64/xen/hypercall.c b/xen/arch/ia64/xen/hypercall.c index 69be18efcd..0a0890c28f 100644 --- a/xen/arch/ia64/xen/hypercall.c +++ b/xen/arch/ia64/xen/hypercall.c @@ -17,6 +17,7 @@ #include /* FOR struct ia64_sal_retval */ #include /* FOR struct fpswa_ret_t */ +#include #include #include #include @@ -32,94 +33,14 @@ #include #include -static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg); -static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg); - -const hypercall_t ia64_hypercall_table[NR_hypercalls] = -{ - (hypercall_t)do_ni_hypercall, /* do_set_trap_table *//* 0 */ - (hypercall_t)do_ni_hypercall, /* do_mmu_update */ - (hypercall_t)do_ni_hypercall, /* do_set_gdt */ - (hypercall_t)do_ni_hypercall, /* do_stack_switch */ - (hypercall_t)do_ni_hypercall, /* do_set_callbacks */ - (hypercall_t)do_ni_hypercall, /* do_fpu_taskswitch *//* 5 */ - (hypercall_t)do_sched_op_compat, - (hypercall_t)do_ni_hypercall, - (hypercall_t)do_ni_hypercall, /* do_set_debugreg */ - (hypercall_t)do_ni_hypercall, /* do_get_debugreg */ - (hypercall_t)do_ni_hypercall, /* do_update_descriptor * 10 */ - (hypercall_t)do_ni_hypercall, /* do_ni_hypercall */ - (hypercall_t)do_memory_op, - (hypercall_t)do_multicall, - (hypercall_t)do_ni_hypercall, /* do_update_va_mapping */ - (hypercall_t)do_ni_hypercall, /* do_set_timer_op */ /* 15 */ - (hypercall_t)do_ni_hypercall, - (hypercall_t)do_xen_version, - (hypercall_t)do_console_io, - (hypercall_t)do_ni_hypercall, - (hypercall_t)do_grant_table_op, /* 20 */ - (hypercall_t)do_ni_hypercall, /* do_vm_assist */ - (hypercall_t)do_ni_hypercall, /* do_update_va_mapping_othe */ - (hypercall_t)do_ni_hypercall, /* (x86 only) */ - (hypercall_t)do_ni_hypercall, /* do_vcpu_op */ - (hypercall_t)do_ni_hypercall, /* (x86_64 only) */ /* 25 */ - (hypercall_t)do_ni_hypercall, /* do_mmuext_op */ - (hypercall_t)do_ni_hypercall, /* do_acm_op */ - (hypercall_t)do_ni_hypercall, /* do_nmi_op */ - (hypercall_t)do_sched_op, - (hypercall_t)do_callback_op, /* */ /* 30 */ - (hypercall_t)do_xenoprof_op, /* */ - (hypercall_t)do_event_channel_op, - (hypercall_t)do_physdev_op, - (hypercall_t)do_hvm_op, /* */ - (hypercall_t)do_sysctl, /* */ /* 35 */ - (hypercall_t)do_domctl, /* */ - (hypercall_t)do_ni_hypercall, /* */ - (hypercall_t)do_ni_hypercall, /* */ - (hypercall_t)do_ni_hypercall, /* */ - (hypercall_t)do_ni_hypercall, /* */ /* 40 */ - (hypercall_t)do_ni_hypercall, /* */ - (hypercall_t)do_ni_hypercall, /* */ - (hypercall_t)do_ni_hypercall, /* */ - (hypercall_t)do_ni_hypercall, /* */ - (hypercall_t)do_ni_hypercall, /* */ /* 45 */ - (hypercall_t)do_ni_hypercall, /* */ - (hypercall_t)do_ni_hypercall, /* */ - (hypercall_t)do_dom0vp_op, /* dom0vp_op */ - (hypercall_t)do_ni_hypercall, /* arch_1 */ - (hypercall_t)do_ni_hypercall, /* arch_2 */ /* 50 */ - (hypercall_t)do_ni_hypercall, /* arch_3 */ - (hypercall_t)do_ni_hypercall, /* arch_4 */ - (hypercall_t)do_ni_hypercall, /* arch_5 */ - (hypercall_t)do_ni_hypercall, /* arch_6 */ - (hypercall_t)do_ni_hypercall, /* arch_7 */ /* 55 */ - (hypercall_t)do_ni_hypercall, - (hypercall_t)do_ni_hypercall, - (hypercall_t)do_ni_hypercall, - (hypercall_t)do_ni_hypercall, - (hypercall_t)do_ni_hypercall, /* 60 */ - (hypercall_t)do_ni_hypercall, - (hypercall_t)do_ni_hypercall, - (hypercall_t)do_ni_hypercall -}; +extern long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg); +extern long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg); static IA64FAULT xen_hypercall (struct pt_regs *regs) { uint32_t cmd = (uint32_t)regs->r2; - - if (cmd < NR_hypercalls) { - perfc_incra(hypercalls, cmd); - regs->r8 = (*ia64_hypercall_table[cmd])( - regs->r14, - regs->r15, - regs->r16, - regs->r17, - regs->r18, - regs->r19); - } else - regs->r8 = -ENOSYS; - + printk("Warning %s should not be called %d\n", __FUNCTION__, cmd); return IA64_NO_FAULT; } @@ -129,7 +50,8 @@ xen_fast_hypercall (struct pt_regs *regs) uint32_t cmd = (uint32_t)regs->r2; switch (cmd) { case __HYPERVISOR_ia64_fast_eoi: - regs->r8 = pirq_guest_eoi(current->domain, regs->r14); + printk("Warning %s should not be called %d\n", + __FUNCTION__, cmd); break; default: regs->r8 = -ENOSYS; @@ -137,6 +59,12 @@ xen_fast_hypercall (struct pt_regs *regs) return IA64_NO_FAULT; } +long do_pirq_guest_eoi(int pirq) +{ + return pirq_guest_eoi(current->domain, pirq); +} + + static void fw_hypercall_ipi (struct pt_regs *regs) { @@ -320,42 +248,42 @@ unsigned long hypercall_create_continuation( va_list args; va_start(args, format); - if ( test_bit(_MCSF_in_multicall, &mcs->flags) ) { - panic("PREEMPT happen in multicall\n"); // Not support yet - } else { - vcpu_set_gr(v, 2, op, 0); - for ( i = 0; *p != '\0'; i++) { - switch ( *p++ ) - { - case 'i': - arg = (unsigned long)va_arg(args, unsigned int); - break; - case 'l': - arg = (unsigned long)va_arg(args, unsigned long); - break; - case 'h': - arg = (unsigned long)va_arg(args, void *); - break; - default: - arg = 0; - BUG(); - } - switch (i) { - case 0: vcpu_set_gr(v, 14, arg, 0); - break; - case 1: vcpu_set_gr(v, 15, arg, 0); - break; - case 2: vcpu_set_gr(v, 16, arg, 0); - break; - case 3: vcpu_set_gr(v, 17, arg, 0); - break; - case 4: vcpu_set_gr(v, 18, arg, 0); - break; - default: panic("Too many args for hypercall continuation\n"); - break; - } - } + if (test_bit(_MCSF_in_multicall, &mcs->flags)) + panic("PREEMPT happen in multicall\n"); // Not support yet + + vcpu_set_gr(v, 15, op, 0); + + for (i = 0; *p != '\0'; i++) { + switch ( *p++ ) + { + case 'i': + arg = (unsigned long)va_arg(args, unsigned int); + break; + case 'l': + arg = (unsigned long)va_arg(args, unsigned long); + break; + case 'h': + arg = (unsigned long)va_arg(args, void *); + break; + default: + arg = 0; + BUG(); + } + vcpu_set_gr(v, 16 + i, arg, 0); } + + if (i >= 6) + panic("Too many args for hypercall continuation\n"); + + // Clean other argument to 0 + while (i < 6) { + vcpu_set_gr(v, 16 + i, 0, 0); + i++; + } + + // re-execute break; + vcpu_decrement_iip(v); + v->arch.hypercall_continuation = 1; va_end(args); return op; @@ -369,7 +297,7 @@ extern int iosapic_guest_write( unsigned long physbase, unsigned int reg, u32 pval); -static long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) +long do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg) { int irq; long ret; @@ -524,7 +452,7 @@ static long unregister_guest_callback(struct callback_unregister *unreg) /* First time to add callback to xen/ia64, so let's just stick to * the newer callback interface. */ -static long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg) +long do_callback_op(int cmd, XEN_GUEST_HANDLE(void) arg) { long ret; diff --git a/xen/arch/ia64/xen/ivt.S b/xen/arch/ia64/xen/ivt.S index 5ceda96599..cd9ba5d83d 100644 --- a/xen/arch/ia64/xen/ivt.S +++ b/xen/arch/ia64/xen/ivt.S @@ -2,6 +2,7 @@ #include #include #include +#include #endif /* * arch/ia64/kernel/ivt.S @@ -1055,7 +1056,6 @@ ENTRY(break_fault) * level. */ DBG_FAULT(11) -#ifdef XEN mov r16=cr.isr mov r17=cr.iim mov r31=pr @@ -1101,103 +1101,202 @@ ENTRY(break_fault) ;; ld8 r22 = [r22] ;; - adds r22=IA64_VCPU_BREAKIMM_OFFSET,r22 + adds r23=IA64_VCPU_BREAKIMM_OFFSET,r22 ;; - ld4 r23=[r22];; + ld4 r23=[r23];; cmp4.eq p6,p7=r23,r17 // Xen-reserved breakimm? -(p6) br.spnt.many dispatch_break_fault +(p6) br.spnt.many fast_hypercall ;; br.sptk.many fast_break_reflect ;; -#else /* !XEN */ - movl r16=THIS_CPU(cpu_kr)+IA64_KR_CURRENT_OFFSET;; - ld8 r16=[r16] - mov r17=cr.iim - mov r18=__IA64_BREAK_SYSCALL - mov r21=ar.fpsr - mov r29=cr.ipsr - mov r19=b6 - mov r25=ar.unat - mov r27=ar.rsc - mov r26=ar.pfs - mov r28=cr.iip -#ifndef XEN - mov r31=pr // prepare to save predicates -#endif - mov r20=r1 + + +fast_hypercall: + shr r25=r2,8;; + cmp.ne p7,p0=r0,r25 +(p7) br.spnt.few dispatch_break_fault ;; + // fall through + + + /* + * The streamlined system call entry/exit paths only save/restore the initial part + * of pt_regs. This implies that the callers of system-calls must adhere to the + * normal procedure calling conventions. + * + * Registers to be saved & restored: + * CR registers: cr.ipsr, cr.iip, cr.ifs + * AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr + * others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15 + * Registers to be restored only: + * r8-r11: output value from the system call. + * + * During system call exit, scratch registers (including r15) are modified/cleared + * to prevent leaking bits from kernel to user level. + */ + +// DBG_FAULT(11) +// mov.m r16=IA64_KR(CURRENT) // M2 r16 <- current task (12 cyc) + mov r16=r22 + mov r29=cr.ipsr // M2 (12 cyc) +// mov r31=pr // I0 (2 cyc) + mov r15=r2 + +// mov r17=cr.iim // M2 (2 cyc) + mov.m r27=ar.rsc // M2 (12 cyc) +// mov r18=__IA64_BREAK_SYSCALL // A + + mov.m ar.rsc=0 // M2 + mov.m r21=ar.fpsr // M2 (12 cyc) + mov r19=b6 // I0 (2 cyc) + ;; + mov.m r23=ar.bspstore // M2 (12 cyc) + mov.m r24=ar.rnat // M2 (5 cyc) + mov.i r26=ar.pfs // I0 (2 cyc) + + invala // M0|1 + nop.m 0 // M + mov r20=r1 // A save r1 + + nop.m 0 +// movl r30=sys_call_table // X + movl r30=ia64_hypercall_table // X + + mov r28=cr.iip // M2 (2 cyc) +// cmp.eq p0,p7=r18,r17 // I0 is this a system call? +//(p7) br.cond.spnt non_syscall // B no -> + // + // From this point on, we are definitely on the syscall-path + // and we can use (non-banked) scratch registers. + // +/////////////////////////////////////////////////////////////////////// + mov r1=r16 // A move task-pointer to "addl"-addressable reg + mov r2=r16 // A setup r2 for ia64_syscall_setup +// add r9=TI_FLAGS+IA64_TASK_SIZE,r16 // A r9 = ¤t_thread_info()->flags + adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 - cmp.eq p0,p7=r18,r17 // is this a system call? - // (p7 <- false, if so) -(p7) br.cond.spnt non_syscall +// adds r15=-1024,r15 // A subtract 1024 from syscall number +// mov r3=NR_syscalls - 1 + mov r3=NR_hypercalls - 1 ;; - ld1 r17=[r16] // load current->thread.on_ustack flag - st1 [r16]=r0 // clear current->thread.on_ustack flag - add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16 - // set r1 for - // MINSTATE_START_SAVE_MIN_VIRT - ;; - invala + ld1.bias r17=[r16] // M0|1 r17 = current->thread.on_ustack flag +// ld4 r9=[r9] // M0|1 r9 = current_thread_info()->flags + mov r9=r0 // force flags = 0 + extr.u r8=r29,41,2 // I0 extract ei field from cr.ipsr - /* adjust return address so we skip over the break instruction: */ - - extr.u r8=r29,41,2 // extract ei field from cr.ipsr - ;; - cmp.eq p6,p7=2,r8 // isr.ei==2? - mov r2=r1 // setup r2 for ia64_syscall_setup - ;; -(p6) mov r8=0 // clear ei to 0 -(p6) adds r28=16,r28 // switch cr.iip to next bundle - // cr.ipsr.ei wrapped -(p7) adds r8=1,r8 // increment ei to next slot - ;; - cmp.eq pKStk,pUStk=r0,r17 // are we in kernel mode already? - dep r29=r8,r29,41,2 // insert new ei into cr.ipsr + shladd r30=r15,3,r30 // A r30 = sys_call_table + 8*(syscall-1024) + addl r22=IA64_RBS_OFFSET,r1 // A compute base of RBS + cmp.leu p6,p7=r15,r3 // A syscall number in range? ;; - // switch from user to kernel RBS: - MINSTATE_START_SAVE_MIN_VIRT - br.call.sptk.many b7=ia64_syscall_setup - ;; - MINSTATE_END_SAVE_MIN_VIRT // switch to bank 1 - ssm psr.ic | PSR_DEFAULT_BITS - ;; - srlz.i // guarantee that interruption - // collection is on - mov r3=NR_syscalls - 1 - ;; -(p15) ssm psr.i // restore psr.i - // p10==true means out registers are more than 8 or r15's Nat is true -(p10) br.cond.spnt.many ia64_ret_from_syscall - ;; - movl r16=sys_call_table + lfetch.fault.excl.nt1 [r22] // M0|1 prefetch RBS +(p6) ld8 r30=[r30] // M0|1 load address of syscall entry point + tnat.nz.or p7,p0=r15 // I0 is syscall nr a NaT? - adds r15=-1024,r15 // r15 contains the syscall number -- - // subtract 1024 from it - movl r2=ia64_ret_from_syscall + mov.m ar.bspstore=r22 // M2 switch to kernel RBS + cmp.eq p8,p9=2,r8 // A isr.ei==2? ;; - shladd r20=r15,3,r16 // r20 = sys_call_table + - // 8*(syscall-1024) - cmp.leu p6,p7=r15,r3 // (syscall > 0 && syscall < 1024 + - // NR_syscalls) ? - mov rp=r2 // set the real return addr - ;; -(p6) ld8 r20=[r20] // load address of syscall entry point -(p7) movl r20=sys_ni_syscall - add r2=TI_FLAGS+IA64_TASK_SIZE,r13 +(p8) mov r8=0 // A clear ei to 0 +//(p7) movl r30=sys_ni_syscall // X +(p7) movl r30=do_ni_hypercall // X + +(p8) adds r28=16,r28 // A switch cr.iip to next bundle +(p9) adds r8=1,r8 // A increment ei to next slot + nop.i 0 ;; - ld4 r2=[r2] // r2 = current_thread_info()->flags + + mov.m r25=ar.unat // M2 (5 cyc) + dep r29=r8,r29,41,2 // I0 insert new ei into cr.ipsr +// adds r15=1024,r15 // A restore original syscall number + // + // If any of the above loads miss in L1D, we'll stall here until + // the data arrives. + // +/////////////////////////////////////////////////////////////////////// + st1 [r16]=r0 // M2|3 clear current->thread.on_ustack flag + mov b6=r30 // I0 setup syscall handler branch reg early + cmp.eq pKStk,pUStk=r0,r17 // A were we on kernel stacks already? + +// and r9=_TIF_SYSCALL_TRACEAUDIT,r9 // A mask trace or audit + mov r18=ar.bsp // M2 (12 cyc) ;; - and r2=_TIF_SYSCALL_TRACEAUDIT,r2 // mask trace or audit +(pUStk) addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1 // A compute base of memory stack +// cmp.eq p14,p0=r9,r0 // A are syscalls being traced/audited? + br.call.sptk.many b7=ia64_syscall_setup // B +1: + mov ar.rsc=0x3 // M2 set eager mode, pl 0, LE, loadrs=0 + nop 0 + bsw.1 // B (6 cyc) regs are saved, switch to bank 1 ;; - cmp.eq p8,p0=r2,r0 - mov b6=r20 + + ssm psr.ic | PSR_DEFAULT_BITS // M2 now it's safe to re-enable intr.-collection +// movl r3=ia64_ret_from_syscall // X + ;; + + srlz.i // M0 ensure interruption collection is on +// mov rp=r3 // I0 set the real return addr +//(p10) br.cond.spnt.many ia64_ret_from_syscall // B return if bad call-frame or r15 is a NaT +(p15) ssm psr.i // M2 restore psr.i +//(p14) br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) +// br.call.sptk.many b6=b6 // B invoke syscall-handker (ignore return addr) + br.call.sptk.many b0=b6 // B invoke syscall-handker (ignore return addr) +// br.cond.spnt.many ia64_trace_syscall // B do syscall-tracing thingamagic + ;; + adds r2=PT(R8)+16,r12 + ;; + st8 [r2]=r8 + ;; + br.call.sptk.many b0=do_softirq + ;; + //restore hypercall argument if continuation + adds r2=IA64_VCPU_HYPERCALL_CONTINUATION_OFS,r13 + ;; + ld1 r20=[r2] + ;; + st1 [r2]=r0 + ;; + cmp.ne p6,p0=r20,r0 + ;; +(p6) adds r2=PT(R16)+16,r12 +(p6) adds r3=PT(R17)+16,r12 + ;; +(p6) ld8 r32=[r2],16 +(p6) ld8 r33=[r3],16 + ;; +(p6) ld8 r34=[r2],16 +(p6) ld8 r35=[r3],16 + ;; +(p6) ld8 r36=[r2],16 + ;; +//save ar.bsp before cover + mov r16=ar.bsp + add r2=PT(R14)+16,r12 + ;; + st8 [r2]=r16 + ;; + rsm psr.i|psr.ic + ;; + srlz.i + ;; + cover + ;; + mov r20=cr.ifs + adds r2=PT(CR_IFS)+16,r12 + ;; + st8 [r2]=r20 + ;; + br.call.sptk.many b0=reflect_event + ;; + adds r2=PT(R14)+16,r12 + adds r3=PT(R8)+16,r12 + ;; + //r16 contains ar.bsp before cover + ld8 r16=[r2] + ld8 r8=[r3] + ;; + br.sptk.many ia64_ret_from_syscall ;; -(p8) br.call.sptk.many b6=b6 // ignore this return addr - br.cond.sptk ia64_trace_syscall - // NOT REACHED -#endif END(break_fault) .org ia64_ivt+0x3000 @@ -1297,7 +1396,150 @@ END(dispatch_break_fault) DBG_FAULT(14) FAULT(14) -#ifndef XEN +#ifdef XEN + // this code segment is from 2.6.16.13 + + /* + * There is no particular reason for this code to be here, other than that + * there happens to be space here that would go unused otherwise. If this + * fault ever gets "unreserved", simply moved the following code to a more + * suitable spot... + * + * ia64_syscall_setup() is a separate subroutine so that it can + * allocate stacked registers so it can safely demine any + * potential NaT values from the input registers. + * + * On entry: + * - executing on bank 0 or bank 1 register set (doesn't matter) + * - r1: stack pointer + * - r2: current task pointer + * - r3: preserved + * - r11: original contents (saved ar.pfs to be saved) + * - r12: original contents (sp to be saved) + * - r13: original contents (tp to be saved) + * - r15: original contents (syscall # to be saved) + * - r18: saved bsp (after switching to kernel stack) + * - r19: saved b6 + * - r20: saved r1 (gp) + * - r21: saved ar.fpsr + * - r22: kernel's register backing store base (krbs_base) + * - r23: saved ar.bspstore + * - r24: saved ar.rnat + * - r25: saved ar.unat + * - r26: saved ar.pfs + * - r27: saved ar.rsc + * - r28: saved cr.iip + * - r29: saved cr.ipsr + * - r31: saved pr + * - b0: original contents (to be saved) + * On exit: + * - p10: TRUE if syscall is invoked with more than 8 out + * registers or r15's Nat is true + * - r1: kernel's gp + * - r3: preserved (same as on entry) + * - r8: -EINVAL if p10 is true + * - r12: points to kernel stack + * - r13: points to current task + * - r14: preserved (same as on entry) + * - p13: preserved + * - p15: TRUE if interrupts need to be re-enabled + * - ar.fpsr: set to kernel settings + * - b6: preserved (same as on entry) + */ +GLOBAL_ENTRY(ia64_syscall_setup) +#if PT(B6) != 0 +# error This code assumes that b6 is the first field in pt_regs. +#endif + st8 [r1]=r19 // save b6 + add r16=PT(CR_IPSR),r1 // initialize first base pointer + add r17=PT(R11),r1 // initialize second base pointer + ;; + alloc r19=ar.pfs,8,0,0,0 // ensure in0-in7 are writable + st8 [r16]=r29,PT(AR_PFS)-PT(CR_IPSR) // save cr.ipsr + tnat.nz p8,p0=in0 + + st8.spill [r17]=r11,PT(CR_IIP)-PT(R11) // save r11 + tnat.nz p9,p0=in1 +(pKStk) mov r18=r0 // make sure r18 isn't NaT + ;; + + st8 [r16]=r26,PT(CR_IFS)-PT(AR_PFS) // save ar.pfs + st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP) // save cr.iip + mov r28=b0 // save b0 (2 cyc) + ;; + + st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT) // save ar.unat + dep r19=0,r19,38,26 // clear all bits but 0..37 [I0] +(p8) mov in0=-1 + ;; + + st8 [r16]=r19,PT(AR_RNAT)-PT(CR_IFS) // store ar.pfs.pfm in cr.ifs + extr.u r11=r19,7,7 // I0 // get sol of ar.pfs + and r8=0x7f,r19 // A // get sof of ar.pfs + + st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc + tbit.nz p15,p0=r29,IA64_PSR_I_BIT // I0 +(p9) mov in1=-1 + ;; + +(pUStk) sub r18=r18,r22 // r18=RSE.ndirty*8 + tnat.nz p10,p0=in2 + add r11=8,r11 + ;; +(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16 // skip over ar_rnat field +(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17 // skip over ar_bspstore field + tnat.nz p11,p0=in3 + ;; +(p10) mov in2=-1 + tnat.nz p12,p0=in4 // [I0] +(p11) mov in3=-1 + ;; +(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT) // save ar.rnat +(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE) // save ar.bspstore + shl r18=r18,16 // compute ar.rsc to be used for "loadrs" + ;; + st8 [r16]=r31,PT(LOADRS)-PT(PR) // save predicates + st8 [r17]=r28,PT(R1)-PT(B0) // save b0 + tnat.nz p13,p0=in5 // [I0] + ;; + st8 [r16]=r18,PT(R12)-PT(LOADRS) // save ar.rsc value for "loadrs" + st8.spill [r17]=r20,PT(R13)-PT(R1) // save original r1 +(p12) mov in4=-1 + ;; + +.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12) // save r12 +.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13) // save r13 +(p13) mov in5=-1 + ;; + st8 [r16]=r21,PT(R8)-PT(AR_FPSR) // save ar.fpsr + tnat.nz p13,p0=in6 + cmp.lt p10,p9=r11,r8 // frame size can't be more than local+8 + ;; + mov r8=1 +(p9) tnat.nz p10,p0=r15 + adds r12=-16,r1 // switch to kernel memory stack (with 16 bytes of scratch) + + st8.spill [r17]=r15 // save r15 + tnat.nz p8,p0=in7 + nop.i 0 + + mov r13=r2 // establish `current' + movl r1=__gp // establish kernel global pointer + ;; + st8 [r16]=r8 // ensure pt_regs.r8 != 0 (see handle_syscall_error) +(p13) mov in6=-1 +(p8) mov in7=-1 + + cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0 + movl r17=FPSR_DEFAULT + ;; + mov.m ar.fpsr=r17 // set ar.fpsr to kernel default value +(p10) mov r8=-EINVAL + br.ret.sptk.many b7 +END(ia64_syscall_setup) + + +#else /* * There is no particular reason for this code to be here, other * than that there happens to be space here that would go unused diff --git a/xen/include/asm-ia64/config.h b/xen/include/asm-ia64/config.h index 65aeb5bbb9..063e6e33eb 100644 --- a/xen/include/asm-ia64/config.h +++ b/xen/include/asm-ia64/config.h @@ -52,6 +52,9 @@ #define CONFIG_VGA 1 + +#define NR_hypercalls 64 + #ifndef __ASSEMBLY__ // can't find where this typedef was before?!? @@ -107,9 +110,6 @@ extern char _end[]; /* standard ELF symbol */ // xen/include/asm/config.h //#define HZ 1000 // FIXME SMP: leave SMP for a later time - -#define NR_hypercalls 64 - /////////////////////////////////////////////////////////////// // xen/include/asm/config.h // Natural boundary upon TR size to define xenheap space diff --git a/xen/include/asm-ia64/hypercall.h b/xen/include/asm-ia64/hypercall.h index 6e4a0320fd..ed0af4678d 100644 --- a/xen/include/asm-ia64/hypercall.h +++ b/xen/include/asm-ia64/hypercall.h @@ -13,6 +13,8 @@ extern long do_event_channel_op_compat( XEN_GUEST_HANDLE(evtchn_op_t) uop); +extern long do_pirq_guest_eoi(int pirq); + extern int vmx_do_mmu_update( mmu_update_t *ureqs, diff --git a/xen/include/public/arch-ia64.h b/xen/include/public/arch-ia64.h index 2da8fba00a..7425cafd94 100644 --- a/xen/include/public/arch-ia64.h +++ b/xen/include/public/arch-ia64.h @@ -463,7 +463,7 @@ struct xen_ia64_boot_param { #define HYPERPRIVOP_MAX (0x19) /* Fast and light hypercalls. */ -#define __HYPERVISOR_ia64_fast_eoi 0x0200 +#define __HYPERVISOR_ia64_fast_eoi __HYPERVISOR_arch_1 /* Xencomm macros. */ #define XENCOMM_INLINE_MASK 0xf800000000000000UL From 4c8688811f74e58a04bf5f10e0240e7c0c11b510 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 12 Jan 2007 10:08:38 +0000 Subject: [PATCH 170/570] [HVM] Fix timer interrupt delivery on x64 Vista. x64 SMP Vista HVM guest uses HPET as the main system timer, and it uses physical destination mode with broadcast to deliver the interrupts generated by HPET. In current code, timer interrupts are injected only to VCPU0 in vioapic.c, but this doesn't satisfy x64 SMP Vista -- when it boots, it complains "a clock interrupt was not received on a secondary processor within the allocated time interval" with Bug Check 0x101. Signed-off-by: Dexuan Cui --- xen/arch/x86/domain.c | 2 +- xen/arch/x86/hvm/vioapic.c | 11 +++++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index b03824f5ca..e23c85bbaa 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -1047,7 +1047,7 @@ void context_switch(struct vcpu *prev, struct vcpu *next) local_irq_disable(); - if ( is_hvm_vcpu(prev) ) + if ( is_hvm_vcpu(prev) && !list_empty(&prev->arch.hvm_vcpu.tm_list) ) pt_freeze_time(prev); set_current(next); diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index 843c76a6dd..6f68a85b77 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -309,6 +309,13 @@ static uint32_t ioapic_get_delivery_bitmask( return mask; } +static inline int pit_channel0_enabled(void) +{ + PITState *pit = ¤t->domain->arch.hvm_domain.pl_time.vpit; + struct periodic_time *pt = &pit->channels[0].pt; + return pt->enabled; +} + static void vioapic_deliver(struct vioapic *vioapic, int irq) { uint16_t dest = vioapic->redirtbl[irq].fields.dest_id; @@ -341,7 +348,7 @@ static void vioapic_deliver(struct vioapic *vioapic, int irq) { #ifdef IRQ0_SPECIAL_ROUTING /* Force round-robin to pick VCPU 0 */ - if ( irq == hvm_isa_irq_to_gsi(0) ) + if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() ) { v = vioapic_domain(vioapic)->vcpu[0]; target = v ? vcpu_vlapic(v) : NULL; @@ -374,7 +381,7 @@ static void vioapic_deliver(struct vioapic *vioapic, int irq) deliver_bitmask &= ~(1 << bit); #ifdef IRQ0_SPECIAL_ROUTING /* Do not deliver timer interrupts to VCPU != 0 */ - if ( irq == hvm_isa_irq_to_gsi(0) ) + if ( (irq == hvm_isa_irq_to_gsi(0)) && pit_channel0_enabled() ) v = vioapic_domain(vioapic)->vcpu[0]; else #endif From 7a6a2373cf56eb0d36396886a2d9b2719f0957b8 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 12 Jan 2007 10:10:28 +0000 Subject: [PATCH 171/570] [XEN] Replace mfn_to_page(lXe_get_pfn()) by lXe_get_page(). Signed-off-by: Jan Beulich --- xen/arch/x86/mm.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 78e9e151fc..5aed0051da 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -826,7 +826,7 @@ static void put_page_from_l2e(l2_pgentry_t l2e, unsigned long pfn) { if ( (l2e_get_flags(l2e) & _PAGE_PRESENT) && (l2e_get_pfn(l2e) != pfn) ) - put_page_and_type(mfn_to_page(l2e_get_pfn(l2e))); + put_page_and_type(l2e_get_page(l2e)); } @@ -835,7 +835,7 @@ static void put_page_from_l3e(l3_pgentry_t l3e, unsigned long pfn) { if ( (l3e_get_flags(l3e) & _PAGE_PRESENT) && (l3e_get_pfn(l3e) != pfn) ) - put_page_and_type(mfn_to_page(l3e_get_pfn(l3e))); + put_page_and_type(l3e_get_page(l3e)); } #endif @@ -844,7 +844,7 @@ static void put_page_from_l4e(l4_pgentry_t l4e, unsigned long pfn) { if ( (l4e_get_flags(l4e) & _PAGE_PRESENT) && (l4e_get_pfn(l4e) != pfn) ) - put_page_and_type(mfn_to_page(l4e_get_pfn(l4e))); + put_page_and_type(l4e_get_page(l4e)); } #endif @@ -3354,7 +3354,6 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, struct cpu_user_regs *regs) { struct domain *d = v->domain; - unsigned long pfn; struct page_info *page; l1_pgentry_t pte; struct ptwr_emulate_ctxt ptwr_ctxt; @@ -3368,8 +3367,7 @@ int ptwr_do_page_fault(struct vcpu *v, unsigned long addr, guest_get_eff_l1e(v, addr, &pte); if ( !(l1e_get_flags(pte) & _PAGE_PRESENT) ) goto bail; - pfn = l1e_get_pfn(pte); - page = mfn_to_page(pfn); + page = l1e_get_page(pte); /* We are looking only for read-only mappings of p.t. pages. */ if ( ((l1e_get_flags(pte) & (_PAGE_PRESENT|_PAGE_RW)) != _PAGE_PRESENT) || From 11ee9a5faa25fc17e09c986134565825836730e9 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 12 Jan 2007 10:13:25 +0000 Subject: [PATCH 172/570] [XEN] Consistent assumption that PTEs contain MFNs in both ptwr page-fault handler and ptwr emulation handler. Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 5aed0051da..a4b93f2b70 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3182,7 +3182,7 @@ static int ptwr_emulated_update( unsigned int do_cmpxchg, struct ptwr_emulate_ctxt *ptwr_ctxt) { - unsigned long gmfn, mfn; + unsigned long mfn; struct page_info *page; l1_pgentry_t pte, ol1e, nl1e, *pl1e; struct vcpu *v = current; @@ -3222,8 +3222,7 @@ static int ptwr_emulated_update( } pte = ptwr_ctxt->pte; - gmfn = l1e_get_pfn(pte); - mfn = gmfn_to_mfn(d, gmfn); + mfn = l1e_get_pfn(pte); page = mfn_to_page(mfn); /* We are looking only for read-only mappings of p.t. pages. */ From 8f529b5debe04825c21cbc6ec787566a66029b2b Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 12 Jan 2007 10:22:36 +0000 Subject: [PATCH 173/570] [LINUX] x86/64: Sync pagetable management with i386 Xen code. PUDs,PMDs,PTEs are all marked as ForeignPage so that they can be grabbed from tlb_remove_page() at the appropriate time and freed in a special way. Signed-off-by: Jan Beulich --- .../arch/x86_64/mm/pageattr-xen.c | 16 ++++ .../include/asm-x86_64/mach-xen/asm/pgalloc.h | 85 +++++++------------ 2 files changed, 48 insertions(+), 53 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c index 3641bfb805..d717708de9 100644 --- a/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c +++ b/linux-2.6-xen-sparse/arch/x86_64/mm/pageattr-xen.c @@ -164,6 +164,18 @@ void _arch_exit_mmap(struct mm_struct *mm) mm_unpin(mm); } +struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) +{ + struct page *pte; + + pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); + if (pte) { + SetPageForeign(pte, pte_free); + set_page_count(pte, 1); + } + return pte; +} + void pte_free(struct page *pte) { unsigned long va = (unsigned long)__va(page_to_pfn(pte)<>PAGE_SHIFT, PAGE_KERNEL), - 0)); - } - free_page((unsigned long)pmd); -} +extern struct page *pte_alloc_one(struct mm_struct *mm, unsigned long addr); +extern void pte_free(struct page *pte); static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr) { - pmd_t *pmd = (pmd_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); - return pmd; + struct page *pg; + + pg = pte_alloc_one(mm, addr); + return pg ? page_address(pg) : NULL; +} + +static inline void pmd_free(pmd_t *pmd) +{ + BUG_ON((unsigned long)pmd & (PAGE_SIZE-1)); + pte_free(virt_to_page(pmd)); } static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr) { - pud_t *pud = (pud_t *) get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); - return pud; + struct page *pg; + + pg = pte_alloc_one(mm, addr); + return pg ? page_address(pg) : NULL; } static inline void pud_free(pud_t *pud) { - pte_t *ptep = virt_to_ptep(pud); - - if (!pte_write(*ptep)) { - BUG_ON(HYPERVISOR_update_va_mapping( - (unsigned long)pud, - pfn_pte(virt_to_phys(pud)>>PAGE_SHIFT, PAGE_KERNEL), - 0)); - } - free_page((unsigned long)pud); + BUG_ON((unsigned long)pud & (PAGE_SIZE-1)); + pte_free(virt_to_page(pud)); } static inline pgd_t *pgd_alloc(struct mm_struct *mm) { - /* - * We allocate two contiguous pages for kernel and user. - */ - unsigned boundary; + /* + * We allocate two contiguous pages for kernel and user. + */ + unsigned boundary; pgd_t *pgd = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 1); if (!pgd) @@ -124,11 +117,11 @@ static inline pgd_t *pgd_alloc(struct mm_struct *mm) (PTRS_PER_PGD - boundary) * sizeof(pgd_t)); memset(__user_pgd(pgd), 0, PAGE_SIZE); /* clean up user pgd */ - /* - * Set level3_user_pgt for vsyscall area - */ + /* + * Set level3_user_pgt for vsyscall area + */ set_pgd(__user_pgd(pgd) + pgd_index(VSYSCALL_START), - mk_kernel_pgd(__pa_symbol(level3_user_pgt))); + mk_kernel_pgd(__pa_symbol(level3_user_pgt))); return pgd; } @@ -160,39 +153,25 @@ static inline void pgd_free(pgd_t *pgd) static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long address) { - pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); - if (pte) + pte_t *pte = (pte_t *)get_zeroed_page(GFP_KERNEL|__GFP_REPEAT); + if (pte) make_page_readonly(pte, XENFEAT_writable_page_tables); return pte; } -static inline struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) -{ - struct page *pte; - - pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); - return pte; -} - /* Should really implement gc for free page table pages. This could be done with a reference count in struct page. */ static inline void pte_free_kernel(pte_t *pte) { BUG_ON((unsigned long)pte & (PAGE_SIZE-1)); - make_page_writable(pte, XENFEAT_writable_page_tables); + make_page_writable(pte, XENFEAT_writable_page_tables); free_page((unsigned long)pte); } -extern void pte_free(struct page *pte); - -//#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) -//#define __pmd_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x)) -//#define __pud_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x)) - -#define __pte_free_tlb(tlb,x) pte_free((x)) -#define __pmd_free_tlb(tlb,x) pmd_free((x)) -#define __pud_free_tlb(tlb,x) pud_free((x)) +#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte)) +#define __pmd_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x)) +#define __pud_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x)) #endif /* _X86_64_PGALLOC_H */ From 9f7105d6ac9eb99fa031682b24570596334d68c9 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 12 Jan 2007 10:28:54 +0000 Subject: [PATCH 174/570] linux/i386: allow CONFIG_HIGHPTE on i386 While, as discussed, the performance impact of this option is certainly higher than on native Linux, the option should not be entirely disallowed if people want to sacrifice performance for less lowmem pressure. Signed-off-by: Jan Beulich --- linux-2.6-xen-sparse/arch/i386/Kconfig | 2 +- .../arch/i386/mm/highmem-xen.c | 1 + .../arch/i386/mm/pgtable-xen.c | 28 +++++++++++++++---- .../include/asm-i386/mach-xen/asm/pgalloc.h | 2 +- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/linux-2.6-xen-sparse/arch/i386/Kconfig b/linux-2.6-xen-sparse/arch/i386/Kconfig index 8c712269d0..4c0d2f8c80 100644 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig @@ -594,7 +594,7 @@ config HAVE_ARCH_EARLY_PFN_TO_NID config HIGHPTE bool "Allocate 3rd-level pagetables from highmem" - depends on (HIGHMEM4G || HIGHMEM64G) && !X86_XEN + depends on HIGHMEM4G || HIGHMEM64G help The VM uses one page table entry for each page of physical memory. For systems with a lot of RAM, this can be wasteful of precious diff --git a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c index 23f0e1b2e9..ee7deae2a7 100644 --- a/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/mm/highmem-xen.c @@ -129,5 +129,6 @@ struct page *kmap_atomic_to_page(void *ptr) EXPORT_SYMBOL(kmap); EXPORT_SYMBOL(kunmap); EXPORT_SYMBOL(kmap_atomic); +EXPORT_SYMBOL(kmap_atomic_pte); EXPORT_SYMBOL(kunmap_atomic); EXPORT_SYMBOL(kmap_atomic_to_page); diff --git a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c index 0ff01f52f8..8f2239b427 100644 --- a/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/mm/pgtable-xen.c @@ -238,23 +238,41 @@ struct page *pte_alloc_one(struct mm_struct *mm, unsigned long address) #ifdef CONFIG_HIGHPTE pte = alloc_pages(GFP_KERNEL|__GFP_HIGHMEM|__GFP_REPEAT|__GFP_ZERO, 0); + if (pte && PageHighMem(pte)) { + struct mmuext_op op; + + kmap_flush_unused(); + op.cmd = MMUEXT_PIN_L1_TABLE; + op.arg1.mfn = pfn_to_mfn(page_to_pfn(pte)); + BUG_ON(HYPERVISOR_mmuext_op(&op, 1, NULL, DOMID_SELF) < 0); + } #else pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); +#endif if (pte) { SetPageForeign(pte, pte_free); set_page_count(pte, 1); } -#endif return pte; } void pte_free(struct page *pte) { - unsigned long va = (unsigned long)__va(page_to_pfn(pte)< Date: Fri, 12 Jan 2007 10:31:16 +0000 Subject: [PATCH 175/570] [LINUX] swiotlb: eliminate KM_SWIOTLB and thus the need for a Xen-specific kmap_types.h. Signed-off-by: Jan Beulich --- .../arch/i386/kernel/swiotlb.c | 8 +++-- .../asm-i386/mach-xen/asm/kmap_types.h | 32 ------------------- 2 files changed, 6 insertions(+), 34 deletions(-) delete mode 100644 linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/kmap_types.h diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c index ac2c0da536..d6ceb72ac9 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/swiotlb.c @@ -238,9 +238,12 @@ __sync_single(struct phys_addr buffer, char *dma_addr, size_t size, int dir) char *dev, *host, *kmp; len = size; while (len != 0) { + unsigned long flags; + if (((bytes = len) + buffer.offset) > PAGE_SIZE) bytes = PAGE_SIZE - buffer.offset; - kmp = kmap_atomic(buffer.page, KM_SWIOTLB); + local_irq_save(flags); /* protects KM_BOUNCE_READ */ + kmp = kmap_atomic(buffer.page, KM_BOUNCE_READ); dev = dma_addr + size - len; host = kmp + buffer.offset; if (dir == DMA_FROM_DEVICE) { @@ -248,7 +251,8 @@ __sync_single(struct phys_addr buffer, char *dma_addr, size_t size, int dir) /* inaccessible */; } else memcpy(dev, host, bytes); - kunmap_atomic(kmp, KM_SWIOTLB); + kunmap_atomic(kmp, KM_BOUNCE_READ); + local_irq_restore(flags); len -= bytes; buffer.page++; buffer.offset = 0; diff --git a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/kmap_types.h b/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/kmap_types.h deleted file mode 100644 index 7a660e8e24..0000000000 --- a/linux-2.6-xen-sparse/include/asm-i386/mach-xen/asm/kmap_types.h +++ /dev/null @@ -1,32 +0,0 @@ -#ifndef _ASM_KMAP_TYPES_H -#define _ASM_KMAP_TYPES_H - -#include - -#ifdef CONFIG_DEBUG_HIGHMEM -# define D(n) __KM_FENCE_##n , -#else -# define D(n) -#endif - -enum km_type { -D(0) KM_BOUNCE_READ, -D(1) KM_SKB_SUNRPC_DATA, -D(2) KM_SKB_DATA_SOFTIRQ, -D(3) KM_USER0, -D(4) KM_USER1, -D(5) KM_BIO_SRC_IRQ, -D(6) KM_BIO_DST_IRQ, -D(7) KM_PTE0, -D(8) KM_PTE1, -D(9) KM_IRQ0, -D(10) KM_IRQ1, -D(11) KM_SOFTIRQ0, -D(12) KM_SOFTIRQ1, -D(13) KM_SWIOTLB, -D(14) KM_TYPE_NR -}; - -#undef D - -#endif From a5e0c983d01566982e34262439db2cb8f524a19c Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 12 Jan 2007 10:48:46 +0000 Subject: [PATCH 176/570] [XEN] Default to 80x50 VGA text console. Signed-off-by: Keir Fraser --- xen/drivers/video/vga.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/xen/drivers/video/vga.c b/xen/drivers/video/vga.c index 08a260a2b7..303210e466 100644 --- a/xen/drivers/video/vga.c +++ b/xen/drivers/video/vga.c @@ -557,7 +557,7 @@ static int vga_load_font(const struct font_desc *font, unsigned rows) static int vgacon_enabled = 0; static int vgacon_keep = 0; -static int vgacon_lines = 25; +static int vgacon_lines = 50; static const struct font_desc *font; static int xpos, ypos; @@ -606,12 +606,9 @@ void vga_init(void) case 60: font = &font_vga_8x8; break; - default: - vgacon_lines = 25; - break; } - if ( (font != NULL) && (vga_load_font(font, vgacon_lines) < 0) ) + if ( (font == NULL) || (vga_load_font(font, vgacon_lines) < 0) ) { vgacon_lines = 25; font = NULL; From 51baeaf819bfd5f601c7c1bd2a2e59eb251cecb9 Mon Sep 17 00:00:00 2001 From: "kfraser@localhost.localdomain" Date: Fri, 12 Jan 2007 14:22:28 +0000 Subject: [PATCH 177/570] [XEN] Fix guest-access macros. From: Christoph Egger --- xen/include/asm-x86/guest_access.h | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/xen/include/asm-x86/guest_access.h b/xen/include/asm-x86/guest_access.h index ce5c290787..0fc5bc98dc 100644 --- a/xen/include/asm-x86/guest_access.h +++ b/xen/include/asm-x86/guest_access.h @@ -32,7 +32,7 @@ * specifying an offset into the guest array. */ #define copy_to_guest_offset(hnd, off, ptr, nr) ({ \ - const typeof(ptr) _x = (hnd).p; \ + typeof(ptr) _x = (hnd).p; \ const typeof(ptr) _y = (ptr); \ is_hvm_vcpu(current) ? \ copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) : \ @@ -45,7 +45,7 @@ */ #define copy_from_guest_offset(ptr, hnd, off, nr) ({ \ const typeof(ptr) _x = (hnd).p; \ - const typeof(ptr) _y = (ptr); \ + typeof(ptr) _y = (ptr); \ is_hvm_vcpu(current) ? \ copy_from_user_hvm(_y, _x+(off), sizeof(*_x)*(nr)) :\ copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \ @@ -53,7 +53,7 @@ /* Copy sub-field of a structure to guest context via a guest handle. */ #define copy_field_to_guest(hnd, ptr, field) ({ \ - const typeof(&(ptr)->field) _x = &(hnd).p->field; \ + typeof(&(ptr)->field) _x = &(hnd).p->field; \ const typeof(&(ptr)->field) _y = &(ptr)->field; \ is_hvm_vcpu(current) ? \ copy_to_user_hvm(_x, _y, sizeof(*_x)) : \ @@ -63,7 +63,7 @@ /* Copy sub-field of a structure from guest context via a guest handle. */ #define copy_field_from_guest(ptr, hnd, field) ({ \ const typeof(&(ptr)->field) _x = &(hnd).p->field; \ - const typeof(&(ptr)->field) _y = &(ptr)->field; \ + typeof(&(ptr)->field) _y = &(ptr)->field; \ is_hvm_vcpu(current) ? \ copy_from_user_hvm(_y, _x, sizeof(*_x)) : \ copy_from_user(_y, _x, sizeof(*_x)); \ @@ -78,7 +78,7 @@ array_access_ok((hnd).p, (nr), sizeof(*(hnd).p))) #define __copy_to_guest_offset(hnd, off, ptr, nr) ({ \ - const typeof(ptr) _x = (hnd).p; \ + typeof(ptr) _x = (hnd).p; \ const typeof(ptr) _y = (ptr); \ is_hvm_vcpu(current) ? \ copy_to_user_hvm(_x+(off), _y, sizeof(*_x)*(nr)) : \ @@ -87,14 +87,14 @@ #define __copy_from_guest_offset(ptr, hnd, off, nr) ({ \ const typeof(ptr) _x = (hnd).p; \ - const typeof(ptr) _y = (ptr); \ + typeof(ptr) _y = (ptr); \ is_hvm_vcpu(current) ? \ copy_from_user_hvm(_y, _x+(off),sizeof(*_x)*(nr)) : \ __copy_from_user(_y, _x+(off), sizeof(*_x)*(nr)); \ }) #define __copy_field_to_guest(hnd, ptr, field) ({ \ - const typeof(&(ptr)->field) _x = &(hnd).p->field; \ + typeof(&(ptr)->field) _x = &(hnd).p->field; \ const typeof(&(ptr)->field) _y = &(ptr)->field; \ is_hvm_vcpu(current) ? \ copy_to_user_hvm(_x, _y, sizeof(*_x)) : \ @@ -103,9 +103,9 @@ #define __copy_field_from_guest(ptr, hnd, field) ({ \ const typeof(&(ptr)->field) _x = &(hnd).p->field; \ - const typeof(&(ptr)->field) _y = &(ptr)->field; \ + typeof(&(ptr)->field) _y = &(ptr)->field; \ is_hvm_vcpu(current) ? \ - copy_from_user_hvm(_x, _y, sizeof(*_x)) : \ + copy_from_user_hvm(_y, _x, sizeof(*_x)) : \ __copy_from_user(_y, _x, sizeof(*_x)); \ }) From 432e7b62cb60b6f6f45e52b3db0268560d9b7cdb Mon Sep 17 00:00:00 2001 From: Christian Limpach Date: Fri, 12 Jan 2007 14:30:49 +0000 Subject: [PATCH 178/570] [linux] Update to linux-2.6.17. Signed-off-by: Christian Limpach --HG-- rename : patches/linux-2.6.16.33/blktap-aio-16_03_06.patch => patches/linux-2.6.17/blktap-aio-16_03_06.patch rename : patches/linux-2.6.16.33/fix-hz-suspend.patch => patches/linux-2.6.17/fix-hz-suspend.patch rename : patches/linux-2.6.16.33/fix-ide-cd-pio-mode.patch => patches/linux-2.6.17/fix-ide-cd-pio-mode.patch rename : patches/linux-2.6.16.33/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch => patches/linux-2.6.17/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch rename : patches/linux-2.6.16.33/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch => patches/linux-2.6.17/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch rename : patches/linux-2.6.16.33/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch => patches/linux-2.6.17/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch rename : patches/linux-2.6.16.33/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch => patches/linux-2.6.17/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch rename : patches/linux-2.6.16.33/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch => patches/linux-2.6.17/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch rename : patches/linux-2.6.16.33/i386-mach-io-check-nmi.patch => patches/linux-2.6.17/i386-mach-io-check-nmi.patch rename : patches/linux-2.6.16.33/ipv6-no-autoconf.patch => patches/linux-2.6.17/ipv6-no-autoconf.patch rename : patches/linux-2.6.16.33/kasprintf.patch => patches/linux-2.6.17/kasprintf.patch rename : patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch => patches/linux-2.6.17/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch rename : patches/linux-2.6.16.33/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch => patches/linux-2.6.17/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch rename : patches/linux-2.6.16.33/net-csum.patch => patches/linux-2.6.17/net-csum.patch rename : patches/linux-2.6.16.33/net-gso-0-base.patch => patches/linux-2.6.17/net-gso-0-base.patch rename : patches/linux-2.6.16.33/net-gso-1-check-dodgy.patch => patches/linux-2.6.17/net-gso-1-check-dodgy.patch rename : patches/linux-2.6.16.33/net-gso-2-checksum-fix.patch => patches/linux-2.6.17/net-gso-2-checksum-fix.patch rename : patches/linux-2.6.16.33/net-gso-3-fix-errorcheck.patch => patches/linux-2.6.17/net-gso-3-fix-errorcheck.patch rename : patches/linux-2.6.16.33/net-gso-4-kill-warnon.patch => patches/linux-2.6.17/net-gso-4-kill-warnon.patch rename : patches/linux-2.6.16.33/net-gso-5-rcv-mss.patch => patches/linux-2.6.17/net-gso-5-rcv-mss.patch rename : patches/linux-2.6.16.33/net-gso-6-linear-segmentation.patch => patches/linux-2.6.17/net-gso-6-linear-segmentation.patch rename : patches/linux-2.6.16.33/pmd-shared.patch => patches/linux-2.6.17/pmd-shared.patch rename : patches/linux-2.6.16.33/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch => patches/linux-2.6.17/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch rename : patches/linux-2.6.16.33/series => patches/linux-2.6.17/series rename : patches/linux-2.6.16.33/vsnprintf.patch => patches/linux-2.6.17/vsnprintf.patch rename : patches/linux-2.6.16.33/x86-elfnote-as-preprocessor-macro.patch => patches/linux-2.6.17/x86-elfnote-as-preprocessor-macro.patch rename : patches/linux-2.6.16.33/x86-increase-interrupt-vector-range.patch => patches/linux-2.6.17/x86-increase-interrupt-vector-range.patch rename : patches/linux-2.6.16.33/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch => patches/linux-2.6.17/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch rename : patches/linux-2.6.16.33/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch => patches/linux-2.6.17/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch rename : patches/linux-2.6.16.33/xen-hotplug.patch => patches/linux-2.6.17/xen-hotplug.patch rename : patches/linux-2.6.16.33/xenoprof-generic.patch => patches/linux-2.6.17/xenoprof-generic.patch --- buildconfigs/linux-defconfig_xen0_x86_32 | 105 +- buildconfigs/linux-defconfig_xen0_x86_64 | 109 +- buildconfigs/linux-defconfig_xenU_x86_32 | 63 +- buildconfigs/linux-defconfig_xenU_x86_64 | 67 +- buildconfigs/linux-defconfig_xen_x86_32 | 273 ++- buildconfigs/linux-defconfig_xen_x86_64 | 266 ++- buildconfigs/mk.linux-2.6-xen | 2 +- linux-2.6-xen-sparse/arch/i386/Kconfig | 136 +- linux-2.6-xen-sparse/arch/i386/Kconfig.cpu | 2 +- linux-2.6-xen-sparse/arch/i386/Kconfig.debug | 94 + linux-2.6-xen-sparse/arch/i386/Makefile | 14 +- .../arch/i386/kernel/Makefile | 5 +- .../arch/i386/kernel/acpi/boot-xen.c | 14 +- .../arch/i386/kernel/apic-xen.c | 13 + .../arch/i386/kernel/cpu/common-xen.c | 57 +- .../i386/kernel/cpu/intel_cacheinfo-xen.c | 693 ++++++++ .../arch/i386/kernel/cpu/mtrr/main-xen.c | 13 +- linux-2.6-xen-sparse/arch/i386/kernel/crash.c | 4 +- .../arch/i386/kernel/entry-xen.S | 4 + .../arch/i386/kernel/head-xen.S | 2 + .../arch/i386/kernel/io_apic-xen.c | 33 +- .../arch/i386/kernel/microcode-xen.c | 25 +- .../arch/i386/kernel/mpparse-xen.c | 62 +- .../arch/i386/kernel/process-xen.c | 11 +- .../arch/i386/kernel/setup-xen.c | 207 +-- .../arch/i386/kernel/smp-xen.c | 26 +- .../arch/i386/kernel/smpalts.c | 85 - .../arch/i386/kernel/smpboot.c | 74 +- .../arch/i386/kernel/traps-xen.c | 105 +- linux-2.6-xen-sparse/arch/i386/kernel/traps.c | 105 +- linux-2.6-xen-sparse/arch/i386/kernel/vm86.c | 2 +- .../arch/i386/kernel/vmlinux.lds.S | 30 +- linux-2.6-xen-sparse/arch/i386/mm/fault-xen.c | 224 ++- linux-2.6-xen-sparse/arch/i386/mm/init-xen.c | 51 +- .../arch/i386/mm/pgtable-xen.c | 6 +- linux-2.6-xen-sparse/arch/i386/mm/pgtable.c | 2 +- linux-2.6-xen-sparse/arch/i386/pci/Makefile | 2 +- linux-2.6-xen-sparse/arch/i386/pci/irq-xen.c | 6 +- linux-2.6-xen-sparse/arch/ia64/Kconfig | 42 +- linux-2.6-xen-sparse/arch/ia64/Makefile | 5 +- linux-2.6-xen-sparse/arch/ia64/dig/setup.c | 5 - linux-2.6-xen-sparse/arch/ia64/kernel/entry.S | 20 +- .../arch/ia64/kernel/gate.lds.S | 1 + .../arch/ia64/kernel/iosapic.c | 275 +-- linux-2.6-xen-sparse/arch/ia64/kernel/patch.c | 8 +- .../arch/ia64/kernel/perfmon.c | 9 +- linux-2.6-xen-sparse/arch/ia64/kernel/setup.c | 71 +- linux-2.6-xen-sparse/arch/ia64/mm/ioremap.c | 46 + linux-2.6-xen-sparse/arch/um/kernel/physmem.c | 7 +- linux-2.6-xen-sparse/arch/x86_64/Kconfig | 69 +- linux-2.6-xen-sparse/arch/x86_64/Makefile | 45 +- .../arch/x86_64/ia32/ia32entry-xen.S | 31 +- .../arch/x86_64/ia32/vsyscall-sigreturn.S | 23 +- .../arch/x86_64/kernel/Makefile | 5 +- .../arch/x86_64/kernel/acpi/Makefile | 1 - .../arch/x86_64/kernel/apic-xen.c | 2 +- .../arch/x86_64/kernel/e820-xen.c | 44 +- .../arch/x86_64/kernel/early_printk-xen.c | 120 +- .../arch/x86_64/kernel/entry-xen.S | 2 +- .../arch/x86_64/kernel/head-xen.S | 10 +- .../arch/x86_64/kernel/io_apic-xen.c | 46 +- .../arch/x86_64/kernel/irq-xen.c | 21 +- .../arch/x86_64/kernel/mpparse-xen.c | 31 +- .../arch/x86_64/kernel/process-xen.c | 40 +- .../arch/x86_64/kernel/setup-xen.c | 138 +- .../arch/x86_64/kernel/setup64-xen.c | 22 +- .../arch/x86_64/kernel/smp-xen.c | 6 +- .../arch/x86_64/kernel/traps-xen.c | 76 +- .../arch/x86_64/kernel/x8664_ksyms-xen.c | 8 - .../arch/x86_64/mm/fault-xen.c | 81 +- .../arch/x86_64/mm/init-xen.c | 66 +- .../arch/x86_64/mm/pageattr-xen.c | 71 +- linux-2.6-xen-sparse/arch/x86_64/pci/Makefile | 3 +- linux-2.6-xen-sparse/drivers/Makefile | 7 +- linux-2.6-xen-sparse/drivers/acpi/Kconfig | 17 +- linux-2.6-xen-sparse/drivers/acpi/tables.c | 626 ------- linux-2.6-xen-sparse/drivers/char/mem.c | 62 +- linux-2.6-xen-sparse/drivers/char/tty_io.c | 127 +- linux-2.6-xen-sparse/drivers/pci/Kconfig | 21 +- linux-2.6-xen-sparse/drivers/serial/Kconfig | 60 +- linux-2.6-xen-sparse/drivers/video/Kconfig | 45 +- .../drivers/xen/balloon/balloon.c | 2 +- .../drivers/xen/blkfront/blkfront.c | 4 +- .../drivers/xen/console/console.c | 6 +- .../drivers/xen/core/smpboot.c | 16 +- .../drivers/xen/netback/netback.c | 2 +- .../drivers/xen/pcifront/pci_op.c | 4 +- .../drivers/xen/xenbus/xenbus_probe.c | 8 +- linux-2.6-xen-sparse/fs/Kconfig | 22 +- linux-2.6-xen-sparse/include/asm-i386/apic.h | 2 + .../include/asm-i386/atomic.h | 254 --- .../include/asm-i386/bitops.h | 463 ----- linux-2.6-xen-sparse/include/asm-i386/futex.h | 108 -- .../include/asm-i386/mach-xen/asm/io.h | 12 - .../include/asm-i386/mach-xen/asm/page.h | 3 +- .../asm-i386/mach-xen/asm/pgtable-2level.h | 2 + .../asm-i386/mach-xen/asm/pgtable-3level.h | 2 + .../include/asm-i386/mach-xen/asm/pgtable.h | 5 +- .../include/asm-i386/mach-xen/asm/processor.h | 7 +- .../include/asm-i386/mach-xen/asm/setup.h | 4 +- .../include/asm-i386/mach-xen/asm/smp.h | 1 + .../include/asm-i386/mach-xen/asm/spinlock.h | 69 +- .../include/asm-i386/mach-xen/asm/system.h | 127 +- linux-2.6-xen-sparse/include/asm-i386/page.h | 3 +- linux-2.6-xen-sparse/include/asm-i386/rwsem.h | 294 ---- .../include/asm-i386/smp_alt.h | 32 - .../include/asm-i386/spinlock.h | 217 --- .../include/asm-i386/system.h | 606 ------- .../include/asm-ia64/intel_intrin.h | 134 +- linux-2.6-xen-sparse/include/asm-ia64/io.h | 25 +- .../include/asm-ia64/machvec.h | 15 + .../include/asm-ia64/machvec_dig.h | 2 - linux-2.6-xen-sparse/include/asm-ia64/page.h | 22 +- linux-2.6-xen-sparse/include/asm-ia64/pal.h | 37 +- .../include/asm-ia64/processor.h | 4 +- .../include/asm-ia64/system.h | 9 + linux-2.6-xen-sparse/include/asm-um/page.h | 4 +- .../include/asm-x86_64/mach-xen/asm/e820.h | 5 +- .../include/asm-x86_64/mach-xen/asm/floppy.h | 2 +- .../include/asm-x86_64/mach-xen/asm/io.h | 40 +- .../asm-x86_64/mach-xen/asm/mmu_context.h | 6 +- .../include/asm-x86_64/mach-xen/asm/page.h | 3 +- .../include/asm-x86_64/mach-xen/asm/pgalloc.h | 29 +- .../include/asm-x86_64/mach-xen/asm/pgtable.h | 8 +- .../asm-x86_64/mach-xen/asm/processor.h | 7 +- .../include/asm-x86_64/mach-xen/asm/smp.h | 1 + .../include/asm-x86_64/mach-xen/asm/system.h | 9 +- .../include/asm-x86_64/mach-xen/mach_time.h | 37 +- linux-2.6-xen-sparse/include/linux/gfp.h | 2 + linux-2.6-xen-sparse/include/linux/highmem.h | 12 + linux-2.6-xen-sparse/include/linux/mm.h | 48 +- linux-2.6-xen-sparse/include/linux/pfn.h | 9 + linux-2.6-xen-sparse/include/linux/skbuff.h | 107 +- linux-2.6-xen-sparse/kernel/fork.c | 168 +- linux-2.6-xen-sparse/lib/Makefile | 3 + linux-2.6-xen-sparse/mm/Kconfig | 12 +- linux-2.6-xen-sparse/mm/highmem.c | 41 +- linux-2.6-xen-sparse/mm/memory.c | 24 +- linux-2.6-xen-sparse/mm/mmap.c | 76 +- linux-2.6-xen-sparse/mm/page_alloc.c | 256 ++- linux-2.6-xen-sparse/net/core/dev.c | 279 ++- linux-2.6-xen-sparse/net/core/skbuff.c | 159 +- patches/linux-2.6.16.33/device_bind.patch | 15 - ...b49f92ff6ae6255762a948375e4036cbdbd2.patch | 47 - patches/linux-2.6.16.33/kasprintf.patch | 59 - .../pci-mmconfig-fix-from-2.6.17.patch | 292 ---- patches/linux-2.6.16.33/rcu_needs_cpu.patch | 35 - patches/linux-2.6.16.33/smp-alts.patch | 591 ------- .../linux-2.6.16.33/tpm_plugin_2.6.17.patch | 1545 ----------------- .../blktap-aio-16_03_06.patch | 56 +- .../fix-hz-suspend.patch | 12 +- .../fix-ide-cd-pio-mode.patch | 6 +- ...3d5b65e86ec1dfef7d268c64a909eab94af7.patch | 28 +- ...55a9cec8418f0e0cde3dc3787a42fddc4411.patch | 44 +- ...561bfadffcb5dbc85d576be80c0dbf2cccc9.patch | 45 +- ...aef01a1badb9e8ffb0c0a37cd2379008d21f.patch | 40 +- ...b49f92ff6ae6255762a948375e4036cbdbd2.patch | 20 + .../i386-mach-io-check-nmi.patch | 14 +- .../ipv6-no-autoconf.patch | 10 +- patches/linux-2.6.17/kasprintf.patch | 42 + ....19-rc1-kexec-move_segment_code-i386.patch | 34 +- ...9-rc1-kexec-move_segment_code-x86_64.patch | 30 +- .../net-csum.patch | 18 +- .../net-gso-0-base.patch | 696 ++++---- .../net-gso-1-check-dodgy.patch | 8 +- .../net-gso-2-checksum-fix.patch | 200 ++- .../net-gso-3-fix-errorcheck.patch | 8 +- .../net-gso-4-kill-warnon.patch | 10 +- .../net-gso-5-rcv-mss.patch | 7 +- .../net-gso-6-linear-segmentation.patch | 11 +- .../pmd-shared.patch | 26 +- ...SS_sysenter_esp0-SYSENTER_stack_esp0.patch | 10 +- .../{linux-2.6.16.33 => linux-2.6.17}/series | 5 - .../vsnprintf.patch | 36 +- .../x86-elfnote-as-preprocessor-macro.patch | 6 +- .../x86-increase-interrupt-vector-range.patch | 42 +- ...ns-into-a-pt_note-segment-in-vmlinux.patch | 28 +- ...ns-into-a-pt_note-segment-in-vmlinux.patch | 18 +- .../xen-hotplug.patch | 8 +- .../xenoprof-generic.patch | 60 +- 180 files changed, 4977 insertions(+), 8462 deletions(-) create mode 100644 linux-2.6-xen-sparse/arch/i386/Kconfig.debug create mode 100644 linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c delete mode 100644 linux-2.6-xen-sparse/arch/i386/kernel/smpalts.c create mode 100644 linux-2.6-xen-sparse/arch/ia64/mm/ioremap.c delete mode 100644 linux-2.6-xen-sparse/drivers/acpi/tables.c delete mode 100644 linux-2.6-xen-sparse/include/asm-i386/atomic.h delete mode 100644 linux-2.6-xen-sparse/include/asm-i386/bitops.h delete mode 100644 linux-2.6-xen-sparse/include/asm-i386/futex.h delete mode 100644 linux-2.6-xen-sparse/include/asm-i386/rwsem.h delete mode 100644 linux-2.6-xen-sparse/include/asm-i386/smp_alt.h delete mode 100644 linux-2.6-xen-sparse/include/asm-i386/spinlock.h delete mode 100644 linux-2.6-xen-sparse/include/asm-i386/system.h create mode 100644 linux-2.6-xen-sparse/include/linux/pfn.h delete mode 100644 patches/linux-2.6.16.33/device_bind.patch delete mode 100644 patches/linux-2.6.16.33/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch delete mode 100644 patches/linux-2.6.16.33/kasprintf.patch delete mode 100644 patches/linux-2.6.16.33/pci-mmconfig-fix-from-2.6.17.patch delete mode 100644 patches/linux-2.6.16.33/rcu_needs_cpu.patch delete mode 100644 patches/linux-2.6.16.33/smp-alts.patch delete mode 100644 patches/linux-2.6.16.33/tpm_plugin_2.6.17.patch rename patches/{linux-2.6.16.33 => linux-2.6.17}/blktap-aio-16_03_06.patch (81%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/fix-hz-suspend.patch (71%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/fix-ide-cd-pio-mode.patch (64%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/git-2a8a3d5b65e86ec1dfef7d268c64a909eab94af7.patch (68%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/git-2efe55a9cec8418f0e0cde3dc3787a42fddc4411.patch (60%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/git-3566561bfadffcb5dbc85d576be80c0dbf2cccc9.patch (88%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/git-4bfaaef01a1badb9e8ffb0c0a37cd2379008d21f.patch (87%) create mode 100644 patches/linux-2.6.17/git-dbaab49f92ff6ae6255762a948375e4036cbdbd2.patch rename patches/{linux-2.6.16.33 => linux-2.6.17}/i386-mach-io-check-nmi.patch (58%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/ipv6-no-autoconf.patch (57%) create mode 100644 patches/linux-2.6.17/kasprintf.patch rename patches/{linux-2.6.16.33 => linux-2.6.17}/linux-2.6.19-rc1-kexec-move_segment_code-i386.patch (74%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/linux-2.6.19-rc1-kexec-move_segment_code-x86_64.patch (75%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/net-csum.patch (64%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/net-gso-0-base.patch (80%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/net-gso-1-check-dodgy.patch (65%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/net-gso-2-checksum-fix.patch (56%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/net-gso-3-fix-errorcheck.patch (50%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/net-gso-4-kill-warnon.patch (58%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/net-gso-5-rcv-mss.patch (58%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/net-gso-6-linear-segmentation.patch (58%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/pmd-shared.patch (71%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/rename-TSS_sysenter_esp0-SYSENTER_stack_esp0.patch (69%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/series (90%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/vsnprintf.patch (71%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/x86-elfnote-as-preprocessor-macro.patch (83%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/x86-increase-interrupt-vector-range.patch (53%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/x86-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch (81%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/x86_64-put-note-sections-into-a-pt_note-segment-in-vmlinux.patch (79%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/xen-hotplug.patch (51%) rename patches/{linux-2.6.16.33 => linux-2.6.17}/xenoprof-generic.patch (87%) diff --git a/buildconfigs/linux-defconfig_xen0_x86_32 b/buildconfigs/linux-defconfig_xen0_x86_32 index 78b2d95cf8..bffd3ab9f6 100644 --- a/buildconfigs/linux-defconfig_xen0_x86_32 +++ b/buildconfigs/linux-defconfig_xen0_x86_32 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16.13-xen0 -# Thu May 11 17:06:31 2006 +# Linux kernel version: 2.6.17-xen0 +# Thu Jan 11 10:23:10 2007 # CONFIG_X86_32=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -9,6 +9,7 @@ CONFIG_X86=y CONFIG_MMU=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_DMI=y @@ -31,6 +32,7 @@ CONFIG_SYSVIPC=y CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y CONFIG_VM86=y @@ -47,10 +49,6 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -62,7 +60,6 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -71,6 +68,8 @@ CONFIG_KMOD=y # Block layer # # CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_LSF=y # # IO Schedulers @@ -88,6 +87,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Processor type and features # +# CONFIG_SMP is not set # CONFIG_X86_PC is not set CONFIG_X86_XEN=y # CONFIG_X86_ELAN is not set @@ -135,7 +135,6 @@ CONFIG_X86_CMPXCHG64=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_USE_PPRO_CHECKSUM=y CONFIG_X86_TSC=y -# CONFIG_SMP is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -158,10 +157,6 @@ CONFIG_SWIOTLB=y # CONFIG_NOHIGHMEM is not set CONFIG_HIGHMEM4G=y # CONFIG_HIGHMEM64G is not set -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_3G_OPT is not set -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_HIGHMEM=y CONFIG_SELECT_MEMORY_MODEL=y @@ -202,6 +197,7 @@ CONFIG_ACPI_PROCESSOR=m CONFIG_ACPI_THERMAL=m CONFIG_ACPI_ASUS=m CONFIG_ACPI_IBM=m +# CONFIG_ACPI_IBM_DOCK is not set CONFIG_ACPI_TOSHIBA=m # CONFIG_ACPI_CUSTOM_DSDT is not set CONFIG_ACPI_BLACKLIST_YEAR=0 @@ -230,7 +226,6 @@ CONFIG_PCI_MMCONFIG=y CONFIG_XEN_PCIDEV_FRONTEND=y # CONFIG_XEN_PCIDEV_FE_DEBUG is not set # CONFIG_PCIEPORTBUS is not set -CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_DEBUG is not set CONFIG_ISA_DMA_API=y # CONFIG_SCx200 is not set @@ -280,6 +275,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set @@ -290,6 +286,8 @@ CONFIG_TCP_CONG_BIC=y # # CONFIG_IP_VS is not set # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_BRIDGE_NETFILTER=y @@ -314,6 +312,7 @@ CONFIG_IP_NF_FTP=m # CONFIG_IP_NF_TFTP is not set # CONFIG_IP_NF_AMANDA is not set # CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_H323 is not set # CONFIG_IP_NF_QUEUE is not set # @@ -339,6 +338,7 @@ CONFIG_IP_NF_FTP=m CONFIG_BRIDGE=y # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set +CONFIG_LLC=y # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -542,6 +542,7 @@ CONFIG_AIC79XX_DEBUG_ENABLE=y CONFIG_AIC79XX_DEBUG_MASK=0 CONFIG_AIC79XX_REG_PRETTY_PRINT=y # CONFIG_SCSI_DPT_I2O is not set +CONFIG_SCSI_ADVANSYS=y CONFIG_MEGARAID_NEWGEN=y # CONFIG_MEGARAID_MM is not set # CONFIG_MEGARAID_LEGACY is not set @@ -573,7 +574,6 @@ CONFIG_SCSI_SATA_INTEL_COMBINED=y # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set # CONFIG_SCSI_LPFC is not set @@ -592,6 +592,7 @@ CONFIG_MD_RAID0=y CONFIG_MD_RAID1=y # CONFIG_MD_RAID10 is not set CONFIG_MD_RAID5=y +# CONFIG_MD_RAID5_RESHAPE is not set # CONFIG_MD_RAID6 is not set # CONFIG_MD_MULTIPATH is not set # CONFIG_MD_FAULTY is not set @@ -904,19 +905,17 @@ CONFIG_DRM_SIS=m # # CONFIG_IBM_ASM is not set -# -# Multimedia Capabilities Port drivers -# - # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set # # Graphics support @@ -928,6 +927,7 @@ CONFIG_DRM_SIS=m # Console display driver support # CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y # @@ -940,6 +940,7 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -992,9 +993,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set +# CONFIG_USB_TOUCHSCREEN is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -1008,15 +1007,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set - -# -# Video4Linux support is needed for USB Multimedia device support -# - # # USB Network Adapters # @@ -1066,6 +1056,19 @@ CONFIG_USB_MON=y # # CONFIG_MMC is not set +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + # # InfiniBand support # @@ -1076,6 +1079,25 @@ CONFIG_USB_MON=y # # CONFIG_EDAC is not set +# +# Real Time Clock +# +CONFIG_RTC_LIB=m +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=m +CONFIG_RTC_INTF_PROC=m +CONFIG_RTC_INTF_DEV=m + +# +# RTC drivers +# +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_TEST=m + # # File systems # @@ -1134,7 +1156,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -1258,11 +1279,13 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_EARLY_PRINTK=y # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_STACK_BACKTRACE_COLS=2 # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUG_RODATA is not set # CONFIG_4KSTACKS is not set @@ -1310,24 +1333,26 @@ CONFIG_CRYPTO_CRC32C=m # # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030202 +CONFIG_XEN_INTERFACE_VERSION=0x00030203 # # XEN # CONFIG_XEN_PRIVILEGED_GUEST=y # CONFIG_XEN_UNPRIVILEGED_GUEST is not set +CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_XENBUS_DEV=y CONFIG_XEN_BACKEND=y -CONFIG_XEN_PCIDEV_BACKEND=y -# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set -CONFIG_XEN_PCIDEV_BACKEND_PASS=y -# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set -# CONFIG_XEN_PCIDEV_BE_DEBUG is not set CONFIG_XEN_BLKDEV_BACKEND=y CONFIG_XEN_BLKDEV_TAP=y CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y +CONFIG_XEN_PCIDEV_BACKEND=y +# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set +CONFIG_XEN_PCIDEV_BACKEND_PASS=y +# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set +# CONFIG_XEN_PCIDEV_BE_DEBUG is not set # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y @@ -1339,7 +1364,13 @@ CONFIG_XEN_COMPAT_030002_AND_LATER=y CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y +CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y +CONFIG_XEN_UTIL=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_DEVMEM=y +CONFIG_XEN_SKBUFF=y +CONFIG_XEN_REBOOT=y # # Library routines diff --git a/buildconfigs/linux-defconfig_xen0_x86_64 b/buildconfigs/linux-defconfig_xen0_x86_64 index 603e0a82d9..76c223fa11 100644 --- a/buildconfigs/linux-defconfig_xen0_x86_64 +++ b/buildconfigs/linux-defconfig_xen0_x86_64 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16.13-xen0 -# Thu May 11 17:17:19 2006 +# Linux kernel version: 2.6.17-xen0 +# Thu Jan 11 09:46:03 2007 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -9,6 +9,7 @@ CONFIG_X86=y CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_MMU=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_X86_CMPXCHG=y CONFIG_EARLY_PRINTK=y @@ -36,6 +37,7 @@ CONFIG_SYSVIPC=y CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y CONFIG_VM86=y @@ -52,10 +54,6 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -67,7 +65,6 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -76,6 +73,8 @@ CONFIG_KMOD=y # Block layer # # CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_LSF=y # # IO Schedulers @@ -103,6 +102,7 @@ CONFIG_X86_NO_TSS=y CONFIG_X86_NO_IDT=y CONFIG_X86_L1_CACHE_BYTES=128 CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_INTERNODE_CACHE_BYTES=128 CONFIG_X86_GOOD_APIC=y CONFIG_MICROCODE=y # CONFIG_X86_MSR is not set @@ -115,7 +115,6 @@ CONFIG_MTRR=y CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set -CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -128,12 +127,13 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096 CONFIG_SWIOTLB=y CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set -CONFIG_PHYSICAL_START=0x100000 +CONFIG_PHYSICAL_START=0x200000 CONFIG_SECCOMP=y CONFIG_HZ_100=y # CONFIG_HZ_250 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=100 +# CONFIG_REORDER is not set CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_ISA_DMA_API=y @@ -157,6 +157,7 @@ CONFIG_ACPI_PROCESSOR=m CONFIG_ACPI_THERMAL=m CONFIG_ACPI_ASUS=m CONFIG_ACPI_IBM=m +# CONFIG_ACPI_IBM_DOCK is not set CONFIG_ACPI_TOSHIBA=m CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set @@ -164,6 +165,7 @@ CONFIG_ACPI_EC=y CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y # CONFIG_ACPI_CONTAINER is not set +CONFIG_ACPI_HOTPLUG_MEMORY=m # # CPU Frequency scaling @@ -178,9 +180,7 @@ CONFIG_PCI_DIRECT=y # CONFIG_PCI_MMCONFIG is not set CONFIG_XEN_PCIDEV_FRONTEND=y # CONFIG_XEN_PCIDEV_FE_DEBUG is not set -# CONFIG_UNORDERED_IO is not set # CONFIG_PCIEPORTBUS is not set -CONFIG_PCI_LEGACY_PROC=y # CONFIG_PCI_DEBUG is not set # @@ -231,6 +231,7 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set @@ -241,6 +242,8 @@ CONFIG_TCP_CONG_BIC=y # # CONFIG_IP_VS is not set # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set CONFIG_NETFILTER=y # CONFIG_NETFILTER_DEBUG is not set CONFIG_BRIDGE_NETFILTER=y @@ -265,6 +268,7 @@ CONFIG_IP_NF_FTP=m # CONFIG_IP_NF_TFTP is not set # CONFIG_IP_NF_AMANDA is not set # CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_H323 is not set # CONFIG_IP_NF_QUEUE is not set # @@ -290,6 +294,7 @@ CONFIG_IP_NF_FTP=m CONFIG_BRIDGE=y # CONFIG_VLAN_8021Q is not set # CONFIG_DECNET is not set +CONFIG_LLC=y # CONFIG_LLC2 is not set # CONFIG_IPX is not set # CONFIG_ATALK is not set @@ -525,7 +530,6 @@ CONFIG_SCSI_BUSLOGIC=y # CONFIG_SCSI_INIA100 is not set # CONFIG_SCSI_SYM53C8XX_2 is not set # CONFIG_SCSI_IPR is not set -# CONFIG_SCSI_QLOGIC_FC is not set # CONFIG_SCSI_QLOGIC_1280 is not set # CONFIG_SCSI_QLA_FC is not set # CONFIG_SCSI_LPFC is not set @@ -795,6 +799,8 @@ CONFIG_RTC=y CONFIG_AGP=m CONFIG_AGP_AMD64=m # CONFIG_AGP_INTEL is not set +CONFIG_AGP_SIS=m +CONFIG_AGP_VIA=m CONFIG_DRM=m CONFIG_DRM_TDFX=m CONFIG_DRM_R128=m @@ -841,19 +847,17 @@ CONFIG_DRM_SIS=m # # CONFIG_IBM_ASM is not set -# -# Multimedia Capabilities Port drivers -# - # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices # # CONFIG_DVB is not set +# CONFIG_USB_DABUSB is not set # # Graphics support @@ -865,6 +869,7 @@ CONFIG_DRM_SIS=m # Console display driver support # CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y # @@ -877,6 +882,7 @@ CONFIG_DUMMY_CONSOLE=y # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=y # CONFIG_USB_DEBUG is not set @@ -929,9 +935,7 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_ACECAD is not set # CONFIG_USB_KBTAB is not set # CONFIG_USB_POWERMATE is not set -# CONFIG_USB_MTOUCH is not set -# CONFIG_USB_ITMTOUCH is not set -# CONFIG_USB_EGALAX is not set +# CONFIG_USB_TOUCHSCREEN is not set # CONFIG_USB_YEALINK is not set # CONFIG_USB_XPAD is not set # CONFIG_USB_ATI_REMOTE is not set @@ -945,15 +949,6 @@ CONFIG_USB_HIDINPUT=y # CONFIG_USB_MDC800 is not set # CONFIG_USB_MICROTEK is not set -# -# USB Multimedia devices -# -# CONFIG_USB_DABUSB is not set - -# -# Video4Linux support is needed for USB Multimedia device support -# - # # USB Network Adapters # @@ -1003,6 +998,23 @@ CONFIG_USB_MON=y # # CONFIG_MMC is not set +# +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=y +CONFIG_LEDS_TRIGGER_IDE_DISK=y + # # InfiniBand support # @@ -1021,6 +1033,25 @@ CONFIG_INFINIBAND_SRP=y # # CONFIG_EDAC is not set +# +# Real Time Clock +# +CONFIG_RTC_LIB=m +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=m +CONFIG_RTC_INTF_PROC=m +CONFIG_RTC_INTF_DEV=m + +# +# RTC drivers +# +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_TEST=m + # # Firmware Drivers # @@ -1085,7 +1116,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -1207,6 +1237,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_RODATA is not set @@ -1251,24 +1282,26 @@ CONFIG_CRYPTO_CRC32C=m # Hardware crypto devices # CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030202 +CONFIG_XEN_INTERFACE_VERSION=0x00030203 # # XEN # CONFIG_XEN_PRIVILEGED_GUEST=y # CONFIG_XEN_UNPRIVILEGED_GUEST is not set +CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_XENBUS_DEV=y CONFIG_XEN_BACKEND=y -CONFIG_XEN_PCIDEV_BACKEND=y -# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set -CONFIG_XEN_PCIDEV_BACKEND_PASS=y -# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set -# CONFIG_XEN_PCIDEV_BE_DEBUG is not set CONFIG_XEN_BLKDEV_BACKEND=y CONFIG_XEN_BLKDEV_TAP=y CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y +CONFIG_XEN_PCIDEV_BACKEND=y +# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set +CONFIG_XEN_PCIDEV_BACKEND_PASS=y +# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set +# CONFIG_XEN_PCIDEV_BE_DEBUG is not set # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y @@ -1280,7 +1313,13 @@ CONFIG_XEN_COMPAT_030002_AND_LATER=y CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y +CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y +CONFIG_XEN_UTIL=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_DEVMEM=y +CONFIG_XEN_SKBUFF=y +CONFIG_XEN_REBOOT=y # # Library routines diff --git a/buildconfigs/linux-defconfig_xenU_x86_32 b/buildconfigs/linux-defconfig_xenU_x86_32 index b1cba934ef..c11e8dfb8e 100644 --- a/buildconfigs/linux-defconfig_xenU_x86_32 +++ b/buildconfigs/linux-defconfig_xenU_x86_32 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16.13-xenU -# Thu May 11 17:08:12 2006 +# Linux kernel version: 2.6.17-xenU +# Thu Jan 11 10:26:13 2007 # CONFIG_X86_32=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -9,6 +9,7 @@ CONFIG_X86=y CONFIG_MMU=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_DMI=y @@ -32,6 +33,7 @@ CONFIG_SYSCTL=y # CONFIG_AUDIT is not set # CONFIG_IKCONFIG is not set # CONFIG_CPUSETS is not set +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y CONFIG_VM86=y @@ -48,10 +50,6 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -63,7 +61,6 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y # CONFIG_MODVERSIONS is not set # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -73,6 +70,8 @@ CONFIG_STOP_MACHINE=y # Block layer # # CONFIG_LBD is not set +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_LSF=y # # IO Schedulers @@ -90,6 +89,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory" # # Processor type and features # +CONFIG_SMP=y # CONFIG_X86_PC is not set CONFIG_X86_XEN=y # CONFIG_X86_ELAN is not set @@ -137,9 +137,8 @@ CONFIG_X86_CMPXCHG64=y CONFIG_X86_GOOD_APIC=y CONFIG_X86_USE_PPRO_CHECKSUM=y CONFIG_X86_TSC=y -CONFIG_SMP=y -CONFIG_SMP_ALTERNATIVES=y CONFIG_NR_CPUS=8 +# CONFIG_SCHED_MC is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set @@ -158,10 +157,6 @@ CONFIG_SWIOTLB=y # CONFIG_NOHIGHMEM is not set CONFIG_HIGHMEM4G=y # CONFIG_HIGHMEM64G is not set -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_3G_OPT is not set -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_HIGHMEM=y CONFIG_SELECT_MEMORY_MODEL=y @@ -233,11 +228,14 @@ CONFIG_IP_PNP=y # CONFIG_INET_AH is not set # CONFIG_INET_ESP is not set # CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set # CONFIG_INET_TUNNEL is not set # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set CONFIG_TCP_CONG_BIC=y # CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set # CONFIG_NETFILTER is not set # @@ -561,14 +559,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # Misc devices # -# -# Multimedia Capabilities Port drivers -# - # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -585,6 +580,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Console display driver support # CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y # @@ -597,6 +593,7 @@ CONFIG_DUMMY_CONSOLE=y # # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -612,6 +609,19 @@ CONFIG_DUMMY_CONSOLE=y # # CONFIG_MMC is not set +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + # # InfiniBand support # @@ -621,6 +631,11 @@ CONFIG_DUMMY_CONSOLE=y # # CONFIG_EDAC is not set +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + # # File systems # @@ -679,7 +694,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -798,11 +812,13 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_EARLY_PRINTK=y # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_STACK_BACKTRACE_COLS=2 # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUG_RODATA is not set # CONFIG_4KSTACKS is not set @@ -848,13 +864,15 @@ CONFIG_CRYPTO_CRC32C=m # # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030202 +CONFIG_XEN_INTERFACE_VERSION=0x00030203 # # XEN # # CONFIG_XEN_PRIVILEGED_GUEST is not set CONFIG_XEN_UNPRIVILEGED_GUEST=y +CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_XENBUS_DEV=y # CONFIG_XEN_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y @@ -866,7 +884,14 @@ CONFIG_XEN_COMPAT_030002_AND_LATER=y CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y +CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y +CONFIG_XEN_UTIL=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_DEVMEM=y +CONFIG_XEN_SKBUFF=y +CONFIG_XEN_REBOOT=y +CONFIG_XEN_SMPBOOT=y # # Library routines diff --git a/buildconfigs/linux-defconfig_xenU_x86_64 b/buildconfigs/linux-defconfig_xenU_x86_64 index ce83a618b8..36ff0cb712 100644 --- a/buildconfigs/linux-defconfig_xenU_x86_64 +++ b/buildconfigs/linux-defconfig_xenU_x86_64 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16.13-xenU -# Thu May 11 17:17:57 2006 +# Linux kernel version: 2.6.17-xenU +# Thu Jan 11 10:17:30 2007 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -9,6 +9,7 @@ CONFIG_X86=y CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_MMU=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_X86_CMPXCHG=y CONFIG_EARLY_PRINTK=y @@ -39,6 +40,7 @@ CONFIG_AUDIT=y CONFIG_AUDITSYSCALL=y # CONFIG_IKCONFIG is not set # CONFIG_CPUSETS is not set +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y CONFIG_VM86=y @@ -55,10 +57,6 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -70,7 +68,6 @@ CONFIG_BASE_SMALL=0 CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_MODULE_FORCE_UNLOAD is not set -CONFIG_OBSOLETE_MODPARM=y CONFIG_MODVERSIONS=y # CONFIG_MODULE_SRCVERSION_ALL is not set CONFIG_KMOD=y @@ -80,6 +77,8 @@ CONFIG_STOP_MACHINE=y # Block layer # CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_LSF=y # # IO Schedulers @@ -107,17 +106,18 @@ CONFIG_X86_NO_TSS=y CONFIG_X86_NO_IDT=y CONFIG_X86_L1_CACHE_BYTES=128 CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_INTERNODE_CACHE_BYTES=128 CONFIG_X86_GOOD_APIC=y # CONFIG_MICROCODE is not set # CONFIG_X86_MSR is not set CONFIG_X86_CPUID=y CONFIG_X86_XEN_GENAPIC=y CONFIG_SMP=y +# CONFIG_SCHED_MC is not set CONFIG_PREEMPT_NONE=y # CONFIG_PREEMPT_VOLUNTARY is not set # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -131,12 +131,13 @@ CONFIG_NR_CPUS=8 CONFIG_HOTPLUG_CPU=y CONFIG_SWIOTLB=y # CONFIG_CRASH_DUMP is not set -CONFIG_PHYSICAL_START=0x100000 +CONFIG_PHYSICAL_START=0x200000 CONFIG_SECCOMP=y CONFIG_HZ_100=y # CONFIG_HZ_250 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=100 +# CONFIG_REORDER is not set CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_ISA_DMA_API=y @@ -146,7 +147,6 @@ CONFIG_GENERIC_PENDING_IRQ=y # Bus options (PCI etc.) # # CONFIG_PCI is not set -# CONFIG_UNORDERED_IO is not set # # PCCARD (PCMCIA/CardBus) support @@ -208,6 +208,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m # CONFIG_INET_DIAG is not set # CONFIG_TCP_CONG_ADVANCED is not set @@ -248,9 +249,11 @@ CONFIG_IP_VS_NQ=m CONFIG_IP_VS_FTP=m CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m +CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y @@ -277,6 +280,7 @@ CONFIG_IP_NF_IRC=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m # CONFIG_IP_NF_PPTP is not set +# CONFIG_IP_NF_H323 is not set CONFIG_IP_NF_QUEUE=m # @@ -435,6 +439,7 @@ CONFIG_DONGLE=y CONFIG_ESI_DONGLE=m CONFIG_ACTISYS_DONGLE=m CONFIG_TEKRAM_DONGLE=m +# CONFIG_TOIM3232_DONGLE is not set CONFIG_LITELINK_DONGLE=m CONFIG_MA600_DONGLE=m CONFIG_GIRBIL_DONGLE=m @@ -476,6 +481,7 @@ CONFIG_BT_HCIUART_H4=y CONFIG_BT_HCIUART_BCSP=y CONFIG_BT_HCIVHCI=m # CONFIG_IEEE80211 is not set +CONFIG_WIRELESS_EXT=y # # Device Drivers @@ -578,6 +584,7 @@ CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID5=m +# CONFIG_MD_RAID5_RESHAPE is not set CONFIG_MD_RAID6=m CONFIG_MD_MULTIPATH=m # CONFIG_MD_FAULTY is not set @@ -637,12 +644,12 @@ CONFIG_MII=m # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y +# CONFIG_NET_WIRELESS_RTNETLINK is not set # # Obsolete Wireless cards support (pre-802.11) # # CONFIG_STRIP is not set -CONFIG_ATMEL=m # CONFIG_HOSTAP is not set # @@ -799,14 +806,11 @@ CONFIG_LEGACY_PTY_COUNT=256 # Misc devices # -# -# Multimedia Capabilities Port drivers -# - # # Multimedia devices # # CONFIG_VIDEO_DEV is not set +CONFIG_VIDEO_V4L2=y # # Digital Video Broadcasting Devices @@ -823,6 +827,7 @@ CONFIG_LEGACY_PTY_COUNT=256 # Console display driver support # CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y # @@ -835,6 +840,7 @@ CONFIG_DUMMY_CONSOLE=y # # CONFIG_USB_ARCH_HAS_HCD is not set # CONFIG_USB_ARCH_HAS_OHCI is not set +# CONFIG_USB_ARCH_HAS_EHCI is not set # # NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' @@ -850,6 +856,19 @@ CONFIG_DUMMY_CONSOLE=y # # CONFIG_MMC is not set +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + # # InfiniBand support # @@ -859,6 +878,11 @@ CONFIG_DUMMY_CONSOLE=y # # CONFIG_EDAC is not set +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + # # Firmware Drivers # @@ -940,7 +964,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -# CONFIG_RELAYFS_FS is not set # CONFIG_CONFIGFS_FS is not set # @@ -1091,6 +1114,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set CONFIG_FRAME_POINTER=y +# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_RODATA is not set @@ -1135,13 +1159,15 @@ CONFIG_CRYPTO_CRC32C=m # Hardware crypto devices # CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030202 +CONFIG_XEN_INTERFACE_VERSION=0x00030203 # # XEN # # CONFIG_XEN_PRIVILEGED_GUEST is not set CONFIG_XEN_UNPRIVILEGED_GUEST=y +CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_XENBUS_DEV=y # CONFIG_XEN_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y @@ -1153,7 +1179,14 @@ CONFIG_XEN_COMPAT_030002_AND_LATER=y CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y +CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y +CONFIG_XEN_UTIL=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_DEVMEM=y +CONFIG_XEN_SKBUFF=y +CONFIG_XEN_REBOOT=y +CONFIG_XEN_SMPBOOT=y # # Library routines diff --git a/buildconfigs/linux-defconfig_xen_x86_32 b/buildconfigs/linux-defconfig_xen_x86_32 index 993da59152..91cf5527d7 100644 --- a/buildconfigs/linux-defconfig_xen_x86_32 +++ b/buildconfigs/linux-defconfig_xen_x86_32 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16.13-xen -# Thu May 11 17:11:00 2006 +# Linux kernel version: 2.6.17-xen +# Thu Jan 11 10:45:59 2007 # CONFIG_X86_32=y CONFIG_SEMAPHORE_SLEEPERS=y @@ -9,6 +9,7 @@ CONFIG_X86=y CONFIG_MMU=y CONFIG_GENERIC_ISA_DMA=y CONFIG_GENERIC_IOMAP=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_ARCH_MAY_HAVE_PC_FDC=y CONFIG_DMI=y @@ -35,6 +36,7 @@ CONFIG_AUDITSYSCALL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CPUSETS=y +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y CONFIG_VM86=y @@ -51,10 +53,6 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -67,7 +65,6 @@ CONFIG_OBSOLETE_INTERMODULE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_KMOD=y @@ -77,6 +74,8 @@ CONFIG_STOP_MACHINE=y # Block layer # CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_LSF=y # # IO Schedulers @@ -94,6 +93,7 @@ CONFIG_DEFAULT_IOSCHED="cfq" # # Processor type and features # +CONFIG_SMP=y # CONFIG_X86_PC is not set CONFIG_X86_XEN=y # CONFIG_X86_ELAN is not set @@ -142,9 +142,8 @@ CONFIG_X86_GOOD_APIC=y CONFIG_X86_INTEL_USERCOPY=y CONFIG_X86_USE_PPRO_CHECKSUM=y CONFIG_X86_TSC=y -CONFIG_SMP=y -CONFIG_SMP_ALTERNATIVES=y CONFIG_NR_CPUS=32 +# CONFIG_SCHED_MC is not set # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set @@ -166,10 +165,6 @@ CONFIG_DCDBAS=m # CONFIG_NOHIGHMEM is not set CONFIG_HIGHMEM4G=y # CONFIG_HIGHMEM64G is not set -CONFIG_VMSPLIT_3G=y -# CONFIG_VMSPLIT_3G_OPT is not set -# CONFIG_VMSPLIT_2G is not set -# CONFIG_VMSPLIT_1G is not set CONFIG_PAGE_OFFSET=0xC0000000 CONFIG_HIGHMEM=y CONFIG_SELECT_MEMORY_MODEL=y @@ -184,10 +179,10 @@ CONFIG_MTRR=y CONFIG_REGPARM=y CONFIG_SECCOMP=y CONFIG_HZ_100=y -CONFIG_KEXEC=y # CONFIG_HZ_250 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=100 +CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set CONFIG_PHYSICAL_START=0x100000 CONFIG_HOTPLUG_CPU=y @@ -212,6 +207,7 @@ CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_THERMAL=m CONFIG_ACPI_ASUS=m CONFIG_ACPI_IBM=m +# CONFIG_ACPI_IBM_DOCK is not set CONFIG_ACPI_TOSHIBA=m CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set @@ -239,7 +235,6 @@ CONFIG_PCI_MMCONFIG=y CONFIG_XEN_PCIDEV_FRONTEND=y # CONFIG_XEN_PCIDEV_FE_DEBUG is not set # CONFIG_PCIEPORTBUS is not set -# CONFIG_PCI_LEGACY_PROC is not set # CONFIG_PCI_DEBUG is not set CONFIG_ISA_DMA_API=y CONFIG_SCx200=m @@ -325,6 +320,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m @@ -377,9 +373,11 @@ CONFIG_IP_VS_NQ=m CONFIG_IP_VS_FTP=m CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m +CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y @@ -403,11 +401,14 @@ CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HELPER=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m CONFIG_NETFILTER_XT_MATCH_REALM=m @@ -431,20 +432,19 @@ CONFIG_IP_NF_NETBIOS_NS=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m CONFIG_IP_NF_PPTP=m +CONFIG_IP_NF_H323=m CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MULTIPORT=m CONFIG_IP_NF_MATCH_TOS=m CONFIG_IP_NF_MATCH_RECENT=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_MATCH_OWNER=m CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_HASHLIMIT=m -CONFIG_IP_NF_MATCH_POLICY=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m @@ -462,6 +462,7 @@ CONFIG_IP_NF_NAT_FTP=m CONFIG_IP_NF_NAT_TFTP=m CONFIG_IP_NF_NAT_AMANDA=m CONFIG_IP_NF_NAT_PPTP=m +CONFIG_IP_NF_NAT_H323=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_TOS=m CONFIG_IP_NF_TARGET_ECN=m @@ -482,12 +483,10 @@ CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_FRAG=m CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_MULTIPORT=m CONFIG_IP6_NF_MATCH_OWNER=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_POLICY=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_TARGET_REJECT=m @@ -529,10 +528,12 @@ CONFIG_BRIDGE_EBT_ULOG=m # CONFIG_IP_DCCP=m CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y # # DCCP CCIDs Configuration (EXPERIMENTAL) # +CONFIG_IP_DCCP_CCID2=m CONFIG_IP_DCCP_CCID3=m CONFIG_IP_DCCP_TFRC_LIB=m @@ -540,7 +541,6 @@ CONFIG_IP_DCCP_TFRC_LIB=m # DCCP Kernel Hacking # # CONFIG_IP_DCCP_DEBUG is not set -# CONFIG_IP_DCCP_UNLOAD_HACK is not set # # SCTP Configuration (EXPERIMENTAL) @@ -694,6 +694,7 @@ CONFIG_DONGLE=y CONFIG_ESI_DONGLE=m CONFIG_ACTISYS_DONGLE=m CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m CONFIG_LITELINK_DONGLE=m CONFIG_MA600_DONGLE=m CONFIG_GIRBIL_DONGLE=m @@ -753,6 +754,9 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_WIRELESS_EXT=y # # Device Drivers @@ -820,7 +824,6 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_OTP is not set CONFIG_MTD_CFI_INTELEXT=m CONFIG_MTD_CFI_AMDSTD=m -CONFIG_MTD_CFI_AMDSTD_RETRY=0 CONFIG_MTD_CFI_STAA=m CONFIG_MTD_CFI_UTIL=m CONFIG_MTD_RAM=m @@ -865,7 +868,6 @@ CONFIG_MTD_PHRAM=m CONFIG_MTD_MTDRAM=m CONFIG_MTDRAM_TOTAL_SIZE=4096 CONFIG_MTDRAM_ERASE_SIZE=128 -CONFIG_MTD_BLKMTD=m CONFIG_MTD_BLOCK2MTD=m # @@ -1102,6 +1104,7 @@ CONFIG_AIC79XX_DEBUG_ENABLE=y CONFIG_AIC79XX_DEBUG_MASK=0 CONFIG_AIC79XX_REG_PRETTY_PRINT=y CONFIG_SCSI_DPT_I2O=m +CONFIG_SCSI_ADVANSYS=m CONFIG_MEGARAID_NEWGEN=y CONFIG_MEGARAID_MM=m CONFIG_MEGARAID_MAILBOX=m @@ -1144,12 +1147,10 @@ CONFIG_SCSI_SYM53C8XX_2=m CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +CONFIG_SCSI_SYM53C8XX_MMIO=y CONFIG_SCSI_IPR=m CONFIG_SCSI_IPR_TRACE=y CONFIG_SCSI_IPR_DUMP=y -CONFIG_SCSI_QLOGIC_FC=m -CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y CONFIG_SCSI_QLOGIC_1280=m CONFIG_SCSI_QLA_FC=m # CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set @@ -1178,6 +1179,7 @@ CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID5=m +CONFIG_MD_RAID5_RESHAPE=y CONFIG_MD_RAID6=m CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m @@ -1236,7 +1238,6 @@ CONFIG_IEEE1394_RAWIO=m CONFIG_I2O=m CONFIG_I2O_LCT_NOTIFY_ON_CHANGES=y CONFIG_I2O_EXT_ADAPTEC=y -CONFIG_I2O_EXT_ADAPTEC_DMA64=y CONFIG_I2O_CONFIG=m CONFIG_I2O_CONFIG_OLD_IOCTL=y CONFIG_I2O_BUS=m @@ -1388,6 +1389,7 @@ CONFIG_ABYSS=m # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y +CONFIG_NET_WIRELESS_RTNETLINK=y # # Obsolete Wireless cards support (pre-802.11) @@ -1408,6 +1410,8 @@ CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y # CONFIG_IPW2100_DEBUG is not set CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW_QOS=y # CONFIG_IPW2200_DEBUG is not set CONFIG_AIRO=m CONFIG_HERMES=m @@ -1437,6 +1441,13 @@ CONFIG_HOSTAP_FIRMWARE_NVRAM=y CONFIG_HOSTAP_PLX=m CONFIG_HOSTAP_PCI=m CONFIG_HOSTAP_CS=m +CONFIG_BCM43XX=m +CONFIG_BCM43XX_DEBUG=y +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_PIO=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +# CONFIG_BCM43XX_PIO_MODE is not set CONFIG_NET_WIRELESS=y # @@ -1636,6 +1647,15 @@ CONFIG_HISAX_HDLC=y # Active cards # +# +# Siemens Gigaset +# +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_DEBUG is not set +# CONFIG_GIGASET_UNDOCREQ is not set + # # CAPI subsystem # @@ -1777,8 +1797,9 @@ CONFIG_HW_CONSOLE=y # Serial drivers # CONFIG_SERIAL_8250=m +CONFIG_SERIAL_8250_PCI=m +CONFIG_SERIAL_8250_PNP=m # CONFIG_SERIAL_8250_CS is not set -# CONFIG_SERIAL_8250_ACPI is not set CONFIG_SERIAL_8250_NR_UARTS=4 CONFIG_SERIAL_8250_RUNTIME_UARTS=4 # CONFIG_SERIAL_8250_EXTENDED is not set @@ -1963,9 +1984,7 @@ CONFIG_SENSORS_EEPROM=m CONFIG_SENSORS_PCF8574=m CONFIG_SENSORS_PCA9539=m CONFIG_SENSORS_PCF8591=m -CONFIG_SENSORS_RTC8564=m CONFIG_SENSORS_MAX6875=m -CONFIG_RTC_X1205_I2C=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -1992,13 +2011,21 @@ CONFIG_SPI_BUTTERFLY=m # Dallas's 1-wire bus # CONFIG_W1=m -CONFIG_W1_MATROX=m -CONFIG_W1_DS9490=m -CONFIG_W1_DS9490_BRIDGE=m -CONFIG_W1_THERM=m -CONFIG_W1_SMEM=m -CONFIG_W1_DS2433=m -CONFIG_W1_DS2433_CRC=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS9490=m +CONFIG_W1_MASTER_DS9490_BRIDGE=m +CONFIG_W1_MASTER_DS2482=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2433=m # # Hardware Monitoring support @@ -2049,23 +2076,23 @@ CONFIG_SENSORS_HDAPS=m # CONFIG_IBM_ASM=m -# -# Multimedia Capabilities Port drivers -# - # # Multimedia devices # CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m # -# Video For Linux +# Video Capture Adapters # # -# Video Adapters +# Video Capture Adapters # # CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_VIVI=m CONFIG_VIDEO_BT848=m CONFIG_VIDEO_BT848_DVB=y CONFIG_VIDEO_SAA6588=m @@ -2075,6 +2102,7 @@ CONFIG_VIDEO_W9966=m CONFIG_VIDEO_CPIA=m CONFIG_VIDEO_CPIA_PP=m CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m CONFIG_VIDEO_SAA5246A=m CONFIG_VIDEO_SAA5249=m CONFIG_TUNER_3036=m @@ -2095,15 +2123,43 @@ CONFIG_VIDEO_MXB=m CONFIG_VIDEO_DPC=m CONFIG_VIDEO_HEXIUM_ORION=m CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_CX88_VP3054=m CONFIG_VIDEO_CX88=m CONFIG_VIDEO_CX88_ALSA=m CONFIG_VIDEO_CX88_DVB=m CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y -CONFIG_VIDEO_CX88_VP3054=m -CONFIG_VIDEO_EM28XX=m CONFIG_VIDEO_OVCAMCHIP=m -CONFIG_VIDEO_AUDIO_DECODER=m -CONFIG_VIDEO_DECODER=m + +# +# Encoders and Decoders +# +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m + +# +# V4L USB devices +# +CONFIG_VIDEO_EM28XX=m +CONFIG_USB_DSBR=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_ET61X251=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_W9968CF=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m # # Radio Adapters @@ -2197,6 +2253,7 @@ CONFIG_DVB_L64781=m CONFIG_DVB_TDA1004X=m CONFIG_DVB_NXT6000=m CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m CONFIG_DVB_DIB3000MB=m CONFIG_DVB_DIB3000MC=m @@ -2224,6 +2281,7 @@ CONFIG_VIDEO_BUF_DVB=m CONFIG_VIDEO_BTCX=m CONFIG_VIDEO_IR=m CONFIG_VIDEO_TVEEPROM=m +CONFIG_USB_DABUSB=m # # Graphics support @@ -2233,6 +2291,7 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_MACMODES is not set +CONFIG_FB_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y CONFIG_FB_CIRRUS=m @@ -2263,7 +2322,6 @@ CONFIG_FB_MATROX_MYSTIQUE=y CONFIG_FB_MATROX_G=y # CONFIG_FB_MATROX_I2C is not set CONFIG_FB_MATROX_MULTIHEAD=y -# CONFIG_FB_RADEON_OLD is not set CONFIG_FB_RADEON=m CONFIG_FB_RADEON_I2C=y # CONFIG_FB_RADEON_DEBUG is not set @@ -2287,6 +2345,7 @@ CONFIG_FB_CYBLA=m CONFIG_FB_TRIDENT=m # CONFIG_FB_TRIDENT_ACCEL is not set CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m CONFIG_FB_GEODE_GX1=m CONFIG_FB_VIRTUAL=m @@ -2294,6 +2353,7 @@ CONFIG_FB_VIRTUAL=m # Console display driver support # CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=m # CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set @@ -2329,11 +2389,13 @@ CONFIG_SND_SEQ_DUMMY=m CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_RTCTIMER=m CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y # CONFIG_SND_DYNAMIC_MINORS is not set CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set @@ -2355,6 +2417,7 @@ CONFIG_SND_MPU401=m # PCI devices # CONFIG_SND_AD1889=m +CONFIG_SND_ALS300=m CONFIG_SND_ALS4000=m CONFIG_SND_ALI5451=m CONFIG_SND_ATIIXP=m @@ -2378,7 +2441,6 @@ CONFIG_SND_ENS1371=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_FM801=m -# CONFIG_SND_FM801_TEA575X_BOOL is not set CONFIG_SND_FM801_TEA575X=m CONFIG_SND_HDA_INTEL=m CONFIG_SND_HDSP=m @@ -2392,6 +2454,7 @@ CONFIG_SND_MAESTRO3=m CONFIG_SND_MIXART=m CONFIG_SND_NM256=m CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m CONFIG_SND_RME32=m CONFIG_SND_RME96=m CONFIG_SND_RME9652=m @@ -2411,17 +2474,24 @@ CONFIG_SND_USB_USX2Y=m # # PCMCIA devices # +CONFIG_SND_VXPOCKET=m +CONFIG_SND_PDAUDIOCF=m # # Open Sound System # CONFIG_SOUND_PRIME=m -# CONFIG_OBSOLETE_OSS_DRIVER is not set +CONFIG_SOUND_BT878=m +CONFIG_SOUND_EMU10K1=m +# CONFIG_MIDI_EMU10K1 is not set CONFIG_SOUND_FUSION=m +CONFIG_SOUND_ES1371=m CONFIG_SOUND_ICH=m CONFIG_SOUND_TRIDENT=m # CONFIG_SOUND_MSNDCLAS is not set # CONFIG_SOUND_MSNDPIN is not set +CONFIG_SOUND_VIA82CXXX=m +# CONFIG_MIDI_VIA82CXXX is not set # CONFIG_SOUND_OSS is not set CONFIG_SOUND_TVMIXER=m @@ -2430,6 +2500,7 @@ CONFIG_SOUND_TVMIXER=m # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=m # CONFIG_USB_DEBUG is not set @@ -2459,7 +2530,6 @@ CONFIG_USB_SL811_CS=m # # USB Device Class drivers # -# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m @@ -2505,9 +2575,11 @@ CONFIG_USB_WACOM=m CONFIG_USB_ACECAD=m CONFIG_USB_KBTAB=m CONFIG_USB_POWERMATE=m -CONFIG_USB_MTOUCH=m -CONFIG_USB_ITMTOUCH=m -CONFIG_USB_EGALAX=m +CONFIG_USB_TOUCHSCREEN=m +CONFIG_USB_TOUCHSCREEN_EGALAX=y +CONFIG_USB_TOUCHSCREEN_PANJIT=y +CONFIG_USB_TOUCHSCREEN_3M=y +CONFIG_USB_TOUCHSCREEN_ITM=y CONFIG_USB_YEALINK=m CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m @@ -2521,22 +2593,6 @@ CONFIG_USB_APPLETOUCH=m CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m -# -# USB Multimedia devices -# -CONFIG_USB_DABUSB=m -CONFIG_USB_VICAM=m -CONFIG_USB_DSBR=m -CONFIG_USB_ET61X251=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_OV511=m -CONFIG_USB_SE401=m -CONFIG_USB_SN9C102=m -CONFIG_USB_STV680=m -CONFIG_USB_W9968CF=m -CONFIG_USB_PWC=m - # # USB Network Adapters # @@ -2573,6 +2629,7 @@ CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_AIRPRIME=m CONFIG_USB_SERIAL_ANYDATA=m +CONFIG_USB_SERIAL_ARK3116=m CONFIG_USB_SERIAL_BELKIN=m CONFIG_USB_SERIAL_WHITEHEAT=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m @@ -2580,6 +2637,7 @@ CONFIG_USB_SERIAL_CP2101=m CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m CONFIG_USB_SERIAL_VISOR=m CONFIG_USB_SERIAL_IPAQ=m CONFIG_USB_SERIAL_IR=m @@ -2604,6 +2662,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y CONFIG_USB_SERIAL_KLSI=m CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_NAVMAN=m CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_SERIAL_HP4X=m CONFIG_USB_SERIAL_SAFE=m @@ -2655,6 +2714,7 @@ CONFIG_USB_NET2280=m # CONFIG_USB_GADGET_GOKU is not set # CONFIG_USB_GADGET_LH7A40X is not set # CONFIG_USB_GADGET_OMAP is not set +# CONFIG_USB_GADGET_AT91 is not set # CONFIG_USB_GADGET_DUMMY_HCD is not set CONFIG_USB_GADGET_DUALSPEED=y CONFIG_USB_ZERO=m @@ -2671,8 +2731,26 @@ CONFIG_USB_G_SERIAL=m CONFIG_MMC=m # CONFIG_MMC_DEBUG is not set CONFIG_MMC_BLOCK=m +CONFIG_MMC_SDHCI=m CONFIG_MMC_WBSD=m +# +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y + # # InfiniBand support # @@ -2680,9 +2758,10 @@ CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_MTHCA=m -# CONFIG_INFINIBAND_MTHCA_DEBUG is not set +CONFIG_INFINIBAND_MTHCA_DEBUG=y CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set CONFIG_INFINIBAND_SRP=m # @@ -2703,6 +2782,29 @@ CONFIG_EDAC_I82860=m CONFIG_EDAC_R82600=m CONFIG_EDAC_POLL=y +# +# Real Time Clock +# +CONFIG_RTC_LIB=m +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=m +CONFIG_RTC_INTF_PROC=m +CONFIG_RTC_INTF_DEV=m + +# +# RTC drivers +# +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_TEST=m + # # File systems # @@ -2777,12 +2879,10 @@ CONFIG_NTFS_FS=m # CONFIG_PROC_FS=y CONFIG_PROC_KCORE=y -# CONFIG_PROC_VMCORE is not set CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -CONFIG_RELAYFS_FS=m CONFIG_CONFIGFS_FS=m # @@ -2954,11 +3054,13 @@ CONFIG_DEBUG_BUGVERBOSE=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set # CONFIG_FRAME_POINTER is not set +# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set CONFIG_EARLY_PRINTK=y CONFIG_DEBUG_STACKOVERFLOW=y # CONFIG_DEBUG_STACK_USAGE is not set +CONFIG_STACK_BACKTRACE_COLS=2 # CONFIG_DEBUG_PAGEALLOC is not set # CONFIG_DEBUG_RODATA is not set # CONFIG_4KSTACKS is not set @@ -3013,24 +3115,26 @@ CONFIG_CRYPTO_TEST=m # # CONFIG_CRYPTO_DEV_PADLOCK is not set CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030202 +CONFIG_XEN_INTERFACE_VERSION=0x00030203 # # XEN # CONFIG_XEN_PRIVILEGED_GUEST=y # CONFIG_XEN_UNPRIVILEGED_GUEST is not set +CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_XENBUS_DEV=y CONFIG_XEN_BACKEND=y -CONFIG_XEN_PCIDEV_BACKEND=m -CONFIG_XEN_PCIDEV_BACKEND_VPCI=y -# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set -# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set -# CONFIG_XEN_PCIDEV_BE_DEBUG is not set CONFIG_XEN_BLKDEV_BACKEND=y CONFIG_XEN_BLKDEV_TAP=y CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y +CONFIG_XEN_PCIDEV_BACKEND=m +CONFIG_XEN_PCIDEV_BACKEND_VPCI=y +# CONFIG_XEN_PCIDEV_BACKEND_PASS is not set +# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set +# CONFIG_XEN_PCIDEV_BE_DEBUG is not set # CONFIG_XEN_TPMDEV_BACKEND is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y @@ -3044,7 +3148,14 @@ CONFIG_XEN_COMPAT_030002_AND_LATER=y CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y +CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y +CONFIG_XEN_UTIL=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_DEVMEM=y +CONFIG_XEN_SKBUFF=y +CONFIG_XEN_REBOOT=y +CONFIG_XEN_SMPBOOT=y # # Library routines diff --git a/buildconfigs/linux-defconfig_xen_x86_64 b/buildconfigs/linux-defconfig_xen_x86_64 index ebee7ab056..645460a8ef 100644 --- a/buildconfigs/linux-defconfig_xen_x86_64 +++ b/buildconfigs/linux-defconfig_xen_x86_64 @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.16.13-xen -# Thu May 11 17:18:58 2006 +# Linux kernel version: 2.6.17-xen +# Thu Jan 11 10:10:22 2007 # CONFIG_X86_64=y CONFIG_64BIT=y @@ -9,6 +9,7 @@ CONFIG_X86=y CONFIG_SEMAPHORE_SLEEPERS=y CONFIG_MMU=y CONFIG_RWSEM_GENERIC_SPINLOCK=y +CONFIG_GENERIC_HWEIGHT=y CONFIG_GENERIC_CALIBRATE_DELAY=y CONFIG_X86_CMPXCHG=y CONFIG_EARLY_PRINTK=y @@ -40,6 +41,7 @@ CONFIG_AUDITSYSCALL=y CONFIG_IKCONFIG=y CONFIG_IKCONFIG_PROC=y CONFIG_CPUSETS=y +# CONFIG_RELAY is not set CONFIG_INITRAMFS_SOURCE="" CONFIG_UID16=y CONFIG_VM86=y @@ -56,10 +58,6 @@ CONFIG_BASE_FULL=y CONFIG_FUTEX=y CONFIG_EPOLL=y CONFIG_SHMEM=y -CONFIG_CC_ALIGN_FUNCTIONS=0 -CONFIG_CC_ALIGN_LABELS=0 -CONFIG_CC_ALIGN_LOOPS=0 -CONFIG_CC_ALIGN_JUMPS=0 CONFIG_SLAB=y # CONFIG_TINY_SHMEM is not set CONFIG_BASE_SMALL=0 @@ -72,7 +70,6 @@ CONFIG_OBSOLETE_INTERMODULE=m CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y CONFIG_MODULE_FORCE_UNLOAD=y -CONFIG_OBSOLETE_MODPARM=y CONFIG_MODVERSIONS=y CONFIG_MODULE_SRCVERSION_ALL=y CONFIG_KMOD=y @@ -82,6 +79,8 @@ CONFIG_STOP_MACHINE=y # Block layer # CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +CONFIG_LSF=y # # IO Schedulers @@ -109,6 +108,7 @@ CONFIG_X86_NO_TSS=y CONFIG_X86_NO_IDT=y CONFIG_X86_L1_CACHE_BYTES=128 CONFIG_X86_L1_CACHE_SHIFT=7 +CONFIG_X86_INTERNODE_CACHE_BYTES=128 CONFIG_X86_GOOD_APIC=y CONFIG_MICROCODE=y CONFIG_X86_MSR=m @@ -118,11 +118,11 @@ CONFIG_X86_XEN_GENAPIC=y CONFIG_X86_LOCAL_APIC=y CONFIG_MTRR=y CONFIG_SMP=y +# CONFIG_SCHED_MC is not set # CONFIG_PREEMPT_NONE is not set CONFIG_PREEMPT_VOLUNTARY=y # CONFIG_PREEMPT is not set CONFIG_PREEMPT_BKL=y -CONFIG_ARCH_SPARSEMEM_ENABLE=y CONFIG_ARCH_FLATMEM_ENABLE=y CONFIG_SELECT_MEMORY_MODEL=y CONFIG_FLATMEM_MANUAL=y @@ -135,14 +135,15 @@ CONFIG_SPLIT_PTLOCK_CPUS=4096 CONFIG_NR_CPUS=32 CONFIG_HOTPLUG_CPU=y CONFIG_SWIOTLB=y +CONFIG_KEXEC=y # CONFIG_CRASH_DUMP is not set -CONFIG_PHYSICAL_START=0x100000 +CONFIG_PHYSICAL_START=0x200000 CONFIG_SECCOMP=y CONFIG_HZ_100=y -CONFIG_KEXEC=y # CONFIG_HZ_250 is not set # CONFIG_HZ_1000 is not set CONFIG_HZ=100 +# CONFIG_REORDER is not set CONFIG_GENERIC_HARDIRQS=y CONFIG_GENERIC_IRQ_PROBE=y CONFIG_ISA_DMA_API=y @@ -168,6 +169,7 @@ CONFIG_ACPI_HOTPLUG_CPU=y CONFIG_ACPI_THERMAL=m CONFIG_ACPI_ASUS=m CONFIG_ACPI_IBM=m +# CONFIG_ACPI_IBM_DOCK is not set CONFIG_ACPI_TOSHIBA=m CONFIG_ACPI_BLACKLIST_YEAR=0 # CONFIG_ACPI_DEBUG is not set @@ -175,6 +177,7 @@ CONFIG_ACPI_EC=y CONFIG_ACPI_POWER=y CONFIG_ACPI_SYSTEM=y CONFIG_ACPI_CONTAINER=m +CONFIG_ACPI_HOTPLUG_MEMORY=m # # CPU Frequency scaling @@ -189,9 +192,7 @@ CONFIG_PCI_DIRECT=y # CONFIG_PCI_MMCONFIG is not set CONFIG_XEN_PCIDEV_FRONTEND=y # CONFIG_XEN_PCIDEV_FE_DEBUG is not set -# CONFIG_UNORDERED_IO is not set # CONFIG_PCIEPORTBUS is not set -# CONFIG_PCI_LEGACY_PROC is not set # CONFIG_PCI_DEBUG is not set # @@ -277,6 +278,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m +CONFIG_INET_XFRM_TUNNEL=m CONFIG_INET_TUNNEL=m CONFIG_INET_DIAG=m CONFIG_INET_TCP_DIAG=m @@ -329,9 +331,11 @@ CONFIG_IP_VS_NQ=m CONFIG_IP_VS_FTP=m CONFIG_IPV6=m CONFIG_IPV6_PRIVACY=y +# CONFIG_IPV6_ROUTER_PREF is not set CONFIG_INET6_AH=m CONFIG_INET6_ESP=m CONFIG_INET6_IPCOMP=m +CONFIG_INET6_XFRM_TUNNEL=m CONFIG_INET6_TUNNEL=m CONFIG_IPV6_TUNNEL=m CONFIG_NETFILTER=y @@ -355,11 +359,14 @@ CONFIG_NETFILTER_XT_MATCH_CONNBYTES=m CONFIG_NETFILTER_XT_MATCH_CONNMARK=m CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m CONFIG_NETFILTER_XT_MATCH_DCCP=m +CONFIG_NETFILTER_XT_MATCH_ESP=m CONFIG_NETFILTER_XT_MATCH_HELPER=m CONFIG_NETFILTER_XT_MATCH_LENGTH=m CONFIG_NETFILTER_XT_MATCH_LIMIT=m CONFIG_NETFILTER_XT_MATCH_MAC=m CONFIG_NETFILTER_XT_MATCH_MARK=m +CONFIG_NETFILTER_XT_MATCH_POLICY=m +CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m CONFIG_NETFILTER_XT_MATCH_PHYSDEV=m CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m CONFIG_NETFILTER_XT_MATCH_REALM=m @@ -383,20 +390,19 @@ CONFIG_IP_NF_NETBIOS_NS=m CONFIG_IP_NF_TFTP=m CONFIG_IP_NF_AMANDA=m CONFIG_IP_NF_PPTP=m +CONFIG_IP_NF_H323=m CONFIG_IP_NF_QUEUE=m CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_MATCH_IPRANGE=m -CONFIG_IP_NF_MATCH_MULTIPORT=m CONFIG_IP_NF_MATCH_TOS=m CONFIG_IP_NF_MATCH_RECENT=m CONFIG_IP_NF_MATCH_ECN=m CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m +CONFIG_IP_NF_MATCH_AH=m CONFIG_IP_NF_MATCH_TTL=m CONFIG_IP_NF_MATCH_OWNER=m CONFIG_IP_NF_MATCH_ADDRTYPE=m CONFIG_IP_NF_MATCH_HASHLIMIT=m -CONFIG_IP_NF_MATCH_POLICY=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_TARGET_REJECT=m CONFIG_IP_NF_TARGET_LOG=m @@ -414,6 +420,7 @@ CONFIG_IP_NF_NAT_FTP=m CONFIG_IP_NF_NAT_TFTP=m CONFIG_IP_NF_NAT_AMANDA=m CONFIG_IP_NF_NAT_PPTP=m +CONFIG_IP_NF_NAT_H323=m CONFIG_IP_NF_MANGLE=m CONFIG_IP_NF_TARGET_TOS=m CONFIG_IP_NF_TARGET_ECN=m @@ -434,12 +441,10 @@ CONFIG_IP6_NF_MATCH_RT=m CONFIG_IP6_NF_MATCH_OPTS=m CONFIG_IP6_NF_MATCH_FRAG=m CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_MULTIPORT=m CONFIG_IP6_NF_MATCH_OWNER=m CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AHESP=m +CONFIG_IP6_NF_MATCH_AH=m CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_MATCH_POLICY=m CONFIG_IP6_NF_FILTER=m CONFIG_IP6_NF_TARGET_LOG=m CONFIG_IP6_NF_TARGET_REJECT=m @@ -481,10 +486,12 @@ CONFIG_BRIDGE_EBT_ULOG=m # CONFIG_IP_DCCP=m CONFIG_INET_DCCP_DIAG=m +CONFIG_IP_DCCP_ACKVEC=y # # DCCP CCIDs Configuration (EXPERIMENTAL) # +CONFIG_IP_DCCP_CCID2=m CONFIG_IP_DCCP_CCID3=m CONFIG_IP_DCCP_TFRC_LIB=m @@ -492,7 +499,6 @@ CONFIG_IP_DCCP_TFRC_LIB=m # DCCP Kernel Hacking # # CONFIG_IP_DCCP_DEBUG is not set -# CONFIG_IP_DCCP_UNLOAD_HACK is not set # # SCTP Configuration (EXPERIMENTAL) @@ -646,6 +652,7 @@ CONFIG_DONGLE=y CONFIG_ESI_DONGLE=m CONFIG_ACTISYS_DONGLE=m CONFIG_TEKRAM_DONGLE=m +CONFIG_TOIM3232_DONGLE=m CONFIG_LITELINK_DONGLE=m CONFIG_MA600_DONGLE=m CONFIG_GIRBIL_DONGLE=m @@ -704,6 +711,9 @@ CONFIG_IEEE80211=m CONFIG_IEEE80211_CRYPT_WEP=m CONFIG_IEEE80211_CRYPT_CCMP=m CONFIG_IEEE80211_CRYPT_TKIP=m +CONFIG_IEEE80211_SOFTMAC=m +# CONFIG_IEEE80211_SOFTMAC_DEBUG is not set +CONFIG_WIRELESS_EXT=y # # Device Drivers @@ -772,7 +782,6 @@ CONFIG_MTD_CFI_I2=y # CONFIG_MTD_OTP is not set CONFIG_MTD_CFI_INTELEXT=m CONFIG_MTD_CFI_AMDSTD=m -CONFIG_MTD_CFI_AMDSTD_RETRY=3 CONFIG_MTD_CFI_STAA=m CONFIG_MTD_CFI_UTIL=m CONFIG_MTD_RAM=m @@ -815,7 +824,6 @@ CONFIG_MTD_M25P80=m CONFIG_MTD_MTDRAM=m CONFIG_MTDRAM_TOTAL_SIZE=4096 CONFIG_MTDRAM_ERASE_SIZE=128 -# CONFIG_MTD_BLKMTD is not set CONFIG_MTD_BLOCK2MTD=m # @@ -1092,10 +1100,8 @@ CONFIG_SCSI_SYM53C8XX_2=m CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set +CONFIG_SCSI_SYM53C8XX_MMIO=y # CONFIG_SCSI_IPR is not set -CONFIG_SCSI_QLOGIC_FC=m -CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y CONFIG_SCSI_QLOGIC_1280=m CONFIG_SCSI_QLA_FC=m # CONFIG_SCSI_QLA2XXX_EMBEDDED_FIRMWARE is not set @@ -1121,6 +1127,7 @@ CONFIG_MD_RAID0=m CONFIG_MD_RAID1=m CONFIG_MD_RAID10=m CONFIG_MD_RAID5=m +CONFIG_MD_RAID5_RESHAPE=y CONFIG_MD_RAID6=m CONFIG_MD_MULTIPATH=m CONFIG_MD_FAULTY=m @@ -1326,6 +1333,7 @@ CONFIG_ABYSS=m # Wireless LAN (non-hamradio) # CONFIG_NET_RADIO=y +CONFIG_NET_WIRELESS_RTNETLINK=y # # Obsolete Wireless cards support (pre-802.11) @@ -1346,6 +1354,8 @@ CONFIG_IPW2100=m CONFIG_IPW2100_MONITOR=y # CONFIG_IPW2100_DEBUG is not set CONFIG_IPW2200=m +CONFIG_IPW2200_MONITOR=y +CONFIG_IPW_QOS=y # CONFIG_IPW2200_DEBUG is not set CONFIG_AIRO=m CONFIG_HERMES=m @@ -1375,6 +1385,13 @@ CONFIG_HOSTAP_FIRMWARE_NVRAM=y CONFIG_HOSTAP_PLX=m CONFIG_HOSTAP_PCI=m # CONFIG_HOSTAP_CS is not set +CONFIG_BCM43XX=m +CONFIG_BCM43XX_DEBUG=y +CONFIG_BCM43XX_DMA=y +CONFIG_BCM43XX_PIO=y +CONFIG_BCM43XX_DMA_AND_PIO_MODE=y +# CONFIG_BCM43XX_DMA_MODE is not set +# CONFIG_BCM43XX_PIO_MODE is not set CONFIG_NET_WIRELESS=y # @@ -1527,6 +1544,15 @@ CONFIG_HISAX_HDLC=y # Active cards # +# +# Siemens Gigaset +# +CONFIG_ISDN_DRV_GIGASET=m +CONFIG_GIGASET_BASE=m +CONFIG_GIGASET_M105=m +# CONFIG_GIGASET_DEBUG is not set +# CONFIG_GIGASET_UNDOCREQ is not set + # # CAPI subsystem # @@ -1739,6 +1765,8 @@ CONFIG_APPLICOM=m CONFIG_AGP=m CONFIG_AGP_AMD64=m CONFIG_AGP_INTEL=m +CONFIG_AGP_SIS=m +CONFIG_AGP_VIA=m CONFIG_DRM=m CONFIG_DRM_TDFX=m CONFIG_DRM_R128=m @@ -1804,7 +1832,6 @@ CONFIG_I2C_PARPORT=m CONFIG_I2C_PARPORT_LIGHT=m CONFIG_I2C_PROSAVAGE=m CONFIG_I2C_SAVAGE4=m -CONFIG_SCx200_ACB=m CONFIG_I2C_SIS5595=m CONFIG_I2C_SIS630=m CONFIG_I2C_SIS96X=m @@ -1823,9 +1850,7 @@ CONFIG_SENSORS_EEPROM=m CONFIG_SENSORS_PCF8574=m CONFIG_SENSORS_PCA9539=m CONFIG_SENSORS_PCF8591=m -CONFIG_SENSORS_RTC8564=m CONFIG_SENSORS_MAX6875=m -CONFIG_RTC_X1205_I2C=m # CONFIG_I2C_DEBUG_CORE is not set # CONFIG_I2C_DEBUG_ALGO is not set # CONFIG_I2C_DEBUG_BUS is not set @@ -1852,13 +1877,21 @@ CONFIG_SPI_BUTTERFLY=m # Dallas's 1-wire bus # CONFIG_W1=m -CONFIG_W1_MATROX=m -CONFIG_W1_DS9490=m -CONFIG_W1_DS9490_BRIDGE=m -CONFIG_W1_THERM=m -CONFIG_W1_SMEM=m -CONFIG_W1_DS2433=m -CONFIG_W1_DS2433_CRC=y + +# +# 1-wire Bus Masters +# +CONFIG_W1_MASTER_MATROX=m +CONFIG_W1_MASTER_DS9490=m +CONFIG_W1_MASTER_DS9490_BRIDGE=m +CONFIG_W1_MASTER_DS2482=m + +# +# 1-wire Slaves +# +CONFIG_W1_SLAVE_THERM=m +CONFIG_W1_SLAVE_SMEM=m +CONFIG_W1_SLAVE_DS2433=m # # Hardware Monitoring support @@ -1909,23 +1942,23 @@ CONFIG_SENSORS_HDAPS=m # CONFIG_IBM_ASM=m -# -# Multimedia Capabilities Port drivers -# - # # Multimedia devices # CONFIG_VIDEO_DEV=m +CONFIG_VIDEO_V4L1=y +CONFIG_VIDEO_V4L1_COMPAT=y +CONFIG_VIDEO_V4L2=m # -# Video For Linux +# Video Capture Adapters # # -# Video Adapters +# Video Capture Adapters # # CONFIG_VIDEO_ADV_DEBUG is not set +CONFIG_VIDEO_VIVI=m CONFIG_VIDEO_BT848=m CONFIG_VIDEO_BT848_DVB=y CONFIG_VIDEO_SAA6588=m @@ -1935,6 +1968,7 @@ CONFIG_VIDEO_W9966=m CONFIG_VIDEO_CPIA=m CONFIG_VIDEO_CPIA_PP=m CONFIG_VIDEO_CPIA_USB=m +CONFIG_VIDEO_CPIA2=m CONFIG_VIDEO_SAA5246A=m CONFIG_VIDEO_SAA5249=m CONFIG_TUNER_3036=m @@ -1953,15 +1987,43 @@ CONFIG_VIDEO_MXB=m CONFIG_VIDEO_DPC=m CONFIG_VIDEO_HEXIUM_ORION=m CONFIG_VIDEO_HEXIUM_GEMINI=m +CONFIG_VIDEO_CX88_VP3054=m CONFIG_VIDEO_CX88=m CONFIG_VIDEO_CX88_ALSA=m CONFIG_VIDEO_CX88_DVB=m CONFIG_VIDEO_CX88_DVB_ALL_FRONTENDS=y -CONFIG_VIDEO_CX88_VP3054=m -CONFIG_VIDEO_EM28XX=m CONFIG_VIDEO_OVCAMCHIP=m -CONFIG_VIDEO_AUDIO_DECODER=m -CONFIG_VIDEO_DECODER=m + +# +# Encoders and Decoders +# +CONFIG_VIDEO_MSP3400=m +CONFIG_VIDEO_CS53L32A=m +CONFIG_VIDEO_WM8775=m +CONFIG_VIDEO_WM8739=m +CONFIG_VIDEO_CX25840=m +CONFIG_VIDEO_SAA711X=m +CONFIG_VIDEO_SAA7127=m +CONFIG_VIDEO_UPD64031A=m +CONFIG_VIDEO_UPD64083=m + +# +# V4L USB devices +# +CONFIG_VIDEO_EM28XX=m +CONFIG_USB_DSBR=m +CONFIG_VIDEO_USBVIDEO=m +CONFIG_USB_VICAM=m +CONFIG_USB_IBMCAM=m +CONFIG_USB_KONICAWC=m +CONFIG_USB_ET61X251=m +CONFIG_USB_OV511=m +CONFIG_USB_SE401=m +CONFIG_USB_SN9C102=m +CONFIG_USB_STV680=m +CONFIG_USB_W9968CF=m +CONFIG_USB_ZC0301=m +CONFIG_USB_PWC=m # # Radio Adapters @@ -2060,6 +2122,7 @@ CONFIG_DVB_L64781=m CONFIG_DVB_TDA1004X=m CONFIG_DVB_NXT6000=m CONFIG_DVB_MT352=m +CONFIG_DVB_ZL10353=m CONFIG_DVB_DIB3000MB=m CONFIG_DVB_DIB3000MC=m @@ -2087,6 +2150,7 @@ CONFIG_VIDEO_BUF_DVB=m CONFIG_VIDEO_BTCX=m CONFIG_VIDEO_IR=m CONFIG_VIDEO_TVEEPROM=m +CONFIG_USB_DABUSB=m # # Graphics support @@ -2096,6 +2160,7 @@ CONFIG_FB_CFB_FILLRECT=y CONFIG_FB_CFB_COPYAREA=y CONFIG_FB_CFB_IMAGEBLIT=y # CONFIG_FB_MACMODES is not set +CONFIG_FB_FIRMWARE_EDID=y CONFIG_FB_MODE_HELPERS=y CONFIG_FB_TILEBLITTING=y CONFIG_FB_CIRRUS=m @@ -2122,7 +2187,6 @@ CONFIG_FB_MATROX_G=y CONFIG_FB_MATROX_I2C=m CONFIG_FB_MATROX_MAVEN=m CONFIG_FB_MATROX_MULTIHEAD=y -# CONFIG_FB_RADEON_OLD is not set CONFIG_FB_RADEON=m CONFIG_FB_RADEON_I2C=y # CONFIG_FB_RADEON_DEBUG is not set @@ -2145,6 +2209,7 @@ CONFIG_FB_VOODOO1=m CONFIG_FB_TRIDENT=m CONFIG_FB_TRIDENT_ACCEL=y CONFIG_FB_GEODE=y +CONFIG_FB_GEODE_GX=m CONFIG_FB_GEODE_GX1=m CONFIG_FB_VIRTUAL=m @@ -2152,6 +2217,7 @@ CONFIG_FB_VIRTUAL=m # Console display driver support # CONFIG_VGA_CONSOLE=y +# CONFIG_VGACON_SOFT_SCROLLBACK is not set CONFIG_DUMMY_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE=y CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y @@ -2190,11 +2256,13 @@ CONFIG_SND_SEQ_DUMMY=m CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m +CONFIG_SND_PCM_OSS_PLUGINS=y CONFIG_SND_SEQUENCER_OSS=y CONFIG_SND_RTCTIMER=m CONFIG_SND_SEQ_RTCTIMER_DEFAULT=y CONFIG_SND_DYNAMIC_MINORS=y CONFIG_SND_SUPPORT_OLD_API=y +CONFIG_SND_VERBOSE_PROCFS=y # CONFIG_SND_VERBOSE_PRINTK is not set # CONFIG_SND_DEBUG is not set @@ -2216,6 +2284,7 @@ CONFIG_SND_MPU401=m # PCI devices # CONFIG_SND_AD1889=m +CONFIG_SND_ALS300=m CONFIG_SND_ALS4000=m CONFIG_SND_ALI5451=m CONFIG_SND_ATIIXP=m @@ -2238,7 +2307,6 @@ CONFIG_SND_ENS1371=m CONFIG_SND_ES1938=m CONFIG_SND_ES1968=m CONFIG_SND_FM801=m -# CONFIG_SND_FM801_TEA575X_BOOL is not set CONFIG_SND_FM801_TEA575X=m CONFIG_SND_HDA_INTEL=m CONFIG_SND_HDSP=m @@ -2252,6 +2320,7 @@ CONFIG_SND_MAESTRO3=m CONFIG_SND_MIXART=m CONFIG_SND_NM256=m CONFIG_SND_PCXHR=m +CONFIG_SND_RIPTIDE=m CONFIG_SND_RME32=m CONFIG_SND_RME96=m CONFIG_SND_RME9652=m @@ -2271,6 +2340,8 @@ CONFIG_SND_USB_USX2Y=m # # PCMCIA devices # +CONFIG_SND_VXPOCKET=m +CONFIG_SND_PDAUDIOCF=m # # Open Sound System @@ -2282,6 +2353,7 @@ CONFIG_SND_USB_USX2Y=m # CONFIG_USB_ARCH_HAS_HCD=y CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y CONFIG_USB=m # CONFIG_USB_DEBUG is not set @@ -2311,7 +2383,6 @@ CONFIG_USB_SL811_HCD=m # # USB Device Class drivers # -# CONFIG_OBSOLETE_OSS_USB_DRIVER is not set CONFIG_USB_ACM=m CONFIG_USB_PRINTER=m @@ -2357,9 +2428,11 @@ CONFIG_USB_WACOM=m CONFIG_USB_ACECAD=m CONFIG_USB_KBTAB=m CONFIG_USB_POWERMATE=m -CONFIG_USB_MTOUCH=m -CONFIG_USB_ITMTOUCH=m -CONFIG_USB_EGALAX=m +CONFIG_USB_TOUCHSCREEN=m +CONFIG_USB_TOUCHSCREEN_EGALAX=y +CONFIG_USB_TOUCHSCREEN_PANJIT=y +CONFIG_USB_TOUCHSCREEN_3M=y +CONFIG_USB_TOUCHSCREEN_ITM=y CONFIG_USB_YEALINK=m CONFIG_USB_XPAD=m CONFIG_USB_ATI_REMOTE=m @@ -2373,22 +2446,6 @@ CONFIG_USB_APPLETOUCH=m CONFIG_USB_MDC800=m CONFIG_USB_MICROTEK=m -# -# USB Multimedia devices -# -CONFIG_USB_DABUSB=m -CONFIG_USB_VICAM=m -CONFIG_USB_DSBR=m -CONFIG_USB_ET61X251=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_OV511=m -CONFIG_USB_SE401=m -CONFIG_USB_SN9C102=m -CONFIG_USB_STV680=m -CONFIG_USB_W9968CF=m -CONFIG_USB_PWC=m - # # USB Network Adapters # @@ -2425,6 +2482,7 @@ CONFIG_USB_SERIAL=m CONFIG_USB_SERIAL_GENERIC=y CONFIG_USB_SERIAL_AIRPRIME=m CONFIG_USB_SERIAL_ANYDATA=m +CONFIG_USB_SERIAL_ARK3116=m CONFIG_USB_SERIAL_BELKIN=m CONFIG_USB_SERIAL_WHITEHEAT=m CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m @@ -2432,6 +2490,7 @@ CONFIG_USB_SERIAL_CP2101=m CONFIG_USB_SERIAL_CYPRESS_M8=m CONFIG_USB_SERIAL_EMPEG=m CONFIG_USB_SERIAL_FTDI_SIO=m +CONFIG_USB_SERIAL_FUNSOFT=m CONFIG_USB_SERIAL_VISOR=m CONFIG_USB_SERIAL_IPAQ=m CONFIG_USB_SERIAL_IR=m @@ -2456,6 +2515,7 @@ CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y CONFIG_USB_SERIAL_KLSI=m CONFIG_USB_SERIAL_KOBIL_SCT=m CONFIG_USB_SERIAL_MCT_U232=m +CONFIG_USB_SERIAL_NAVMAN=m CONFIG_USB_SERIAL_PL2303=m CONFIG_USB_SERIAL_HP4X=m CONFIG_USB_SERIAL_SAFE=m @@ -2506,8 +2566,26 @@ CONFIG_USB_XUSBATM=m CONFIG_MMC=m # CONFIG_MMC_DEBUG is not set CONFIG_MMC_BLOCK=m +CONFIG_MMC_SDHCI=m CONFIG_MMC_WBSD=m +# +# LED devices +# +CONFIG_NEW_LEDS=y +CONFIG_LEDS_CLASS=m + +# +# LED drivers +# + +# +# LED Triggers +# +CONFIG_LEDS_TRIGGERS=y +CONFIG_LEDS_TRIGGER_TIMER=m +CONFIG_LEDS_TRIGGER_IDE_DISK=y + # # InfiniBand support # @@ -2515,9 +2593,10 @@ CONFIG_INFINIBAND=m CONFIG_INFINIBAND_USER_MAD=m CONFIG_INFINIBAND_USER_ACCESS=m CONFIG_INFINIBAND_MTHCA=m -# CONFIG_INFINIBAND_MTHCA_DEBUG is not set +CONFIG_INFINIBAND_MTHCA_DEBUG=y CONFIG_INFINIBAND_IPOIB=m -# CONFIG_INFINIBAND_IPOIB_DEBUG is not set +CONFIG_INFINIBAND_IPOIB_DEBUG=y +# CONFIG_INFINIBAND_IPOIB_DEBUG_DATA is not set CONFIG_INFINIBAND_SRP=m # @@ -2530,13 +2609,32 @@ CONFIG_EDAC=m # # CONFIG_EDAC_DEBUG is not set CONFIG_EDAC_MM_EDAC=m -CONFIG_EDAC_E7XXX=m CONFIG_EDAC_E752X=m -CONFIG_EDAC_I82875P=m -CONFIG_EDAC_I82860=m -CONFIG_EDAC_R82600=m CONFIG_EDAC_POLL=y +# +# Real Time Clock +# +CONFIG_RTC_LIB=m +CONFIG_RTC_CLASS=m + +# +# RTC interfaces +# +CONFIG_RTC_INTF_SYSFS=m +CONFIG_RTC_INTF_PROC=m +CONFIG_RTC_INTF_DEV=m + +# +# RTC drivers +# +CONFIG_RTC_DRV_X1205=m +CONFIG_RTC_DRV_DS1672=m +CONFIG_RTC_DRV_PCF8563=m +CONFIG_RTC_DRV_RS5C372=m +CONFIG_RTC_DRV_M48T86=m +CONFIG_RTC_DRV_TEST=m + # # Firmware Drivers # @@ -2621,7 +2719,6 @@ CONFIG_SYSFS=y CONFIG_TMPFS=y # CONFIG_HUGETLB_PAGE is not set CONFIG_RAMFS=y -CONFIG_RELAYFS_FS=m CONFIG_CONFIGFS_FS=m # @@ -2793,6 +2890,7 @@ CONFIG_DETECT_SOFTLOCKUP=y # CONFIG_DEBUG_FS is not set # CONFIG_DEBUG_VM is not set # CONFIG_FRAME_POINTER is not set +# CONFIG_UNWIND_INFO is not set CONFIG_FORCED_INLINING=y # CONFIG_RCU_TORTURE_TEST is not set # CONFIG_DEBUG_RODATA is not set @@ -2844,26 +2942,27 @@ CONFIG_CRYPTO_TEST=m # Hardware crypto devices # CONFIG_XEN=y -CONFIG_XEN_INTERFACE_VERSION=0x00030202 +CONFIG_XEN_INTERFACE_VERSION=0x00030203 # # XEN # CONFIG_XEN_PRIVILEGED_GUEST=y # CONFIG_XEN_UNPRIVILEGED_GUEST is not set +CONFIG_XEN_PRIVCMD=y +CONFIG_XEN_XENBUS_DEV=y CONFIG_XEN_BACKEND=y -CONFIG_XEN_PCIDEV_BACKEND=m -# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set -CONFIG_XEN_PCIDEV_BACKEND_PASS=y -# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set -# CONFIG_XEN_PCIDEV_BE_DEBUG is not set CONFIG_XEN_BLKDEV_BACKEND=y CONFIG_XEN_BLKDEV_TAP=y CONFIG_XEN_NETDEV_BACKEND=y # CONFIG_XEN_NETDEV_PIPELINED_TRANSMITTER is not set CONFIG_XEN_NETDEV_LOOPBACK=y +CONFIG_XEN_PCIDEV_BACKEND=m +# CONFIG_XEN_PCIDEV_BACKEND_VPCI is not set +CONFIG_XEN_PCIDEV_BACKEND_PASS=y +# CONFIG_XEN_PCIDEV_BACKEND_SLOT is not set +# CONFIG_XEN_PCIDEV_BE_DEBUG is not set CONFIG_XEN_TPMDEV_BACKEND=m -# CONFIG_XEN_TPMDEV_CLOSE_IF_VTPM_FAILS is not set CONFIG_XEN_BLKDEV_FRONTEND=y CONFIG_XEN_NETDEV_FRONTEND=y CONFIG_XEN_FRAMEBUFFER=y @@ -2876,7 +2975,14 @@ CONFIG_XEN_COMPAT_030002_AND_LATER=y CONFIG_XEN_COMPAT_030002=y CONFIG_HAVE_ARCH_ALLOC_SKB=y CONFIG_HAVE_ARCH_DEV_ALLOC_SKB=y +CONFIG_HAVE_IRQ_IGNORE_UNHANDLED=y CONFIG_NO_IDLE_HZ=y +CONFIG_XEN_UTIL=y +CONFIG_XEN_BALLOON=y +CONFIG_XEN_DEVMEM=y +CONFIG_XEN_SKBUFF=y +CONFIG_XEN_REBOOT=y +CONFIG_XEN_SMPBOOT=y # # Library routines diff --git a/buildconfigs/mk.linux-2.6-xen b/buildconfigs/mk.linux-2.6-xen index 272a58479d..d5741a77d2 100644 --- a/buildconfigs/mk.linux-2.6-xen +++ b/buildconfigs/mk.linux-2.6-xen @@ -1,5 +1,5 @@ LINUX_SERIES = 2.6 -LINUX_VER = 2.6.16.33 +LINUX_VER = 2.6.17 EXTRAVERSION ?= xen diff --git a/linux-2.6-xen-sparse/arch/i386/Kconfig b/linux-2.6-xen-sparse/arch/i386/Kconfig index 8c712269d0..957c2a92f7 100644 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig @@ -37,6 +37,10 @@ config GENERIC_IOMAP bool default y +config GENERIC_HWEIGHT + bool + default y + config ARCH_MAY_HAVE_PC_FDC bool default y @@ -49,6 +53,35 @@ source "init/Kconfig" menu "Processor type and features" +config SMP + bool "Symmetric multi-processing support" + ---help--- + This enables support for systems with more than one CPU. If you have + a system with only one CPU, like most personal computers, say N. If + you have a system with more than one CPU, say Y. + + If you say N here, the kernel will run on single and multiprocessor + machines, but will use only one CPU of a multiprocessor machine. If + you say Y here, the kernel will run on many, but not all, + singleprocessor machines. On a singleprocessor machine, the kernel + will run faster if you say N here. + + Note that if you say Y here and choose architecture "586" or + "Pentium" under "Processor family", the kernel will not work on 486 + architectures. Similarly, multiprocessor kernels for the "PPro" + architecture may not work on all Pentium based boards. + + People using multiprocessor machines who say Y here should also say + Y to "Enhanced Real Time Clock Support", below. The "Advanced Power + Management" code will be disabled if you say Y here. + + See also the , + , + and the SMP-HOWTO available at + . + + If you don't know what to do here, say N. + choice prompt "Subarchitecture Type" default X86_PC @@ -89,6 +122,7 @@ config X86_VOYAGER config X86_NUMAQ bool "NUMAQ (IBM/Sequent)" + select SMP select NUMA help This option is used for getting Linux to run on a (IBM/Sequent) NUMA @@ -183,48 +217,6 @@ config HPET_EMULATE_RTC depends on HPET_TIMER && RTC=y default y -config SMP - bool "Symmetric multi-processing support" - ---help--- - This enables support for systems with more than one CPU. If you have - a system with only one CPU, like most personal computers, say N. If - you have a system with more than one CPU, say Y. - - If you say N here, the kernel will run on single and multiprocessor - machines, but will use only one CPU of a multiprocessor machine. If - you say Y here, the kernel will run on many, but not all, - singleprocessor machines. On a singleprocessor machine, the kernel - will run faster if you say N here. - - Note that if you say Y here and choose architecture "586" or - "Pentium" under "Processor family", the kernel will not work on 486 - architectures. Similarly, multiprocessor kernels for the "PPro" - architecture may not work on all Pentium based boards. - - People using multiprocessor machines who say Y here should also say - Y to "Enhanced Real Time Clock Support", below. The "Advanced Power - Management" code will be disabled if you say Y here. - - See also the , - , - and the SMP-HOWTO available at - . - - If you don't know what to do here, say N. - -config SMP_ALTERNATIVES - bool "SMP alternatives support (EXPERIMENTAL)" - depends on SMP && EXPERIMENTAL - help - Try to reduce the overhead of running an SMP kernel on a uniprocessor - host slightly by replacing certain key instruction sequences - according to whether we currently have more than one CPU available. - This should provide a noticeable boost to performance when - running SMP kernels on UP machines, and have negligible impact - when running on an true SMP host. - - If unsure, say N. - config NR_CPUS int "Maximum number of CPUs (2-255)" range 2 255 @@ -249,6 +241,15 @@ config SCHED_SMT cost of slightly increased overhead in some places. If unsure say N here. +config SCHED_MC + bool "Multi-core scheduler support" + depends on SMP + default y + help + Multi-core scheduler support improves the CPU scheduler's decision + making when dealing with multi-core CPU chips at a cost of slightly + increased overhead in some places. If unsure say N here. + source "kernel/Kconfig.preempt" config X86_UP_APIC @@ -434,6 +435,7 @@ choice config NOHIGHMEM bool "off" + depends on !X86_NUMAQ ---help--- Linux can use up to 64 Gigabytes of physical memory on x86 systems. However, the address space of 32-bit x86 processors is only 4 @@ -470,6 +472,7 @@ config NOHIGHMEM config HIGHMEM4G bool "4GB" + depends on !X86_NUMAQ help Select this if you have a 32-bit processor and between 1 and 4 gigabytes of physical RAM. @@ -485,7 +488,7 @@ endchoice choice depends on EXPERIMENTAL && !X86_PAE - prompt "Memory split" + prompt "Memory split" if EMBEDDED default VMSPLIT_3G help Select the desired split between kernel and user memory. @@ -537,13 +540,15 @@ config NUMA default n if X86_PC default y if (X86_NUMAQ || X86_SUMMIT) -# Need comments to help the hapless user trying to turn on NUMA support -comment "NUMA (NUMA-Q) requires SMP, 64GB highmem support" - depends on X86_NUMAQ && (!HIGHMEM64G || !SMP) - comment "NUMA (Summit) requires SMP, 64GB highmem support, ACPI" depends on X86_SUMMIT && (!HIGHMEM64G || !ACPI) +config NODES_SHIFT + int + default "4" if X86_NUMAQ + default "3" + depends on NEED_MULTIPLE_NODES + config HAVE_ARCH_BOOTMEM_NODE bool depends on NUMA @@ -697,13 +702,18 @@ config BOOT_IOREMAP default y config REGPARM - bool "Use register arguments (EXPERIMENTAL)" - depends on EXPERIMENTAL - default n + bool "Use register arguments" + default y help - Compile the kernel with -mregparm=3. This uses a different ABI - and passes the first three arguments of a function call in registers. - This will probably break binary only modules. + Compile the kernel with -mregparm=3. This instructs gcc to use + a more efficient function call ABI which passes the first three + arguments of a function call via registers, which results in denser + and faster code. + + If this option is disabled, then the default ABI of passing + arguments via the stack is used. + + If unsure, say Y. config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" @@ -772,26 +782,12 @@ config HOTPLUG_CPU bool "Support for hot-pluggable CPUs (EXPERIMENTAL)" depends on SMP && HOTPLUG && EXPERIMENTAL && !X86_VOYAGER ---help--- - Say Y here to experiment with turning CPUs off and on. CPUs - can be controlled through /sys/devices/system/cpu. - - Say N. - -config DOUBLEFAULT - default y - bool "Enable doublefault exception handler" if EMBEDDED - depends on !X86_NO_TSS - help - This option allows trapping of rare doublefault exceptions that - would otherwise cause a system to silently reboot. Disabling this - option saves about 4k and might cause you much additional grey - hair. + Say Y here to experiment with turning CPUs off and on, and to + enable suspend on SMP systems. CPUs can be controlled through + /sys/devices/system/cpu. endmenu -config ARCH_ENABLE_MEMORY_HOTPLUG - def_bool y - depends on HIGHMEM menu "Power management options (ACPI, APM)" depends on !(X86_VOYAGER || XEN_UNPRIVILEGED_GUEST) diff --git a/linux-2.6-xen-sparse/arch/i386/Kconfig.cpu b/linux-2.6-xen-sparse/arch/i386/Kconfig.cpu index a52d7d494f..f90d8d0df1 100644 --- a/linux-2.6-xen-sparse/arch/i386/Kconfig.cpu +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig.cpu @@ -311,5 +311,5 @@ config X86_OOSTORE config X86_TSC bool - depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1) && !X86_NUMAQ + depends on (MWINCHIP3D || MWINCHIP2 || MCRUSOE || MEFFICEON || MCYRIXIII || MK7 || MK6 || MPENTIUM4 || MPENTIUMM || MPENTIUMIII || MPENTIUMII || M686 || M586MMX || M586TSC || MK8 || MVIAC3_2 || MGEODEGX1 || MGEODE_LX) && !X86_NUMAQ default y diff --git a/linux-2.6-xen-sparse/arch/i386/Kconfig.debug b/linux-2.6-xen-sparse/arch/i386/Kconfig.debug new file mode 100644 index 0000000000..fb28fe7418 --- /dev/null +++ b/linux-2.6-xen-sparse/arch/i386/Kconfig.debug @@ -0,0 +1,94 @@ +menu "Kernel hacking" + +source "lib/Kconfig.debug" + +config EARLY_PRINTK + bool "Early printk" if EMBEDDED && DEBUG_KERNEL + default y + help + Write kernel log output directly into the VGA buffer or to a serial + port. + + This is useful for kernel debugging when your machine crashes very + early before the console code is initialized. For normal operation + it is not recommended because it looks ugly and doesn't cooperate + with klogd/syslogd or the X server. You should normally N here, + unless you want to debug such a crash. + +config DEBUG_STACKOVERFLOW + bool "Check for stack overflows" + depends on DEBUG_KERNEL + help + This option will cause messages to be printed if free stack space + drops below a certain limit. + +config DEBUG_STACK_USAGE + bool "Stack utilization instrumentation" + depends on DEBUG_KERNEL + help + Enables the display of the minimum amount of free stack which each + task has ever had available in the sysrq-T and sysrq-P debug output. + + This option will slow down process creation somewhat. + +config STACK_BACKTRACE_COLS + int "Stack backtraces per line" if DEBUG_KERNEL + range 1 3 + default 2 + help + Selects how many stack backtrace entries per line to display. + + This can save screen space when displaying traces. + +comment "Page alloc debug is incompatible with Software Suspend on i386" + depends on DEBUG_KERNEL && SOFTWARE_SUSPEND + +config DEBUG_PAGEALLOC + bool "Debug page memory allocations" + depends on DEBUG_KERNEL && !SOFTWARE_SUSPEND && !HUGETLBFS + help + Unmap pages from the kernel linear mapping after free_pages(). + This results in a large slowdown, but helps to find certain types + of memory corruptions. + +config DEBUG_RODATA + bool "Write protect kernel read-only data structures" + depends on DEBUG_KERNEL + help + Mark the kernel read-only data as write-protected in the pagetables, + in order to catch accidental (and incorrect) writes to such const + data. This option may have a slight performance impact because a + portion of the kernel code won't be covered by a 2MB TLB anymore. + If in doubt, say "N". + +config 4KSTACKS + bool "Use 4Kb for kernel stacks instead of 8Kb" + depends on DEBUG_KERNEL + help + If you say Y here the kernel will use a 4Kb stacksize for the + kernel stack attached to each process/thread. This facilitates + running more threads on a system and also reduces the pressure + on the VM subsystem for higher order allocations. This option + will also use IRQ stacks to compensate for the reduced stackspace. + +config X86_FIND_SMP_CONFIG + bool + depends on X86_LOCAL_APIC || X86_VOYAGER + default y + +config X86_MPPARSE + bool + depends on X86_LOCAL_APIC && !X86_VISWS + default y + +config DOUBLEFAULT + default y + bool "Enable doublefault exception handler" if EMBEDDED + depends on !X86_NO_TSS + help + This option allows trapping of rare doublefault exceptions that + would otherwise cause a system to silently reboot. Disabling this + option saves about 4k and might cause you much additional grey + hair. + +endmenu diff --git a/linux-2.6-xen-sparse/arch/i386/Makefile b/linux-2.6-xen-sparse/arch/i386/Makefile index 99a8fa2aaa..d6d0f45999 100644 --- a/linux-2.6-xen-sparse/arch/i386/Makefile +++ b/linux-2.6-xen-sparse/arch/i386/Makefile @@ -39,6 +39,9 @@ include $(srctree)/arch/i386/Makefile.cpu cflags-$(CONFIG_REGPARM) += -mregparm=3 +# temporary until string.h is fixed +cflags-y += -ffreestanding + # Disable unit-at-a-time mode on pre-gcc-4.0 compilers, it makes gcc use # a lot more stack due to the lack of sharing of stacklots: CFLAGS += $(shell if [ $(call cc-version) -lt 0400 ] ; then echo $(call cc-option,-fno-unit-at-a-time); fi ;) @@ -108,8 +111,8 @@ AFLAGS += $(mflags-y) boot := arch/i386/boot -.PHONY: zImage bzImage compressed zlilo bzlilo \ - zdisk bzdisk fdimage fdimage144 fdimage288 install +PHONY += zImage bzImage compressed zlilo bzlilo \ + zdisk bzdisk fdimage fdimage144 fdimage288 isoimage install ifdef CONFIG_XEN CPPFLAGS := -Iinclude$(if $(KBUILD_SRC),2)/asm/mach-xen $(CPPFLAGS) @@ -141,7 +144,7 @@ zlilo bzlilo: vmlinux zdisk bzdisk: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) zdisk -fdimage fdimage144 fdimage288: vmlinux +fdimage fdimage144 fdimage288 isoimage: vmlinux $(Q)$(MAKE) $(build)=$(boot) BOOTIMAGE=$(KBUILD_IMAGE) $@ install: @@ -159,7 +162,10 @@ define archhelp echo ' install to $$(INSTALL_PATH) and run lilo' echo ' bzdisk - Create a boot floppy in /dev/fd0' echo ' fdimage - Create a boot floppy image' + echo ' isoimage - Create a boot CD-ROM image' endef -CLEAN_FILES += arch/$(ARCH)/boot/fdimage arch/$(ARCH)/boot/mtools.conf +CLEAN_FILES += arch/$(ARCH)/boot/fdimage \ + arch/$(ARCH)/boot/image.iso \ + arch/$(ARCH)/boot/mtools.conf CLEAN_FILES += vmlinuz vmlinux-stripped diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/Makefile b/linux-2.6-xen-sparse/arch/i386/kernel/Makefile index d0ccf7b375..ddaa19d896 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/Makefile +++ b/linux-2.6-xen-sparse/arch/i386/kernel/Makefile @@ -6,8 +6,8 @@ extra-y := head.o init_task.o vmlinux.lds obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o \ ptrace.o time.o ioport.o ldt.o setup.o i8259.o sys_i386.o \ - pci-dma.o i386_ksyms.o i387.o dmi_scan.o bootflag.o \ - quirks.o i8237.o topology.o + pci-dma.o i386_ksyms.o i387.o bootflag.o \ + quirks.o i8237.o topology.o alternative.o obj-y += cpu/ obj-y += timers/ @@ -37,7 +37,6 @@ obj-$(CONFIG_EFI) += efi.o efi_stub.o obj-$(CONFIG_DOUBLEFAULT) += doublefault.o obj-$(CONFIG_VM86) += vm86.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -obj-$(CONFIG_SMP_ALTERNATIVES) += smpalts.o EXTRA_AFLAGS := -traditional diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/acpi/boot-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/acpi/boot-xen.c index 96e452577d..08e8352ea4 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/acpi/boot-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/acpi/boot-xen.c @@ -671,10 +671,10 @@ unsigned long __init acpi_find_rsdp(void) unsigned long rsdp_phys = 0; if (efi_enabled) { - if (efi.acpi20) - return __pa(efi.acpi20); - else if (efi.acpi) - return __pa(efi.acpi); + if (efi.acpi20 != EFI_INVALID_TABLE_ADDR) + return efi.acpi20; + else if (efi.acpi != EFI_INVALID_TABLE_ADDR) + return efi.acpi; } /* * Scan memory looking for the RSDP signature. First search EBDA (low @@ -696,6 +696,9 @@ static int __init acpi_parse_madt_lapic_entries(void) { int count; + if (!cpu_has_apic) + return -ENODEV; + /* * Note that the LAPIC address is obtained from the MADT (32-bit value) * and (optionally) overriden by a LAPIC_ADDR_OVR entry (64-bit value). @@ -754,6 +757,9 @@ static int __init acpi_parse_madt_ioapic_entries(void) return -ENODEV; } + if (!cpu_has_apic) + return -ENODEV; + /* * if "noapic" boot option, don't look for IO-APICs */ diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/apic-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/apic-xen.c index 07a0994307..1f8297bc65 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/apic-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/apic-xen.c @@ -38,6 +38,7 @@ #include #include +#include #include #include "io_ports.h" @@ -60,6 +61,18 @@ int enable_local_apic __initdata = 0; /* -1=force-disable, +1=force-enable */ */ int apic_verbosity; +int modern_apic(void) +{ + unsigned int lvr, version; + /* AMD systems use old APIC versions, so check the CPU */ + if (boot_cpu_data.x86_vendor == X86_VENDOR_AMD && + boot_cpu_data.x86 >= 0xf) + return 1; + lvr = apic_read(APIC_LVR); + version = GET_APIC_VERSION(lvr); + return version >= 0x14; +} + /* * 'what should we do if we get a hw irq event on an illegal vector'. * each architecture has to answer this themselves. diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c index ffcee15c86..4d1a486dee 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/common-xen.c @@ -15,6 +15,10 @@ #include #include #include +#else +#ifdef CONFIG_XEN +#define phys_pkg_id(a,b) a +#endif #endif #include @@ -28,9 +32,10 @@ DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]); EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack); #endif -static int cachesize_override __devinitdata = -1; -static int disable_x86_fxsr __devinitdata = 0; -static int disable_x86_serial_nr __devinitdata = 1; +static int cachesize_override __cpuinitdata = -1; +static int disable_x86_fxsr __cpuinitdata; +static int disable_x86_serial_nr __cpuinitdata = 1; +static int disable_x86_sep __cpuinitdata; struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {}; @@ -62,7 +67,7 @@ static int __init cachesize_setup(char *str) } __setup("cachesize=", cachesize_setup); -int __devinit get_model_name(struct cpuinfo_x86 *c) +int __cpuinit get_model_name(struct cpuinfo_x86 *c) { unsigned int *v; char *p, *q; @@ -92,7 +97,7 @@ int __devinit get_model_name(struct cpuinfo_x86 *c) } -void __devinit display_cacheinfo(struct cpuinfo_x86 *c) +void __cpuinit display_cacheinfo(struct cpuinfo_x86 *c) { unsigned int n, dummy, ecx, edx, l2size; @@ -133,7 +138,7 @@ void __devinit display_cacheinfo(struct cpuinfo_x86 *c) /* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */ /* Look up CPU names by table lookup. */ -static char __devinit *table_lookup_model(struct cpuinfo_x86 *c) +static char __cpuinit *table_lookup_model(struct cpuinfo_x86 *c) { struct cpu_model_info *info; @@ -154,7 +159,7 @@ static char __devinit *table_lookup_model(struct cpuinfo_x86 *c) } -static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) +static void __cpuinit get_cpu_vendor(struct cpuinfo_x86 *c, int early) { char *v = c->x86_vendor_id; int i; @@ -190,6 +195,14 @@ static int __init x86_fxsr_setup(char * s) __setup("nofxsr", x86_fxsr_setup); +static int __init x86_sep_setup(char * s) +{ + disable_x86_sep = 1; + return 1; +} +__setup("nosep", x86_sep_setup); + + /* Standard macro to see if a specific flag is changeable */ static inline int flag_is_changeable_p(u32 flag) { @@ -213,7 +226,7 @@ static inline int flag_is_changeable_p(u32 flag) /* Probe for the CPUID instruction */ -static int __devinit have_cpuid_p(void) +static int __cpuinit have_cpuid_p(void) { return flag_is_changeable_p(X86_EFLAGS_ID); } @@ -257,10 +270,10 @@ static void __init early_cpu_detect(void) } } -void __devinit generic_identify(struct cpuinfo_x86 * c) +void __cpuinit generic_identify(struct cpuinfo_x86 * c) { u32 tfms, xlvl; - int junk; + int ebx; if (have_cpuid_p()) { /* Get vendor name */ @@ -276,7 +289,7 @@ void __devinit generic_identify(struct cpuinfo_x86 * c) /* Intel-defined flags: level 0x00000001 */ if ( c->cpuid_level >= 0x00000001 ) { u32 capability, excap; - cpuid(0x00000001, &tfms, &junk, &excap, &capability); + cpuid(0x00000001, &tfms, &ebx, &excap, &capability); c->x86_capability[0] = capability; c->x86_capability[4] = excap; c->x86 = (tfms >> 8) & 15; @@ -286,6 +299,11 @@ void __devinit generic_identify(struct cpuinfo_x86 * c) if (c->x86 >= 0x6) c->x86_model += ((tfms >> 16) & 0xF) << 4; c->x86_mask = tfms & 15; +#ifdef CONFIG_SMP + c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); +#else + c->apicid = (ebx >> 24) & 0xFF; +#endif } else { /* Have CPUID level 0 only - unheard of */ c->x86 = 4; @@ -310,7 +328,7 @@ void __devinit generic_identify(struct cpuinfo_x86 * c) #endif } -static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) +static void __cpuinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c) { if (cpu_has(c, X86_FEATURE_PN) && disable_x86_serial_nr ) { /* Disable processor serial number */ @@ -338,7 +356,7 @@ __setup("serialnumber", x86_serial_nr_setup); /* * This does the hard work of actually picking apart the CPU stuff... */ -void __devinit identify_cpu(struct cpuinfo_x86 *c) +void __cpuinit identify_cpu(struct cpuinfo_x86 *c) { int i; @@ -408,6 +426,10 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c) clear_bit(X86_FEATURE_XMM, c->x86_capability); } + /* SEP disabled? */ + if (disable_x86_sep) + clear_bit(X86_FEATURE_SEP, c->x86_capability); + if (disable_pse) clear_bit(X86_FEATURE_PSE, c->x86_capability); @@ -420,7 +442,7 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c) else /* Last resort... */ sprintf(c->x86_model_id, "%02x/%02x", - c->x86_vendor, c->x86_model); + c->x86, c->x86_model); } /* Now the feature flags better reflect actual CPU features! */ @@ -456,7 +478,7 @@ void __devinit identify_cpu(struct cpuinfo_x86 *c) } #ifdef CONFIG_X86_HT -void __devinit detect_ht(struct cpuinfo_x86 *c) +void __cpuinit detect_ht(struct cpuinfo_x86 *c) { u32 eax, ebx, ecx, edx; int index_msb, core_bits; @@ -464,7 +486,6 @@ void __devinit detect_ht(struct cpuinfo_x86 *c) cpuid(1, &eax, &ebx, &ecx, &edx); - c->apicid = phys_pkg_id((ebx >> 24) & 0xFF, 0); if (!cpu_has(c, X86_FEATURE_HT) || cpu_has(c, X86_FEATURE_CMP_LEGACY)) return; @@ -503,7 +524,7 @@ void __devinit detect_ht(struct cpuinfo_x86 *c) } #endif -void __devinit print_cpu_info(struct cpuinfo_x86 *c) +void __cpuinit print_cpu_info(struct cpuinfo_x86 *c) { char *vendor = NULL; @@ -703,7 +724,7 @@ void __cpuinit cpu_init(void) } #ifdef CONFIG_HOTPLUG_CPU -void __devinit cpu_uninit(void) +void __cpuinit cpu_uninit(void) { int cpu = raw_smp_processor_id(); cpu_clear(cpu, cpu_initialized); diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c new file mode 100644 index 0000000000..f549dd2af6 --- /dev/null +++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/intel_cacheinfo-xen.c @@ -0,0 +1,693 @@ +/* + * Routines to indentify caches on Intel CPU. + * + * Changes: + * Venkatesh Pallipadi : Adding cache identification through cpuid(4) + * Ashok Raj : Work with CPU hotplug infrastructure. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include + +#define LVL_1_INST 1 +#define LVL_1_DATA 2 +#define LVL_2 3 +#define LVL_3 4 +#define LVL_TRACE 5 + +struct _cache_table +{ + unsigned char descriptor; + char cache_type; + short size; +}; + +/* all the cache descriptor types we care about (no TLB or trace cache entries) */ +static struct _cache_table cache_table[] __cpuinitdata = +{ + { 0x06, LVL_1_INST, 8 }, /* 4-way set assoc, 32 byte line size */ + { 0x08, LVL_1_INST, 16 }, /* 4-way set assoc, 32 byte line size */ + { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */ + { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */ + { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x23, LVL_3, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */ + { 0x25, LVL_3, 2048 }, /* 8-way set assoc, sectored cache, 64 byte line size */ + { 0x29, LVL_3, 4096 }, /* 8-way set assoc, sectored cache, 64 byte line size */ + { 0x2c, LVL_1_DATA, 32 }, /* 8-way set assoc, 64 byte line size */ + { 0x30, LVL_1_INST, 32 }, /* 8-way set assoc, 64 byte line size */ + { 0x39, LVL_2, 128 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x3a, LVL_2, 192 }, /* 6-way set assoc, sectored cache, 64 byte line size */ + { 0x3b, LVL_2, 128 }, /* 2-way set assoc, sectored cache, 64 byte line size */ + { 0x3c, LVL_2, 256 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x3d, LVL_2, 384 }, /* 6-way set assoc, sectored cache, 64 byte line size */ + { 0x3e, LVL_2, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x41, LVL_2, 128 }, /* 4-way set assoc, 32 byte line size */ + { 0x42, LVL_2, 256 }, /* 4-way set assoc, 32 byte line size */ + { 0x43, LVL_2, 512 }, /* 4-way set assoc, 32 byte line size */ + { 0x44, LVL_2, 1024 }, /* 4-way set assoc, 32 byte line size */ + { 0x45, LVL_2, 2048 }, /* 4-way set assoc, 32 byte line size */ + { 0x46, LVL_3, 4096 }, /* 4-way set assoc, 64 byte line size */ + { 0x47, LVL_3, 8192 }, /* 8-way set assoc, 64 byte line size */ + { 0x49, LVL_3, 4096 }, /* 16-way set assoc, 64 byte line size */ + { 0x4a, LVL_3, 6144 }, /* 12-way set assoc, 64 byte line size */ + { 0x4b, LVL_3, 8192 }, /* 16-way set assoc, 64 byte line size */ + { 0x4c, LVL_3, 12288 }, /* 12-way set assoc, 64 byte line size */ + { 0x4d, LVL_3, 16384 }, /* 16-way set assoc, 64 byte line size */ + { 0x60, LVL_1_DATA, 16 }, /* 8-way set assoc, sectored cache, 64 byte line size */ + { 0x66, LVL_1_DATA, 8 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x67, LVL_1_DATA, 16 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x68, LVL_1_DATA, 32 }, /* 4-way set assoc, sectored cache, 64 byte line size */ + { 0x70, LVL_TRACE, 12 }, /* 8-way set assoc */ + { 0x71, LVL_TRACE, 16 }, /* 8-way set assoc */ + { 0x72, LVL_TRACE, 32 }, /* 8-way set assoc */ + { 0x73, LVL_TRACE, 64 }, /* 8-way set assoc */ + { 0x78, LVL_2, 1024 }, /* 4-way set assoc, 64 byte line size */ + { 0x79, LVL_2, 128 }, /* 8-way set assoc, sectored cache, 64 byte line size */ + { 0x7a, LVL_2, 256 }, /* 8-way set assoc, sectored cache, 64 byte line size */ + { 0x7b, LVL_2, 512 }, /* 8-way set assoc, sectored cache, 64 byte line size */ + { 0x7c, LVL_2, 1024 }, /* 8-way set assoc, sectored cache, 64 byte line size */ + { 0x7d, LVL_2, 2048 }, /* 8-way set assoc, 64 byte line size */ + { 0x7f, LVL_2, 512 }, /* 2-way set assoc, 64 byte line size */ + { 0x82, LVL_2, 256 }, /* 8-way set assoc, 32 byte line size */ + { 0x83, LVL_2, 512 }, /* 8-way set assoc, 32 byte line size */ + { 0x84, LVL_2, 1024 }, /* 8-way set assoc, 32 byte line size */ + { 0x85, LVL_2, 2048 }, /* 8-way set assoc, 32 byte line size */ + { 0x86, LVL_2, 512 }, /* 4-way set assoc, 64 byte line size */ + { 0x87, LVL_2, 1024 }, /* 8-way set assoc, 64 byte line size */ + { 0x00, 0, 0} +}; + + +enum _cache_type +{ + CACHE_TYPE_NULL = 0, + CACHE_TYPE_DATA = 1, + CACHE_TYPE_INST = 2, + CACHE_TYPE_UNIFIED = 3 +}; + +union _cpuid4_leaf_eax { + struct { + enum _cache_type type:5; + unsigned int level:3; + unsigned int is_self_initializing:1; + unsigned int is_fully_associative:1; + unsigned int reserved:4; + unsigned int num_threads_sharing:12; + unsigned int num_cores_on_die:6; + } split; + u32 full; +}; + +union _cpuid4_leaf_ebx { + struct { + unsigned int coherency_line_size:12; + unsigned int physical_line_partition:10; + unsigned int ways_of_associativity:10; + } split; + u32 full; +}; + +union _cpuid4_leaf_ecx { + struct { + unsigned int number_of_sets:32; + } split; + u32 full; +}; + +struct _cpuid4_info { + union _cpuid4_leaf_eax eax; + union _cpuid4_leaf_ebx ebx; + union _cpuid4_leaf_ecx ecx; + unsigned long size; + cpumask_t shared_cpu_map; +}; + +static unsigned short num_cache_leaves; + +static int __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf) +{ + unsigned int eax, ebx, ecx, edx; + union _cpuid4_leaf_eax cache_eax; + + cpuid_count(4, index, &eax, &ebx, &ecx, &edx); + cache_eax.full = eax; + if (cache_eax.split.type == CACHE_TYPE_NULL) + return -EIO; /* better error ? */ + + this_leaf->eax.full = eax; + this_leaf->ebx.full = ebx; + this_leaf->ecx.full = ecx; + this_leaf->size = (this_leaf->ecx.split.number_of_sets + 1) * + (this_leaf->ebx.split.coherency_line_size + 1) * + (this_leaf->ebx.split.physical_line_partition + 1) * + (this_leaf->ebx.split.ways_of_associativity + 1); + return 0; +} + +/* will only be called once; __init is safe here */ +static int __init find_num_cache_leaves(void) +{ + unsigned int eax, ebx, ecx, edx; + union _cpuid4_leaf_eax cache_eax; + int i = -1; + + do { + ++i; + /* Do cpuid(4) loop to find out num_cache_leaves */ + cpuid_count(4, i, &eax, &ebx, &ecx, &edx); + cache_eax.full = eax; + } while (cache_eax.split.type != CACHE_TYPE_NULL); + return i; +} + +unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c) +{ + unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ + unsigned int new_l1d = 0, new_l1i = 0; /* Cache sizes from cpuid(4) */ + unsigned int new_l2 = 0, new_l3 = 0, i; /* Cache sizes from cpuid(4) */ + unsigned int l2_id = 0, l3_id = 0, num_threads_sharing, index_msb; +#ifdef CONFIG_SMP +#ifndef CONFIG_XEN + unsigned int cpu = (c == &boot_cpu_data) ? 0 : (c - cpu_data); +#endif +#endif + + if (c->cpuid_level > 3) { + static int is_initialized; + + if (is_initialized == 0) { + /* Init num_cache_leaves from boot CPU */ + num_cache_leaves = find_num_cache_leaves(); + is_initialized++; + } + + /* + * Whenever possible use cpuid(4), deterministic cache + * parameters cpuid leaf to find the cache details + */ + for (i = 0; i < num_cache_leaves; i++) { + struct _cpuid4_info this_leaf; + + int retval; + + retval = cpuid4_cache_lookup(i, &this_leaf); + if (retval >= 0) { + switch(this_leaf.eax.split.level) { + case 1: + if (this_leaf.eax.split.type == + CACHE_TYPE_DATA) + new_l1d = this_leaf.size/1024; + else if (this_leaf.eax.split.type == + CACHE_TYPE_INST) + new_l1i = this_leaf.size/1024; + break; + case 2: + new_l2 = this_leaf.size/1024; + num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; + index_msb = get_count_order(num_threads_sharing); + l2_id = c->apicid >> index_msb; + break; + case 3: + new_l3 = this_leaf.size/1024; + num_threads_sharing = 1 + this_leaf.eax.split.num_threads_sharing; + index_msb = get_count_order(num_threads_sharing); + l3_id = c->apicid >> index_msb; + break; + default: + break; + } + } + } + } + /* + * Don't use cpuid2 if cpuid4 is supported. For P4, we use cpuid2 for + * trace cache + */ + if ((num_cache_leaves == 0 || c->x86 == 15) && c->cpuid_level > 1) { + /* supports eax=2 call */ + int i, j, n; + int regs[4]; + unsigned char *dp = (unsigned char *)regs; + int only_trace = 0; + + if (num_cache_leaves != 0 && c->x86 == 15) + only_trace = 1; + + /* Number of times to iterate */ + n = cpuid_eax(2) & 0xFF; + + for ( i = 0 ; i < n ; i++ ) { + cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); + + /* If bit 31 is set, this is an unknown format */ + for ( j = 0 ; j < 3 ; j++ ) { + if ( regs[j] < 0 ) regs[j] = 0; + } + + /* Byte 0 is level count, not a descriptor */ + for ( j = 1 ; j < 16 ; j++ ) { + unsigned char des = dp[j]; + unsigned char k = 0; + + /* look up this descriptor in the table */ + while (cache_table[k].descriptor != 0) + { + if (cache_table[k].descriptor == des) { + if (only_trace && cache_table[k].cache_type != LVL_TRACE) + break; + switch (cache_table[k].cache_type) { + case LVL_1_INST: + l1i += cache_table[k].size; + break; + case LVL_1_DATA: + l1d += cache_table[k].size; + break; + case LVL_2: + l2 += cache_table[k].size; + break; + case LVL_3: + l3 += cache_table[k].size; + break; + case LVL_TRACE: + trace += cache_table[k].size; + break; + } + + break; + } + + k++; + } + } + } + } + + if (new_l1d) + l1d = new_l1d; + + if (new_l1i) + l1i = new_l1i; + + if (new_l2) { + l2 = new_l2; +#ifdef CONFIG_SMP +#ifndef CONFIG_XEN + cpu_llc_id[cpu] = l2_id; +#endif +#endif + } + + if (new_l3) { + l3 = new_l3; +#ifdef CONFIG_SMP +#ifndef CONFIG_XEN + cpu_llc_id[cpu] = l3_id; +#endif +#endif + } + + if (trace) + printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); + else if ( l1i ) + printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); + + if (l1d) + printk(", L1 D cache: %dK\n", l1d); + else + printk("\n"); + + if (l2) + printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); + + if (l3) + printk(KERN_INFO "CPU: L3 cache: %dK\n", l3); + + c->x86_cache_size = l3 ? l3 : (l2 ? l2 : (l1i+l1d)); + + return l2; +} + +/* pointer to _cpuid4_info array (for each cache leaf) */ +static struct _cpuid4_info *cpuid4_info[NR_CPUS]; +#define CPUID4_INFO_IDX(x,y) (&((cpuid4_info[x])[y])) + +#ifdef CONFIG_SMP +static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index) +{ + struct _cpuid4_info *this_leaf, *sibling_leaf; + unsigned long num_threads_sharing; + int index_msb, i; + struct cpuinfo_x86 *c = cpu_data; + + this_leaf = CPUID4_INFO_IDX(cpu, index); + num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing; + + if (num_threads_sharing == 1) + cpu_set(cpu, this_leaf->shared_cpu_map); + else { + index_msb = get_count_order(num_threads_sharing); + + for_each_online_cpu(i) { + if (c[i].apicid >> index_msb == + c[cpu].apicid >> index_msb) { + cpu_set(i, this_leaf->shared_cpu_map); + if (i != cpu && cpuid4_info[i]) { + sibling_leaf = CPUID4_INFO_IDX(i, index); + cpu_set(cpu, sibling_leaf->shared_cpu_map); + } + } + } + } +} +static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index) +{ + struct _cpuid4_info *this_leaf, *sibling_leaf; + int sibling; + + this_leaf = CPUID4_INFO_IDX(cpu, index); + for_each_cpu_mask(sibling, this_leaf->shared_cpu_map) { + sibling_leaf = CPUID4_INFO_IDX(sibling, index); + cpu_clear(cpu, sibling_leaf->shared_cpu_map); + } +} +#else +static void __init cache_shared_cpu_map_setup(unsigned int cpu, int index) {} +static void __init cache_remove_shared_cpu_map(unsigned int cpu, int index) {} +#endif + +static void free_cache_attributes(unsigned int cpu) +{ + kfree(cpuid4_info[cpu]); + cpuid4_info[cpu] = NULL; +} + +static int __cpuinit detect_cache_attributes(unsigned int cpu) +{ + struct _cpuid4_info *this_leaf; + unsigned long j; + int retval; + cpumask_t oldmask; + + if (num_cache_leaves == 0) + return -ENOENT; + + cpuid4_info[cpu] = kmalloc( + sizeof(struct _cpuid4_info) * num_cache_leaves, GFP_KERNEL); + if (unlikely(cpuid4_info[cpu] == NULL)) + return -ENOMEM; + memset(cpuid4_info[cpu], 0, + sizeof(struct _cpuid4_info) * num_cache_leaves); + + oldmask = current->cpus_allowed; + retval = set_cpus_allowed(current, cpumask_of_cpu(cpu)); + if (retval) + goto out; + + /* Do cpuid and store the results */ + retval = 0; + for (j = 0; j < num_cache_leaves; j++) { + this_leaf = CPUID4_INFO_IDX(cpu, j); + retval = cpuid4_cache_lookup(j, this_leaf); + if (unlikely(retval < 0)) + break; + cache_shared_cpu_map_setup(cpu, j); + } + set_cpus_allowed(current, oldmask); + +out: + if (retval) + free_cache_attributes(cpu); + return retval; +} + +#ifdef CONFIG_SYSFS + +#include +#include + +extern struct sysdev_class cpu_sysdev_class; /* from drivers/base/cpu.c */ + +/* pointer to kobject for cpuX/cache */ +static struct kobject * cache_kobject[NR_CPUS]; + +struct _index_kobject { + struct kobject kobj; + unsigned int cpu; + unsigned short index; +}; + +/* pointer to array of kobjects for cpuX/cache/indexY */ +static struct _index_kobject *index_kobject[NR_CPUS]; +#define INDEX_KOBJECT_PTR(x,y) (&((index_kobject[x])[y])) + +#define show_one_plus(file_name, object, val) \ +static ssize_t show_##file_name \ + (struct _cpuid4_info *this_leaf, char *buf) \ +{ \ + return sprintf (buf, "%lu\n", (unsigned long)this_leaf->object + val); \ +} + +show_one_plus(level, eax.split.level, 0); +show_one_plus(coherency_line_size, ebx.split.coherency_line_size, 1); +show_one_plus(physical_line_partition, ebx.split.physical_line_partition, 1); +show_one_plus(ways_of_associativity, ebx.split.ways_of_associativity, 1); +show_one_plus(number_of_sets, ecx.split.number_of_sets, 1); + +static ssize_t show_size(struct _cpuid4_info *this_leaf, char *buf) +{ + return sprintf (buf, "%luK\n", this_leaf->size / 1024); +} + +static ssize_t show_shared_cpu_map(struct _cpuid4_info *this_leaf, char *buf) +{ + char mask_str[NR_CPUS]; + cpumask_scnprintf(mask_str, NR_CPUS, this_leaf->shared_cpu_map); + return sprintf(buf, "%s\n", mask_str); +} + +static ssize_t show_type(struct _cpuid4_info *this_leaf, char *buf) { + switch(this_leaf->eax.split.type) { + case CACHE_TYPE_DATA: + return sprintf(buf, "Data\n"); + break; + case CACHE_TYPE_INST: + return sprintf(buf, "Instruction\n"); + break; + case CACHE_TYPE_UNIFIED: + return sprintf(buf, "Unified\n"); + break; + default: + return sprintf(buf, "Unknown\n"); + break; + } +} + +struct _cache_attr { + struct attribute attr; + ssize_t (*show)(struct _cpuid4_info *, char *); + ssize_t (*store)(struct _cpuid4_info *, const char *, size_t count); +}; + +#define define_one_ro(_name) \ +static struct _cache_attr _name = \ + __ATTR(_name, 0444, show_##_name, NULL) + +define_one_ro(level); +define_one_ro(type); +define_one_ro(coherency_line_size); +define_one_ro(physical_line_partition); +define_one_ro(ways_of_associativity); +define_one_ro(number_of_sets); +define_one_ro(size); +define_one_ro(shared_cpu_map); + +static struct attribute * default_attrs[] = { + &type.attr, + &level.attr, + &coherency_line_size.attr, + &physical_line_partition.attr, + &ways_of_associativity.attr, + &number_of_sets.attr, + &size.attr, + &shared_cpu_map.attr, + NULL +}; + +#define to_object(k) container_of(k, struct _index_kobject, kobj) +#define to_attr(a) container_of(a, struct _cache_attr, attr) + +static ssize_t show(struct kobject * kobj, struct attribute * attr, char * buf) +{ + struct _cache_attr *fattr = to_attr(attr); + struct _index_kobject *this_leaf = to_object(kobj); + ssize_t ret; + + ret = fattr->show ? + fattr->show(CPUID4_INFO_IDX(this_leaf->cpu, this_leaf->index), + buf) : + 0; + return ret; +} + +static ssize_t store(struct kobject * kobj, struct attribute * attr, + const char * buf, size_t count) +{ + return 0; +} + +static struct sysfs_ops sysfs_ops = { + .show = show, + .store = store, +}; + +static struct kobj_type ktype_cache = { + .sysfs_ops = &sysfs_ops, + .default_attrs = default_attrs, +}; + +static struct kobj_type ktype_percpu_entry = { + .sysfs_ops = &sysfs_ops, +}; + +static void cpuid4_cache_sysfs_exit(unsigned int cpu) +{ + kfree(cache_kobject[cpu]); + kfree(index_kobject[cpu]); + cache_kobject[cpu] = NULL; + index_kobject[cpu] = NULL; + free_cache_attributes(cpu); +} + +static int __cpuinit cpuid4_cache_sysfs_init(unsigned int cpu) +{ + + if (num_cache_leaves == 0) + return -ENOENT; + + detect_cache_attributes(cpu); + if (cpuid4_info[cpu] == NULL) + return -ENOENT; + + /* Allocate all required memory */ + cache_kobject[cpu] = kmalloc(sizeof(struct kobject), GFP_KERNEL); + if (unlikely(cache_kobject[cpu] == NULL)) + goto err_out; + memset(cache_kobject[cpu], 0, sizeof(struct kobject)); + + index_kobject[cpu] = kmalloc( + sizeof(struct _index_kobject ) * num_cache_leaves, GFP_KERNEL); + if (unlikely(index_kobject[cpu] == NULL)) + goto err_out; + memset(index_kobject[cpu], 0, + sizeof(struct _index_kobject) * num_cache_leaves); + + return 0; + +err_out: + cpuid4_cache_sysfs_exit(cpu); + return -ENOMEM; +} + +/* Add/Remove cache interface for CPU device */ +static int __cpuinit cache_add_dev(struct sys_device * sys_dev) +{ + unsigned int cpu = sys_dev->id; + unsigned long i, j; + struct _index_kobject *this_object; + int retval = 0; + + retval = cpuid4_cache_sysfs_init(cpu); + if (unlikely(retval < 0)) + return retval; + + cache_kobject[cpu]->parent = &sys_dev->kobj; + kobject_set_name(cache_kobject[cpu], "%s", "cache"); + cache_kobject[cpu]->ktype = &ktype_percpu_entry; + retval = kobject_register(cache_kobject[cpu]); + + for (i = 0; i < num_cache_leaves; i++) { + this_object = INDEX_KOBJECT_PTR(cpu,i); + this_object->cpu = cpu; + this_object->index = i; + this_object->kobj.parent = cache_kobject[cpu]; + kobject_set_name(&(this_object->kobj), "index%1lu", i); + this_object->kobj.ktype = &ktype_cache; + retval = kobject_register(&(this_object->kobj)); + if (unlikely(retval)) { + for (j = 0; j < i; j++) { + kobject_unregister( + &(INDEX_KOBJECT_PTR(cpu,j)->kobj)); + } + kobject_unregister(cache_kobject[cpu]); + cpuid4_cache_sysfs_exit(cpu); + break; + } + } + return retval; +} + +static void __cpuexit cache_remove_dev(struct sys_device * sys_dev) +{ + unsigned int cpu = sys_dev->id; + unsigned long i; + + for (i = 0; i < num_cache_leaves; i++) { + cache_remove_shared_cpu_map(cpu, i); + kobject_unregister(&(INDEX_KOBJECT_PTR(cpu,i)->kobj)); + } + kobject_unregister(cache_kobject[cpu]); + cpuid4_cache_sysfs_exit(cpu); + return; +} + +static int cacheinfo_cpu_callback(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + unsigned int cpu = (unsigned long)hcpu; + struct sys_device *sys_dev; + + sys_dev = get_cpu_sysdev(cpu); + switch (action) { + case CPU_ONLINE: + cache_add_dev(sys_dev); + break; + case CPU_DEAD: + cache_remove_dev(sys_dev); + break; + } + return NOTIFY_OK; +} + +static struct notifier_block cacheinfo_cpu_notifier = +{ + .notifier_call = cacheinfo_cpu_callback, +}; + +static int __cpuinit cache_sysfs_init(void) +{ + int i; + + if (num_cache_leaves == 0) + return 0; + + register_cpu_notifier(&cacheinfo_cpu_notifier); + + for_each_online_cpu(i) { + cacheinfo_cpu_callback(&cacheinfo_cpu_notifier, CPU_ONLINE, + (void *)(long)i); + } + + return 0; +} + +device_initcall(cache_sysfs_init); + +#endif diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c index 06720038ff..380e20ec5b 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/cpu/mtrr/main-xen.c @@ -4,11 +4,12 @@ #include #include #include +#include #include #include "mtrr.h" -static DECLARE_MUTEX(mtrr_sem); +static DEFINE_MUTEX(mtrr_mutex); void generic_get_mtrr(unsigned int reg, unsigned long *base, unsigned int *size, mtrr_type * type) @@ -65,7 +66,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, int error; dom0_op_t op; - down(&mtrr_sem); + mutex_lock(&mtrr_mutex); op.cmd = DOM0_ADD_MEMTYPE; op.u.add_memtype.mfn = base; @@ -73,7 +74,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, op.u.add_memtype.type = type; error = HYPERVISOR_dom0_op(&op); if (error) { - up(&mtrr_sem); + mutex_unlock(&mtrr_mutex); BUG_ON(error > 0); return error; } @@ -81,7 +82,7 @@ int mtrr_add_page(unsigned long base, unsigned long size, if (increment) ++usage_table[op.u.add_memtype.reg]; - up(&mtrr_sem); + mutex_unlock(&mtrr_mutex); return op.u.add_memtype.reg; } @@ -118,7 +119,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) int error = -EINVAL; dom0_op_t op; - down(&mtrr_sem); + mutex_lock(&mtrr_mutex); if (reg < 0) { /* Search for existing MTRR */ @@ -151,7 +152,7 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size) } error = reg; out: - up(&mtrr_sem); + mutex_unlock(&mtrr_mutex); return error; } diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/crash.c b/linux-2.6-xen-sparse/arch/i386/kernel/crash.c index 75aab8ef35..4b6698c7aa 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/crash.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/crash.c @@ -69,7 +69,7 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) * for the data I pass, and I need tags * on the data to indicate what information I have * squirrelled away. ELF notes happen to provide - * all of that that no need to invent something new. + * all of that, so there is no need to invent something new. */ buf = (u32*)per_cpu_ptr(crash_notes, cpu); if (!buf) @@ -106,7 +106,7 @@ static int crash_nmi_callback(struct pt_regs *regs, int cpu) return 1; local_irq_disable(); - if (!user_mode(regs)) { + if (!user_mode_vm(regs)) { crash_fixup_ss_esp(&fixed_regs, regs); regs = &fixed_regs; } diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S index 8c5ace45ef..75654a1c84 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S +++ b/linux-2.6-xen-sparse/arch/i386/kernel/entry-xen.S @@ -271,6 +271,10 @@ ENTRY(system_call) pushl %eax # save orig_eax SAVE_ALL GET_THREAD_INFO(%ebp) + testl $TF_MASK,EFLAGS(%esp) + jz no_singlestep + orl $_TIF_SINGLESTEP,TI_flags(%ebp) +no_singlestep: # system call tracing in operation / emulation /* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */ testw $(_TIF_SYSCALL_EMU|_TIF_SYSCALL_TRACE|_TIF_SECCOMP|_TIF_SYSCALL_AUDIT),TI_flags(%ebp) diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S index 1d0278c69b..edf86d6fb1 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S +++ b/linux-2.6-xen-sparse/arch/i386/kernel/head-xen.S @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,7 @@ ENTRY(empty_zero_page) /* * The Global Descriptor Table contains 28 quadwords, per-CPU. */ + .align L1_CACHE_BYTES ENTRY(cpu_gdt_table) .quad 0x0000000000000000 /* NULL descriptor */ .quad 0x0000000000000000 /* 0x0b reserved */ diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c index 844d6e9ad9..4b26c5bf8a 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/io_apic-xen.c @@ -394,8 +394,8 @@ static inline void rotate_irqs_among_cpus(unsigned long useful_load_threshold) { int i, j; Dprintk("Rotating IRQs among CPUs.\n"); - for (i = 0; i < NR_CPUS; i++) { - for (j = 0; cpu_online(i) && (j < NR_IRQS); j++) { + for_each_online_cpu(i) { + for (j = 0; j < NR_IRQS; j++) { if (!irq_desc[j].action) continue; /* Is it a significant load ? */ @@ -424,7 +424,7 @@ static void do_irq_balance(void) unsigned long imbalance = 0; cpumask_t allowed_mask, target_cpu_mask, tmp; - for (i = 0; i < NR_CPUS; i++) { + for_each_possible_cpu(i) { int package_index; CPU_IRQ(i) = 0; if (!cpu_online(i)) @@ -465,9 +465,7 @@ static void do_irq_balance(void) } } /* Find the least loaded processor package */ - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_online(i)) - continue; + for_each_online_cpu(i) { if (i != CPU_TO_PACKAGEINDEX(i)) continue; if (min_cpu_irq > CPU_IRQ(i)) { @@ -484,9 +482,7 @@ tryanothercpu: */ tmp_cpu_irq = 0; tmp_loaded = -1; - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_online(i)) - continue; + for_each_online_cpu(i) { if (i != CPU_TO_PACKAGEINDEX(i)) continue; if (max_cpu_irq <= CPU_IRQ(i)) @@ -662,9 +658,7 @@ static int __init balanced_irq_init(void) if (smp_num_siblings > 1 && !cpus_empty(tmp)) physical_balance = 1; - for (i = 0; i < NR_CPUS; i++) { - if (!cpu_online(i)) - continue; + for_each_online_cpu(i) { irq_cpu_data[i].irq_delta = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); irq_cpu_data[i].last_irq = kmalloc(sizeof(unsigned long) * NR_IRQS, GFP_KERNEL); if (irq_cpu_data[i].irq_delta == NULL || irq_cpu_data[i].last_irq == NULL) { @@ -681,9 +675,11 @@ static int __init balanced_irq_init(void) else printk(KERN_ERR "balanced_irq_init: failed to spawn balanced_irq"); failed: - for (i = 0; i < NR_CPUS; i++) { + for_each_possible_cpu(i) { kfree(irq_cpu_data[i].irq_delta); + irq_cpu_data[i].irq_delta = NULL; kfree(irq_cpu_data[i].last_irq); + irq_cpu_data[i].last_irq = NULL; } return 0; } @@ -691,7 +687,7 @@ failed: int __init irqbalance_disable(char *str) { irqbalance_disabled = 1; - return 0; + return 1; } __setup("noirqbalance", irqbalance_disable); @@ -1813,7 +1809,8 @@ static void __init setup_ioapic_ids_from_mpc(void) * Don't check I/O APIC IDs for xAPIC systems. They have * no meaning without the serial APIC bus. */ - if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL && boot_cpu_data.x86 < 15)) + if (!(boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) + || APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) return; /* * This is broken; anything with a real cpu count has to @@ -2298,6 +2295,8 @@ static inline void unlock_ExtINT_logic(void) spin_unlock_irqrestore(&ioapic_lock, flags); } +int timer_uses_ioapic_pin_0; + /* * This code may look a bit paranoid, but it's supposed to cooperate with * a wide range of boards and BIOS bugs. Fortunately only the timer IRQ @@ -2334,6 +2333,9 @@ static inline void check_timer(void) pin2 = ioapic_i8259.pin; apic2 = ioapic_i8259.apic; + if (pin1 == 0) + timer_uses_ioapic_pin_0 = 1; + printk(KERN_INFO "..TIMER: vector=0x%02X apic1=%d pin1=%d apic2=%d pin2=%d\n", vector, apic1, pin1, apic2, pin2); @@ -2419,6 +2421,7 @@ static inline void check_timer(void) "report. Then try booting with the 'noapic' option"); } #else +int timer_uses_ioapic_pin_0 = 0; #define check_timer() ((void)0) #endif diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c index 926ba175c3..c77a40b8fd 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/microcode-xen.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include @@ -49,7 +50,7 @@ MODULE_LICENSE("GPL"); #define DEFAULT_UCODE_TOTALSIZE (DEFAULT_UCODE_DATASIZE + MC_HEADER_SIZE) /* 2048 bytes */ /* no concurrent ->write()s are allowed on /dev/cpu/microcode */ -static DECLARE_MUTEX(microcode_sem); +static DEFINE_MUTEX(microcode_mutex); static int microcode_open (struct inode *unused1, struct file *unused2) { @@ -90,37 +91,20 @@ static ssize_t microcode_write (struct file *file, const char __user *buf, size_ return -EINVAL; } - down(µcode_sem); + mutex_lock(µcode_mutex); ret = do_microcode_update(buf, len); if (!ret) ret = (ssize_t)len; - up(µcode_sem); + mutex_unlock(µcode_mutex); return ret; } -static int microcode_ioctl (struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) -{ - switch (cmd) { - /* - * XXX: will be removed after microcode_ctl - * is updated to ignore failure of this ioctl() - */ - case MICROCODE_IOCFREE: - return 0; - default: - return -EINVAL; - } - return -EINVAL; -} - static struct file_operations microcode_fops = { .owner = THIS_MODULE, .write = microcode_write, - .ioctl = microcode_ioctl, .open = microcode_open, }; @@ -151,7 +135,6 @@ static int __init microcode_init (void) static void __exit microcode_exit (void) { misc_deregister(µcode_dev); - printk(KERN_INFO "IA-32 Microcode Update Driver v" MICROCODE_VERSION " unregistered\n"); } module_init(microcode_init) diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/mpparse-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/mpparse-xen.c index f5daedb2df..48e0bc0f8a 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/mpparse-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/mpparse-xen.c @@ -38,12 +38,6 @@ int smp_found_config; unsigned int __initdata maxcpus = NR_CPUS; -#ifdef CONFIG_HOTPLUG_CPU -#define CPU_HOTPLUG_ENABLED (1) -#else -#define CPU_HOTPLUG_ENABLED (0) -#endif - /* * Various Linux-internal data structures created from the * MP-table. @@ -110,21 +104,6 @@ static int __init mpf_checksum(unsigned char *mp, int len) static int mpc_record; static struct mpc_config_translation *translation_table[MAX_MPC_ENTRY] __initdata; -#ifdef CONFIG_X86_NUMAQ -static int MP_valid_apicid(int apicid, int version) -{ - return hweight_long(apicid & 0xf) == 1 && (apicid >> 4) != 0xf; -} -#elif !defined(CONFIG_XEN) -static int MP_valid_apicid(int apicid, int version) -{ - if (version >= 0x14) - return apicid < 0xff; - else - return apicid < 0xf; -} -#endif - #ifndef CONFIG_XEN static void __devinit MP_processor_info (struct mpc_config_processor *m) { @@ -191,12 +170,6 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m) ver = m->mpc_apicver; - if (!MP_valid_apicid(apicid, ver)) { - printk(KERN_WARNING "Processor #%d INVALID. (Max ID: %d).\n", - m->mpc_apicid, MAX_APICS); - return; - } - /* * Validate version */ @@ -226,7 +199,14 @@ static void __devinit MP_processor_info (struct mpc_config_processor *m) cpu_set(num_processors, cpu_possible_map); num_processors++; - if (CPU_HOTPLUG_ENABLED || (num_processors > 8)) { + /* + * Would be preferable to switch to bigsmp when CONFIG_HOTPLUG_CPU=y + * but we need to work other dependencies like SMP_SUSPEND etc + * before this can be done without some confusion. + * if (CPU_HOTPLUG_ENABLED || num_processors > 8) + * - Ashok Raj + */ + if (num_processors > 8) { switch (boot_cpu_data.x86_vendor) { case X86_VENDOR_INTEL: if (!APIC_XAPIC(ver)) { @@ -256,6 +236,13 @@ static void __init MP_bus_info (struct mpc_config_bus *m) mpc_oem_bus_info(m, str, translation_table[mpc_record]); + if (m->mpc_busid >= MAX_MP_BUSSES) { + printk(KERN_WARNING "MP table busid value (%d) for bustype %s " + " is too large, max. supported is %d\n", + m->mpc_busid, str, MAX_MP_BUSSES - 1); + return; + } + if (strncmp(str, BUSTYPE_ISA, sizeof(BUSTYPE_ISA)-1) == 0) { mp_bus_id_to_type[m->mpc_busid] = MP_BUS_ISA; } else if (strncmp(str, BUSTYPE_EISA, sizeof(BUSTYPE_EISA)-1) == 0) { @@ -844,6 +831,8 @@ void __init find_smp_config (void) #endif } +int es7000_plat; + /* -------------------------------------------------------------------------- ACPI-based MP Configuration -------------------------------------------------------------------------- */ @@ -957,7 +946,8 @@ void __init mp_register_ioapic ( #ifndef CONFIG_XEN set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address); #endif - if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) && (boot_cpu_data.x86 < 15)) + if ((boot_cpu_data.x86_vendor == X86_VENDOR_INTEL) + && !APIC_XAPIC(apic_version[boot_cpu_physical_apicid])) tmpid = io_apic_get_unique_id(idx, id); else tmpid = id; @@ -1033,8 +1023,6 @@ void __init mp_override_legacy_irq ( return; } -int es7000_plat; - void __init mp_config_acpi_legacy_irqs (void) { struct mpc_config_intsrc intsrc; @@ -1164,7 +1152,17 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity) */ int irq = gsi; if (gsi < MAX_GSI_NUM) { - if (gsi > 15) + /* + * Retain the VIA chipset work-around (gsi > 15), but + * avoid a problem where the 8254 timer (IRQ0) is setup + * via an override (so it's not on pin 0 of the ioapic), + * and at the same time, the pin 0 interrupt is a PCI + * type. The gsi > 15 test could cause these two pins + * to be shared as IRQ0, and they are not shareable. + * So test for this condition, and if necessary, avoid + * the pin collision. + */ + if (gsi > 15 || (gsi == 0 && !timer_uses_ioapic_pin_0)) gsi = pci_irq++; /* * Don't assign IRQ used by ACPI SCI diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c index 0dbc6a412e..b64dec23ec 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/process-xen.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -245,7 +244,7 @@ void show_regs(struct pt_regs * regs) printk("EIP: %04x:[<%08lx>] CPU: %d\n",0xffff & regs->xcs,regs->eip, smp_processor_id()); print_symbol("EIP is at %s\n", regs->eip); - if (user_mode(regs)) + if (user_mode_vm(regs)) printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); printk(" EFLAGS: %08lx %s (%s %.*s)\n", regs->eflags, print_tainted(), system_utsname.release, @@ -314,13 +313,6 @@ void exit_thread(void) struct task_struct *tsk = current; struct thread_struct *t = &tsk->thread; - /* - * Remove function-return probe instances associated with this task - * and put them back on the free list. Do not insert an exit probe for - * this function, it will be disabled by kprobe_flush_task if you do. - */ - kprobe_flush_task(tsk); - /* The process may have allocated an io port bitmap... nuke it. */ if (unlikely(NULL != t->io_bitmap_ptr)) { struct physdev_set_iobitmap set_iobitmap = { 0 }; @@ -731,7 +723,6 @@ unsigned long get_wchan(struct task_struct *p) } while (count++ < 16); return 0; } -EXPORT_SYMBOL(get_wchan); /* * sys_alloc_thread_area: get a yet unused TLS descriptor index. diff --git a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c index 819f36f11e..63d993b58f 100644 --- a/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c +++ b/linux-2.6-xen-sparse/arch/i386/kernel/setup-xen.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -49,6 +50,7 @@ #include #include #include +#include #include