ia64/xen-unstable
changeset 8527:8af1199488d3
Merged.
author | emellor@leeni.uk.xensource.com |
---|---|
date | Mon Jan 09 11:22:17 2006 +0000 (2006-01-09) |
parents | 25e3c8668f1f 299d6ff8fdb2 |
children | 0ba3b9d60da6 970cf1fff5f2 a51fcb5de470 |
files | tools/libxc/xc_linux_save.c tools/python/xen/lowlevel/xc/xc.c xen/common/grant_table.c |
line diff
1.1 --- a/.hgignore Mon Jan 09 11:19:55 2006 +0000 1.2 +++ b/.hgignore Mon Jan 09 11:22:17 2006 +0000 1.3 @@ -181,6 +181,7 @@ 1.4 ^xen/TAGS$ 1.5 ^xen/arch/x86/asm-offsets\.s$ 1.6 ^xen/arch/x86/boot/mkelf32$ 1.7 +^xen/arch/x86/xen\.lds$ 1.8 ^xen/ddb/.*$ 1.9 ^xen/include/asm$ 1.10 ^xen/include/asm-.*/asm-offsets\.h$
2.1 --- a/linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c Mon Jan 09 11:19:55 2006 +0000 2.2 +++ b/linux-2.6-xen-sparse/arch/ia64/xen/drivers/xenia64_init.c Mon Jan 09 11:22:17 2006 +0000 2.3 @@ -25,8 +25,9 @@ int xen_init(void) 2.4 2.5 xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT); 2.6 xen_start_info->flags = s->arch.flags; 2.7 - printk("Running on Xen! start_info_pfn=0x%lx lags=0x%x\n", 2.8 - s->arch.start_info_pfn, xen_start_info->flags); 2.9 + printk("Running on Xen! start_info_pfn=0x%lx nr_pages=%d flags=0x%x\n", 2.10 + s->arch.start_info_pfn, xen_start_info->nr_pages, 2.11 + xen_start_info->flags); 2.12 2.13 evtchn_init(); 2.14 initialized = 1;
3.1 --- a/linux-2.6-xen-sparse/arch/xen/Makefile Mon Jan 09 11:19:55 2006 +0000 3.2 +++ b/linux-2.6-xen-sparse/arch/xen/Makefile Mon Jan 09 11:22:17 2006 +0000 3.3 @@ -77,8 +77,6 @@ install kernel_install: 3.4 install -m0664 .config $(INSTALL_PATH)/boot/config-$(XINSTALL_NAME)$(INSTALL_SUFFIX) 3.5 install -m0664 System.map $(INSTALL_PATH)/boot/System.map-$(XINSTALL_NAME)$(INSTALL_SUFFIX) 3.6 ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_PATH)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX) 3.7 - mkdir -p $(INSTALL_PATH)/usr/include/xen/linux 3.8 - install -m0644 $(srctree)/include/asm-xen/linux-public/*.h $(INSTALL_PATH)/usr/include/xen/linux 3.9 3.10 archclean: 3.11 @if [ -e arch/xen/arch ]; then $(MAKE) $(clean)=arch/xen/arch; fi;
4.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/acpi/boot.c Mon Jan 09 11:19:55 2006 +0000 4.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/acpi/boot.c Mon Jan 09 11:22:17 2006 +0000 4.3 @@ -40,8 +40,6 @@ 4.4 #include <asm/fixmap.h> 4.5 #endif 4.6 4.7 -void (*pm_power_off)(void) = NULL; 4.8 - 4.9 #ifdef CONFIG_X86_64 4.10 4.11 static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) { }
5.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c Mon Jan 09 11:19:55 2006 +0000 5.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/cpu/mtrr/main.c Mon Jan 09 11:22:17 2006 +0000 5.3 @@ -67,8 +67,11 @@ int mtrr_add_page(unsigned long base, un 5.4 op.u.add_memtype.pfn = base; 5.5 op.u.add_memtype.nr_pfns = size; 5.6 op.u.add_memtype.type = type; 5.7 - if ((error = HYPERVISOR_dom0_op(&op))) 5.8 + error = HYPERVISOR_dom0_op(&op); 5.9 + if (error) { 5.10 + BUG_ON(error > 0); 5.11 return error; 5.12 + } 5.13 5.14 if (increment) 5.15 ++usage_table[op.u.add_memtype.reg]; 5.16 @@ -121,8 +124,12 @@ int mtrr_del_page(int reg, unsigned long 5.17 if (--usage_table[reg] < 1) { 5.18 op.cmd = DOM0_DEL_MEMTYPE; 5.19 op.u.del_memtype.handle = 0; 5.20 - op.u.add_memtype.reg = reg; 5.21 - (void)HYPERVISOR_dom0_op(&op); 5.22 + op.u.del_memtype.reg = reg; 5.23 + error = HYPERVISOR_dom0_op(&op); 5.24 + if (error) { 5.25 + BUG_ON(error > 0); 5.26 + goto out; 5.27 + } 5.28 } 5.29 error = reg; 5.30 out:
6.1 --- a/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c Mon Jan 09 11:19:55 2006 +0000 6.2 +++ b/linux-2.6-xen-sparse/arch/xen/i386/kernel/i386_ksyms.c Mon Jan 09 11:22:17 2006 +0000 6.3 @@ -76,9 +76,7 @@ EXPORT_SYMBOL(ioremap_nocache); 6.4 EXPORT_SYMBOL(iounmap); 6.5 EXPORT_SYMBOL(kernel_thread); 6.6 EXPORT_SYMBOL(pm_idle); 6.7 -#ifdef CONFIG_ACPI_BOOT 6.8 EXPORT_SYMBOL(pm_power_off); 6.9 -#endif 6.10 EXPORT_SYMBOL(get_cmos_time); 6.11 EXPORT_SYMBOL(cpu_khz); 6.12 EXPORT_SYMBOL(apm_info);
7.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Mon Jan 09 11:19:55 2006 +0000 7.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/gnttab.c Mon Jan 09 11:22:17 2006 +0000 7.3 @@ -389,6 +389,30 @@ grant_write(struct file *file, const cha 7.4 return -ENOSYS; 7.5 } 7.6 7.7 +static int __init 7.8 +gnttab_proc_init(void) 7.9 +{ 7.10 + /* 7.11 + * /proc/xen/grant : used by libxc to access grant tables 7.12 + */ 7.13 + if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) { 7.14 + WPRINTK("Unable to create grant xen proc entry\n"); 7.15 + return -1; 7.16 + } 7.17 + 7.18 + grant_file_ops.read = grant_pde->proc_fops->read; 7.19 + grant_file_ops.write = grant_pde->proc_fops->write; 7.20 + 7.21 + grant_pde->proc_fops = &grant_file_ops; 7.22 + 7.23 + grant_pde->read_proc = &grant_read; 7.24 + grant_pde->write_proc = &grant_write; 7.25 + 7.26 + return 0; 7.27 +} 7.28 + 7.29 +device_initcall(gnttab_proc_init); 7.30 + 7.31 #endif /* CONFIG_PROC_FS */ 7.32 7.33 int 7.34 @@ -446,29 +470,11 @@ gnttab_init(void) 7.35 gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES; 7.36 gnttab_free_head = NR_RESERVED_ENTRIES; 7.37 7.38 -#ifdef CONFIG_PROC_FS 7.39 - /* 7.40 - * /proc/xen/grant : used by libxc to access grant tables 7.41 - */ 7.42 - if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) { 7.43 - WPRINTK("Unable to create grant xen proc entry\n"); 7.44 - return -1; 7.45 - } 7.46 - 7.47 - grant_file_ops.read = grant_pde->proc_fops->read; 7.48 - grant_file_ops.write = grant_pde->proc_fops->write; 7.49 - 7.50 - grant_pde->proc_fops = &grant_file_ops; 7.51 - 7.52 - grant_pde->read_proc = &grant_read; 7.53 - grant_pde->write_proc = &grant_write; 7.54 -#endif 7.55 - 7.56 printk("Grant table initialized\n"); 7.57 return 0; 7.58 } 7.59 7.60 -__initcall(gnttab_init); 7.61 +core_initcall(gnttab_init); 7.62 7.63 /* 7.64 * Local variables:
8.1 --- a/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Mon Jan 09 11:19:55 2006 +0000 8.2 +++ b/linux-2.6-xen-sparse/arch/xen/kernel/reboot.c Mon Jan 09 11:22:17 2006 +0000 8.3 @@ -17,6 +17,13 @@ 8.4 #include <linux/kthread.h> 8.5 #include <asm-xen/xencons.h> 8.6 8.7 +#if defined(__i386__) || defined(__x86_64__) 8.8 +/* 8.9 + * Power off function, if any 8.10 + */ 8.11 +void (*pm_power_off)(void); 8.12 +#endif 8.13 + 8.14 #define SHUTDOWN_INVALID -1 8.15 #define SHUTDOWN_POWEROFF 0 8.16 #define SHUTDOWN_REBOOT 1
9.1 --- a/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c Mon Jan 09 11:19:55 2006 +0000 9.2 +++ b/linux-2.6-xen-sparse/arch/xen/x86_64/kernel/x8664_ksyms.c Mon Jan 09 11:22:17 2006 +0000 9.3 @@ -59,9 +59,7 @@ EXPORT_SYMBOL(disable_irq_nosync); 9.4 EXPORT_SYMBOL(probe_irq_mask); 9.5 EXPORT_SYMBOL(kernel_thread); 9.6 EXPORT_SYMBOL(pm_idle); 9.7 -#ifdef CONFIG_ACPI_BOOT 9.8 EXPORT_SYMBOL(pm_power_off); 9.9 -#endif 9.10 EXPORT_SYMBOL(get_cmos_time); 9.11 9.12 EXPORT_SYMBOL(__down_failed);
10.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Mon Jan 09 11:19:55 2006 +0000 10.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c Mon Jan 09 11:22:17 2006 +0000 10.3 @@ -540,6 +540,9 @@ static int __init blkif_init(void) 10.4 pending_vaddrs = kmalloc(sizeof(pending_vaddrs[0]) * 10.5 mmap_pages, GFP_KERNEL); 10.6 if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) { 10.7 + kfree(pending_reqs); 10.8 + kfree(pending_grant_handles); 10.9 + kfree(pending_vaddrs); 10.10 printk("%s: out of memory\n", __FUNCTION__); 10.11 return -1; 10.12 }
11.1 --- a/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon Jan 09 11:19:55 2006 +0000 11.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blkfront/blkfront.c Mon Jan 09 11:22:17 2006 +0000 11.3 @@ -331,7 +331,12 @@ static void connect(struct blkfront_info 11.4 return; 11.5 } 11.6 11.7 - xlvbd_add(sectors, info->vdevice, binfo, sector_size, info); 11.8 + err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info); 11.9 + if (err) { 11.10 + xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s", 11.11 + info->xbdev->otherend); 11.12 + return; 11.13 + } 11.14 11.15 (void)xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected); 11.16
12.1 --- a/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Mon Jan 09 11:19:55 2006 +0000 12.2 +++ b/linux-2.6-xen-sparse/drivers/xen/blktap/blktap.c Mon Jan 09 11:22:17 2006 +0000 12.3 @@ -208,7 +208,7 @@ static struct page *blktap_nopage(struct 12.4 } 12.5 12.6 struct vm_operations_struct blktap_vm_ops = { 12.7 - nopage: blktap_nopage, 12.8 + .nopage = blktap_nopage, 12.9 }; 12.10 12.11 /****************************************************************** 12.12 @@ -225,7 +225,7 @@ static int blktap_open(struct inode *ino 12.13 /* Allocate the fe ring. */ 12.14 sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL); 12.15 if (sring == NULL) 12.16 - goto fail_nomem; 12.17 + return -ENOMEM; 12.18 12.19 SetPageReserved(virt_to_page(sring)); 12.20 12.21 @@ -233,9 +233,6 @@ static int blktap_open(struct inode *ino 12.22 FRONT_RING_INIT(&blktap_ufe_ring, sring, PAGE_SIZE); 12.23 12.24 return 0; 12.25 - 12.26 - fail_nomem: 12.27 - return -ENOMEM; 12.28 } 12.29 12.30 static int blktap_release(struct inode *inode, struct file *filp) 12.31 @@ -391,12 +388,12 @@ void blktap_kick_user(void) 12.32 } 12.33 12.34 static struct file_operations blktap_fops = { 12.35 - owner: THIS_MODULE, 12.36 - poll: blktap_poll, 12.37 - ioctl: blktap_ioctl, 12.38 - open: blktap_open, 12.39 - release: blktap_release, 12.40 - mmap: blktap_mmap, 12.41 + .owner = THIS_MODULE, 12.42 + .poll = blktap_poll, 12.43 + .ioctl = blktap_ioctl, 12.44 + .open = blktap_open, 12.45 + .release = blktap_release, 12.46 + .mmap = blktap_mmap, 12.47 }; 12.48 12.49
13.1 --- a/linux-2.6-xen-sparse/drivers/xen/console/console.c Mon Jan 09 11:19:55 2006 +0000 13.2 +++ b/linux-2.6-xen-sparse/drivers/xen/console/console.c Mon Jan 09 11:22:17 2006 +0000 13.3 @@ -314,39 +314,31 @@ static void __xencons_tx_flush(void) 13.4 { 13.5 int sent, sz, work_done = 0; 13.6 13.7 - if (xen_start_info->flags & SIF_INITDOMAIN) { 13.8 - if (x_char) { 13.9 + if (x_char) { 13.10 + if (xen_start_info->flags & SIF_INITDOMAIN) 13.11 kcons_write_dom0(NULL, &x_char, 1); 13.12 - x_char = 0; 13.13 - work_done = 1; 13.14 - } 13.15 + else 13.16 + while (x_char) 13.17 + if (xencons_ring_send(&x_char, 1) == 1) 13.18 + break; 13.19 + x_char = 0; 13.20 + work_done = 1; 13.21 + } 13.22 13.23 - while (wc != wp) { 13.24 - sz = wp - wc; 13.25 - if (sz > (wbuf_size - WBUF_MASK(wc))) 13.26 - sz = wbuf_size - WBUF_MASK(wc); 13.27 + while (wc != wp) { 13.28 + sz = wp - wc; 13.29 + if (sz > (wbuf_size - WBUF_MASK(wc))) 13.30 + sz = wbuf_size - WBUF_MASK(wc); 13.31 + if (xen_start_info->flags & SIF_INITDOMAIN) { 13.32 kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz); 13.33 wc += sz; 13.34 - work_done = 1; 13.35 - } 13.36 - } else { 13.37 - while (x_char) { 13.38 - if (xencons_ring_send(&x_char, 1) == 1) { 13.39 - x_char = 0; 13.40 - work_done = 1; 13.41 - } 13.42 - } 13.43 - 13.44 - while (wc != wp) { 13.45 - sz = wp - wc; 13.46 - if (sz > (wbuf_size - WBUF_MASK(wc))) 13.47 - sz = wbuf_size - WBUF_MASK(wc); 13.48 + } else { 13.49 sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz); 13.50 if (sent == 0) 13.51 break; 13.52 wc += sent; 13.53 - work_done = 1; 13.54 } 13.55 + work_done = 1; 13.56 } 13.57 13.58 if (work_done && (xencons_tty != NULL)) {
14.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Mon Jan 09 11:19:55 2006 +0000 14.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Mon Jan 09 11:22:17 2006 +0000 14.3 @@ -82,7 +82,7 @@ typedef struct netif_st { 14.4 #define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE) 14.5 14.6 void netif_creditlimit(netif_t *netif); 14.7 -int netif_disconnect(netif_t *netif); 14.8 +void netif_disconnect(netif_t *netif); 14.9 14.10 netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]); 14.11 void free_netif(netif_t *netif);
15.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Mon Jan 09 11:19:55 2006 +0000 15.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Mon Jan 09 11:22:17 2006 +0000 15.3 @@ -183,7 +183,7 @@ static void unmap_frontend_pages(netif_t 15.4 int netif_map(netif_t *netif, unsigned long tx_ring_ref, 15.5 unsigned long rx_ring_ref, unsigned int evtchn) 15.6 { 15.7 - int err; 15.8 + int err = -ENOMEM; 15.9 netif_tx_sring_t *txs; 15.10 netif_rx_sring_t *rxs; 15.11 evtchn_op_t op = { 15.12 @@ -196,24 +196,19 @@ int netif_map(netif_t *netif, unsigned l 15.13 return 0; 15.14 15.15 netif->tx_comms_area = alloc_vm_area(PAGE_SIZE); 15.16 + if (netif->tx_comms_area == NULL) 15.17 + return -ENOMEM; 15.18 netif->rx_comms_area = alloc_vm_area(PAGE_SIZE); 15.19 - if (netif->tx_comms_area == NULL || netif->rx_comms_area == NULL) 15.20 - return -ENOMEM; 15.21 + if (netif->rx_comms_area == NULL) 15.22 + goto err_rx; 15.23 15.24 err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref); 15.25 - if (err) { 15.26 - free_vm_area(netif->tx_comms_area); 15.27 - free_vm_area(netif->rx_comms_area); 15.28 - return err; 15.29 - } 15.30 + if (err) 15.31 + goto err_map; 15.32 15.33 err = HYPERVISOR_event_channel_op(&op); 15.34 - if (err) { 15.35 - unmap_frontend_pages(netif); 15.36 - free_vm_area(netif->tx_comms_area); 15.37 - free_vm_area(netif->rx_comms_area); 15.38 - return err; 15.39 - } 15.40 + if (err) 15.41 + goto err_hypervisor; 15.42 15.43 netif->evtchn = op.u.bind_interdomain.local_port; 15.44 15.45 @@ -241,19 +236,22 @@ int netif_map(netif_t *netif, unsigned l 15.46 rtnl_unlock(); 15.47 15.48 return 0; 15.49 +err_hypervisor: 15.50 + unmap_frontend_pages(netif); 15.51 +err_map: 15.52 + free_vm_area(netif->rx_comms_area); 15.53 +err_rx: 15.54 + free_vm_area(netif->tx_comms_area); 15.55 + return err; 15.56 } 15.57 15.58 static void free_netif_callback(void *arg) 15.59 { 15.60 netif_t *netif = (netif_t *)arg; 15.61 15.62 - /* Already disconnected? */ 15.63 - if (!netif->irq) 15.64 - return; 15.65 - 15.66 - unbind_from_irqhandler(netif->irq, netif); 15.67 - netif->irq = 0; 15.68 - 15.69 + if (netif->irq) 15.70 + unbind_from_irqhandler(netif->irq, netif); 15.71 + 15.72 unregister_netdev(netif->dev); 15.73 15.74 if (netif->tx.sring) { 15.75 @@ -290,10 +288,10 @@ void netif_creditlimit(netif_t *netif) 15.76 #endif 15.77 } 15.78 15.79 -int netif_disconnect(netif_t *netif) 15.80 +void netif_disconnect(netif_t *netif) 15.81 { 15.82 - 15.83 - if (netif->status == CONNECTED) { 15.84 + switch (netif->status) { 15.85 + case CONNECTED: 15.86 rtnl_lock(); 15.87 netif->status = DISCONNECTING; 15.88 wmb(); 15.89 @@ -301,10 +299,14 @@ int netif_disconnect(netif_t *netif) 15.90 __netif_down(netif); 15.91 rtnl_unlock(); 15.92 netif_put(netif); 15.93 - return 0; /* Caller should not send response message. */ 15.94 + break; 15.95 + case DISCONNECTED: 15.96 + BUG_ON(atomic_read(&netif->refcnt) != 0); 15.97 + free_netif(netif); 15.98 + break; 15.99 + default: 15.100 + BUG(); 15.101 } 15.102 - 15.103 - return 1; 15.104 } 15.105 15.106 /*
16.1 --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon Jan 09 11:19:55 2006 +0000 16.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Mon Jan 09 11:22:17 2006 +0000 16.3 @@ -14,6 +14,7 @@ 16.4 #include <asm-xen/balloon.h> 16.5 #include <asm-xen/xen-public/memory.h> 16.6 16.7 +/*#define NETBE_DEBUG_INTERRUPT*/ 16.8 16.9 static void netif_idx_release(u16 pending_idx); 16.10 static void netif_page_release(struct page *page); 16.11 @@ -727,6 +728,7 @@ static int make_rx_response(netif_t *net 16.12 return notify; 16.13 } 16.14 16.15 +#ifdef NETBE_DEBUG_INTERRUPT 16.16 static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs) 16.17 { 16.18 struct list_head *ent; 16.19 @@ -758,6 +760,7 @@ static irqreturn_t netif_be_dbg(int irq, 16.20 16.21 return IRQ_HANDLED; 16.22 } 16.23 +#endif 16.24 16.25 static int __init netback_init(void) 16.26 { 16.27 @@ -794,6 +797,7 @@ static int __init netback_init(void) 16.28 16.29 netif_xenbus_init(); 16.30 16.31 +#ifdef NETBE_DEBUG_INTERRUPT 16.32 (void)bind_virq_to_irqhandler( 16.33 VIRQ_DEBUG, 16.34 0, 16.35 @@ -801,6 +805,7 @@ static int __init netback_init(void) 16.36 SA_SHIRQ, 16.37 "net-be-dbg", 16.38 &netif_be_dbg); 16.39 +#endif 16.40 16.41 return 0; 16.42 }
17.1 --- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon Jan 09 11:19:55 2006 +0000 17.2 +++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Mon Jan 09 11:22:17 2006 +0000 17.3 @@ -117,6 +117,8 @@ struct netfront_info 17.4 int rx_min_target, rx_max_target, rx_target; 17.5 struct sk_buff_head rx_batch; 17.6 17.7 + struct timer_list rx_refill_timer; 17.8 + 17.9 /* 17.10 * {tx,rx}_skbs store outstanding skbuffs. The first entry in each 17.11 * array is an index into a chain of free entries. 17.12 @@ -517,6 +519,13 @@ static void network_tx_buf_gc(struct net 17.13 } 17.14 17.15 17.16 +static void rx_refill_timeout(unsigned long data) 17.17 +{ 17.18 + struct net_device *dev = (struct net_device *)data; 17.19 + netif_rx_schedule(dev); 17.20 +} 17.21 + 17.22 + 17.23 static void network_alloc_rx_buffers(struct net_device *dev) 17.24 { 17.25 unsigned short id; 17.26 @@ -534,7 +543,7 @@ static void network_alloc_rx_buffers(str 17.27 * Allocate skbuffs greedily, even though we batch updates to the 17.28 * receive ring. This creates a less bursty demand on the memory 17.29 * allocator, so should reduce the chance of failed allocation requests 17.30 - * both for ourself and for other kernel subsystems. 17.31 + * both for ourself and for other kernel subsystems. 17.32 */ 17.33 batch_target = np->rx_target - (req_prod - np->rx.rsp_cons); 17.34 for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) { 17.35 @@ -545,8 +554,15 @@ static void network_alloc_rx_buffers(str 17.36 skb = alloc_xen_skb( 17.37 ((PAGE_SIZE - sizeof(struct skb_shared_info)) & 17.38 (-SKB_DATA_ALIGN(1))) - 16); 17.39 - if (skb == NULL) 17.40 - break; 17.41 + if (skb == NULL) { 17.42 + /* Any skbuffs queued for refill? Force them out. */ 17.43 + if (i != 0) 17.44 + goto refill; 17.45 + /* Could not allocate any skbuffs. Try again later. */ 17.46 + mod_timer(&np->rx_refill_timer, 17.47 + jiffies + (HZ/10)); 17.48 + return; 17.49 + } 17.50 __skb_queue_tail(&np->rx_batch, skb); 17.51 } 17.52 17.53 @@ -554,6 +570,12 @@ static void network_alloc_rx_buffers(str 17.54 if (i < (np->rx_target/2)) 17.55 return; 17.56 17.57 + /* Adjust our fill target if we risked running out of buffers. */ 17.58 + if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) && 17.59 + ((np->rx_target *= 2) > np->rx_max_target)) 17.60 + np->rx_target = np->rx_max_target; 17.61 + 17.62 + refill: 17.63 for (i = 0; ; i++) { 17.64 if ((skb = __skb_dequeue(&np->rx_batch)) == NULL) 17.65 break; 17.66 @@ -608,11 +630,6 @@ static void network_alloc_rx_buffers(str 17.67 /* Above is a suitable barrier to ensure backend will see requests. */ 17.68 np->rx.req_prod_pvt = req_prod + i; 17.69 RING_PUSH_REQUESTS(&np->rx); 17.70 - 17.71 - /* Adjust our fill target if we risked running out of buffers. */ 17.72 - if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) && 17.73 - ((np->rx_target *= 2) > np->rx_max_target)) 17.74 - np->rx_target = np->rx_max_target; 17.75 } 17.76 17.77 17.78 @@ -1077,6 +1094,10 @@ static int create_netdev(int handle, str 17.79 np->rx_min_target = RX_MIN_TARGET; 17.80 np->rx_max_target = RX_MAX_TARGET; 17.81 17.82 + init_timer(&np->rx_refill_timer); 17.83 + np->rx_refill_timer.data = (unsigned long)netdev; 17.84 + np->rx_refill_timer.function = rx_refill_timeout; 17.85 + 17.86 /* Initialise {tx,rx}_skbs as a free chain containing every entry. */ 17.87 for (i = 0; i <= NET_TX_RING_SIZE; i++) { 17.88 np->tx_skbs[i] = (void *)((unsigned long) i+1); 17.89 @@ -1188,29 +1209,26 @@ static int netfront_remove(struct xenbus 17.90 17.91 DPRINTK("%s\n", dev->nodename); 17.92 17.93 - netif_free(info); 17.94 - kfree(info); 17.95 + netif_disconnect_backend(info); 17.96 + free_netdev(info->netdev); 17.97 17.98 return 0; 17.99 } 17.100 17.101 17.102 -static void netif_free(struct netfront_info *info) 17.103 -{ 17.104 - netif_disconnect_backend(info); 17.105 - close_netdev(info); 17.106 -} 17.107 - 17.108 - 17.109 static void close_netdev(struct netfront_info *info) 17.110 { 17.111 - if (info->netdev) { 17.112 + spin_lock_irq(&info->netdev->xmit_lock); 17.113 + netif_stop_queue(info->netdev); 17.114 + spin_unlock_irq(&info->netdev->xmit_lock); 17.115 + 17.116 #ifdef CONFIG_PROC_FS 17.117 - xennet_proc_delif(info->netdev); 17.118 + xennet_proc_delif(info->netdev); 17.119 #endif 17.120 - unregister_netdev(info->netdev); 17.121 - info->netdev = NULL; 17.122 - } 17.123 + 17.124 + del_timer_sync(&info->rx_refill_timer); 17.125 + 17.126 + unregister_netdev(info->netdev); 17.127 } 17.128 17.129 17.130 @@ -1219,21 +1237,28 @@ static void netif_disconnect_backend(str 17.131 /* Stop old i/f to prevent errors whilst we rebuild the state. */ 17.132 spin_lock_irq(&info->tx_lock); 17.133 spin_lock(&info->rx_lock); 17.134 - netif_stop_queue(info->netdev); 17.135 - /* info->backend_state = BEST_DISCONNECTED; */ 17.136 + info->backend_state = BEST_DISCONNECTED; 17.137 spin_unlock(&info->rx_lock); 17.138 spin_unlock_irq(&info->tx_lock); 17.139 - 17.140 + 17.141 + if (info->irq) 17.142 + unbind_from_irqhandler(info->irq, info->netdev); 17.143 + info->evtchn = info->irq = 0; 17.144 + 17.145 end_access(info->tx_ring_ref, info->tx.sring); 17.146 end_access(info->rx_ring_ref, info->rx.sring); 17.147 info->tx_ring_ref = GRANT_INVALID_REF; 17.148 info->rx_ring_ref = GRANT_INVALID_REF; 17.149 info->tx.sring = NULL; 17.150 info->rx.sring = NULL; 17.151 +} 17.152 17.153 - if (info->irq) 17.154 - unbind_from_irqhandler(info->irq, info->netdev); 17.155 - info->evtchn = info->irq = 0; 17.156 + 17.157 +static void netif_free(struct netfront_info *info) 17.158 +{ 17.159 + close_netdev(info); 17.160 + netif_disconnect_backend(info); 17.161 + free_netdev(info->netdev); 17.162 } 17.163 17.164
18.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Mon Jan 09 11:19:55 2006 +0000 18.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_dev.c Mon Jan 09 11:22:17 2006 +0000 18.3 @@ -111,7 +111,6 @@ static ssize_t xenbus_dev_write(struct f 18.4 struct xenbus_dev_data *u = filp->private_data; 18.5 struct xenbus_dev_transaction *trans; 18.6 void *reply; 18.7 - int err = 0; 18.8 18.9 if ((len + u->len) > sizeof(u->u.buffer)) 18.10 return -EINVAL; 18.11 @@ -136,41 +135,36 @@ static ssize_t xenbus_dev_write(struct f 18.12 case XS_RM: 18.13 case XS_SET_PERMS: 18.14 reply = xenbus_dev_request_and_reply(&u->u.msg); 18.15 - if (IS_ERR(reply)) { 18.16 - err = PTR_ERR(reply); 18.17 - } else { 18.18 - if (u->u.msg.type == XS_TRANSACTION_START) { 18.19 - trans = kmalloc(sizeof(*trans), GFP_KERNEL); 18.20 - trans->handle = (struct xenbus_transaction *) 18.21 - simple_strtoul(reply, NULL, 0); 18.22 - list_add(&trans->list, &u->transactions); 18.23 - } else if (u->u.msg.type == XS_TRANSACTION_END) { 18.24 - list_for_each_entry(trans, &u->transactions, 18.25 - list) 18.26 - if ((unsigned long)trans->handle == 18.27 - (unsigned long)u->u.msg.tx_id) 18.28 - break; 18.29 - BUG_ON(&trans->list == &u->transactions); 18.30 - list_del(&trans->list); 18.31 - kfree(trans); 18.32 - } 18.33 - queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg)); 18.34 - queue_reply(u, (char *)reply, u->u.msg.len); 18.35 - kfree(reply); 18.36 + if (IS_ERR(reply)) 18.37 + return PTR_ERR(reply); 18.38 + 18.39 + if (u->u.msg.type == XS_TRANSACTION_START) { 18.40 + trans = kmalloc(sizeof(*trans), GFP_KERNEL); 18.41 + if (!trans) 18.42 + return -ENOMEM; 18.43 + trans->handle = (struct xenbus_transaction *) 18.44 + simple_strtoul(reply, NULL, 0); 18.45 + list_add(&trans->list, &u->transactions); 18.46 + } else if (u->u.msg.type == XS_TRANSACTION_END) { 18.47 + list_for_each_entry(trans, &u->transactions, list) 18.48 + if ((unsigned long)trans->handle == 18.49 + (unsigned long)u->u.msg.tx_id) 18.50 + break; 18.51 + BUG_ON(&trans->list == &u->transactions); 18.52 + list_del(&trans->list); 18.53 + kfree(trans); 18.54 } 18.55 + queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg)); 18.56 + queue_reply(u, (char *)reply, u->u.msg.len); 18.57 + kfree(reply); 18.58 break; 18.59 18.60 default: 18.61 - err = -EINVAL; 18.62 - break; 18.63 + return -EINVAL; 18.64 } 18.65 18.66 - if (err == 0) { 18.67 - u->len = 0; 18.68 - err = len; 18.69 - } 18.70 - 18.71 - return err; 18.72 + u->len = 0; 18.73 + return len; 18.74 } 18.75 18.76 static int xenbus_dev_open(struct inode *inode, struct file *filp)
19.1 --- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon Jan 09 11:19:55 2006 +0000 19.2 +++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_probe.c Mon Jan 09 11:22:17 2006 +0000 19.3 @@ -542,14 +542,6 @@ static int xenbus_probe_node(struct xen_ 19.4 const char *type, 19.5 const char *nodename) 19.6 { 19.7 -#define CHECK_FAIL \ 19.8 - do { \ 19.9 - if (err) \ 19.10 - goto fail; \ 19.11 - } \ 19.12 - while (0) \ 19.13 - 19.14 - 19.15 int err; 19.16 struct xenbus_device *xendev; 19.17 size_t stringlen; 19.18 @@ -584,19 +576,18 @@ static int xenbus_probe_node(struct xen_ 19.19 xendev->dev.release = xenbus_dev_release; 19.20 19.21 err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename); 19.22 - CHECK_FAIL; 19.23 + if (err) 19.24 + goto fail; 19.25 19.26 /* Register with generic device framework. */ 19.27 err = device_register(&xendev->dev); 19.28 - CHECK_FAIL; 19.29 + if (err) 19.30 + goto fail; 19.31 19.32 device_create_file(&xendev->dev, &dev_attr_nodename); 19.33 device_create_file(&xendev->dev, &dev_attr_devtype); 19.34 19.35 return 0; 19.36 - 19.37 -#undef CHECK_FAIL 19.38 - 19.39 fail: 19.40 xenbus_dev_free(xendev); 19.41 return err;
20.1 --- a/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h Mon Jan 09 11:19:55 2006 +0000 20.2 +++ b/linux-2.6-xen-sparse/include/asm-xen/asm-ia64/hypercall.h Mon Jan 09 11:22:17 2006 +0000 20.3 @@ -372,7 +372,7 @@ HYPERVISOR_memory_op( 20.4 int ret; 20.5 __asm__ __volatile__ ( ";; mov r14=%2 ; mov r15=%3 ; mov r2=%1 ; break 0x1000 ;; mov %0=r8 ;;" 20.6 : "=r" (ret) 20.7 - : "i" (__HYPERVISOR_console_io), "r"(cmd), "r"(arg) 20.8 + : "i" (__HYPERVISOR_memory_op), "r"(cmd), "r"(arg) 20.9 : "r14","r15","r2","r8","memory" ); 20.10 return ret; 20.11 }
21.1 --- a/tools/Makefile Mon Jan 09 11:19:55 2006 +0000 21.2 +++ b/tools/Makefile Mon Jan 09 11:22:17 2006 +0000 21.3 @@ -12,6 +12,7 @@ SUBDIRS += firmware 21.4 SUBDIRS += security 21.5 SUBDIRS += console 21.6 SUBDIRS += xenmon 21.7 +SUBDIRS += guest-headers 21.8 ifeq ($(VTPM_TOOLS),y) 21.9 SUBDIRS += vtpm_manager 21.10 SUBDIRS += vtpm
22.1 --- a/tools/Rules.mk Mon Jan 09 11:19:55 2006 +0000 22.2 +++ b/tools/Rules.mk Mon Jan 09 11:22:17 2006 +0000 22.3 @@ -35,6 +35,8 @@ mk-symlinks: LINUX_ROOT=$(XEN_ROOT)/linu 22.4 mk-symlinks: 22.5 mkdir -p xen 22.6 ( cd xen && ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . ) 22.7 + mkdir -p xen/hvm 22.8 + ( cd xen/hvm && ln -sf ../../$(XEN_ROOT)/xen/include/public/hvm/*.h . ) 22.9 mkdir -p xen/io 22.10 ( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . ) 22.11 mkdir -p xen/linux
23.1 --- a/tools/debugger/libxendebug/xendebug.c Mon Jan 09 11:19:55 2006 +0000 23.2 +++ b/tools/debugger/libxendebug/xendebug.c Mon Jan 09 11:22:17 2006 +0000 23.3 @@ -119,8 +119,8 @@ xendebug_get_context (int xc_handle, uin 23.4 23.5 if ( !ctxt->valid[vcpu] ) 23.6 { 23.7 - if ( (rc = xc_domain_get_vcpu_context(xc_handle, domid, vcpu, 23.8 - &ctxt->context[vcpu])) ) 23.9 + if ( (rc = xc_vcpu_getcontext(xc_handle, domid, vcpu, 23.10 + &ctxt->context[vcpu])) ) 23.11 return NULL; 23.12 23.13 ctxt->valid[vcpu] = true; 23.14 @@ -139,10 +139,10 @@ xendebug_set_context (int xc_handle, dom 23.15 return -EINVAL; 23.16 23.17 op.interface_version = DOM0_INTERFACE_VERSION; 23.18 - op.cmd = DOM0_SETDOMAININFO; 23.19 - op.u.setdomaininfo.domain = ctxt->domid; 23.20 - op.u.setdomaininfo.vcpu = vcpu; 23.21 - op.u.setdomaininfo.ctxt = &ctxt->context[vcpu]; 23.22 + op.cmd = DOM0_SETVCPUCONTEXT; 23.23 + op.u.setvcpucontext.domain = ctxt->domid; 23.24 + op.u.setvcpucontext.vcpu = vcpu; 23.25 + op.u.setvcpucontext.ctxt = &ctxt->context[vcpu]; 23.26 23.27 if ( (rc = mlock(&ctxt->context[vcpu], sizeof(vcpu_guest_context_t))) ) 23.28 return rc;
24.1 --- a/tools/examples/xmexample.vmx Mon Jan 09 11:19:55 2006 +0000 24.2 +++ b/tools/examples/xmexample.vmx Mon Jan 09 11:22:17 2006 +0000 24.3 @@ -28,7 +28,13 @@ name = "ExampleVMXDomain" 24.4 24.5 #----------------------------------------------------------------------------- 24.6 # the number of cpus guest platform has, default=1 24.7 -vcpus=1 24.8 +#vcpus=1 24.9 + 24.10 +# enable/disalbe vmx guest ACPI, default=0 (disabled) 24.11 +#acpi=0 24.12 + 24.13 +# enable/disalbe vmx guest APIC, default=0 (disabled) 24.14 +#apic=0 24.15 24.16 # List of which CPUS this domain is allowed to use, default Xen picks 24.17 #cpus = "" # leave to Xen to pick
25.1 --- a/tools/firmware/vmxassist/Makefile Mon Jan 09 11:19:55 2006 +0000 25.2 +++ b/tools/firmware/vmxassist/Makefile Mon Jan 09 11:22:17 2006 +0000 25.3 @@ -24,7 +24,7 @@ include $(XEN_ROOT)/tools/Rules.mk 25.4 # The emulator code lives in ROM space 25.5 TEXTADDR=0x000D0000 25.6 25.7 -DEFINES=-DDEBUG -D_ACPI_ -DTEXTADDR=$(TEXTADDR) 25.8 +DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR) 25.9 XENINC=-I$(XEN_ROOT)/tools/libxc 25.10 25.11 LD = ld
26.1 --- a/tools/firmware/vmxassist/acpi_madt.c Mon Jan 09 11:19:55 2006 +0000 26.2 +++ b/tools/firmware/vmxassist/acpi_madt.c Mon Jan 09 11:22:17 2006 +0000 26.3 @@ -17,30 +17,73 @@ 26.4 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 26.5 * Place - Suite 330, Boston, MA 02111-1307 USA. 26.6 */ 26.7 + 26.8 #include "../acpi/acpi2_0.h" 26.9 #include "../acpi/acpi_madt.h" 26.10 26.11 +#include <xen/hvm/hvm_info_table.h> 26.12 + 26.13 #define NULL ((void*)0) 26.14 26.15 extern int puts(const char *s); 26.16 26.17 -#define VCPU_NR_PAGE 0x0009F000 26.18 -#define VCPU_NR_OFFSET 0x00000800 26.19 -#define VCPU_MAGIC 0x76637075 /* "vcpu" */ 26.20 +static struct hvm_info_table *table = NULL; 26.21 + 26.22 +static int validate_hvm_info(struct hvm_info_table *t) 26.23 +{ 26.24 + char signature[] = "HVM INFO"; 26.25 + uint8_t *ptr = (uint8_t *)t; 26.26 + uint8_t sum = 0; 26.27 + int i; 26.28 + 26.29 + /* strncmp(t->signature, "HVM INFO", 8) */ 26.30 + for (i = 0; i < 8; i++) { 26.31 + if (signature[i] != t->signature[i]) { 26.32 + puts("Bad hvm info signature\n"); 26.33 + return 0; 26.34 + } 26.35 + } 26.36 + 26.37 + for (i = 0; i < t->length; i++) 26.38 + sum += ptr[i]; 26.39 + 26.40 + return (sum == 0); 26.41 +} 26.42 26.43 -/* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */ 26.44 -static int 26.45 +/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */ 26.46 +static struct hvm_info_table * 26.47 +get_hvm_info_table(void) 26.48 +{ 26.49 + struct hvm_info_table *t; 26.50 + int i; 26.51 + 26.52 + if (table != NULL) 26.53 + return table; 26.54 + 26.55 + t = (struct hvm_info_table *)HVM_INFO_PADDR; 26.56 + 26.57 + if (!validate_hvm_info(t)) { 26.58 + puts("Bad hvm info table\n"); 26.59 + return NULL; 26.60 + } 26.61 + 26.62 + table = t; 26.63 + 26.64 + return table; 26.65 +} 26.66 + 26.67 +int 26.68 get_vcpu_nr(void) 26.69 { 26.70 - unsigned int *vcpus; 26.71 + struct hvm_info_table *t = get_hvm_info_table(); 26.72 + return (t ? t->nr_vcpus : 1); /* default 1 vcpu */ 26.73 +} 26.74 26.75 - vcpus = (unsigned int *)(VCPU_NR_PAGE + VCPU_NR_OFFSET); 26.76 - if (vcpus[0] != VCPU_MAGIC) { 26.77 - puts("Bad vcpus magic, set vcpu number to 1 by default.\n"); 26.78 - return 1; 26.79 - } 26.80 - 26.81 - return vcpus[1]; 26.82 +int 26.83 +get_acpi_enabled(void) 26.84 +{ 26.85 + struct hvm_info_table *t = get_hvm_info_table(); 26.86 + return (t ? t->acpi_enabled : 0); /* default no acpi */ 26.87 } 26.88 26.89 static void * 26.90 @@ -74,10 +117,10 @@ acpi_madt_get_madt(unsigned char *acpi_s 26.91 return madt; 26.92 } 26.93 26.94 -static void 26.95 +static void 26.96 set_checksum(void *start, int checksum_offset, int len) 26.97 { 26.98 - unsigned char sum = 0; 26.99 + unsigned char sum = 0; 26.100 unsigned char *ptr; 26.101 26.102 ptr = start; 26.103 @@ -89,9 +132,9 @@ set_checksum(void *start, int checksum_o 26.104 ptr[checksum_offset] = -sum; 26.105 } 26.106 26.107 -static int 26.108 +static int 26.109 acpi_madt_set_local_apics( 26.110 - int nr_vcpu, 26.111 + int nr_vcpu, 26.112 ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt) 26.113 { 26.114 int i; 26.115 @@ -104,14 +147,14 @@ acpi_madt_set_local_apics( 26.116 madt->LocalApic[i].Length = sizeof (ACPI_LOCAL_APIC_STRUCTURE); 26.117 madt->LocalApic[i].AcpiProcessorId = i; 26.118 madt->LocalApic[i].ApicId = i; 26.119 - madt->LocalApic[i].Flags = 1; 26.120 + madt->LocalApic[i].Flags = 1; 26.121 } 26.122 26.123 madt->Header.Header.Length = 26.124 - sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) - 26.125 + sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) - 26.126 (MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE); 26.127 26.128 - return 0; 26.129 + return 0; 26.130 } 26.131 26.132 #define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field))) 26.133 @@ -133,7 +176,7 @@ int acpi_madt_update(unsigned char *acpi 26.134 madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum), 26.135 madt->Header.Header.Length); 26.136 26.137 - return 0; 26.138 + return 0; 26.139 } 26.140 26.141 /*
27.1 --- a/tools/firmware/vmxassist/vm86.h Mon Jan 09 11:19:55 2006 +0000 27.2 +++ b/tools/firmware/vmxassist/vm86.h Mon Jan 09 11:22:17 2006 +0000 27.3 @@ -24,7 +24,7 @@ 27.4 #include <stdint.h> 27.5 #endif 27.6 27.7 -#include <xen/vmx_assist.h> 27.8 +#include <xen/hvm/vmx_assist.h> 27.9 27.10 #define NR_EXCEPTION_HANDLER 32 27.11 #define NR_INTERRUPT_HANDLERS 16
28.1 --- a/tools/firmware/vmxassist/vmxloader.c Mon Jan 09 11:19:55 2006 +0000 28.2 +++ b/tools/firmware/vmxassist/vmxloader.c Mon Jan 09 11:22:17 2006 +0000 28.3 @@ -24,12 +24,10 @@ 28.4 #include "machine.h" 28.5 #include "roms.h" 28.6 28.7 -#ifdef _ACPI_ 28.8 #include "acpi.h" 28.9 #include "../acpi/acpi2_0.h" // for ACPI_PHYSICAL_ADDRESS 28.10 int acpi_madt_update(unsigned char* acpi_start); 28.11 -#endif 28.12 - 28.13 +int get_acpi_enabled(void); 28.14 28.15 /* 28.16 * C runtime start off 28.17 @@ -120,18 +118,17 @@ main(void) 28.18 memcpy((void *)0xC0000, 28.19 vgabios_stdvga, sizeof(vgabios_stdvga)); 28.20 } 28.21 -#ifdef _ACPI_ 28.22 - puts("Loading ACPI ...\n"); 28.23 28.24 - acpi_madt_update(acpi); 28.25 - 28.26 - if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) { 28.27 - /* make sure acpi table does not overlap rombios 28.28 - * currently acpi less than 8K will be OK. 28.29 - */ 28.30 - memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi)); 28.31 + if (get_acpi_enabled() != 0) { 28.32 + puts("Loading ACPI ...\n"); 28.33 + acpi_madt_update((unsigned char*)acpi); 28.34 + if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) { 28.35 + /* make sure acpi table does not overlap rombios 28.36 + * currently acpi less than 8K will be OK. 28.37 + */ 28.38 + memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi)); 28.39 + } 28.40 } 28.41 -#endif 28.42 28.43 puts("Loading VMXAssist ...\n"); 28.44 memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
29.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 29.2 +++ b/tools/guest-headers/Makefile Mon Jan 09 11:22:17 2006 +0000 29.3 @@ -0,0 +1,11 @@ 29.4 + 29.5 +XEN_ROOT=../.. 29.6 +linuxsparsetree = $(XEN_ROOT)/linux-2.6-xen-sparse 29.7 + 29.8 +check: 29.9 + 29.10 +install: 29.11 + mkdir -p $(DESTDIR)/usr/include/xen/linux 29.12 + install -m0644 $(linuxsparsetree)/include/asm-xen/linux-public/*.h $(DESTDIR)/usr/include/xen/linux 29.13 + 29.14 +clean:
30.1 --- a/tools/ioemu/hw/i8254.c Mon Jan 09 11:19:55 2006 +0000 30.2 +++ b/tools/ioemu/hw/i8254.c Mon Jan 09 11:22:17 2006 +0000 30.3 @@ -23,7 +23,7 @@ 30.4 */ 30.5 #include "vl.h" 30.6 #include <xenctrl.h> 30.7 -#include <xen/io/ioreq.h> 30.8 +#include <xen/hvm/ioreq.h> 30.9 30.10 //#define DEBUG_PIT 30.11
31.1 --- a/tools/ioemu/hw/i8259.c Mon Jan 09 11:19:55 2006 +0000 31.2 +++ b/tools/ioemu/hw/i8259.c Mon Jan 09 11:22:17 2006 +0000 31.3 @@ -23,7 +23,7 @@ 31.4 */ 31.5 #include "vl.h" 31.6 #include <xenctrl.h> 31.7 -#include <xen/io/ioreq.h> 31.8 +#include <xen/hvm/ioreq.h> 31.9 31.10 /* debug PIC */ 31.11 //#define DEBUG_PIC
32.1 --- a/tools/ioemu/hw/i8259_stub.c Mon Jan 09 11:19:55 2006 +0000 32.2 +++ b/tools/ioemu/hw/i8259_stub.c Mon Jan 09 11:22:17 2006 +0000 32.3 @@ -22,7 +22,7 @@ 32.4 * THE SOFTWARE. 32.5 */ 32.6 #include "xenctrl.h" 32.7 -#include <xen/io/ioreq.h> 32.8 +#include <xen/hvm/ioreq.h> 32.9 #include <stdio.h> 32.10 #include "cpu.h" 32.11 #include "cpu-all.h"
33.1 --- a/tools/ioemu/target-i386-dm/helper2.c Mon Jan 09 11:19:55 2006 +0000 33.2 +++ b/tools/ioemu/target-i386-dm/helper2.c Mon Jan 09 11:22:17 2006 +0000 33.3 @@ -48,7 +48,7 @@ 33.4 #include <sys/ioctl.h> 33.5 33.6 #include <xenctrl.h> 33.7 -#include <xen/io/ioreq.h> 33.8 +#include <xen/hvm/ioreq.h> 33.9 #include <xen/linux/evtchn.h> 33.10 33.11 #include "cpu.h"
34.1 --- a/tools/ioemu/vl.c Mon Jan 09 11:19:55 2006 +0000 34.2 +++ b/tools/ioemu/vl.c Mon Jan 09 11:22:17 2006 +0000 34.3 @@ -2948,6 +2948,7 @@ int main(int argc, char **argv) 34.4 case QEMU_OPTION_vcpus: 34.5 vcpus = atoi(optarg); 34.6 fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus); 34.7 + break; 34.8 case QEMU_OPTION_pci: 34.9 pci_enabled = 1; 34.10 break;
35.1 --- a/tools/libxc/xc_core.c Mon Jan 09 11:19:55 2006 +0000 35.2 +++ b/tools/libxc/xc_core.c Mon Jan 09 11:22:17 2006 +0000 35.3 @@ -55,7 +55,7 @@ xc_domain_dumpcore(int xc_handle, 35.4 } 35.5 35.6 for (i = 0; i < info.max_vcpu_id; i++) 35.7 - if (xc_domain_get_vcpu_context(xc_handle, domid, 35.8 + if (xc_vcpu_getcontext(xc_handle, domid, 35.9 i, &ctxt[nr_vcpus]) == 0) 35.10 nr_vcpus++; 35.11
36.1 --- a/tools/libxc/xc_domain.c Mon Jan 09 11:19:55 2006 +0000 36.2 +++ b/tools/libxc/xc_domain.c Mon Jan 09 11:22:17 2006 +0000 36.3 @@ -58,16 +58,16 @@ int xc_domain_destroy(int xc_handle, 36.4 return do_dom0_op(xc_handle, &op); 36.5 } 36.6 36.7 -int xc_domain_pincpu(int xc_handle, 36.8 - uint32_t domid, 36.9 - int vcpu, 36.10 - cpumap_t cpumap) 36.11 +int xc_vcpu_setaffinity(int xc_handle, 36.12 + uint32_t domid, 36.13 + int vcpu, 36.14 + cpumap_t cpumap) 36.15 { 36.16 DECLARE_DOM0_OP; 36.17 - op.cmd = DOM0_PINCPUDOMAIN; 36.18 - op.u.pincpudomain.domain = (domid_t)domid; 36.19 - op.u.pincpudomain.vcpu = vcpu; 36.20 - op.u.pincpudomain.cpumap = cpumap; 36.21 + op.cmd = DOM0_SETVCPUAFFINITY; 36.22 + op.u.setvcpuaffinity.domain = (domid_t)domid; 36.23 + op.u.setvcpuaffinity.vcpu = vcpu; 36.24 + op.u.setvcpuaffinity.cpumap = cpumap; 36.25 return do_dom0_op(xc_handle, &op); 36.26 } 36.27 36.28 @@ -155,7 +155,7 @@ int xc_domain_getinfolist(int xc_handle, 36.29 return ret; 36.30 } 36.31 36.32 -int xc_domain_get_vcpu_context(int xc_handle, 36.33 +int xc_vcpu_getcontext(int xc_handle, 36.34 uint32_t domid, 36.35 uint32_t vcpu, 36.36 vcpu_guest_context_t *ctxt) 36.37 @@ -345,10 +345,10 @@ int xc_domain_sethandle(int xc_handle, u 36.38 return do_dom0_op(xc_handle, &op); 36.39 } 36.40 36.41 -int xc_domain_get_vcpu_info(int xc_handle, 36.42 - uint32_t domid, 36.43 - uint32_t vcpu, 36.44 - xc_vcpuinfo_t *info) 36.45 +int xc_vcpu_getinfo(int xc_handle, 36.46 + uint32_t domid, 36.47 + uint32_t vcpu, 36.48 + xc_vcpuinfo_t *info) 36.49 { 36.50 int rc; 36.51 DECLARE_DOM0_OP; 36.52 @@ -380,18 +380,18 @@ int xc_domain_ioport_permission(int xc_h 36.53 return do_dom0_op(xc_handle, &op); 36.54 } 36.55 36.56 -int xc_domain_setinfo(int xc_handle, 36.57 - uint32_t domid, 36.58 - uint32_t vcpu, 36.59 - vcpu_guest_context_t *ctxt) 36.60 +int xc_vcpu_setcontext(int xc_handle, 36.61 + uint32_t domid, 36.62 + uint32_t vcpu, 36.63 + vcpu_guest_context_t *ctxt) 36.64 { 36.65 dom0_op_t op; 36.66 int rc; 36.67 36.68 - op.cmd = DOM0_SETDOMAININFO; 36.69 - op.u.setdomaininfo.domain = domid; 36.70 - op.u.setdomaininfo.vcpu = vcpu; 36.71 - op.u.setdomaininfo.ctxt = ctxt; 36.72 + op.cmd = DOM0_SETVCPUCONTEXT; 36.73 + op.u.setvcpucontext.domain = domid; 36.74 + op.u.setvcpucontext.vcpu = vcpu; 36.75 + op.u.setvcpucontext.ctxt = ctxt; 36.76 36.77 if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 ) 36.78 return rc; 36.79 @@ -404,6 +404,38 @@ int xc_domain_setinfo(int xc_handle, 36.80 36.81 } 36.82 36.83 +int xc_domain_irq_permission(int xc_handle, 36.84 + uint32_t domid, 36.85 + uint8_t pirq, 36.86 + uint8_t allow_access) 36.87 +{ 36.88 + dom0_op_t op; 36.89 + 36.90 + op.cmd = DOM0_IRQ_PERMISSION; 36.91 + op.u.irq_permission.domain = domid; 36.92 + op.u.irq_permission.pirq = pirq; 36.93 + op.u.irq_permission.allow_access = allow_access; 36.94 + 36.95 + return do_dom0_op(xc_handle, &op); 36.96 +} 36.97 + 36.98 +int xc_domain_iomem_permission(int xc_handle, 36.99 + uint32_t domid, 36.100 + unsigned long first_pfn, 36.101 + unsigned long nr_pfns, 36.102 + uint8_t allow_access) 36.103 +{ 36.104 + dom0_op_t op; 36.105 + 36.106 + op.cmd = DOM0_IOMEM_PERMISSION; 36.107 + op.u.iomem_permission.domain = domid; 36.108 + op.u.iomem_permission.first_pfn = first_pfn; 36.109 + op.u.iomem_permission.nr_pfns = nr_pfns; 36.110 + op.u.iomem_permission.allow_access = allow_access; 36.111 + 36.112 + return do_dom0_op(xc_handle, &op); 36.113 +} 36.114 + 36.115 /* 36.116 * Local variables: 36.117 * mode: C
37.1 --- a/tools/libxc/xc_ia64_stubs.c Mon Jan 09 11:19:55 2006 +0000 37.2 +++ b/tools/libxc/xc_ia64_stubs.c Mon Jan 09 11:22:17 2006 +0000 37.3 @@ -5,7 +5,7 @@ 37.4 #include <stdlib.h> 37.5 #include <zlib.h> 37.6 #include "xen/arch-ia64.h" 37.7 -#include <xen/io/ioreq.h> 37.8 +#include <xen/hvm/ioreq.h> 37.9 37.10 /* this is a very ugly way of getting FPSR_DEFAULT. struct ia64_fpreg is 37.11 * mysteriously declared in two places: /usr/include/asm/fpu.h and 37.12 @@ -627,6 +627,7 @@ int xc_vmx_build(int xc_handle, 37.13 unsigned int control_evtchn, 37.14 unsigned int lapic, 37.15 unsigned int vcpus, 37.16 + unsigned int acpi, 37.17 unsigned int store_evtchn, 37.18 unsigned long *store_mfn) 37.19 { 37.20 @@ -663,7 +664,7 @@ int xc_vmx_build(int xc_handle, 37.21 goto error_out; 37.22 } 37.23 37.24 - if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ){ 37.25 + if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) ){ 37.26 PERROR("Could not get vcpu context"); 37.27 goto error_out; 37.28 } 37.29 @@ -687,11 +688,11 @@ int xc_vmx_build(int xc_handle, 37.30 37.31 memset( &launch_op, 0, sizeof(launch_op) ); 37.32 37.33 - launch_op.u.setdomaininfo.domain = (domid_t)domid; 37.34 - launch_op.u.setdomaininfo.vcpu = 0; 37.35 - launch_op.u.setdomaininfo.ctxt = ctxt; 37.36 + launch_op.u.setvcpucontext.domain = (domid_t)domid; 37.37 + launch_op.u.setvcpucontext.vcpu = 0; 37.38 + launch_op.u.setvcpucontext.ctxt = ctxt; 37.39 37.40 - launch_op.cmd = DOM0_SETDOMAININFO; 37.41 + launch_op.cmd = DOM0_SETVCPUCONTEXT; 37.42 rc = do_dom0_op(xc_handle, &launch_op); 37.43 return rc; 37.44
38.1 --- a/tools/libxc/xc_linux_build.c Mon Jan 09 11:19:55 2006 +0000 38.2 +++ b/tools/libxc/xc_linux_build.c Mon Jan 09 11:22:17 2006 +0000 38.3 @@ -393,10 +393,14 @@ static int setup_guest(int xc_handle, 38.4 start_info->store_evtchn = store_evtchn; 38.5 start_info->console_mfn = nr_pages - 1; 38.6 start_info->console_evtchn = console_evtchn; 38.7 + start_info->nr_pages = nr_pages; // FIXME?: nr_pages - 2 ???? 38.8 if ( initrd_len != 0 ) 38.9 { 38.10 ctxt->initrd.start = vinitrd_start; 38.11 ctxt->initrd.size = initrd_len; 38.12 + } else { 38.13 + ctxt->initrd.start = 0; 38.14 + ctxt->initrd.size = 0; 38.15 } 38.16 strncpy((char *)ctxt->cmdline, cmdline, IA64_COMMAND_LINE_SIZE); 38.17 ctxt->cmdline[IA64_COMMAND_LINE_SIZE-1] = '\0'; 38.18 @@ -790,7 +794,7 @@ int xc_linux_build(int xc_handle, 38.19 goto error_out; 38.20 } 38.21 38.22 - if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ) 38.23 + if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) ) 38.24 { 38.25 PERROR("Could not get vcpu context"); 38.26 goto error_out; 38.27 @@ -893,11 +897,11 @@ int xc_linux_build(int xc_handle, 38.28 38.29 memset( &launch_op, 0, sizeof(launch_op) ); 38.30 38.31 - launch_op.u.setdomaininfo.domain = (domid_t)domid; 38.32 - launch_op.u.setdomaininfo.vcpu = 0; 38.33 - launch_op.u.setdomaininfo.ctxt = ctxt; 38.34 + launch_op.u.setvcpucontext.domain = (domid_t)domid; 38.35 + launch_op.u.setvcpucontext.vcpu = 0; 38.36 + launch_op.u.setvcpucontext.ctxt = ctxt; 38.37 38.38 - launch_op.cmd = DOM0_SETDOMAININFO; 38.39 + launch_op.cmd = DOM0_SETVCPUCONTEXT; 38.40 rc = xc_dom0_op(xc_handle, &launch_op); 38.41 38.42 return rc;
39.1 --- a/tools/libxc/xc_linux_restore.c Mon Jan 09 11:19:55 2006 +0000 39.2 +++ b/tools/libxc/xc_linux_restore.c Mon Jan 09 11:22:17 2006 +0000 39.3 @@ -171,7 +171,7 @@ int xc_linux_restore(int xc_handle, int 39.4 39.5 39.6 /* Only have to worry about vcpu 0 even for SMP */ 39.7 - if (xc_domain_get_vcpu_context( xc_handle, dom, 0, &ctxt)) { 39.8 + if (xc_vcpu_getcontext( xc_handle, dom, 0, &ctxt)) { 39.9 ERR("Could not get vcpu context"); 39.10 goto out; 39.11 } 39.12 @@ -735,10 +735,10 @@ int xc_linux_restore(int xc_handle, int 39.13 39.14 DPRINTF("Domain ready to be built.\n"); 39.15 39.16 - op.cmd = DOM0_SETDOMAININFO; 39.17 - op.u.setdomaininfo.domain = (domid_t)dom; 39.18 - op.u.setdomaininfo.vcpu = 0; 39.19 - op.u.setdomaininfo.ctxt = &ctxt; 39.20 + op.cmd = DOM0_SETVCPUCONTEXT; 39.21 + op.u.setvcpucontext.domain = (domid_t)dom; 39.22 + op.u.setvcpucontext.vcpu = 0; 39.23 + op.u.setvcpucontext.ctxt = &ctxt; 39.24 rc = xc_dom0_op(xc_handle, &op); 39.25 39.26 if (rc != 0) {
40.1 --- a/tools/libxc/xc_linux_save.c Mon Jan 09 11:19:55 2006 +0000 40.2 +++ b/tools/libxc/xc_linux_save.c Mon Jan 09 11:22:17 2006 +0000 40.3 @@ -382,7 +382,7 @@ static int suspend_and_state(int xc_hand 40.4 return -1; 40.5 } 40.6 40.7 - if ( xc_domain_get_vcpu_context(xc_handle, dom, 0 /* XXX */, ctxt)) 40.8 + if ( xc_vcpu_getcontext(xc_handle, dom, 0 /* XXX */, ctxt)) 40.9 ERR("Could not get vcpu context"); 40.10 40.11 40.12 @@ -643,7 +643,7 @@ int xc_linux_save(int xc_handle, int io_ 40.13 } 40.14 40.15 /* Only have to worry about vcpu 0 even for SMP */ 40.16 - if (xc_domain_get_vcpu_context(xc_handle, dom, 0, &ctxt)) { 40.17 + if (xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt)) { 40.18 ERR("Could not get vcpu context"); 40.19 goto out; 40.20 }
41.1 --- a/tools/libxc/xc_pagetab.c Mon Jan 09 11:19:55 2006 +0000 41.2 +++ b/tools/libxc/xc_pagetab.c Mon Jan 09 11:22:17 2006 +0000 41.3 @@ -74,7 +74,7 @@ unsigned long xc_translate_foreign_addre 41.4 #define pt_levels 4 41.5 #endif 41.6 41.7 - if (xc_domain_get_vcpu_context(xc_handle, dom, vcpu, &ctx) != 0) { 41.8 + if (xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0) { 41.9 fprintf(stderr, "failed to retreive vcpu context\n"); 41.10 goto out; 41.11 }
42.1 --- a/tools/libxc/xc_ptrace.c Mon Jan 09 11:19:55 2006 +0000 42.2 +++ b/tools/libxc/xc_ptrace.c Mon Jan 09 11:22:17 2006 +0000 42.3 @@ -33,7 +33,7 @@ fetch_regs(int xc_handle, int cpu, int * 42.4 if (online) 42.5 *online = 0; 42.6 if ( !(regs_valid & (1 << cpu)) ) { 42.7 - retval = xc_domain_get_vcpu_context(xc_handle, current_domid, 42.8 + retval = xc_vcpu_getcontext(xc_handle, current_domid, 42.9 cpu, &ctxt[cpu]); 42.10 if ( retval ) 42.11 goto done; 42.12 @@ -43,8 +43,7 @@ fetch_regs(int xc_handle, int cpu, int * 42.13 if ( online == NULL ) 42.14 goto done; 42.15 42.16 - retval = xc_domain_get_vcpu_info(xc_handle, current_domid, 42.17 - cpu, &info); 42.18 + retval = xc_vcpu_getinfo(xc_handle, current_domid, cpu, &info); 42.19 *online = info.online; 42.20 42.21 done: 42.22 @@ -395,7 +394,7 @@ xc_ptrace( 42.23 42.24 case PTRACE_SETREGS: 42.25 SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs); 42.26 - retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]); 42.27 + retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]); 42.28 if (retval) 42.29 goto error_out; 42.30 break; 42.31 @@ -405,7 +404,7 @@ xc_ptrace( 42.32 * during single-stepping - but that just seems retarded 42.33 */ 42.34 ctxt[cpu].user_regs.eflags |= PSL_T; 42.35 - retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]); 42.36 + retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]); 42.37 if ( retval ) 42.38 { 42.39 perror("dom0 op failed"); 42.40 @@ -423,8 +422,8 @@ xc_ptrace( 42.41 /* Clear trace flag */ 42.42 if ( ctxt[cpu].user_regs.eflags & PSL_T ) { 42.43 ctxt[cpu].user_regs.eflags &= ~PSL_T; 42.44 - retval = xc_domain_setinfo(xc_handle, current_domid, 42.45 - cpu, &ctxt[cpu]); 42.46 + retval = xc_vcpu_setcontext(xc_handle, current_domid, 42.47 + cpu, &ctxt[cpu]); 42.48 if ( retval ) { 42.49 perror("dom0 op failed"); 42.50 goto error_out;
43.1 --- a/tools/libxc/xc_vmx_build.c Mon Jan 09 11:19:55 2006 +0000 43.2 +++ b/tools/libxc/xc_vmx_build.c Mon Jan 09 11:22:17 2006 +0000 43.3 @@ -9,7 +9,8 @@ 43.4 #include <stdlib.h> 43.5 #include <unistd.h> 43.6 #include <zlib.h> 43.7 -#include <xen/io/ioreq.h> 43.8 +#include <xen/hvm/hvm_info_table.h> 43.9 +#include <xen/hvm/ioreq.h> 43.10 43.11 #define VMX_LOADER_ENTR_ADDR 0x00100000 43.12 43.13 @@ -33,9 +34,6 @@ 43.14 #define E820_MAP_NR_OFFSET 0x000001E8 43.15 #define E820_MAP_OFFSET 0x000002D0 43.16 43.17 -#define VCPU_NR_PAGE 0x0009F000 43.18 -#define VCPU_NR_OFFSET 0x00000800 43.19 - 43.20 struct e820entry { 43.21 uint64_t addr; 43.22 uint64_t size; 43.23 @@ -119,26 +117,50 @@ static unsigned char build_e820map(void 43.24 return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map); 43.25 } 43.26 43.27 +static void 43.28 +set_hvm_info_checksum(struct hvm_info_table *t) 43.29 +{ 43.30 + uint8_t *ptr = (uint8_t *)t, sum = 0; 43.31 + unsigned int i; 43.32 + 43.33 + t->checksum = 0; 43.34 + 43.35 + for (i = 0; i < t->length; i++) 43.36 + sum += *ptr++; 43.37 + 43.38 + t->checksum = -sum; 43.39 +} 43.40 + 43.41 /* 43.42 - * Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader 43.43 - * vmxloader will use it to config ACPI MADT table 43.44 + * Use E820 reserved memory 0x9F800 to pass HVM info to vmxloader 43.45 + * vmxloader will use this info to set BIOS accordingly 43.46 */ 43.47 -#define VCPU_MAGIC 0x76637075 /* "vcpu" */ 43.48 -static int set_vcpu_nr(int xc_handle, uint32_t dom, 43.49 - unsigned long *pfn_list, unsigned int vcpus) 43.50 +static int set_hvm_info(int xc_handle, uint32_t dom, 43.51 + unsigned long *pfn_list, unsigned int vcpus, 43.52 + unsigned int acpi, unsigned int apic) 43.53 { 43.54 - char *va_map; 43.55 - unsigned int *va_vcpus; 43.56 + char *va_map; 43.57 + struct hvm_info_table *va_hvm; 43.58 43.59 - va_map = xc_map_foreign_range(xc_handle, dom, 43.60 - PAGE_SIZE, PROT_READ|PROT_WRITE, 43.61 - pfn_list[VCPU_NR_PAGE >> PAGE_SHIFT]); 43.62 + va_map = xc_map_foreign_range( 43.63 + xc_handle, 43.64 + dom, 43.65 + PAGE_SIZE, 43.66 + PROT_READ|PROT_WRITE, 43.67 + pfn_list[HVM_INFO_PFN]); 43.68 + 43.69 if ( va_map == NULL ) 43.70 return -1; 43.71 43.72 - va_vcpus = (unsigned int *)(va_map + VCPU_NR_OFFSET); 43.73 - va_vcpus[0] = VCPU_MAGIC; 43.74 - va_vcpus[1] = vcpus; 43.75 + va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET); 43.76 + memset(va_hvm, 0, sizeof(*va_hvm)); 43.77 + strncpy(va_hvm->signature, "HVM INFO", 8); 43.78 + va_hvm->length = sizeof(struct hvm_info_table); 43.79 + va_hvm->acpi_enabled = acpi; 43.80 + va_hvm->apic_enabled = apic; 43.81 + va_hvm->nr_vcpus = vcpus; 43.82 + 43.83 + set_hvm_info_checksum(va_hvm); 43.84 43.85 munmap(va_map, PAGE_SIZE); 43.86 43.87 @@ -279,8 +301,9 @@ static int setup_guest(int xc_handle, 43.88 vcpu_guest_context_t *ctxt, 43.89 unsigned long shared_info_frame, 43.90 unsigned int control_evtchn, 43.91 - unsigned int lapic, 43.92 unsigned int vcpus, 43.93 + unsigned int acpi, 43.94 + unsigned int apic, 43.95 unsigned int store_evtchn, 43.96 unsigned long *store_mfn) 43.97 { 43.98 @@ -490,20 +513,14 @@ static int setup_guest(int xc_handle, 43.99 goto error_out; 43.100 } 43.101 43.102 - if (set_vcpu_nr(xc_handle, dom, page_array, vcpus)) { 43.103 - fprintf(stderr, "Couldn't set vcpu number for VMX guest.\n"); 43.104 + if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi, apic) ) { 43.105 + fprintf(stderr, "Couldn't set hvm info for VMX guest.\n"); 43.106 goto error_out; 43.107 } 43.108 43.109 - *store_mfn = page_array[(v_end-2) >> PAGE_SHIFT]; 43.110 - if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) ) 43.111 - goto error_out; 43.112 - 43.113 - shared_page_frame = (v_end - PAGE_SIZE) >> PAGE_SHIFT; 43.114 - 43.115 - if ((e820_page = xc_map_foreign_range( 43.116 - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 43.117 - page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0) 43.118 + if ( (e820_page = xc_map_foreign_range( 43.119 + xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 43.120 + page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0 ) 43.121 goto error_out; 43.122 memset(e820_page, 0, PAGE_SIZE); 43.123 e820_map_nr = build_e820map(e820_page, v_end); 43.124 @@ -518,26 +535,30 @@ static int setup_guest(int xc_handle, 43.125 munmap(e820_page, PAGE_SIZE); 43.126 43.127 /* shared_info page starts its life empty. */ 43.128 - if ((shared_info = xc_map_foreign_range( 43.129 - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 43.130 - shared_info_frame)) == 0) 43.131 + if ( (shared_info = xc_map_foreign_range( 43.132 + xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 43.133 + shared_info_frame)) == 0 ) 43.134 goto error_out; 43.135 memset(shared_info, 0, sizeof(shared_info_t)); 43.136 /* Mask all upcalls... */ 43.137 for ( i = 0; i < MAX_VIRT_CPUS; i++ ) 43.138 shared_info->vcpu_info[i].evtchn_upcall_mask = 1; 43.139 - 43.140 munmap(shared_info, PAGE_SIZE); 43.141 43.142 /* Populate the event channel port in the shared page */ 43.143 - if ((sp = (shared_iopage_t *) xc_map_foreign_range( 43.144 - xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 43.145 - page_array[shared_page_frame])) == 0) 43.146 + shared_page_frame = page_array[(v_end >> PAGE_SHIFT) - 1]; 43.147 + if ( (sp = (shared_iopage_t *) xc_map_foreign_range( 43.148 + xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE, 43.149 + shared_page_frame)) == 0 ) 43.150 goto error_out; 43.151 memset(sp, 0, PAGE_SIZE); 43.152 sp->sp_global.eport = control_evtchn; 43.153 munmap(sp, PAGE_SIZE); 43.154 43.155 + *store_mfn = page_array[(v_end >> PAGE_SHIFT) - 2]; 43.156 + if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) ) 43.157 + goto error_out; 43.158 + 43.159 /* Send the page update requests down to the hypervisor. */ 43.160 if ( xc_finish_mmu_updates(xc_handle, mmu) ) 43.161 goto error_out; 43.162 @@ -559,7 +580,7 @@ static int setup_guest(int xc_handle, 43.163 ctxt->user_regs.eax = 0; 43.164 ctxt->user_regs.esp = 0; 43.165 ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */ 43.166 - ctxt->user_regs.ecx = lapic; 43.167 + ctxt->user_regs.ecx = 0; 43.168 ctxt->user_regs.esi = 0; 43.169 ctxt->user_regs.edi = 0; 43.170 ctxt->user_regs.ebp = 0; 43.171 @@ -574,36 +595,14 @@ static int setup_guest(int xc_handle, 43.172 return -1; 43.173 } 43.174 43.175 -#define VMX_FEATURE_FLAG 0x20 43.176 - 43.177 -static int vmx_identify(void) 43.178 -{ 43.179 - int eax, ecx; 43.180 - 43.181 - __asm__ __volatile__ ( 43.182 -#if defined(__i386__) 43.183 - "push %%ebx; cpuid; pop %%ebx" 43.184 -#elif defined(__x86_64__) 43.185 - "push %%rbx; cpuid; pop %%rbx" 43.186 -#endif 43.187 - : "=a" (eax), "=c" (ecx) 43.188 - : "0" (1) 43.189 - : "dx"); 43.190 - 43.191 - if (!(ecx & VMX_FEATURE_FLAG)) { 43.192 - return -1; 43.193 - } 43.194 - 43.195 - return 0; 43.196 -} 43.197 - 43.198 int xc_vmx_build(int xc_handle, 43.199 uint32_t domid, 43.200 int memsize, 43.201 const char *image_name, 43.202 unsigned int control_evtchn, 43.203 - unsigned int lapic, 43.204 unsigned int vcpus, 43.205 + unsigned int acpi, 43.206 + unsigned int apic, 43.207 unsigned int store_evtchn, 43.208 unsigned long *store_mfn) 43.209 { 43.210 @@ -613,10 +612,18 @@ int xc_vmx_build(int xc_handle, 43.211 unsigned long nr_pages; 43.212 char *image = NULL; 43.213 unsigned long image_size; 43.214 + xen_capabilities_info_t xen_caps; 43.215 43.216 - if ( vmx_identify() < 0 ) 43.217 + if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 ) 43.218 { 43.219 - PERROR("CPU doesn't support VMX Extensions"); 43.220 + PERROR("Failed to get xen version info"); 43.221 + goto error_out; 43.222 + } 43.223 + 43.224 + if ( !strstr(xen_caps, "hvm") ) 43.225 + { 43.226 + PERROR("CPU doesn't support VMX Extensions or " 43.227 + "CPU VMX Extensions are not turned on"); 43.228 goto error_out; 43.229 } 43.230 43.231 @@ -644,7 +651,7 @@ int xc_vmx_build(int xc_handle, 43.232 goto error_out; 43.233 } 43.234 43.235 - if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ) 43.236 + if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) ) 43.237 { 43.238 PERROR("Could not get vcpu context"); 43.239 goto error_out; 43.240 @@ -659,7 +666,7 @@ int xc_vmx_build(int xc_handle, 43.241 43.242 if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages, 43.243 ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn, 43.244 - lapic, vcpus, store_evtchn, store_mfn) < 0) 43.245 + vcpus, acpi, apic, store_evtchn, store_mfn) < 0) 43.246 { 43.247 ERROR("Error constructing guest OS"); 43.248 goto error_out; 43.249 @@ -701,11 +708,11 @@ int xc_vmx_build(int xc_handle, 43.250 43.251 memset( &launch_op, 0, sizeof(launch_op) ); 43.252 43.253 - launch_op.u.setdomaininfo.domain = (domid_t)domid; 43.254 - launch_op.u.setdomaininfo.vcpu = 0; 43.255 - launch_op.u.setdomaininfo.ctxt = ctxt; 43.256 + launch_op.u.setvcpucontext.domain = (domid_t)domid; 43.257 + launch_op.u.setvcpucontext.vcpu = 0; 43.258 + launch_op.u.setvcpucontext.ctxt = ctxt; 43.259 43.260 - launch_op.cmd = DOM0_SETDOMAININFO; 43.261 + launch_op.cmd = DOM0_SETVCPUCONTEXT; 43.262 rc = xc_dom0_op(xc_handle, &launch_op); 43.263 43.264 return rc;
44.1 --- a/tools/libxc/xenctrl.h Mon Jan 09 11:19:55 2006 +0000 44.2 +++ b/tools/libxc/xenctrl.h Mon Jan 09 11:22:17 2006 +0000 44.3 @@ -181,10 +181,11 @@ int xc_domain_unpause(int xc_handle, 44.4 */ 44.5 int xc_domain_destroy(int xc_handle, 44.6 uint32_t domid); 44.7 -int xc_domain_pincpu(int xc_handle, 44.8 - uint32_t domid, 44.9 - int vcpu, 44.10 - cpumap_t cpumap); 44.11 + 44.12 +int xc_vcpu_setaffinity(int xc_handle, 44.13 + uint32_t domid, 44.14 + int vcpu, 44.15 + cpumap_t cpumap); 44.16 44.17 /** 44.18 * This function will return information about one or more domains. It is 44.19 @@ -208,7 +209,7 @@ int xc_domain_getinfo(int xc_handle, 44.20 44.21 44.22 /** 44.23 - * This function will set the vcpu context for the specified domain. 44.24 + * This function will set the execution context for the specified vcpu. 44.25 * 44.26 * @parm xc_handle a handle to an open hypervisor interface 44.27 * @parm domid the domain to set the vcpu context for 44.28 @@ -216,10 +217,10 @@ int xc_domain_getinfo(int xc_handle, 44.29 * @parm ctxt pointer to the the cpu context with the values to set 44.30 * @return the number of domains enumerated or -1 on error 44.31 */ 44.32 -int xc_domain_setinfo(int xc_handle, 44.33 - uint32_t domid, 44.34 - uint32_t vcpu, 44.35 - vcpu_guest_context_t *ctxt); 44.36 +int xc_vcpu_setcontext(int xc_handle, 44.37 + uint32_t domid, 44.38 + uint32_t vcpu, 44.39 + vcpu_guest_context_t *ctxt); 44.40 /** 44.41 * This function will return information about one or more domains, using a 44.42 * single hypercall. The domain information will be stored into the supplied 44.43 @@ -249,17 +250,16 @@ int xc_domain_getinfolist(int xc_handle, 44.44 * domain 44.45 * @return 0 on success, -1 on failure 44.46 */ 44.47 -int xc_domain_get_vcpu_context(int xc_handle, 44.48 +int xc_vcpu_getcontext(int xc_handle, 44.49 uint32_t domid, 44.50 uint32_t vcpu, 44.51 vcpu_guest_context_t *ctxt); 44.52 44.53 typedef dom0_getvcpuinfo_t xc_vcpuinfo_t; 44.54 -int xc_domain_get_vcpu_info(int xc_handle, 44.55 - uint32_t domid, 44.56 - uint32_t vcpu, 44.57 - xc_vcpuinfo_t *info); 44.58 - 44.59 +int xc_vcpu_getinfo(int xc_handle, 44.60 + uint32_t domid, 44.61 + uint32_t vcpu, 44.62 + xc_vcpuinfo_t *info); 44.63 44.64 int xc_domain_setcpuweight(int xc_handle, 44.65 uint32_t domid, 44.66 @@ -380,6 +380,17 @@ int xc_domain_ioport_permission(int xc_h 44.67 uint32_t nr_ports, 44.68 uint32_t allow_access); 44.69 44.70 +int xc_domain_irq_permission(int xc_handle, 44.71 + uint32_t domid, 44.72 + uint8_t pirq, 44.73 + uint8_t allow_access); 44.74 + 44.75 +int xc_domain_iomem_permission(int xc_handle, 44.76 + uint32_t domid, 44.77 + unsigned long first_pfn, 44.78 + unsigned long nr_pfns, 44.79 + uint8_t allow_access); 44.80 + 44.81 unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid, 44.82 unsigned long mfn); 44.83
45.1 --- a/tools/libxc/xenguest.h Mon Jan 09 11:19:55 2006 +0000 45.2 +++ b/tools/libxc/xenguest.h Mon Jan 09 11:22:17 2006 +0000 45.3 @@ -56,8 +56,9 @@ int xc_vmx_build(int xc_handle, 45.4 int memsize, 45.5 const char *image_name, 45.6 unsigned int control_evtchn, 45.7 - unsigned int lapic, 45.8 unsigned int vcpus, 45.9 + unsigned int acpi, 45.10 + unsigned int apic, 45.11 unsigned int store_evtchn, 45.12 unsigned long *store_mfn); 45.13
46.1 --- a/tools/python/xen/lowlevel/xc/xc.c Mon Jan 09 11:19:55 2006 +0000 46.2 +++ b/tools/python/xen/lowlevel/xc/xc.c Mon Jan 09 11:22:17 2006 +0000 46.3 @@ -135,9 +135,9 @@ static PyObject *pyxc_domain_destroy(XcO 46.4 } 46.5 46.6 46.7 -static PyObject *pyxc_domain_pincpu(XcObject *self, 46.8 - PyObject *args, 46.9 - PyObject *kwds) 46.10 +static PyObject *pyxc_vcpu_setaffinity(XcObject *self, 46.11 + PyObject *args, 46.12 + PyObject *kwds) 46.13 { 46.14 uint32_t dom; 46.15 int vcpu = 0, i; 46.16 @@ -157,7 +157,7 @@ static PyObject *pyxc_domain_pincpu(XcOb 46.17 cpumap |= (cpumap_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i)); 46.18 } 46.19 46.20 - if ( xc_domain_pincpu(self->xc_handle, dom, vcpu, cpumap) != 0 ) 46.21 + if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 ) 46.22 return PyErr_SetFromErrno(xc_error); 46.23 46.24 Py_INCREF(zero); 46.25 @@ -297,7 +297,7 @@ static PyObject *pyxc_vcpu_getinfo(XcObj 46.26 &dom, &vcpu) ) 46.27 return NULL; 46.28 46.29 - rc = xc_domain_get_vcpu_info(self->xc_handle, dom, vcpu, &info); 46.30 + rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info); 46.31 if ( rc < 0 ) 46.32 return PyErr_SetFromErrno(xc_error); 46.33 46.34 @@ -362,21 +362,23 @@ static PyObject *pyxc_vmx_build(XcObject 46.35 uint32_t dom; 46.36 char *image; 46.37 int control_evtchn, store_evtchn; 46.38 + int memsize; 46.39 int vcpus = 1; 46.40 - int lapic = 0; 46.41 - int memsize; 46.42 + int acpi = 0; 46.43 + int apic = 0; 46.44 unsigned long store_mfn = 0; 46.45 46.46 static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn", 46.47 - "memsize", "image", "lapic", "vcpus", NULL }; 46.48 + "memsize", "image", "vcpus", "acpi", "apic", 46.49 + NULL }; 46.50 46.51 - if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list, 46.52 + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiii", kwd_list, 46.53 &dom, &control_evtchn, &store_evtchn, 46.54 - &memsize, &image, &lapic, &vcpus) ) 46.55 + &memsize, &image, &vcpus, &acpi, &apic) ) 46.56 return NULL; 46.57 46.58 if ( xc_vmx_build(self->xc_handle, dom, memsize, image, control_evtchn, 46.59 - lapic, vcpus, store_evtchn, &store_mfn) != 0 ) 46.60 + vcpus, acpi, apic, store_evtchn, &store_mfn) != 0 ) 46.61 return PyErr_SetFromErrno(xc_error); 46.62 46.63 return Py_BuildValue("{s:i}", "store_mfn", store_mfn); 46.64 @@ -774,6 +776,52 @@ static PyObject *pyxc_domain_ioport_perm 46.65 return zero; 46.66 } 46.67 46.68 +static PyObject *pyxc_domain_irq_permission(PyObject *self, 46.69 + PyObject *args, 46.70 + PyObject *kwds) 46.71 +{ 46.72 + XcObject *xc = (XcObject *)self; 46.73 + uint32_t dom; 46.74 + int pirq, allow_access, ret; 46.75 + 46.76 + static char *kwd_list[] = { "dom", "pirq", "allow_access", NULL }; 46.77 + 46.78 + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list, 46.79 + &dom, &pirq, &allow_access) ) 46.80 + return NULL; 46.81 + 46.82 + ret = xc_domain_irq_permission( 46.83 + xc->xc_handle, dom, pirq, allow_access); 46.84 + if ( ret != 0 ) 46.85 + return PyErr_SetFromErrno(xc_error); 46.86 + 46.87 + Py_INCREF(zero); 46.88 + return zero; 46.89 +} 46.90 + 46.91 +static PyObject *pyxc_domain_iomem_permission(PyObject *self, 46.92 + PyObject *args, 46.93 + PyObject *kwds) 46.94 +{ 46.95 + XcObject *xc = (XcObject *)self; 46.96 + uint32_t dom; 46.97 + unsigned long first_pfn, nr_pfns, allow_access, ret; 46.98 + 46.99 + static char *kwd_list[] = { "dom", "first_pfn", "nr_pfns", "allow_access", NULL }; 46.100 + 46.101 + if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list, 46.102 + &dom, &first_pfn, &nr_pfns, &allow_access) ) 46.103 + return NULL; 46.104 + 46.105 + ret = xc_domain_iomem_permission( 46.106 + xc->xc_handle, dom, first_pfn, nr_pfns, allow_access); 46.107 + if ( ret != 0 ) 46.108 + return PyErr_SetFromErrno(xc_error); 46.109 + 46.110 + Py_INCREF(zero); 46.111 + return zero; 46.112 +} 46.113 + 46.114 46.115 static PyObject *dom_op(XcObject *self, PyObject *args, 46.116 int (*fn)(int, uint32_t)) 46.117 @@ -842,8 +890,8 @@ static PyMethodDef pyxc_methods[] = { 46.118 " dom [int]: Identifier of domain to be destroyed.\n\n" 46.119 "Returns: [int] 0 on success; -1 on error.\n" }, 46.120 46.121 - { "domain_pincpu", 46.122 - (PyCFunction)pyxc_domain_pincpu, 46.123 + { "vcpu_setaffinity", 46.124 + (PyCFunction)pyxc_vcpu_setaffinity, 46.125 METH_VARARGS | METH_KEYWORDS, "\n" 46.126 "Pin a VCPU to a specified set CPUs.\n" 46.127 " dom [int]: Identifier of domain to which VCPU belongs.\n" 46.128 @@ -1070,6 +1118,25 @@ static PyMethodDef pyxc_methods[] = { 46.129 " allow_access [int]: Non-zero means enable access; else disable access\n\n" 46.130 "Returns: [int] 0 on success; -1 on error.\n" }, 46.131 46.132 + { "domain_irq_permission", 46.133 + (PyCFunction)pyxc_domain_irq_permission, 46.134 + METH_VARARGS | METH_KEYWORDS, "\n" 46.135 + "Allow a domain access to a physical IRQ\n" 46.136 + " dom [int]: Identifier of domain to be allowed access.\n" 46.137 + " pirq [int]: The Physical IRQ\n" 46.138 + " allow_access [int]: Non-zero means enable access; else disable access\n\n" 46.139 + "Returns: [int] 0 on success; -1 on error.\n" }, 46.140 + 46.141 + { "domain_iomem_permission", 46.142 + (PyCFunction)pyxc_domain_iomem_permission, 46.143 + METH_VARARGS | METH_KEYWORDS, "\n" 46.144 + "Allow a domain access to a range of IO memory pages\n" 46.145 + " dom [int]: Identifier of domain to be allowed access.\n" 46.146 + " first_pfn [long]: First page of I/O Memory\n" 46.147 + " nr_pfns [long]: Number of pages of I/O Memory (>0)\n" 46.148 + " allow_access [int]: Non-zero means enable access; else disable access\n\n" 46.149 + "Returns: [int] 0 on success; -1 on error.\n" }, 46.150 + 46.151 { "pages_to_kib", 46.152 (PyCFunction)pyxc_pages_to_kib, 46.153 METH_VARARGS, "\n"
47.1 --- a/tools/python/xen/xend/XendDomain.py Mon Jan 09 11:19:55 2006 +0000 47.2 +++ b/tools/python/xen/xend/XendDomain.py Mon Jan 09 11:22:17 2006 +0000 47.3 @@ -443,7 +443,7 @@ class XendDomain: 47.4 cpumap = map(lambda x: int(x), 47.5 cpumap.replace("[", "").replace("]", "").split(",")) 47.6 try: 47.7 - return xc.domain_pincpu(dominfo.getDomid(), vcpu, cpumap) 47.8 + return xc.vcpu_setaffinity(dominfo.getDomid(), vcpu, cpumap) 47.9 except Exception, ex: 47.10 raise XendError(str(ex)) 47.11
48.1 --- a/tools/python/xen/xend/XendDomainInfo.py Mon Jan 09 11:19:55 2006 +0000 48.2 +++ b/tools/python/xen/xend/XendDomainInfo.py Mon Jan 09 11:22:17 2006 +0000 48.3 @@ -1179,7 +1179,7 @@ class XendDomainInfo: 48.4 for v in range(0, self.info['max_vcpu_id']+1): 48.5 # pincpu takes a list of ints 48.6 cpu = [ int( cpus[v % len(cpus)] ) ] 48.7 - xc.domain_pincpu(self.domid, v, cpu) 48.8 + xc.vcpu_setaffinity(self.domid, v, cpu) 48.9 48.10 m = self.image.getDomainMemory(self.info['memory'] * 1024) 48.11 balloon.free(m)
49.1 --- a/tools/python/xen/xend/image.py Mon Jan 09 11:19:55 2006 +0000 49.2 +++ b/tools/python/xen/xend/image.py Mon Jan 09 11:22:17 2006 +0000 49.3 @@ -189,11 +189,16 @@ class VmxImageHandler(ImageHandler): 49.4 def configure(self, imageConfig, deviceConfig): 49.5 ImageHandler.configure(self, imageConfig, deviceConfig) 49.6 49.7 + info = xc.xeninfo() 49.8 + if not 'hvm' in info['xen_caps']: 49.9 + raise VmError("vmx: not an Intel VT platform, we stop creating!") 49.10 + 49.11 self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig) 49.12 self.device_model = sxp.child_value(imageConfig, 'device_model') 49.13 if not self.device_model: 49.14 raise VmError("vmx: missing device model") 49.15 self.display = sxp.child_value(imageConfig, 'display') 49.16 + self.xauthority = sxp.child_value(imageConfig, 'xauthority') 49.17 49.18 self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)), 49.19 ("image/device-model", self.device_model), 49.20 @@ -204,10 +209,8 @@ class VmxImageHandler(ImageHandler): 49.21 49.22 self.dmargs += self.configVNC(imageConfig) 49.23 49.24 - self.lapic = 0 49.25 - lapic = sxp.child_value(imageConfig, 'lapic') 49.26 - if not lapic is None: 49.27 - self.lapic = int(lapic) 49.28 + self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0)) 49.29 + self.apic = int(sxp.child_value(imageConfig, 'apic', 0)) 49.30 49.31 def buildDomain(self): 49.32 # Create an event channel 49.33 @@ -222,17 +225,18 @@ class VmxImageHandler(ImageHandler): 49.34 log.debug("control_evtchn = %d", self.device_channel) 49.35 log.debug("store_evtchn = %d", store_evtchn) 49.36 log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024) 49.37 - log.debug("lapic = %d", self.lapic) 49.38 log.debug("vcpus = %d", self.vm.getVCpuCount()) 49.39 + log.debug("acpi = %d", self.acpi) 49.40 + log.debug("apic = %d", self.apic) 49.41 49.42 return xc.vmx_build(dom = self.vm.getDomid(), 49.43 image = self.kernel, 49.44 control_evtchn = self.device_channel, 49.45 store_evtchn = store_evtchn, 49.46 memsize = self.vm.getMemoryTarget() / 1024, 49.47 - lapic = self.lapic, 49.48 - vcpus = self.vm.getVCpuCount()) 49.49 - 49.50 + vcpus = self.vm.getVCpuCount(), 49.51 + acpi = self.acpi, 49.52 + apic = self.apic) 49.53 49.54 # Return a list of cmd line args to the device models based on the 49.55 # xm config file 49.56 @@ -264,44 +268,44 @@ class VmxImageHandler(ImageHandler): 49.57 nics = 0 49.58 for (name, info) in deviceConfig: 49.59 if name == 'vbd': 49.60 - uname = sxp.child_value(info, 'uname') 49.61 - typedev = sxp.child_value(info, 'dev') 49.62 - (_, vbdparam) = string.split(uname, ':', 1) 49.63 - if re.match('^ioemu:', typedev): 49.64 - (emtype, vbddev) = string.split(typedev, ':', 1) 49.65 - else: 49.66 - emtype = 'vbd' 49.67 - vbddev = typedev 49.68 - if emtype != 'ioemu': 49.69 - continue; 49.70 - vbddev_list = ['hda', 'hdb', 'hdc', 'hdd'] 49.71 - if vbddev not in vbddev_list: 49.72 - raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd") 49.73 - ret.append("-%s" % vbddev) 49.74 - ret.append("%s" % vbdparam) 49.75 + uname = sxp.child_value(info, 'uname') 49.76 + typedev = sxp.child_value(info, 'dev') 49.77 + (_, vbdparam) = string.split(uname, ':', 1) 49.78 + if 'ioemu:' in typedev: 49.79 + (emtype, vbddev) = string.split(typedev, ':', 1) 49.80 + else: 49.81 + emtype = 'vbd' 49.82 + vbddev = typedev 49.83 + if emtype == 'vbd': 49.84 + continue; 49.85 + vbddev_list = ['hda', 'hdb', 'hdc', 'hdd'] 49.86 + if vbddev not in vbddev_list: 49.87 + raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd") 49.88 + ret.append("-%s" % vbddev) 49.89 + ret.append("%s" % vbdparam) 49.90 if name == 'vif': 49.91 - type = sxp.child_value(info, 'type') 49.92 - if type != 'ioemu': 49.93 - continue 49.94 - nics += 1 49.95 - if mac != None: 49.96 - continue 49.97 - mac = sxp.child_value(info, 'mac') 49.98 - bridge = sxp.child_value(info, 'bridge') 49.99 - if mac == None: 49.100 - mac = randomMAC() 49.101 - if bridge == None: 49.102 - bridge = 'xenbr0' 49.103 - ret.append("-macaddr") 49.104 - ret.append("%s" % mac) 49.105 - ret.append("-bridge") 49.106 - ret.append("%s" % bridge) 49.107 + type = sxp.child_value(info, 'type') 49.108 + if type != 'ioemu': 49.109 + continue 49.110 + nics += 1 49.111 + if mac != None: 49.112 + continue 49.113 + mac = sxp.child_value(info, 'mac') 49.114 + bridge = sxp.child_value(info, 'bridge') 49.115 + if mac == None: 49.116 + mac = randomMAC() 49.117 + if bridge == None: 49.118 + bridge = 'xenbr0' 49.119 + ret.append("-macaddr") 49.120 + ret.append("%s" % mac) 49.121 + ret.append("-bridge") 49.122 + ret.append("%s" % bridge) 49.123 if name == 'vtpm': 49.124 - instance = sxp.child_value(info, 'pref_instance') 49.125 - ret.append("-instance") 49.126 - ret.append("%s" % instance) 49.127 + instance = sxp.child_value(info, 'pref_instance') 49.128 + ret.append("-instance") 49.129 + ret.append("%s" % instance) 49.130 ret.append("-nics") 49.131 - ret.append("%d" % nics) 49.132 + ret.append("%d" % nics) 49.133 return ret 49.134 49.135 def configVNC(self, config): 49.136 @@ -340,6 +344,8 @@ class VmxImageHandler(ImageHandler): 49.137 env = dict(os.environ) 49.138 if self.display: 49.139 env['DISPLAY'] = self.display 49.140 + if self.xauthority: 49.141 + env['XAUTHORITY'] = self.xauthority 49.142 log.info("spawning device models: %s %s", self.device_model, args) 49.143 self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env) 49.144 log.info("device model pid: %d", self.pid)
50.1 --- a/tools/python/xen/xend/server/blkif.py Mon Jan 09 11:19:55 2006 +0000 50.2 +++ b/tools/python/xen/xend/server/blkif.py Mon Jan 09 11:22:17 2006 +0000 50.3 @@ -31,7 +31,7 @@ class BlkifController(DevController): 50.4 """Block device interface controller. Handles all block devices 50.5 for a domain. 50.6 """ 50.7 - 50.8 + 50.9 def __init__(self, vm): 50.10 """Create a block device controller. 50.11 """ 50.12 @@ -40,9 +40,9 @@ class BlkifController(DevController): 50.13 50.14 def getDeviceDetails(self, config): 50.15 """@see DevController.getDeviceDetails""" 50.16 - 50.17 + 50.18 dev = sxp.child_value(config, 'dev') 50.19 - if re.match('^ioemu:', dev): 50.20 + if 'ioemu:' in dev: 50.21 return (None,{},{}) 50.22 50.23 devid = blkif.blkdev_name_to_number(dev)
51.1 --- a/tools/python/xen/xm/create.py Mon Jan 09 11:19:55 2006 +0000 51.2 +++ b/tools/python/xen/xm/create.py Mon Jan 09 11:22:17 2006 +0000 51.3 @@ -160,9 +160,13 @@ gopts.var('cpus', val='CPUS', 51.4 fn=set_int, default=None, 51.5 use="CPUS to run the domain on.") 51.6 51.7 -gopts.var('lapic', val='LAPIC', 51.8 +gopts.var('acpi', val='ACPI', 51.9 fn=set_int, default=0, 51.10 - use="Disable or enable local APIC of VMX domain.") 51.11 + use="Disable or enable ACPI of VMX domain.") 51.12 + 51.13 +gopts.var('apic', val='APIC', 51.14 + fn=set_int, default=0, 51.15 + use="Disable or enable APIC of VMX domain.") 51.16 51.17 gopts.var('vcpus', val='VCPUS', 51.18 fn=set_int, default=1, 51.19 @@ -388,6 +392,10 @@ gopts.var('display', val='DISPLAY', 51.20 fn=set_value, default=None, 51.21 use="X11 display to use") 51.22 51.23 +gopts.var('xauthority', val='XAUTHORITY', 51.24 + fn=set_value, default=None, 51.25 + use="X11 Authority to use") 51.26 + 51.27 51.28 def err(msg): 51.29 """Print an error to stderr and exit. 51.30 @@ -526,7 +534,8 @@ def configure_vmx(config_image, vals): 51.31 """ 51.32 args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb', 51.33 'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio', 51.34 - 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic'] 51.35 + 'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'acpi', 'apic', 51.36 + 'xauthority' ] 51.37 for a in args: 51.38 if (vals.__dict__[a]): 51.39 config_image.append([a, vals.__dict__[a]]) 51.40 @@ -801,6 +810,9 @@ def parseCommandLine(argv): 51.41 if not gopts.vals.display: 51.42 gopts.vals.display = os.getenv("DISPLAY") 51.43 51.44 + if not gopts.vals.xauthority: 51.45 + gopts.vals.xauthority = os.getenv("XAUTHORITY") 51.46 + 51.47 # Process remaining args as config variables. 51.48 for arg in args: 51.49 if '=' in arg:
52.1 --- a/tools/python/xen/xm/main.py Mon Jan 09 11:19:55 2006 +0000 52.2 +++ b/tools/python/xen/xm/main.py Mon Jan 09 11:22:17 2006 +0000 52.3 @@ -390,7 +390,6 @@ def xm_brief_list(doms): 52.4 52.5 52.6 def xm_vcpu_list(args): 52.7 - print 'Name ID VCPU CPU State Time(s) CPU Affinity' 52.8 52.9 from xen.xend.XendClient import server 52.10 if args: 52.11 @@ -401,6 +400,8 @@ def xm_vcpu_list(args): 52.12 lambda x: server.xend_domain_vcpuinfo(sxp.child_value(x, 'name')), 52.13 doms) 52.14 52.15 + print 'Name ID VCPU CPU State Time(s) CPU Affinity' 52.16 + 52.17 for dom in dominfo: 52.18 def get_info(n): 52.19 return sxp.child_value(dom, n) 52.20 @@ -625,6 +626,8 @@ def xm_sched_sedf(args): 52.21 server.xend_domain_cpu_sedf_set(dom, *v) 52.22 52.23 def xm_info(args): 52.24 + arg_check(args, "info", 0) 52.25 + 52.26 from xen.xend.XendClient import server 52.27 info = server.xend_node() 52.28 52.29 @@ -645,9 +648,12 @@ def xm_console(args): 52.30 52.31 52.32 def xm_top(args): 52.33 + arg_check(args, "top", 0) 52.34 + 52.35 os.execvp('xentop', ['xentop']) 52.36 52.37 def xm_dmesg(args): 52.38 + arg_check(args, "dmesg", 0) 52.39 52.40 gopts = Opts(use="""[-c|--clear] 52.41
53.1 --- a/tools/tests/test_x86_emulator.c Mon Jan 09 11:19:55 2006 +0000 53.2 +++ b/tools/tests/test_x86_emulator.c Mon Jan 09 11:22:17 2006 +0000 53.3 @@ -92,7 +92,7 @@ int main(int argc, char **argv) 53.4 regs.ecx = 0x12345678; 53.5 cr2 = (unsigned long)&res; 53.6 res = 0x7FFFFFFF; 53.7 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.8 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.9 if ( (rc != 0) || 53.10 (res != 0x92345677) || 53.11 (regs.eflags != 0xa94) || 53.12 @@ -110,7 +110,7 @@ int main(int argc, char **argv) 53.13 regs.ecx = 0x12345678UL; 53.14 #endif 53.15 cr2 = (unsigned long)&res; 53.16 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.17 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.18 if ( (rc != 0) || 53.19 (res != 0x92345677) || 53.20 (regs.ecx != 0x8000000FUL) || 53.21 @@ -125,7 +125,7 @@ int main(int argc, char **argv) 53.22 regs.eax = 0x92345677UL; 53.23 regs.ecx = 0xAA; 53.24 cr2 = (unsigned long)&res; 53.25 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.26 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.27 if ( (rc != 0) || 53.28 (res != 0x923456AA) || 53.29 (regs.eflags != 0x244) || 53.30 @@ -141,7 +141,7 @@ int main(int argc, char **argv) 53.31 regs.eax = 0xAABBCC77UL; 53.32 regs.ecx = 0xFF; 53.33 cr2 = (unsigned long)&res; 53.34 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.35 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.36 if ( (rc != 0) || 53.37 (res != 0x923456AA) || 53.38 ((regs.eflags&0x240) != 0x200) || 53.39 @@ -157,7 +157,7 @@ int main(int argc, char **argv) 53.40 regs.eip = (unsigned long)&instr[0]; 53.41 regs.ecx = 0x12345678; 53.42 cr2 = (unsigned long)&res; 53.43 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.44 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.45 if ( (rc != 0) || 53.46 (res != 0x12345678) || 53.47 (regs.eflags != 0x200) || 53.48 @@ -174,7 +174,7 @@ int main(int argc, char **argv) 53.49 regs.eax = 0x923456AAUL; 53.50 regs.ecx = 0xDDEEFF00L; 53.51 cr2 = (unsigned long)&res; 53.52 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.53 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.54 if ( (rc != 0) || 53.55 (res != 0xDDEEFF00) || 53.56 (regs.eflags != 0x244) || 53.57 @@ -193,7 +193,7 @@ int main(int argc, char **argv) 53.58 regs.edi = (unsigned long)&res + 2; 53.59 regs.error_code = 0; /* read fault */ 53.60 cr2 = regs.esi; 53.61 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.62 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.63 if ( (rc != 0) || 53.64 (res != 0x44554455) || 53.65 (regs.eflags != 0x200) || 53.66 @@ -211,7 +211,7 @@ int main(int argc, char **argv) 53.67 regs.eip = (unsigned long)&instr[0]; 53.68 regs.edi = (unsigned long)&res; 53.69 cr2 = regs.edi; 53.70 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.71 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.72 if ( (rc != 0) || 53.73 (res != 0x2233445D) || 53.74 ((regs.eflags&0x201) != 0x201) || 53.75 @@ -229,7 +229,7 @@ int main(int argc, char **argv) 53.76 regs.eip = (unsigned long)&instr[0]; 53.77 regs.edi = (unsigned long)cmpxchg8b_res; 53.78 cr2 = regs.edi; 53.79 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.80 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.81 if ( (rc != 0) || 53.82 (cmpxchg8b_res[0] != 0x9999AAAA) || 53.83 (cmpxchg8b_res[1] != 0xCCCCFFFF) || 53.84 @@ -243,7 +243,7 @@ int main(int argc, char **argv) 53.85 regs.eip = (unsigned long)&instr[0]; 53.86 regs.edi = (unsigned long)cmpxchg8b_res; 53.87 cr2 = regs.edi; 53.88 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.89 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.90 if ( (rc != 0) || 53.91 (cmpxchg8b_res[0] != 0x9999AAAA) || 53.92 (cmpxchg8b_res[1] != 0xCCCCFFFF) || 53.93 @@ -260,7 +260,7 @@ int main(int argc, char **argv) 53.94 regs.ecx = 0x12345678; 53.95 cr2 = (unsigned long)&res; 53.96 res = 0x82; 53.97 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.98 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.99 if ( (rc != 0) || 53.100 (res != 0x82) || 53.101 (regs.ecx != 0xFFFFFF82) || 53.102 @@ -275,7 +275,7 @@ int main(int argc, char **argv) 53.103 regs.ecx = 0x12345678; 53.104 cr2 = (unsigned long)&res; 53.105 res = 0x1234aa82; 53.106 - rc = x86_emulate_memop(®s, cr2, &emulops, 4); 53.107 + rc = x86_emulate_memop(®s, cr2, &emulops, X86EMUL_MODE_PROT32); 53.108 if ( (rc != 0) || 53.109 (res != 0x1234aa82) || 53.110 (regs.ecx != 0xaa82) ||
54.1 --- a/tools/vtpm_manager/README Mon Jan 09 11:19:55 2006 +0000 54.2 +++ b/tools/vtpm_manager/README Mon Jan 09 11:22:17 2006 +0000 54.3 @@ -53,11 +53,6 @@ DUMMY_BACKEND -> vtpm_man 54.4 54.5 MANUAL_DM_LAUNCH -> Must manually launch & kill VTPMs 54.6 54.7 -WELL_KNOWN_SRK_AUTH -> Rather than randomly generating the password for the SRK, 54.8 - use a well known value. This is necessary for sharing use 54.9 - of the SRK across applications. Such as VTPM and Dom0 54.10 - measurement software. 54.11 - 54.12 WELL_KNOWN_OWNER_AUTH -> Rather than randomly generating the password for the owner, 54.13 use a well known value. This is useful for debugging and for 54.14 poor bios which do not support clearing TPM if OwnerAuth is
55.1 --- a/tools/vtpm_manager/Rules.mk Mon Jan 09 11:19:55 2006 +0000 55.2 +++ b/tools/vtpm_manager/Rules.mk Mon Jan 09 11:22:17 2006 +0000 55.3 @@ -56,8 +56,7 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VT 55.4 # Do not have manager launch DMs. 55.5 #CFLAGS += -DMANUAL_DM_LAUNCH 55.6 55.7 -# Fixed SRK 55.8 -CFLAGS += -DWELL_KNOWN_SRK_AUTH 55.9 +# Fixed OwnerAuth 55.10 #CFLAGS += -DWELL_KNOWN_OWNER_AUTH 55.11 55.12 # TPM Hardware Device or TPM Simulator
56.1 --- a/tools/vtpm_manager/manager/securestorage.c Mon Jan 09 11:19:55 2006 +0000 56.2 +++ b/tools/vtpm_manager/manager/securestorage.c Mon Jan 09 11:22:17 2006 +0000 56.3 @@ -65,7 +65,7 @@ TPM_RESULT envelope_encrypt(const buffer 56.4 UINT32 i; 56.5 struct pack_constbuf_t symkey_cipher32, data_cipher32; 56.6 56.7 - vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf)); 56.8 + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Input[%d]: 0x", buffer_len(inbuf)); 56.9 for (i=0; i< buffer_len(inbuf); i++) 56.10 vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]); 56.11 vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); 56.12 @@ -94,6 +94,12 @@ TPM_RESULT envelope_encrypt(const buffer 56.13 BSG_TPM_SIZE32_DATA, &data_cipher32); 56.14 56.15 vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher)); 56.16 + 56.17 + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Output[%d]: 0x", buffer_len(sealed_data)); 56.18 + for (i=0; i< buffer_len(sealed_data); i++) 56.19 + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_data->bytes[i]); 56.20 + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); 56.21 + 56.22 goto egress; 56.23 56.24 abort_egress: 56.25 @@ -125,7 +131,7 @@ TPM_RESULT envelope_decrypt(const long 56.26 56.27 memset(&symkey, 0, sizeof(symkey_t)); 56.28 56.29 - vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size); 56.30 + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%ld]: 0x", cipher_size); 56.31 for (i=0; i< cipher_size; i++) 56.32 vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]); 56.33 vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); 56.34 @@ -155,6 +161,11 @@ TPM_RESULT envelope_decrypt(const long 56.35 56.36 // Decrypt State 56.37 TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) ); 56.38 + 56.39 + vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", buffer_len(unsealed_data)); 56.40 + for (i=0; i< buffer_len(unsealed_data); i++) 56.41 + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", unsealed_data->bytes[i]); 56.42 + vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n"); 56.43 56.44 goto egress; 56.45 56.46 @@ -291,124 +302,175 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI 56.47 return status; 56.48 } 56.49 56.50 + 56.51 TPM_RESULT VTPM_SaveService(void) { 56.52 TPM_RESULT status=TPM_SUCCESS; 56.53 int fh, dmis=-1; 56.54 - 56.55 - BYTE *flat_global; 56.56 - int flat_global_size, bytes_written; 56.57 + 56.58 + BYTE *flat_boot_key, *flat_dmis, *flat_enc; 56.59 + buffer_t clear_flat_global, enc_flat_global; 56.60 UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap); 56.61 + UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap); 56.62 struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes}; 56.63 - 56.64 + struct pack_buf_t boot_key_pack = {bootKeySize, vtpm_globals->bootKeyWrap.bytes}; 56.65 + 56.66 struct hashtable_itr *dmi_itr; 56.67 VTPM_DMI_RESOURCE *dmi_res; 56.68 - 56.69 - UINT32 flat_global_full_size; 56.70 - 56.71 - // Global Values needing to be saved 56.72 - flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths 56.73 - sizeof(UINT32) + // storagekeysize 56.74 - storageKeySize + // storage key 56.75 - hashtable_count(vtpm_globals->dmi_map) * // num DMIS 56.76 - (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info 56.77 - 56.78 - 56.79 - flat_global = (BYTE *) malloc( flat_global_full_size); 56.80 - 56.81 - flat_global_size = BSG_PackList(flat_global, 4, 56.82 - BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth, 56.83 - BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth, 56.84 - BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth, 56.85 - BSG_TPM_SIZE32_DATA, &storage_key_pack); 56.86 - 56.87 + 56.88 + UINT32 boot_key_size, flat_dmis_size; 56.89 + 56.90 + // Initially fill these with buffer sizes for each data type. Later fill 56.91 + // in actual size, once flattened. 56.92 + boot_key_size = sizeof(UINT32) + // bootkeysize 56.93 + bootKeySize; // boot key 56.94 + 56.95 + TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths 56.96 + sizeof(UINT32) +// storagekeysize 56.97 + storageKeySize, NULL) ); // storage key 56.98 + 56.99 + flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0) 56.100 + (sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info 56.101 + 56.102 + flat_boot_key = (BYTE *) malloc( boot_key_size ); 56.103 + flat_enc = (BYTE *) malloc( sizeof(UINT32) ); 56.104 + flat_dmis = (BYTE *) malloc( flat_dmis_size ); 56.105 + 56.106 + boot_key_size = BSG_PackList(flat_boot_key, 1, 56.107 + BSG_TPM_SIZE32_DATA, &boot_key_pack); 56.108 + 56.109 + BSG_PackList(clear_flat_global.bytes, 3, 56.110 + BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth, 56.111 + BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth, 56.112 + BSG_TPM_SIZE32_DATA, &storage_key_pack); 56.113 + 56.114 + TPMTRYRETURN(envelope_encrypt(&clear_flat_global, 56.115 + &vtpm_globals->bootKey, 56.116 + &enc_flat_global) ); 56.117 + 56.118 + BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc); 56.119 + 56.120 // Per DMI values to be saved 56.121 if (hashtable_count(vtpm_globals->dmi_map) > 0) { 56.122 - 56.123 + 56.124 dmi_itr = hashtable_iterator(vtpm_globals->dmi_map); 56.125 do { 56.126 dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr); 56.127 dmis++; 56.128 56.129 // No need to save dmi0. 56.130 - if (dmi_res->dmi_id == 0) 56.131 - continue; 56.132 - 56.133 - 56.134 - flat_global_size += BSG_PackList( flat_global + flat_global_size, 3, 56.135 - BSG_TYPE_UINT32, &dmi_res->dmi_id, 56.136 - BSG_TPM_DIGEST, &dmi_res->NVM_measurement, 56.137 - BSG_TPM_DIGEST, &dmi_res->DMI_measurement); 56.138 - 56.139 + if (dmi_res->dmi_id == 0) 56.140 + continue; 56.141 + 56.142 + 56.143 + flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3, 56.144 + BSG_TYPE_UINT32, &dmi_res->dmi_id, 56.145 + BSG_TPM_DIGEST, &dmi_res->NVM_measurement, 56.146 + BSG_TPM_DIGEST, &dmi_res->DMI_measurement); 56.147 + 56.148 } while (hashtable_iterator_advance(dmi_itr)); 56.149 } 56.150 - 56.151 - //FIXME: Once we have a way to protect a TPM key, we should use it to 56.152 - // encrypt this blob. BUT, unless there is a way to ensure the key is 56.153 - // not used by other apps, this encryption is useless. 56.154 + 56.155 fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE); 56.156 if (fh == -1) { 56.157 vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", STATE_FILE); 56.158 status = TPM_IOERROR; 56.159 goto abort_egress; 56.160 } 56.161 - 56.162 - if ( (bytes_written = write(fh, flat_global, flat_global_size)) != flat_global_size ) { 56.163 - vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes written.\n", bytes_written, flat_global_size); 56.164 + 56.165 + if ( ( write(fh, flat_boot_key, boot_key_size) != boot_key_size ) || 56.166 + ( write(fh, flat_enc, sizeof(UINT32)) != sizeof(UINT32) ) || 56.167 + ( write(fh, enc_flat_global.bytes, buffer_len(&enc_flat_global)) != buffer_len(&enc_flat_global) ) || 56.168 + ( write(fh, flat_dmis, flat_dmis_size) != flat_dmis_size ) ) { 56.169 + vtpmlogerror(VTPM_LOG_VTPM, "Failed to completely write service data.\n"); 56.170 status = TPM_IOERROR; 56.171 goto abort_egress; 56.172 - } 56.173 - vtpm_globals->DMI_table_dirty = FALSE; 56.174 - 56.175 + } 56.176 + 56.177 + vtpm_globals->DMI_table_dirty = FALSE; 56.178 + 56.179 goto egress; 56.180 - 56.181 + 56.182 abort_egress: 56.183 egress: 56.184 - 56.185 - free(flat_global); 56.186 + 56.187 + free(flat_boot_key); 56.188 + free(flat_enc); 56.189 + buffer_free(&enc_flat_global); 56.190 + free(flat_dmis); 56.191 close(fh); 56.192 - 56.193 + 56.194 vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = %d)\n", (int) status, dmis); 56.195 return status; 56.196 } 56.197 56.198 TPM_RESULT VTPM_LoadService(void) { 56.199 - 56.200 + 56.201 TPM_RESULT status=TPM_SUCCESS; 56.202 int fh, stat_ret, dmis=0; 56.203 long fh_size = 0, step_size; 56.204 - BYTE *flat_global=NULL; 56.205 - struct pack_buf_t storage_key_pack; 56.206 - UINT32 *dmi_id_key; 56.207 - 56.208 + BYTE *flat_table=NULL; 56.209 + buffer_t unsealed_data; 56.210 + struct pack_buf_t storage_key_pack, boot_key_pack; 56.211 + UINT32 *dmi_id_key, enc_size; 56.212 + 56.213 VTPM_DMI_RESOURCE *dmi_res; 56.214 struct stat file_stat; 56.215 - 56.216 + 56.217 + TPM_HANDLE boot_key_handle; 56.218 + TPM_AUTHDATA boot_usage_auth; 56.219 + memset(&boot_usage_auth, 0, sizeof(TPM_AUTHDATA)); 56.220 + 56.221 fh = open(STATE_FILE, O_RDONLY ); 56.222 stat_ret = fstat(fh, &file_stat); 56.223 - if (stat_ret == 0) 56.224 + if (stat_ret == 0) 56.225 fh_size = file_stat.st_size; 56.226 else { 56.227 status = TPM_IOERROR; 56.228 goto abort_egress; 56.229 } 56.230 - 56.231 - flat_global = (BYTE *) malloc(fh_size); 56.232 - 56.233 - if ((long) read(fh, flat_global, fh_size) != fh_size ) { 56.234 + 56.235 + flat_table = (BYTE *) malloc(fh_size); 56.236 + 56.237 + if ((long) read(fh, flat_table, fh_size) != fh_size ) { 56.238 status = TPM_IOERROR; 56.239 goto abort_egress; 56.240 } 56.241 - 56.242 + 56.243 + // Read Boot Key 56.244 + step_size = BSG_UnpackList( flat_table, 2, 56.245 + BSG_TPM_SIZE32_DATA, &boot_key_pack, 56.246 + BSG_TYPE_UINT32, &enc_size); 56.247 + 56.248 + TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) ); 56.249 + TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) ); 56.250 + 56.251 + //Load Boot Key 56.252 + TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle, 56.253 + TPM_SRK_KEYHANDLE, 56.254 + &vtpm_globals->bootKeyWrap, 56.255 + &SRK_AUTH, 56.256 + &boot_key_handle, 56.257 + &vtpm_globals->keyAuth, 56.258 + &vtpm_globals->bootKey, 56.259 + FALSE) ); 56.260 + 56.261 + TPMTRYRETURN( envelope_decrypt(enc_size, 56.262 + flat_table + step_size, 56.263 + vtpm_globals->manager_tcs_handle, 56.264 + boot_key_handle, 56.265 + (const TPM_AUTHDATA*) &boot_usage_auth, 56.266 + &unsealed_data) ); 56.267 + step_size += enc_size; 56.268 + 56.269 // Global Values needing to be saved 56.270 - step_size = BSG_UnpackList( flat_global, 4, 56.271 - BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth, 56.272 - BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth, 56.273 - BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth, 56.274 - BSG_TPM_SIZE32_DATA, &storage_key_pack); 56.275 - 56.276 + BSG_UnpackList( unsealed_data.bytes, 3, 56.277 + BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth, 56.278 + BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth, 56.279 + BSG_TPM_SIZE32_DATA, &storage_key_pack); 56.280 + 56.281 TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) ); 56.282 TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) ); 56.283 - 56.284 + 56.285 // Per DMI values to be saved 56.286 while ( step_size < fh_size ){ 56.287 if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) { 56.288 @@ -417,35 +479,38 @@ TPM_RESULT VTPM_LoadService(void) { 56.289 } else { 56.290 dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE)); 56.291 dmis++; 56.292 - 56.293 + 56.294 dmi_res->connected = FALSE; 56.295 - 56.296 - step_size += BSG_UnpackList(flat_global + step_size, 3, 56.297 - BSG_TYPE_UINT32, &dmi_res->dmi_id, 56.298 - BSG_TPM_DIGEST, &dmi_res->NVM_measurement, 56.299 - BSG_TPM_DIGEST, &dmi_res->DMI_measurement); 56.300 - 56.301 + 56.302 + step_size += BSG_UnpackList(flat_table + step_size, 3, 56.303 + BSG_TYPE_UINT32, &dmi_res->dmi_id, 56.304 + BSG_TPM_DIGEST, &dmi_res->NVM_measurement, 56.305 + BSG_TPM_DIGEST, &dmi_res->DMI_measurement); 56.306 + 56.307 // install into map 56.308 dmi_id_key = (UINT32 *) malloc (sizeof(UINT32)); 56.309 *dmi_id_key = dmi_res->dmi_id; 56.310 if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) { 56.311 - status = TPM_FAIL; 56.312 - goto abort_egress; 56.313 + status = TPM_FAIL; 56.314 + goto abort_egress; 56.315 } 56.316 - 56.317 + 56.318 } 56.319 - 56.320 + 56.321 } 56.322 - 56.323 + 56.324 vtpmloginfo(VTPM_LOG_VTPM, "Loaded saved state (dmis = %d).\n", dmis); 56.325 goto egress; 56.326 - 56.327 + 56.328 abort_egress: 56.329 vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", tpm_get_error_name(status)); 56.330 egress: 56.331 - 56.332 - free(flat_global); 56.333 + 56.334 + free(flat_table); 56.335 close(fh); 56.336 - 56.337 + 56.338 + // TODO: Could be nice and evict BootKey. (Need to add EvictKey to VTSP. 56.339 + 56.340 return status; 56.341 } 56.342 +
57.1 --- a/tools/vtpm_manager/manager/vtpm_manager.c Mon Jan 09 11:19:55 2006 +0000 57.2 +++ b/tools/vtpm_manager/manager/vtpm_manager.c Mon Jan 09 11:22:17 2006 +0000 57.3 @@ -74,16 +74,15 @@ VTPM_GLOBALS *vtpm_globals=NULL; 57.4 #endif 57.5 57.6 // --------------------------- Well Known Auths -------------------------- 57.7 -#ifdef WELL_KNOWN_SRK_AUTH 57.8 -static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 57.9 +const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 57.10 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 57.11 -#endif 57.12 57.13 #ifdef WELL_KNOWN_OWNER_AUTH 57.14 static BYTE FIXED_OWNER_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 57.15 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 57.16 #endif 57.17 - 57.18 + 57.19 + 57.20 // -------------------------- Hash table functions -------------------- 57.21 57.22 static unsigned int hashfunc32(void *ky) { 57.23 @@ -100,13 +99,7 @@ TPM_RESULT VTPM_Create_Service(){ 57.24 57.25 TPM_RESULT status = TPM_SUCCESS; 57.26 57.27 - // Generate Auth's for SRK & Owner 57.28 -#ifdef WELL_KNOWN_SRK_AUTH 57.29 - memcpy(vtpm_globals->srk_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA)); 57.30 -#else 57.31 - Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) ); 57.32 -#endif 57.33 - 57.34 + // Generate Auth for Owner 57.35 #ifdef WELL_KNOWN_OWNER_AUTH 57.36 memcpy(vtpm_globals->owner_usage_auth, FIXED_OWNER_AUTH, sizeof(TPM_AUTHDATA)); 57.37 #else 57.38 @@ -116,14 +109,14 @@ TPM_RESULT VTPM_Create_Service(){ 57.39 // Take Owership of TPM 57.40 CRYPTO_INFO ek_cryptoInfo; 57.41 57.42 - vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n"); 57.43 status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo); 57.44 57.45 // If we can read PubEK then there is no owner and we should take it. 57.46 if (status == TPM_SUCCESS) { 57.47 + vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n"); 57.48 TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle, 57.49 (const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth, 57.50 - (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth, 57.51 + &SRK_AUTH, 57.52 &ek_cryptoInfo, 57.53 &vtpm_globals->keyAuth)); 57.54 57.55 @@ -142,7 +135,7 @@ TPM_RESULT VTPM_Create_Service(){ 57.56 TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle, 57.57 TPM_ET_KEYHANDLE, 57.58 TPM_SRK_KEYHANDLE, 57.59 - (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth, 57.60 + &SRK_AUTH, 57.61 &sharedsecret, 57.62 &osap) ); 57.63 57.64 @@ -157,8 +150,43 @@ TPM_RESULT VTPM_Create_Service(){ 57.65 &vtpm_globals->storageKeyWrap, 57.66 &osap) ); 57.67 57.68 - vtpm_globals->keyAuth.fContinueAuthSession = TRUE; 57.69 + // Generate boot key's auth 57.70 + Crypto_GetRandom( &vtpm_globals->storage_key_usage_auth, 57.71 + sizeof(TPM_AUTHDATA) ); 57.72 + 57.73 + TPM_AUTHDATA bootKeyWrapAuth; 57.74 + memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth)); 57.75 57.76 + TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle, 57.77 + TPM_ET_KEYHANDLE, 57.78 + TPM_SRK_KEYHANDLE, 57.79 + &SRK_AUTH, 57.80 + &sharedsecret, 57.81 + &osap) ); 57.82 + 57.83 + osap.fContinueAuthSession = FALSE; 57.84 + 57.85 + // FIXME: This key protects the global secrets on disk. It should use TPM 57.86 + // PCR bindings to limit its use to legit configurations. 57.87 + // Current binds are open, implying a Trusted VM contains this code. 57.88 + // If this VM is not Trusted, use measurement and PCR bindings. 57.89 + TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle, 57.90 + TPM_KEY_BIND, 57.91 + (const TPM_AUTHDATA*)&bootKeyWrapAuth, 57.92 + TPM_SRK_KEYHANDLE, 57.93 + (const TPM_AUTHDATA*)&sharedsecret, 57.94 + &vtpm_globals->bootKeyWrap, 57.95 + &osap) ); 57.96 + 57.97 + // Populate CRYPTO_INFO vtpm_globals->bootKey. This does not load it into the TPM 57.98 + TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle, 57.99 + TPM_SRK_KEYHANDLE, 57.100 + &vtpm_globals->bootKeyWrap, 57.101 + NULL, 57.102 + NULL, 57.103 + NULL, 57.104 + &vtpm_globals->bootKey, 57.105 + TRUE ) ); 57.106 goto egress; 57.107 57.108 abort_egress: 57.109 @@ -278,24 +306,26 @@ void *VTPM_Service_Handler(void *threadT 57.110 #endif 57.111 57.112 // Check status of rx_fh. If necessary attempt to re-open it. 57.113 + char* s = NULL; 57.114 if (*rx_fh < 0) { 57.115 #ifdef VTPM_MULTI_VM 57.116 - *rx_fh = open(VTPM_BE_DEV, O_RDWR); 57.117 + s = VTPM_BE_DEV; 57.118 #else 57.119 if (threadType == BE_LISTENER_THREAD) 57.120 #ifdef DUMMY_BACKEND 57.121 - *rx_fh = open("/tmp/in.fifo", O_RDWR); 57.122 + s = "/tmp/in.fifo"; 57.123 #else 57.124 - *rx_fh = open(VTPM_BE_DEV, O_RDWR); 57.125 + s = VTPM_BE_DEV; 57.126 #endif 57.127 else // DMI Listener 57.128 - *rx_fh = open(VTPM_RX_FIFO, O_RDWR); 57.129 + s = VTPM_RX_FIFO; 57.130 + *rx_fh = open(s, O_RDWR); 57.131 #endif 57.132 } 57.133 57.134 // Respond to failures to open rx_fh 57.135 if (*rx_fh < 0) { 57.136 - vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n"); 57.137 + vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh for %s.\n", s); 57.138 #ifdef VTPM_MULTI_VM 57.139 return TPM_IOERROR; 57.140 #else 57.141 @@ -713,7 +743,7 @@ void *VTPM_Service_Handler(void *threadT 57.142 57.143 /////////////////////////////////////////////////////////////////////////////// 57.144 TPM_RESULT VTPM_Init_Service() { 57.145 - TPM_RESULT status = TPM_FAIL; 57.146 + TPM_RESULT status = TPM_FAIL, serviceStatus; 57.147 BYTE *randomsead; 57.148 UINT32 randomsize; 57.149 57.150 @@ -737,7 +767,7 @@ TPM_RESULT VTPM_Init_Service() { 57.151 57.152 // Create new TCS Object 57.153 vtpm_globals->manager_tcs_handle = 0; 57.154 - 57.155 + 57.156 TPMTRYRETURN(TCS_create()); 57.157 57.158 // Create TCS Context for service 57.159 @@ -756,17 +786,24 @@ TPM_RESULT VTPM_Init_Service() { 57.160 vtpm_globals->keyAuth.fContinueAuthSession = TRUE; 57.161 57.162 // If failed, create new Service. 57.163 - if (VTPM_LoadService() != TPM_SUCCESS) 57.164 + serviceStatus = VTPM_LoadService(); 57.165 + if (serviceStatus == TPM_IOERROR) { 57.166 + vtpmloginfo(VTPM_LOG_VTPM, "Failed to read service file. Assuming first time initialization.\n"); 57.167 TPMTRYRETURN( VTPM_Create_Service() ); 57.168 + } else if (serviceStatus != TPM_SUCCESS) { 57.169 + vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing service file"); 57.170 + exit(1); 57.171 + } 57.172 57.173 //Load Storage Key 57.174 TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle, 57.175 TPM_SRK_KEYHANDLE, 57.176 &vtpm_globals->storageKeyWrap, 57.177 - (const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth, 57.178 + &SRK_AUTH, 57.179 &vtpm_globals->storageKeyHandle, 57.180 &vtpm_globals->keyAuth, 57.181 - &vtpm_globals->storageKey) ); 57.182 + &vtpm_globals->storageKey, 57.183 + FALSE ) ); 57.184 57.185 // Create entry for Dom0 for control messages 57.186 TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) ); 57.187 @@ -797,12 +834,11 @@ void VTPM_Stop_Service() { 57.188 free (dmi_itr); 57.189 } 57.190 57.191 - 57.192 + if ( (vtpm_globals->DMI_table_dirty) && (VTPM_SaveService() != TPM_SUCCESS) ) 57.193 + vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n"); 57.194 + 57.195 TCS_CloseContext(vtpm_globals->manager_tcs_handle); 57.196 - 57.197 - if ( (vtpm_globals->DMI_table_dirty) && 57.198 - (VTPM_SaveService() != TPM_SUCCESS) ) 57.199 - vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n"); 57.200 + TCS_destroy(); 57.201 57.202 hashtable_destroy(vtpm_globals->dmi_map, 1); 57.203 free(vtpm_globals);
58.1 --- a/tools/vtpm_manager/manager/vtpmpriv.h Mon Jan 09 11:19:55 2006 +0000 58.2 +++ b/tools/vtpm_manager/manager/vtpmpriv.h Mon Jan 09 11:22:17 2006 +0000 58.3 @@ -108,6 +108,7 @@ typedef struct tdVTPM_GLOBALS { 58.4 TCS_CONTEXT_HANDLE manager_tcs_handle; // TCS Handle used by manager 58.5 TPM_HANDLE storageKeyHandle; // Key used by persistent store 58.6 CRYPTO_INFO storageKey; // For software encryption 58.7 + CRYPTO_INFO bootKey; // For saving table 58.8 TCS_AUTH keyAuth; // OIAP session for storageKey 58.9 BOOL DMI_table_dirty; // Indicates that a command 58.10 // has updated the DMI table 58.11 @@ -115,15 +116,17 @@ typedef struct tdVTPM_GLOBALS { 58.12 58.13 // Persistent Data 58.14 TPM_AUTHDATA owner_usage_auth; // OwnerAuth of real TPM 58.15 - TPM_AUTHDATA srk_usage_auth; // SRK Auth of real TPM 58.16 buffer_t storageKeyWrap; // Wrapped copy of storageKey 58.17 + TPM_AUTHDATA srk_usage_auth; 58.18 + TPM_AUTHDATA storage_key_usage_auth; 58.19 58.20 - TPM_AUTHDATA storage_key_usage_auth; 58.21 - 58.22 + buffer_t bootKeyWrap; // Wrapped copy of boot key 58.23 + 58.24 }VTPM_GLOBALS; 58.25 58.26 -//Global dmi map 58.27 -extern VTPM_GLOBALS *vtpm_globals; 58.28 +// --------------------------- Global Values -------------------------- 58.29 +extern VTPM_GLOBALS *vtpm_globals; // Key info and DMI states 58.30 +extern const TPM_AUTHDATA SRK_AUTH; // SRK Well Known Auth Value 58.31 58.32 // ********************** Command Handler Prototypes *********************** 58.33 TPM_RESULT VTPM_Handle_Load_NVM( VTPM_DMI_RESOURCE *myDMI,
59.1 --- a/tools/vtpm_manager/manager/vtsp.c Mon Jan 09 11:19:55 2006 +0000 59.2 +++ b/tools/vtpm_manager/manager/vtsp.c Mon Jan 09 11:22:17 2006 +0000 59.3 @@ -144,7 +144,10 @@ TPM_RESULT VerifyAuth( /*[IN]*/ const BY 59.4 if (memcmp (&hm, &(auth->HMAC), sizeof(TPM_DIGEST)) == 0) // 0 indicates equality 59.5 return (TPM_SUCCESS); 59.6 else { 59.7 - VTSP_OIAP( hContext, auth); 59.8 + // If specified, reconnect the OIAP session. 59.9 + // NOTE: This only works for TCS's that never have a 0 context. 59.10 + if (hContext) 59.11 + VTSP_OIAP( hContext, auth); 59.12 return (TPM_AUTHFAIL); 59.13 } 59.14 } 59.15 @@ -157,6 +160,10 @@ TPM_RESULT VTSP_OIAP(const TCS_CONTEXT_H 59.16 TPMTRYRETURN( TCSP_OIAP(hContext, 59.17 &auth->AuthHandle, 59.18 &auth->NonceEven) ); 59.19 + 59.20 + memset(&auth->HMAC, 0, sizeof(TPM_DIGEST)); 59.21 + auth->fContinueAuthSession = FALSE; 59.22 + 59.23 goto egress; 59.24 59.25 abort_egress: 59.26 @@ -195,6 +202,9 @@ TPM_RESULT VTSP_OSAP(const TCS_CONTEXT_H 59.27 BSG_TPM_NONCE, &nonceOddOSAP); 59.28 59.29 Crypto_HMAC(sharedSecretText, sizeof(sharedSecretText), (BYTE *) usageAuth, TPM_DIGEST_SIZE, (BYTE *) sharedSecret); 59.30 + 59.31 + memset(&auth->HMAC, 0, sizeof(TPM_DIGEST)); 59.32 + auth->fContinueAuthSession = FALSE; 59.33 59.34 goto egress; 59.35 59.36 @@ -288,9 +298,6 @@ TPM_RESULT VTSP_TakeOwnership( const T 59.37 59.38 struct pack_buf_t srkText; 59.39 59.40 - // GenerateAuth new nonceOdd 59.41 - Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) ); 59.42 - 59.43 //These values are accurate for an enc(AuthData). 59.44 struct pack_buf_t encOwnerAuth, encSrkAuth; 59.45 59.46 @@ -383,9 +390,6 @@ TPM_RESULT VTSP_DisablePubekRead( const 59.47 BYTE *paramText; // Digest to make Auth. 59.48 UINT32 paramTextSize; 59.49 59.50 - // Generate HMAC 59.51 - Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) ); 59.52 - 59.53 paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); 59.54 59.55 paramTextSize = BSG_PackList(paramText, 1, 59.56 @@ -504,9 +508,6 @@ TPM_RESULT VTSP_CreateWrapKey( const TC 59.57 newKeyText.data = flatKey; 59.58 newKeyText.size = flatKeySize; 59.59 59.60 - // GenerateAuth new nonceOdd 59.61 - Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) ); 59.62 - 59.63 // Generate HMAC 59.64 paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); 59.65 59.66 @@ -563,63 +564,66 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEX 59.67 const TPM_AUTHDATA *parentAuth, 59.68 TPM_HANDLE *newKeyHandle, 59.69 TCS_AUTH *auth, 59.70 - CRYPTO_INFO *cryptoinfo /*= NULL*/) { 59.71 + CRYPTO_INFO *cryptoinfo, 59.72 + const BOOL skipTPMLoad) { 59.73 59.74 59.75 - vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s",""); 59.76 + vtpmloginfo(VTPM_LOG_VTSP, "Loading Key %s.\n", (!skipTPMLoad ? "into TPM" : "only into memory")); 59.77 59.78 TPM_RESULT status = TPM_SUCCESS; 59.79 TPM_COMMAND_CODE command = TPM_ORD_LoadKey; 59.80 - 59.81 - BYTE *paramText; // Digest to make Auth. 59.82 + 59.83 + BYTE *paramText=NULL; // Digest to make Auth. 59.84 UINT32 paramTextSize; 59.85 + 59.86 + // SkipTPMLoad stops key from being loaded into TPM, but still generates CRYPTO_INFO for it 59.87 + if (! skipTPMLoad) { 59.88 59.89 - if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 59.90 - (newKeyHandle==NULL) || (auth==NULL)) { 59.91 - status = TPM_BAD_PARAMETER; 59.92 - goto abort_egress; 59.93 - } 59.94 - 59.95 - // Generate Extra TCS Parameters 59.96 - TPM_HANDLE phKeyHMAC; 59.97 + if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) || 59.98 + (newKeyHandle==NULL) || (auth==NULL)) { 59.99 + status = TPM_BAD_PARAMETER; 59.100 + goto abort_egress; 59.101 + } 59.102 59.103 - // Generate HMAC 59.104 - Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) ); 59.105 + // Generate Extra TCS Parameters 59.106 + TPM_HANDLE phKeyHMAC; 59.107 59.108 - paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); 59.109 + paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); 59.110 59.111 - paramTextSize = BSG_PackList(paramText, 1, 59.112 - BSG_TPM_COMMAND_CODE, &command); 59.113 + paramTextSize = BSG_PackList(paramText, 1, 59.114 + BSG_TPM_COMMAND_CODE, &command); 59.115 59.116 - memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob)); 59.117 - paramTextSize += buffer_len(rgbWrappedKeyBlob); 59.118 + memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob)); 59.119 + paramTextSize += buffer_len(rgbWrappedKeyBlob); 59.120 59.121 - TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, 59.122 + TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, 59.123 parentAuth, auth) ); 59.124 59.125 - // Call TCS 59.126 - TPMTRYRETURN( TCSP_LoadKeyByBlob( hContext, 59.127 - hUnwrappingKey, 59.128 - buffer_len(rgbWrappedKeyBlob), 59.129 - rgbWrappedKeyBlob->bytes, 59.130 - auth, 59.131 - newKeyHandle, 59.132 - &phKeyHMAC) ); 59.133 + // Call TCS 59.134 + TPMTRYRETURN( TCSP_LoadKeyByBlob( hContext, 59.135 + hUnwrappingKey, 59.136 + buffer_len(rgbWrappedKeyBlob), 59.137 + rgbWrappedKeyBlob->bytes, 59.138 + auth, 59.139 + newKeyHandle, 59.140 + &phKeyHMAC) ); 59.141 59.142 - // Verify Auth 59.143 - paramTextSize = BSG_PackList(paramText, 3, 59.144 - BSG_TPM_RESULT, &status, 59.145 - BSG_TPM_COMMAND_CODE, &command, 59.146 - BSG_TPM_HANDLE, newKeyHandle); 59.147 + // Verify Auth 59.148 + paramTextSize = BSG_PackList(paramText, 3, 59.149 + BSG_TPM_RESULT, &status, 59.150 + BSG_TPM_COMMAND_CODE, &command, 59.151 + BSG_TPM_HANDLE, newKeyHandle); 59.152 59.153 - TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, 59.154 - parentAuth, auth, 59.155 - hContext) ); 59.156 + TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, 59.157 + parentAuth, auth, 59.158 + hContext) ); 59.159 + } 59.160 59.161 - // Unpack/return key structure 59.162 + // Build cryptoinfo structure for software crypto function. 59.163 if (cryptoinfo != NULL) { 59.164 TPM_KEY newKey; 59.165 59.166 + // Unpack/return key structure 59.167 BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey); 59.168 TPM_RSA_KEY_PARMS rsaKeyParms; 59.169 59.170 @@ -670,9 +674,6 @@ TPM_RESULT VTSP_Unbind( const TCS_CONTEX 59.171 BYTE *clear_data_text; 59.172 UINT32 clear_data_size; 59.173 59.174 - // Generate HMAC 59.175 - Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) ); 59.176 - 59.177 struct pack_buf_t bound_data32 = {bound_data->size, bound_data->bytes}; 59.178 59.179 paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); 59.180 @@ -781,6 +782,196 @@ TPM_RESULT VTSP_Bind( CRYPTO_INFO *cry 59.181 return TPM_SUCCESS; 59.182 } 59.183 59.184 +TPM_RESULT VTSP_Seal(const TCS_CONTEXT_HANDLE hContext, 59.185 + const TPM_KEY_HANDLE keyHandle, 59.186 + const TPM_AUTHDATA *sealDataAuth, 59.187 + const TPM_PCR_COMPOSITE *pcrComp, 59.188 + const buffer_t *inData, 59.189 + TPM_STORED_DATA *sealedData, 59.190 + const TPM_SECRET *osapSharedSecret, 59.191 + TCS_AUTH *auth) { 59.192 + 59.193 + TPM_RESULT status = TPM_SUCCESS; 59.194 + TPM_COMMAND_CODE command = TPM_ORD_Seal; 59.195 + 59.196 + BYTE *paramText; // Digest to make Auth. 59.197 + UINT32 paramTextSize; 59.198 + 59.199 + // Generate PCR_Info Struct from Comp 59.200 + TPM_PCR_INFO pcrInfo; 59.201 + UINT32 pcrInfoSize, flatpcrSize; 59.202 + BYTE flatpcr[3 + // PCR_Select = 3 1 byte banks 59.203 + sizeof(UINT16) + // 2 byte UINT16 59.204 + sizeof(UINT32) + // PCR_Comp = 4 byte UINT32 59.205 + 24 * sizeof(TPM_PCRVALUE) ]; // up to 24 PCRs 59.206 + 59.207 + if (pcrComp != NULL) { 59.208 + //printf("\n\tBinding to PCRs: "); 59.209 + //for(int i = 0 ; i < pcrComp->select.sizeOfSelect ; i++) 59.210 + //printf("%2.2x", pcrComp->select.pcrSelect[i]); 59.211 + 59.212 + memcpy(&pcrInfo.pcrSelection, &pcrComp->select, sizeof(TPM_PCR_SELECTION)); 59.213 + 59.214 + flatpcrSize = BSG_Pack(BSG_TPM_PCR_COMPOSITE, (BYTE *) pcrComp, flatpcr); 59.215 + Crypto_SHA1Full((BYTE *) flatpcr, flatpcrSize, (BYTE *) &(pcrInfo.digestAtRelease)); 59.216 + memset(&(pcrInfo.digestAtCreation), 0, sizeof(TPM_DIGEST)); 59.217 + pcrInfoSize = BSG_Pack(BSG_TPM_PCR_INFO, (BYTE *) &pcrInfo, flatpcr); 59.218 + } else { 59.219 + //printf("\n\tBinding to no PCRS."); 59.220 + pcrInfoSize = 0; 59.221 + } 59.222 + 59.223 + // Calculate encUsageAuth 59.224 + BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)]; 59.225 + UINT32 XORbufferSize = sizeof(XORbuffer); 59.226 + TPM_DIGEST XORKey; 59.227 + TPM_ENCAUTH encAuth; 59.228 + 59.229 + BSG_PackList( XORbuffer, 2, 59.230 + BSG_TPM_SECRET, osapSharedSecret, 59.231 + BSG_TPM_NONCE, &auth->NonceEven ); 59.232 + 59.233 + Crypto_SHA1Full(XORbuffer, XORbufferSize, (BYTE *) &XORKey); 59.234 + 59.235 + int i; 59.236 + for (i=0; i < TPM_DIGEST_SIZE; i++) 59.237 + ((BYTE *) &encAuth)[i] = ((BYTE *) &XORKey)[i] ^ ((BYTE *) sealDataAuth)[i]; 59.238 + 59.239 + // Generate Extra TCS Parameters 59.240 + UINT32 inDataSize = buffer_len(inData); 59.241 + struct pack_buf_t inData_pack = {inDataSize, inData->bytes}; 59.242 + struct pack_buf_t pcrInfo_pack = {pcrInfoSize, flatpcr}; 59.243 + 59.244 + UINT32 sealedDataSize; 59.245 + BYTE *flatSealedData=NULL; 59.246 + 59.247 + paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); 59.248 + 59.249 + paramTextSize = BSG_PackList(paramText, 4, 59.250 + BSG_TPM_COMMAND_CODE, &command, 59.251 + BSG_TPM_ENCAUTH, &encAuth, 59.252 + BSG_TPM_SIZE32_DATA, &pcrInfo_pack, 59.253 + BSG_TPM_SIZE32_DATA, &inData_pack); 59.254 + 59.255 + TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, 59.256 + osapSharedSecret, auth) ); 59.257 + 59.258 + // Call TCS 59.259 + TPMTRYRETURN( TCSP_Seal( hContext, 59.260 + keyHandle, 59.261 + encAuth, 59.262 + pcrInfoSize, 59.263 + flatpcr, 59.264 + inDataSize, 59.265 + inData->bytes, 59.266 + auth, 59.267 + &sealedDataSize, 59.268 + &flatSealedData) ); 59.269 + 59.270 + // Unpack/return key structure 59.271 + BSG_Unpack( BSG_TPM_STORED_DATA, flatSealedData, sealedData ); 59.272 + 59.273 + paramTextSize = BSG_PackList(paramText, 3, 59.274 + BSG_TPM_RESULT, &status, 59.275 + BSG_TPM_COMMAND_CODE, &command, 59.276 + BSG_TPM_STORED_DATA, sealedData); 59.277 + 59.278 + TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, 59.279 + osapSharedSecret, auth, 59.280 + 0) ); 59.281 + 59.282 + 59.283 + goto egress; 59.284 + 59.285 + abort_egress: 59.286 + egress: 59.287 + 59.288 + if (flatSealedData) 59.289 + TCS_FreeMemory( hContext, flatSealedData); 59.290 + 59.291 + free(paramText); 59.292 + return status; 59.293 +} 59.294 + 59.295 + 59.296 +TPM_RESULT VTSP_Unseal(const TCS_CONTEXT_HANDLE hContext, 59.297 + const TPM_KEY_HANDLE keyHandle, 59.298 + const TPM_STORED_DATA *sealedData, 59.299 + const TPM_AUTHDATA *key_usage_auth, 59.300 + const TPM_AUTHDATA *data_usage_auth, 59.301 + buffer_t *outData, 59.302 + TCS_AUTH *auth, 59.303 + TCS_AUTH *dataAuth) { 59.304 + 59.305 + TPM_RESULT status = TPM_SUCCESS; 59.306 + TPM_COMMAND_CODE command = TPM_ORD_Unseal; 59.307 + 59.308 + BYTE *paramText; // Digest to make Auth. 59.309 + UINT32 paramTextSize; 59.310 + 59.311 + // Generate Extra TCS Parameters 59.312 + UINT32 sealDataSize, clearDataSize; 59.313 + BYTE *flatSealedData= (BYTE *) malloc(sizeof(TPM_VERSION) + 59.314 + 2 * sizeof(UINT32) + 59.315 + sealedData->sealInfoSize + 59.316 + sealedData->encDataSize), 59.317 + *clearData=NULL; 59.318 + 59.319 + sealDataSize = BSG_Pack(BSG_TPM_STORED_DATA, sealedData, flatSealedData ); 59.320 + 59.321 + paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH); 59.322 + 59.323 + paramTextSize = BSG_PackList(paramText, 2, 59.324 + BSG_TPM_COMMAND_CODE, &command, 59.325 + BSG_TPM_STORED_DATA, sealedData); 59.326 + 59.327 + TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, 59.328 + key_usage_auth, auth) ); 59.329 + 59.330 + TPMTRYRETURN( GenerateAuth( paramText, paramTextSize, 59.331 + data_usage_auth, dataAuth) ); 59.332 + // Call TCS 59.333 + TPMTRYRETURN( TCSP_Unseal( hContext, 59.334 + keyHandle, 59.335 + sealDataSize, 59.336 + flatSealedData, 59.337 + auth, 59.338 + dataAuth, 59.339 + &clearDataSize, 59.340 + &clearData) ); 59.341 + 59.342 + // Verify Auth 59.343 + struct pack_buf_t clearData_pack = {clearDataSize, clearData}; 59.344 + 59.345 + paramTextSize = BSG_PackList(paramText, 3, 59.346 + BSG_TPM_RESULT, &status, 59.347 + BSG_TPM_COMMAND_CODE, &command, 59.348 + BSG_TPM_SIZE32_DATA, &clearData_pack); 59.349 + 59.350 + TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, 59.351 + key_usage_auth, auth, 59.352 + hContext) ); 59.353 + 59.354 + TPMTRYRETURN( VerifyAuth( paramText, paramTextSize, 59.355 + data_usage_auth, dataAuth, 59.356 + hContext) ); 59.357 + 59.358 + // Unpack/return key structure 59.359 + TPMTRYRETURN( buffer_init(outData, clearDataSize, clearData) ); 59.360 + 59.361 + goto egress; 59.362 + 59.363 + abort_egress: 59.364 + egress: 59.365 + 59.366 + if (flatSealedData) 59.367 + TCS_FreeMemory( hContext, clearData); 59.368 + 59.369 + free(paramText); 59.370 + return status; 59.371 +} 59.372 + 59.373 + 59.374 // Function Reaches into unsupported TCS command, beware. 59.375 TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE hContext, 59.376 const buffer_t *inbuf,
60.1 --- a/tools/vtpm_manager/manager/vtsp.h Mon Jan 09 11:19:55 2006 +0000 60.2 +++ b/tools/vtpm_manager/manager/vtsp.h Mon Jan 09 11:22:17 2006 +0000 60.3 @@ -86,7 +86,8 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEX 60.4 const TPM_AUTHDATA *parentAuth, 60.5 TPM_HANDLE *newKeyHandle, 60.6 TCS_AUTH *pAuth, 60.7 - CRYPTO_INFO *cryptoinfo); 60.8 + CRYPTO_INFO *cryptoinfo, 60.9 + const BOOL skipTPMLoad); 60.10 60.11 TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE hContext, 60.12 const TPM_KEY_HANDLE key_handle, 60.13 @@ -99,4 +100,22 @@ TPM_RESULT VTSP_Bind( CRYPTO_INFO *cry 60.14 const buffer_t *inData, 60.15 buffer_t *outData); 60.16 60.17 +TPM_RESULT VTSP_Seal(const TCS_CONTEXT_HANDLE hContext, 60.18 + const TPM_KEY_HANDLE keyHandle, 60.19 + const TPM_AUTHDATA *sealDataAuth, 60.20 + const TPM_PCR_COMPOSITE *pcrComp, 60.21 + const buffer_t *inData, 60.22 + TPM_STORED_DATA *sealedData, 60.23 + const TPM_SECRET *osapSharedSecret, 60.24 + TCS_AUTH *auth); 60.25 + 60.26 +TPM_RESULT VTSP_Unseal(const TCS_CONTEXT_HANDLE hContext, 60.27 + const TPM_KEY_HANDLE keyHandle, 60.28 + const TPM_STORED_DATA *sealedData, 60.29 + const TPM_AUTHDATA *key_usage_auth, 60.30 + const TPM_AUTHDATA *data_usage_auth, 60.31 + buffer_t *outData, 60.32 + TCS_AUTH *auth, 60.33 + TCS_AUTH *dataAuth); 60.34 + 60.35 #endif //_VTSP_H_
61.1 --- a/tools/vtpm_manager/tcs/tcs.c Mon Jan 09 11:19:55 2006 +0000 61.2 +++ b/tools/vtpm_manager/tcs/tcs.c Mon Jan 09 11:22:17 2006 +0000 61.3 @@ -636,7 +636,7 @@ TPM_RESULT TCSP_Seal( TCS_CONTEXT_HAND 61.4 TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH; 61.5 61.6 // check input params 61.7 - if (inData == NULL || pubAuth == NULL || SealedDataSize == NULL || *SealedData == NULL) 61.8 + if (inData == NULL || pubAuth == NULL || SealedDataSize == NULL || SealedData == NULL) 61.9 return TPM_BAD_PARAMETER; 61.10 61.11 // Convert Byte Input parameter in the input byte stream InBuf
62.1 --- a/tools/xentrace/Makefile Mon Jan 09 11:19:55 2006 +0000 62.2 +++ b/tools/xentrace/Makefile Mon Jan 09 11:22:17 2006 +0000 62.3 @@ -15,24 +15,32 @@ HDRS = $(wildcard *.h) 62.4 OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) 62.5 62.6 BIN = xentrace tbctl setsize 62.7 -LIBBIN = xenctx 62.8 +LIBBIN = 62.9 SCRIPTS = xentrace_format 62.10 MAN1 = $(wildcard *.1) 62.11 MAN8 = $(wildcard *.8) 62.12 62.13 +ifeq ($(XEN_TARGET_ARCH),x86_32) 62.14 +LIBBIN += xenctx 62.15 +endif 62.16 + 62.17 +ifeq ($(XEN_TARGET_ARCH),x86_64) 62.18 +LIBBIN += xenctx 62.19 +endif 62.20 + 62.21 all: build 62.22 build: $(BIN) $(LIBBIN) 62.23 62.24 install: build 62.25 [ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin 62.26 - [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \ 62.27 + [ -z "$(LIBBIN)"] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \ 62.28 $(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin 62.29 [ -d $(DESTDIR)/usr/share/man/man1 ] || \ 62.30 $(INSTALL_DIR) $(DESTDIR)/usr/share/man/man1 62.31 [ -d $(DESTDIR)/usr/share/man/man8 ] || \ 62.32 $(INSTALL_DIR) $(DESTDIR)/usr/share/man/man8 62.33 $(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin 62.34 - $(INSTALL_PROG) $(LIBBIN) $(DESTDIR)/usr/$(LIBDIR)/xen/bin 62.35 + [ -z "$(LIBBIN)"] || $(INSTALL_PROG) $(LIBBIN) $(DESTDIR)/usr/$(LIBDIR)/xen/bin 62.36 $(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/share/man/man1 62.37 $(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/share/man/man8 62.38
63.1 --- a/tools/xentrace/xenctx.c Mon Jan 09 11:19:55 2006 +0000 63.2 +++ b/tools/xentrace/xenctx.c Mon Jan 09 11:22:17 2006 +0000 63.3 @@ -380,10 +380,10 @@ void dump_ctx(int vcpu) 63.4 exit(-1); 63.5 } 63.6 63.7 - ret = xc_domain_get_vcpu_context(xc_handle, domid, vcpu, &ctx); 63.8 + ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx); 63.9 if (ret < 0) { 63.10 xc_domain_unpause(xc_handle, domid); 63.11 - perror("xc_domain_get_vcpu_context"); 63.12 + perror("xc_vcpu_getcontext"); 63.13 exit(-1); 63.14 } 63.15
64.1 --- a/tools/xm-test/tests/network-attach/Makefile.am Mon Jan 09 11:19:55 2006 +0000 64.2 +++ b/tools/xm-test/tests/network-attach/Makefile.am Mon Jan 09 11:22:17 2006 +0000 64.3 @@ -6,7 +6,7 @@ TESTS = 01_network_attach_pos.test \ 64.4 03_network_attach_detach_multiple_pos.test \ 64.5 04_network_attach_baddomain_neg.test 64.6 64.7 -XFAIL_TESTS = 03_network_attach_detach_multiple_pos.test 64.8 +XFAIL_TESTS = 64.9 64.10 EXTRA_DIST = $(TESTS) $(XFAIL_TESTS) network_utils.py 64.11
65.1 --- a/xen/arch/ia64/Makefile Mon Jan 09 11:19:55 2006 +0000 65.2 +++ b/xen/arch/ia64/Makefile Mon Jan 09 11:22:17 2006 +0000 65.3 @@ -23,6 +23,13 @@ OBJS += bitop.o clear_page.o flush.o cop 65.4 __divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \ 65.5 __divdi3.o __udivdi3.o __moddi3.o __umoddi3.o 65.6 65.7 +# xen stack unwinder 65.8 +# unwind_decoder.c is included in unwind.c 65.9 +OBJS += unwind.o 65.10 +#unwind.o: CFLAGS += -DUNW_DEBUG=4 65.11 + 65.12 +OBJS += process-linux-xen.o 65.13 + 65.14 # perfmon.o 65.15 # unwind.o needed for kernel unwinding (rare) 65.16 65.17 @@ -31,11 +38,26 @@ OBJS := $(subst $(TARGET_ARCH)/asm-offse 65.18 # remove following line if not privifying in memory 65.19 # OBJS += privify.o 65.20 65.21 -default: $(OBJS) head.o xen.lds.s 65.22 - $(LD) -r -o arch.o $(OBJS) 65.23 +default: $(TARGET) 65.24 + 65.25 +$(CURDIR)/arch.o: $(OBJS) 65.26 + $(LD) -r -o $@ $(OBJS) 65.27 + 65.28 +$(TARGET)-syms: $(ALL_OBJS) head.o xen.lds.s 65.29 $(LD) $(LDFLAGS) -T $(BASEDIR)/arch/$(TARGET_ARCH)/xen.lds.s -N \ 65.30 - -Map map.out head.o $(ALL_OBJS) -o $(TARGET)-syms 65.31 - $(OBJCOPY) -R .note -R .comment -S $(TARGET)-syms $(TARGET) 65.32 + -Map map.out head.o $(ALL_OBJS) -o $@ 65.33 + $(NM) -n $@ | $(BASEDIR)/tools/symbols > $(BASEDIR)/xen-syms.S 65.34 + $(MAKE) $(BASEDIR)/xen-syms.o 65.35 + $(LD) $(LDFLAGS) -T $(BASEDIR)/arch/$(TARGET_ARCH)/xen.lds.s -N \ 65.36 + -Map map.out head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@ 65.37 + $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S 65.38 + $(MAKE) $(BASEDIR)/xen-syms.o 65.39 + $(LD) $(LDFLAGS) -T $(BASEDIR)/arch/$(TARGET_ARCH)/xen.lds.s -N \ 65.40 + -Map map.out head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@ 65.41 + rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o 65.42 + 65.43 +$(TARGET): $(TARGET)-syms 65.44 + $(OBJCOPY) -R .note -R .comment -S $(TARGET)-syms $@ 65.45 $(NM) -n $(TARGET)-syms | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)'\ 65.46 > $(BASEDIR)/System.map 65.47
66.1 --- a/xen/arch/ia64/linux-xen/entry.S Mon Jan 09 11:19:55 2006 +0000 66.2 +++ b/xen/arch/ia64/linux-xen/entry.S Mon Jan 09 11:22:17 2006 +0000 66.3 @@ -1417,7 +1417,6 @@ GLOBAL_ENTRY(ia64_prepare_handle_unalign 66.4 br.cond.sptk.many rp // goes to ia64_leave_kernel 66.5 END(ia64_prepare_handle_unaligned) 66.6 66.7 -#ifndef XEN 66.8 // 66.9 // unw_init_running(void (*callback)(info, arg), void *arg) 66.10 // 66.11 @@ -1463,6 +1462,7 @@ 1: mov gp=loc2 // restore gp 66.12 br.ret.sptk.many rp 66.13 END(unw_init_running) 66.14 66.15 +#ifndef XEN 66.16 .rodata 66.17 .align 8 66.18 .globl sys_call_table
67.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 67.2 +++ b/xen/arch/ia64/linux-xen/process-linux-xen.c Mon Jan 09 11:22:17 2006 +0000 67.3 @@ -0,0 +1,848 @@ 67.4 +/* 67.5 + * Architecture-specific setup. 67.6 + * 67.7 + * Copyright (C) 1998-2003 Hewlett-Packard Co 67.8 + * David Mosberger-Tang <davidm@hpl.hp.com> 67.9 + * 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support 67.10 + */ 67.11 +#ifdef XEN 67.12 +#include <xen/types.h> 67.13 +#include <xen/lib.h> 67.14 +#include <xen/symbols.h> 67.15 +#include <xen/smp.h> 67.16 +#include <asm/uaccess.h> 67.17 +#include <asm/processor.h> 67.18 +#include <asm/ptrace.h> 67.19 +#include <asm/unwind.h> 67.20 +#else 67.21 +#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */ 67.22 +#include <linux/config.h> 67.23 + 67.24 +#include <linux/cpu.h> 67.25 +#include <linux/pm.h> 67.26 +#include <linux/elf.h> 67.27 +#include <linux/errno.h> 67.28 +#include <linux/kallsyms.h> 67.29 +#include <linux/kernel.h> 67.30 +#include <linux/mm.h> 67.31 +#include <linux/module.h> 67.32 +#include <linux/notifier.h> 67.33 +#include <linux/personality.h> 67.34 +#include <linux/sched.h> 67.35 +#include <linux/slab.h> 67.36 +#include <linux/smp_lock.h> 67.37 +#include <linux/stddef.h> 67.38 +#include <linux/thread_info.h> 67.39 +#include <linux/unistd.h> 67.40 +#include <linux/efi.h> 67.41 +#include <linux/interrupt.h> 67.42 +#include <linux/delay.h> 67.43 +#include <linux/kprobes.h> 67.44 + 67.45 +#include <asm/cpu.h> 67.46 +#include <asm/delay.h> 67.47 +#include <asm/elf.h> 67.48 +#include <asm/ia32.h> 67.49 +#include <asm/irq.h> 67.50 +#include <asm/pgalloc.h> 67.51 +#include <asm/processor.h> 67.52 +#include <asm/sal.h> 67.53 +#include <asm/tlbflush.h> 67.54 +#include <asm/uaccess.h> 67.55 +#include <asm/unwind.h> 67.56 +#include <asm/user.h> 67.57 + 67.58 +#include "entry.h" 67.59 + 67.60 +#ifdef CONFIG_PERFMON 67.61 +# include <asm/perfmon.h> 67.62 +#endif 67.63 + 67.64 +#include "sigframe.h" 67.65 + 67.66 +void (*ia64_mark_idle)(int); 67.67 +static DEFINE_PER_CPU(unsigned int, cpu_idle_state); 67.68 + 67.69 +unsigned long boot_option_idle_override = 0; 67.70 +EXPORT_SYMBOL(boot_option_idle_override); 67.71 +#endif 67.72 + 67.73 +void 67.74 +ia64_do_show_stack (struct unw_frame_info *info, void *arg) 67.75 +{ 67.76 + unsigned long ip, sp, bsp; 67.77 + char buf[128]; /* don't make it so big that it overflows the stack! */ 67.78 + 67.79 + printk("\nCall Trace:\n"); 67.80 + do { 67.81 + unw_get_ip(info, &ip); 67.82 + if (ip == 0) 67.83 + break; 67.84 + 67.85 + unw_get_sp(info, &sp); 67.86 + unw_get_bsp(info, &bsp); 67.87 + snprintf(buf, sizeof(buf), 67.88 + " [<%016lx>] %%s\n" 67.89 + " sp=%016lx bsp=%016lx\n", 67.90 + ip, sp, bsp); 67.91 + print_symbol(buf, ip); 67.92 + } while (unw_unwind(info) >= 0); 67.93 +} 67.94 + 67.95 +void 67.96 +show_stack (struct task_struct *task, unsigned long *sp) 67.97 +{ 67.98 + if (!task) 67.99 + unw_init_running(ia64_do_show_stack, NULL); 67.100 + else { 67.101 + struct unw_frame_info info; 67.102 + 67.103 + unw_init_from_blocked_task(&info, task); 67.104 + ia64_do_show_stack(&info, NULL); 67.105 + } 67.106 +} 67.107 + 67.108 +#ifndef XEN 67.109 +void 67.110 +dump_stack (void) 67.111 +{ 67.112 + show_stack(NULL, NULL); 67.113 +} 67.114 + 67.115 +EXPORT_SYMBOL(dump_stack); 67.116 +#endif 67.117 + 67.118 +#ifdef XEN 67.119 +void 67.120 +show_registers(struct pt_regs *regs) 67.121 +#else 67.122 +void 67.123 +show_regs (struct pt_regs *regs) 67.124 +#endif 67.125 +{ 67.126 + unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri; 67.127 + 67.128 +#ifndef XEN 67.129 + print_modules(); 67.130 + printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm); 67.131 + printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n", 67.132 + regs->cr_ipsr, regs->cr_ifs, ip, print_tainted()); 67.133 +#else 67.134 + printk("\nCPU %d\n", smp_processor_id()); 67.135 + printk("psr : %016lx ifs : %016lx ip : [<%016lx>]\n", 67.136 + regs->cr_ipsr, regs->cr_ifs, ip); 67.137 +#endif 67.138 + print_symbol("ip is at %s\n", ip); 67.139 + printk("unat: %016lx pfs : %016lx rsc : %016lx\n", 67.140 + regs->ar_unat, regs->ar_pfs, regs->ar_rsc); 67.141 + printk("rnat: %016lx bsps: %016lx pr : %016lx\n", 67.142 + regs->ar_rnat, regs->ar_bspstore, regs->pr); 67.143 + printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n", 67.144 + regs->loadrs, regs->ar_ccv, regs->ar_fpsr); 67.145 + printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd); 67.146 + printk("b0 : %016lx b6 : %016lx b7 : %016lx\n", regs->b0, regs->b6, regs->b7); 67.147 + printk("f6 : %05lx%016lx f7 : %05lx%016lx\n", 67.148 + regs->f6.u.bits[1], regs->f6.u.bits[0], 67.149 + regs->f7.u.bits[1], regs->f7.u.bits[0]); 67.150 + printk("f8 : %05lx%016lx f9 : %05lx%016lx\n", 67.151 + regs->f8.u.bits[1], regs->f8.u.bits[0], 67.152 + regs->f9.u.bits[1], regs->f9.u.bits[0]); 67.153 + printk("f10 : %05lx%016lx f11 : %05lx%016lx\n", 67.154 + regs->f10.u.bits[1], regs->f10.u.bits[0], 67.155 + regs->f11.u.bits[1], regs->f11.u.bits[0]); 67.156 + 67.157 + printk("r1 : %016lx r2 : %016lx r3 : %016lx\n", regs->r1, regs->r2, regs->r3); 67.158 + printk("r8 : %016lx r9 : %016lx r10 : %016lx\n", regs->r8, regs->r9, regs->r10); 67.159 + printk("r11 : %016lx r12 : %016lx r13 : %016lx\n", regs->r11, regs->r12, regs->r13); 67.160 + printk("r14 : %016lx r15 : %016lx r16 : %016lx\n", regs->r14, regs->r15, regs->r16); 67.161 + printk("r17 : %016lx r18 : %016lx r19 : %016lx\n", regs->r17, regs->r18, regs->r19); 67.162 + printk("r20 : %016lx r21 : %016lx r22 : %016lx\n", regs->r20, regs->r21, regs->r22); 67.163 + printk("r23 : %016lx r24 : %016lx r25 : %016lx\n", regs->r23, regs->r24, regs->r25); 67.164 + printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, regs->r27, regs->r28); 67.165 + printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, regs->r30, regs->r31); 67.166 + 67.167 + if (user_mode(regs)) { 67.168 + /* print the stacked registers */ 67.169 + unsigned long val, *bsp, ndirty; 67.170 + int i, sof, is_nat = 0; 67.171 + 67.172 + sof = regs->cr_ifs & 0x7f; /* size of frame */ 67.173 + ndirty = (regs->loadrs >> 19); 67.174 + bsp = ia64_rse_skip_regs((unsigned long *) regs->ar_bspstore, ndirty); 67.175 + for (i = 0; i < sof; ++i) { 67.176 + get_user(val, (unsigned long __user *) ia64_rse_skip_regs(bsp, i)); 67.177 + printk("r%-3u:%c%016lx%s", 32 + i, is_nat ? '*' : ' ', val, 67.178 + ((i == sof - 1) || (i % 3) == 2) ? "\n" : " "); 67.179 + } 67.180 + } else 67.181 + show_stack(NULL, NULL); 67.182 +} 67.183 + 67.184 +#ifndef XEN 67.185 +void 67.186 +do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall) 67.187 +{ 67.188 + if (fsys_mode(current, &scr->pt)) { 67.189 + /* defer signal-handling etc. until we return to privilege-level 0. */ 67.190 + if (!ia64_psr(&scr->pt)->lp) 67.191 + ia64_psr(&scr->pt)->lp = 1; 67.192 + return; 67.193 + } 67.194 + 67.195 +#ifdef CONFIG_PERFMON 67.196 + if (current->thread.pfm_needs_checking) 67.197 + pfm_handle_work(); 67.198 +#endif 67.199 + 67.200 + /* deal with pending signal delivery */ 67.201 + if (test_thread_flag(TIF_SIGPENDING)) 67.202 + ia64_do_signal(oldset, scr, in_syscall); 67.203 +} 67.204 + 67.205 +static int pal_halt = 1; 67.206 +static int can_do_pal_halt = 1; 67.207 + 67.208 +static int __init nohalt_setup(char * str) 67.209 +{ 67.210 + pal_halt = can_do_pal_halt = 0; 67.211 + return 1; 67.212 +} 67.213 +__setup("nohalt", nohalt_setup); 67.214 + 67.215 +void 67.216 +update_pal_halt_status(int status) 67.217 +{ 67.218 + can_do_pal_halt = pal_halt && status; 67.219 +} 67.220 + 67.221 +/* 67.222 + * We use this if we don't have any better idle routine.. 67.223 + */ 67.224 +void 67.225 +default_idle (void) 67.226 +{ 67.227 + local_irq_enable(); 67.228 + while (!need_resched()) 67.229 + if (can_do_pal_halt) 67.230 + safe_halt(); 67.231 + else 67.232 + cpu_relax(); 67.233 +} 67.234 + 67.235 +#ifdef CONFIG_HOTPLUG_CPU 67.236 +/* We don't actually take CPU down, just spin without interrupts. */ 67.237 +static inline void play_dead(void) 67.238 +{ 67.239 + extern void ia64_cpu_local_tick (void); 67.240 + unsigned int this_cpu = smp_processor_id(); 67.241 + 67.242 + /* Ack it */ 67.243 + __get_cpu_var(cpu_state) = CPU_DEAD; 67.244 + 67.245 + max_xtp(); 67.246 + local_irq_disable(); 67.247 + idle_domain_exit(); 67.248 + ia64_jump_to_sal(&sal_boot_rendez_state[this_cpu]); 67.249 + /* 67.250 + * The above is a point of no-return, the processor is 67.251 + * expected to be in SAL loop now. 67.252 + */ 67.253 + BUG(); 67.254 +} 67.255 +#else 67.256 +static inline void play_dead(void) 67.257 +{ 67.258 + BUG(); 67.259 +} 67.260 +#endif /* CONFIG_HOTPLUG_CPU */ 67.261 + 67.262 +void cpu_idle_wait(void) 67.263 +{ 67.264 + unsigned int cpu, this_cpu = get_cpu(); 67.265 + cpumask_t map; 67.266 + 67.267 + set_cpus_allowed(current, cpumask_of_cpu(this_cpu)); 67.268 + put_cpu(); 67.269 + 67.270 + cpus_clear(map); 67.271 + for_each_online_cpu(cpu) { 67.272 + per_cpu(cpu_idle_state, cpu) = 1; 67.273 + cpu_set(cpu, map); 67.274 + } 67.275 + 67.276 + __get_cpu_var(cpu_idle_state) = 0; 67.277 + 67.278 + wmb(); 67.279 + do { 67.280 + ssleep(1); 67.281 + for_each_online_cpu(cpu) { 67.282 + if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu)) 67.283 + cpu_clear(cpu, map); 67.284 + } 67.285 + cpus_and(map, map, cpu_online_map); 67.286 + } while (!cpus_empty(map)); 67.287 +} 67.288 +EXPORT_SYMBOL_GPL(cpu_idle_wait); 67.289 + 67.290 +void __attribute__((noreturn)) 67.291 +cpu_idle (void) 67.292 +{ 67.293 + void (*mark_idle)(int) = ia64_mark_idle; 67.294 + 67.295 + /* endless idle loop with no priority at all */ 67.296 + while (1) { 67.297 +#ifdef CONFIG_SMP 67.298 + if (!need_resched()) 67.299 + min_xtp(); 67.300 +#endif 67.301 + while (!need_resched()) { 67.302 + void (*idle)(void); 67.303 + 67.304 + if (__get_cpu_var(cpu_idle_state)) 67.305 + __get_cpu_var(cpu_idle_state) = 0; 67.306 + 67.307 + rmb(); 67.308 + if (mark_idle) 67.309 + (*mark_idle)(1); 67.310 + 67.311 + idle = pm_idle; 67.312 + if (!idle) 67.313 + idle = default_idle; 67.314 + (*idle)(); 67.315 + } 67.316 + 67.317 + if (mark_idle) 67.318 + (*mark_idle)(0); 67.319 + 67.320 +#ifdef CONFIG_SMP 67.321 + normal_xtp(); 67.322 +#endif 67.323 + schedule(); 67.324 + check_pgt_cache(); 67.325 + if (cpu_is_offline(smp_processor_id())) 67.326 + play_dead(); 67.327 + } 67.328 +} 67.329 + 67.330 +void 67.331 +ia64_save_extra (struct task_struct *task) 67.332 +{ 67.333 +#ifdef CONFIG_PERFMON 67.334 + unsigned long info; 67.335 +#endif 67.336 + 67.337 + if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) 67.338 + ia64_save_debug_regs(&task->thread.dbr[0]); 67.339 + 67.340 +#ifdef CONFIG_PERFMON 67.341 + if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) 67.342 + pfm_save_regs(task); 67.343 + 67.344 + info = __get_cpu_var(pfm_syst_info); 67.345 + if (info & PFM_CPUINFO_SYST_WIDE) 67.346 + pfm_syst_wide_update_task(task, info, 0); 67.347 +#endif 67.348 + 67.349 +#ifdef CONFIG_IA32_SUPPORT 67.350 + if (IS_IA32_PROCESS(ia64_task_regs(task))) 67.351 + ia32_save_state(task); 67.352 +#endif 67.353 +} 67.354 + 67.355 +void 67.356 +ia64_load_extra (struct task_struct *task) 67.357 +{ 67.358 +#ifdef CONFIG_PERFMON 67.359 + unsigned long info; 67.360 +#endif 67.361 + 67.362 + if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) 67.363 + ia64_load_debug_regs(&task->thread.dbr[0]); 67.364 + 67.365 +#ifdef CONFIG_PERFMON 67.366 + if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0) 67.367 + pfm_load_regs(task); 67.368 + 67.369 + info = __get_cpu_var(pfm_syst_info); 67.370 + if (info & PFM_CPUINFO_SYST_WIDE) 67.371 + pfm_syst_wide_update_task(task, info, 1); 67.372 +#endif 67.373 + 67.374 +#ifdef CONFIG_IA32_SUPPORT 67.375 + if (IS_IA32_PROCESS(ia64_task_regs(task))) 67.376 + ia32_load_state(task); 67.377 +#endif 67.378 +} 67.379 + 67.380 +/* 67.381 + * Copy the state of an ia-64 thread. 67.382 + * 67.383 + * We get here through the following call chain: 67.384 + * 67.385 + * from user-level: from kernel: 67.386 + * 67.387 + * <clone syscall> <some kernel call frames> 67.388 + * sys_clone : 67.389 + * do_fork do_fork 67.390 + * copy_thread copy_thread 67.391 + * 67.392 + * This means that the stack layout is as follows: 67.393 + * 67.394 + * +---------------------+ (highest addr) 67.395 + * | struct pt_regs | 67.396 + * +---------------------+ 67.397 + * | struct switch_stack | 67.398 + * +---------------------+ 67.399 + * | | 67.400 + * | memory stack | 67.401 + * | | <-- sp (lowest addr) 67.402 + * +---------------------+ 67.403 + * 67.404 + * Observe that we copy the unat values that are in pt_regs and switch_stack. Spilling an 67.405 + * integer to address X causes bit N in ar.unat to be set to the NaT bit of the register, 67.406 + * with N=(X & 0x1ff)/8. Thus, copying the unat value preserves the NaT bits ONLY if the 67.407 + * pt_regs structure in the parent is congruent to that of the child, modulo 512. Since 67.408 + * the stack is page aligned and the page size is at least 4KB, this is always the case, 67.409 + * so there is nothing to worry about. 67.410 + */ 67.411 +int 67.412 +copy_thread (int nr, unsigned long clone_flags, 67.413 + unsigned long user_stack_base, unsigned long user_stack_size, 67.414 + struct task_struct *p, struct pt_regs *regs) 67.415 +{ 67.416 + extern char ia64_ret_from_clone, ia32_ret_from_clone; 67.417 + struct switch_stack *child_stack, *stack; 67.418 + unsigned long rbs, child_rbs, rbs_size; 67.419 + struct pt_regs *child_ptregs; 67.420 + int retval = 0; 67.421 + 67.422 +#ifdef CONFIG_SMP 67.423 + /* 67.424 + * For SMP idle threads, fork_by_hand() calls do_fork with 67.425 + * NULL regs. 67.426 + */ 67.427 + if (!regs) 67.428 + return 0; 67.429 +#endif 67.430 + 67.431 + stack = ((struct switch_stack *) regs) - 1; 67.432 + 67.433 + child_ptregs = (struct pt_regs *) ((unsigned long) p + IA64_STK_OFFSET) - 1; 67.434 + child_stack = (struct switch_stack *) child_ptregs - 1; 67.435 + 67.436 + /* copy parent's switch_stack & pt_regs to child: */ 67.437 + memcpy(child_stack, stack, sizeof(*child_ptregs) + sizeof(*child_stack)); 67.438 + 67.439 + rbs = (unsigned long) current + IA64_RBS_OFFSET; 67.440 + child_rbs = (unsigned long) p + IA64_RBS_OFFSET; 67.441 + rbs_size = stack->ar_bspstore - rbs; 67.442 + 67.443 + /* copy the parent's register backing store to the child: */ 67.444 + memcpy((void *) child_rbs, (void *) rbs, rbs_size); 67.445 + 67.446 + if (likely(user_mode(child_ptregs))) { 67.447 + if ((clone_flags & CLONE_SETTLS) && !IS_IA32_PROCESS(regs)) 67.448 + child_ptregs->r13 = regs->r16; /* see sys_clone2() in entry.S */ 67.449 + if (user_stack_base) { 67.450 + child_ptregs->r12 = user_stack_base + user_stack_size - 16; 67.451 + child_ptregs->ar_bspstore = user_stack_base; 67.452 + child_ptregs->ar_rnat = 0; 67.453 + child_ptregs->loadrs = 0; 67.454 + } 67.455 + } else { 67.456 + /* 67.457 + * Note: we simply preserve the relative position of 67.458 + * the stack pointer here. There is no need to 67.459 + * allocate a scratch area here, since that will have 67.460 + * been taken care of by the caller of sys_clone() 67.461 + * already. 67.462 + */ 67.463 + child_ptregs->r12 = (unsigned long) child_ptregs - 16; /* kernel sp */ 67.464 + child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */ 67.465 + } 67.466 + child_stack->ar_bspstore = child_rbs + rbs_size; 67.467 + if (IS_IA32_PROCESS(regs)) 67.468 + child_stack->b0 = (unsigned long) &ia32_ret_from_clone; 67.469 + else 67.470 + child_stack->b0 = (unsigned long) &ia64_ret_from_clone; 67.471 + 67.472 + /* copy parts of thread_struct: */ 67.473 + p->thread.ksp = (unsigned long) child_stack - 16; 67.474 + 67.475 + /* stop some PSR bits from being inherited. 67.476 + * the psr.up/psr.pp bits must be cleared on fork but inherited on execve() 67.477 + * therefore we must specify them explicitly here and not include them in 67.478 + * IA64_PSR_BITS_TO_CLEAR. 67.479 + */ 67.480 + child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET) 67.481 + & ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP)); 67.482 + 67.483 + /* 67.484 + * NOTE: The calling convention considers all floating point 67.485 + * registers in the high partition (fph) to be scratch. Since 67.486 + * the only way to get to this point is through a system call, 67.487 + * we know that the values in fph are all dead. Hence, there 67.488 + * is no need to inherit the fph state from the parent to the 67.489 + * child and all we have to do is to make sure that 67.490 + * IA64_THREAD_FPH_VALID is cleared in the child. 67.491 + * 67.492 + * XXX We could push this optimization a bit further by 67.493 + * clearing IA64_THREAD_FPH_VALID on ANY system call. 67.494 + * However, it's not clear this is worth doing. Also, it 67.495 + * would be a slight deviation from the normal Linux system 67.496 + * call behavior where scratch registers are preserved across 67.497 + * system calls (unless used by the system call itself). 67.498 + */ 67.499 +# define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \ 67.500 + | IA64_THREAD_PM_VALID) 67.501 +# define THREAD_FLAGS_TO_SET 0 67.502 + p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR) 67.503 + | THREAD_FLAGS_TO_SET); 67.504 + ia64_drop_fpu(p); /* don't pick up stale state from a CPU's fph */ 67.505 +#ifdef CONFIG_IA32_SUPPORT 67.506 + /* 67.507 + * If we're cloning an IA32 task then save the IA32 extra 67.508 + * state from the current task to the new task 67.509 + */ 67.510 + if (IS_IA32_PROCESS(ia64_task_regs(current))) { 67.511 + ia32_save_state(p); 67.512 + if (clone_flags & CLONE_SETTLS) 67.513 + retval = ia32_clone_tls(p, child_ptregs); 67.514 + 67.515 + /* Copy partially mapped page list */ 67.516 + if (!retval) 67.517 + retval = ia32_copy_partial_page_list(p, clone_flags); 67.518 + } 67.519 +#endif 67.520 + 67.521 +#ifdef CONFIG_PERFMON 67.522 + if (current->thread.pfm_context) 67.523 + pfm_inherit(p, child_ptregs); 67.524 +#endif 67.525 + return retval; 67.526 +} 67.527 + 67.528 +static void 67.529 +do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg) 67.530 +{ 67.531 + unsigned long mask, sp, nat_bits = 0, ip, ar_rnat, urbs_end, cfm; 67.532 + elf_greg_t *dst = arg; 67.533 + struct pt_regs *pt; 67.534 + char nat; 67.535 + int i; 67.536 + 67.537 + memset(dst, 0, sizeof(elf_gregset_t)); /* don't leak any kernel bits to user-level */ 67.538 + 67.539 + if (unw_unwind_to_user(info) < 0) 67.540 + return; 67.541 + 67.542 + unw_get_sp(info, &sp); 67.543 + pt = (struct pt_regs *) (sp + 16); 67.544 + 67.545 + urbs_end = ia64_get_user_rbs_end(task, pt, &cfm); 67.546 + 67.547 + if (ia64_sync_user_rbs(task, info->sw, pt->ar_bspstore, urbs_end) < 0) 67.548 + return; 67.549 + 67.550 + ia64_peek(task, info->sw, urbs_end, (long) ia64_rse_rnat_addr((long *) urbs_end), 67.551 + &ar_rnat); 67.552 + 67.553 + /* 67.554 + * coredump format: 67.555 + * r0-r31 67.556 + * NaT bits (for r0-r31; bit N == 1 iff rN is a NaT) 67.557 + * predicate registers (p0-p63) 67.558 + * b0-b7 67.559 + * ip cfm user-mask 67.560 + * ar.rsc ar.bsp ar.bspstore ar.rnat 67.561 + * ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec 67.562 + */ 67.563 + 67.564 + /* r0 is zero */ 67.565 + for (i = 1, mask = (1UL << i); i < 32; ++i) { 67.566 + unw_get_gr(info, i, &dst[i], &nat); 67.567 + if (nat) 67.568 + nat_bits |= mask; 67.569 + mask <<= 1; 67.570 + } 67.571 + dst[32] = nat_bits; 67.572 + unw_get_pr(info, &dst[33]); 67.573 + 67.574 + for (i = 0; i < 8; ++i) 67.575 + unw_get_br(info, i, &dst[34 + i]); 67.576 + 67.577 + unw_get_rp(info, &ip); 67.578 + dst[42] = ip + ia64_psr(pt)->ri; 67.579 + dst[43] = cfm; 67.580 + dst[44] = pt->cr_ipsr & IA64_PSR_UM; 67.581 + 67.582 + unw_get_ar(info, UNW_AR_RSC, &dst[45]); 67.583 + /* 67.584 + * For bsp and bspstore, unw_get_ar() would return the kernel 67.585 + * addresses, but we need the user-level addresses instead: 67.586 + */ 67.587 + dst[46] = urbs_end; /* note: by convention PT_AR_BSP points to the end of the urbs! */ 67.588 + dst[47] = pt->ar_bspstore; 67.589 + dst[48] = ar_rnat; 67.590 + unw_get_ar(info, UNW_AR_CCV, &dst[49]); 67.591 + unw_get_ar(info, UNW_AR_UNAT, &dst[50]); 67.592 + unw_get_ar(info, UNW_AR_FPSR, &dst[51]); 67.593 + dst[52] = pt->ar_pfs; /* UNW_AR_PFS is == to pt->cr_ifs for interrupt frames */ 67.594 + unw_get_ar(info, UNW_AR_LC, &dst[53]); 67.595 + unw_get_ar(info, UNW_AR_EC, &dst[54]); 67.596 + unw_get_ar(info, UNW_AR_CSD, &dst[55]); 67.597 + unw_get_ar(info, UNW_AR_SSD, &dst[56]); 67.598 +} 67.599 + 67.600 +void 67.601 +do_dump_task_fpu (struct task_struct *task, struct unw_frame_info *info, void *arg) 67.602 +{ 67.603 + elf_fpreg_t *dst = arg; 67.604 + int i; 67.605 + 67.606 + memset(dst, 0, sizeof(elf_fpregset_t)); /* don't leak any "random" bits */ 67.607 + 67.608 + if (unw_unwind_to_user(info) < 0) 67.609 + return; 67.610 + 67.611 + /* f0 is 0.0, f1 is 1.0 */ 67.612 + 67.613 + for (i = 2; i < 32; ++i) 67.614 + unw_get_fr(info, i, dst + i); 67.615 + 67.616 + ia64_flush_fph(task); 67.617 + if ((task->thread.flags & IA64_THREAD_FPH_VALID) != 0) 67.618 + memcpy(dst + 32, task->thread.fph, 96*16); 67.619 +} 67.620 + 67.621 +void 67.622 +do_copy_regs (struct unw_frame_info *info, void *arg) 67.623 +{ 67.624 + do_copy_task_regs(current, info, arg); 67.625 +} 67.626 + 67.627 +void 67.628 +do_dump_fpu (struct unw_frame_info *info, void *arg) 67.629 +{ 67.630 + do_dump_task_fpu(current, info, arg); 67.631 +} 67.632 + 67.633 +int 67.634 +dump_task_regs(struct task_struct *task, elf_gregset_t *regs) 67.635 +{ 67.636 + struct unw_frame_info tcore_info; 67.637 + 67.638 + if (current == task) { 67.639 + unw_init_running(do_copy_regs, regs); 67.640 + } else { 67.641 + memset(&tcore_info, 0, sizeof(tcore_info)); 67.642 + unw_init_from_blocked_task(&tcore_info, task); 67.643 + do_copy_task_regs(task, &tcore_info, regs); 67.644 + } 67.645 + return 1; 67.646 +} 67.647 + 67.648 +void 67.649 +ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst) 67.650 +{ 67.651 + unw_init_running(do_copy_regs, dst); 67.652 +} 67.653 + 67.654 +int 67.655 +dump_task_fpu (struct task_struct *task, elf_fpregset_t *dst) 67.656 +{ 67.657 + struct unw_frame_info tcore_info; 67.658 + 67.659 + if (current == task) { 67.660 + unw_init_running(do_dump_fpu, dst); 67.661 + } else { 67.662 + memset(&tcore_info, 0, sizeof(tcore_info)); 67.663 + unw_init_from_blocked_task(&tcore_info, task); 67.664 + do_dump_task_fpu(task, &tcore_info, dst); 67.665 + } 67.666 + return 1; 67.667 +} 67.668 + 67.669 +int 67.670 +dump_fpu (struct pt_regs *pt, elf_fpregset_t dst) 67.671 +{ 67.672 + unw_init_running(do_dump_fpu, dst); 67.673 + return 1; /* f0-f31 are always valid so we always return 1 */ 67.674 +} 67.675 + 67.676 +long 67.677 +sys_execve (char __user *filename, char __user * __user *argv, char __user * __user *envp, 67.678 + struct pt_regs *regs) 67.679 +{ 67.680 + char *fname; 67.681 + int error; 67.682 + 67.683 + fname = getname(filename); 67.684 + error = PTR_ERR(fname); 67.685 + if (IS_ERR(fname)) 67.686 + goto out; 67.687 + error = do_execve(fname, argv, envp, regs); 67.688 + putname(fname); 67.689 +out: 67.690 + return error; 67.691 +} 67.692 + 67.693 +pid_t 67.694 +kernel_thread (int (*fn)(void *), void *arg, unsigned long flags) 67.695 +{ 67.696 + extern void start_kernel_thread (void); 67.697 + unsigned long *helper_fptr = (unsigned long *) &start_kernel_thread; 67.698 + struct { 67.699 + struct switch_stack sw; 67.700 + struct pt_regs pt; 67.701 + } regs; 67.702 + 67.703 + memset(®s, 0, sizeof(regs)); 67.704 + regs.pt.cr_iip = helper_fptr[0]; /* set entry point (IP) */ 67.705 + regs.pt.r1 = helper_fptr[1]; /* set GP */ 67.706 + regs.pt.r9 = (unsigned long) fn; /* 1st argument */ 67.707 + regs.pt.r11 = (unsigned long) arg; /* 2nd argument */ 67.708 + /* Preserve PSR bits, except for bits 32-34 and 37-45, which we can't read. */ 67.709 + regs.pt.cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN; 67.710 + regs.pt.cr_ifs = 1UL << 63; /* mark as valid, empty frame */ 67.711 + regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR); 67.712 + regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET; 67.713 + regs.sw.pr = (1 << PRED_KERNEL_STACK); 67.714 + return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s.pt, 0, NULL, NULL); 67.715 +} 67.716 +EXPORT_SYMBOL(kernel_thread); 67.717 + 67.718 +/* This gets called from kernel_thread() via ia64_invoke_thread_helper(). */ 67.719 +int 67.720 +kernel_thread_helper (int (*fn)(void *), void *arg) 67.721 +{ 67.722 +#ifdef CONFIG_IA32_SUPPORT 67.723 + if (IS_IA32_PROCESS(ia64_task_regs(current))) { 67.724 + /* A kernel thread is always a 64-bit process. */ 67.725 + current->thread.map_base = DEFAULT_MAP_BASE; 67.726 + current->thread.task_size = DEFAULT_TASK_SIZE; 67.727 + ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob); 67.728 + ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1); 67.729 + } 67.730 +#endif 67.731 + return (*fn)(arg); 67.732 +} 67.733 + 67.734 +/* 67.735 + * Flush thread state. This is called when a thread does an execve(). 67.736 + */ 67.737 +void 67.738 +flush_thread (void) 67.739 +{ 67.740 + /* 67.741 + * Remove function-return probe instances associated with this task 67.742 + * and put them back on the free list. Do not insert an exit probe for 67.743 + * this function, it will be disabled by kprobe_flush_task if you do. 67.744 + */ 67.745 + kprobe_flush_task(current); 67.746 + 67.747 + /* drop floating-point and debug-register state if it exists: */ 67.748 + current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID); 67.749 + ia64_drop_fpu(current); 67.750 + if (IS_IA32_PROCESS(ia64_task_regs(current))) 67.751 + ia32_drop_partial_page_list(current); 67.752 +} 67.753 + 67.754 +/* 67.755 + * Clean up state associated with current thread. This is called when 67.756 + * the thread calls exit(). 67.757 + */ 67.758 +void 67.759 +exit_thread (void) 67.760 +{ 67.761 + 67.762 + /* 67.763 + * Remove function-return probe instances associated with this task 67.764 + * and put them back on the free list. Do not insert an exit probe for 67.765 + * this function, it will be disabled by kprobe_flush_task if you do. 67.766 + */ 67.767 + kprobe_flush_task(current); 67.768 + 67.769 + ia64_drop_fpu(current); 67.770 +#ifdef CONFIG_PERFMON 67.771 + /* if needed, stop monitoring and flush state to perfmon context */ 67.772 + if (current->thread.pfm_context) 67.773 + pfm_exit_thread(current); 67.774 + 67.775 + /* free debug register resources */ 67.776 + if (current->thread.flags & IA64_THREAD_DBG_VALID) 67.777 + pfm_release_debug_registers(current); 67.778 +#endif 67.779 + if (IS_IA32_PROCESS(ia64_task_regs(current))) 67.780 + ia32_drop_partial_page_list(current); 67.781 +} 67.782 + 67.783 +unsigned long 67.784 +get_wchan (struct task_struct *p) 67.785 +{ 67.786 + struct unw_frame_info info; 67.787 + unsigned long ip; 67.788 + int count = 0; 67.789 + 67.790 + /* 67.791 + * Note: p may not be a blocked task (it could be current or 67.792 + * another process running on some other CPU. Rather than 67.793 + * trying to determine if p is really blocked, we just assume 67.794 + * it's blocked and rely on the unwind routines to fail 67.795 + * gracefully if the process wasn't really blocked after all. 67.796 + * --davidm 99/12/15 67.797 + */ 67.798 + unw_init_from_blocked_task(&info, p); 67.799 + do { 67.800 + if (unw_unwind(&info) < 0) 67.801 + return 0; 67.802 + unw_get_ip(&info, &ip); 67.803 + if (!in_sched_functions(ip)) 67.804 + return ip; 67.805 + } while (count++ < 16); 67.806 + return 0; 67.807 +} 67.808 + 67.809 +void 67.810 +cpu_halt (void) 67.811 +{ 67.812 + pal_power_mgmt_info_u_t power_info[8]; 67.813 + unsigned long min_power; 67.814 + int i, min_power_state; 67.815 + 67.816 + if (ia64_pal_halt_info(power_info) != 0) 67.817 + return; 67.818 + 67.819 + min_power_state = 0; 67.820 + min_power = power_info[0].pal_power_mgmt_info_s.power_consumption; 67.821 + for (i = 1; i < 8; ++i) 67.822 + if (power_info[i].pal_power_mgmt_info_s.im 67.823 + && power_info[i].pal_power_mgmt_info_s.power_consumption < min_power) { 67.824 + min_power = power_info[i].pal_power_mgmt_info_s.power_consumption; 67.825 + min_power_state = i; 67.826 + } 67.827 + 67.828 + while (1) 67.829 + ia64_pal_halt(min_power_state); 67.830 +} 67.831 + 67.832 +void 67.833 +machine_restart (char *restart_cmd) 67.834 +{ 67.835 + (*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL); 67.836 +} 67.837 + 67.838 +void 67.839 +machine_halt (void) 67.840 +{ 67.841 + cpu_halt(); 67.842 +} 67.843 + 67.844 +void 67.845 +machine_power_off (void) 67.846 +{ 67.847 + if (pm_power_off) 67.848 + pm_power_off(); 67.849 + machine_halt(); 67.850 +} 67.851 +#endif // !XEN
68.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 68.2 +++ b/xen/arch/ia64/linux-xen/unwind.c Mon Jan 09 11:22:17 2006 +0000 68.3 @@ -0,0 +1,2332 @@ 68.4 +/* 68.5 + * Copyright (C) 1999-2004 Hewlett-Packard Co 68.6 + * David Mosberger-Tang <davidm@hpl.hp.com> 68.7 + * Copyright (C) 2003 Fenghua Yu <fenghua.yu@intel.com> 68.8 + * - Change pt_regs_off() to make it less dependant on pt_regs structure. 68.9 + */ 68.10 +/* 68.11 + * This file implements call frame unwind support for the Linux 68.12 + * kernel. Parsing and processing the unwind information is 68.13 + * time-consuming, so this implementation translates the unwind 68.14 + * descriptors into unwind scripts. These scripts are very simple 68.15 + * (basically a sequence of assignments) and efficient to execute. 68.16 + * They are cached for later re-use. Each script is specific for a 68.17 + * given instruction pointer address and the set of predicate values 68.18 + * that the script depends on (most unwind descriptors are 68.19 + * unconditional and scripts often do not depend on predicates at 68.20 + * all). This code is based on the unwind conventions described in 68.21 + * the "IA-64 Software Conventions and Runtime Architecture" manual. 68.22 + * 68.23 + * SMP conventions: 68.24 + * o updates to the global unwind data (in structure "unw") are serialized 68.25 + * by the unw.lock spinlock 68.26 + * o each unwind script has its own read-write lock; a thread must acquire 68.27 + * a read lock before executing a script and must acquire a write lock 68.28 + * before modifying a script 68.29 + * o if both the unw.lock spinlock and a script's read-write lock must be 68.30 + * acquired, then the read-write lock must be acquired first. 68.31 + */ 68.32 +#ifdef XEN 68.33 +#include <xen/types.h> 68.34 +#include <xen/elf.h> 68.35 +#include <xen/kernel.h> 68.36 +#include <xen/sched.h> 68.37 +#include <xen/xmalloc.h> 68.38 +#include <xen/spinlock.h> 68.39 + 68.40 +// work around 68.41 +#ifdef CONFIG_SMP 68.42 +#define write_trylock(lock) _raw_write_trylock(lock) 68.43 +#else 68.44 +#define write_trylock(lock) ({1;}) 68.45 +#endif 68.46 + 68.47 +#else 68.48 +#include <linux/module.h> 68.49 +#include <linux/bootmem.h> 68.50 +#include <linux/elf.h> 68.51 +#include <linux/kernel.h> 68.52 +#include <linux/sched.h> 68.53 +#include <linux/slab.h> 68.54 +#endif 68.55 + 68.56 +#include <asm/unwind.h> 68.57 + 68.58 +#include <asm/delay.h> 68.59 +#include <asm/page.h> 68.60 +#include <asm/ptrace.h> 68.61 +#include <asm/ptrace_offsets.h> 68.62 +#include <asm/rse.h> 68.63 +#include <asm/sections.h> 68.64 +#include <asm/system.h> 68.65 +#include <asm/uaccess.h> 68.66 + 68.67 +#include "entry.h" 68.68 +#include "unwind_i.h" 68.69 + 68.70 +#define UNW_LOG_CACHE_SIZE 7 /* each unw_script is ~256 bytes in size */ 68.71 +#define UNW_CACHE_SIZE (1 << UNW_LOG_CACHE_SIZE) 68.72 + 68.73 +#define UNW_LOG_HASH_SIZE (UNW_LOG_CACHE_SIZE + 1) 68.74 +#define UNW_HASH_SIZE (1 << UNW_LOG_HASH_SIZE) 68.75 + 68.76 +#define UNW_STATS 0 /* WARNING: this disabled interrupts for long time-spans!! */ 68.77 + 68.78 +#ifdef UNW_DEBUG 68.79 + static unsigned int unw_debug_level = UNW_DEBUG; 68.80 +# define UNW_DEBUG_ON(n) unw_debug_level >= n 68.81 + /* Do not code a printk level, not all debug lines end in newline */ 68.82 +# define UNW_DPRINT(n, ...) if (UNW_DEBUG_ON(n)) printk(__VA_ARGS__) 68.83 +# define inline 68.84 +#else /* !UNW_DEBUG */ 68.85 +# define UNW_DEBUG_ON(n) 0 68.86 +# define UNW_DPRINT(n, ...) 68.87 +#endif /* UNW_DEBUG */ 68.88 + 68.89 +#if UNW_STATS 68.90 +# define STAT(x...) x 68.91 +#else 68.92 +# define STAT(x...) 68.93 +#endif 68.94 + 68.95 +#ifdef XEN 68.96 +#define alloc_reg_state() xmalloc(struct unw_reg_state) 68.97 +#define free_reg_state(usr) xfree(usr) 68.98 +#define alloc_labeled_state() xmalloc(struct unw_labeled_state) 68.99 +#define free_labeled_state(usr) xfree(usr) 68.100 +#else 68.101 +#define alloc_reg_state() kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC) 68.102 +#define free_reg_state(usr) kfree(usr) 68.103 +#define alloc_labeled_state() kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC) 68.104 +#define free_labeled_state(usr) kfree(usr) 68.105 +#endif 68.106 + 68.107 +typedef unsigned long unw_word; 68.108 +typedef unsigned char unw_hash_index_t; 68.109 + 68.110 +static struct { 68.111 + spinlock_t lock; /* spinlock for unwind data */ 68.112 + 68.113 + /* list of unwind tables (one per load-module) */ 68.114 + struct unw_table *tables; 68.115 + 68.116 + unsigned long r0; /* constant 0 for r0 */ 68.117 + 68.118 + /* table of registers that prologues can save (and order in which they're saved): */ 68.119 + const unsigned char save_order[8]; 68.120 + 68.121 + /* maps a preserved register index (preg_index) to corresponding switch_stack offset: */ 68.122 + unsigned short sw_off[sizeof(struct unw_frame_info) / 8]; 68.123 + 68.124 + unsigned short lru_head; /* index of lead-recently used script */ 68.125 + unsigned short lru_tail; /* index of most-recently used script */ 68.126 + 68.127 + /* index into unw_frame_info for preserved register i */ 68.128 + unsigned short preg_index[UNW_NUM_REGS]; 68.129 + 68.130 + short pt_regs_offsets[32]; 68.131 + 68.132 + /* unwind table for the kernel: */ 68.133 + struct unw_table kernel_table; 68.134 + 68.135 + /* unwind table describing the gate page (kernel code that is mapped into user space): */ 68.136 + size_t gate_table_size; 68.137 + unsigned long *gate_table; 68.138 + 68.139 + /* hash table that maps instruction pointer to script index: */ 68.140 + unsigned short hash[UNW_HASH_SIZE]; 68.141 + 68.142 + /* script cache: */ 68.143 + struct unw_script cache[UNW_CACHE_SIZE]; 68.144 + 68.145 +# ifdef UNW_DEBUG 68.146 + const char *preg_name[UNW_NUM_REGS]; 68.147 +# endif 68.148 +# if UNW_STATS 68.149 + struct { 68.150 + struct { 68.151 + int lookups; 68.152 + int hinted_hits; 68.153 + int normal_hits; 68.154 + int collision_chain_traversals; 68.155 + } cache; 68.156 + struct { 68.157 + unsigned long build_time; 68.158 + unsigned long run_time; 68.159 + unsigned long parse_time; 68.160 + int builds; 68.161 + int news; 68.162 + int collisions; 68.163 + int runs; 68.164 + } script; 68.165 + struct { 68.166 + unsigned long init_time; 68.167 + unsigned long unwind_time; 68.168 + int inits; 68.169 + int unwinds; 68.170 + } api; 68.171 + } stat; 68.172 +# endif 68.173 +} unw = { 68.174 + .tables = &unw.kernel_table, 68.175 + .lock = SPIN_LOCK_UNLOCKED, 68.176 + .save_order = { 68.177 + UNW_REG_RP, UNW_REG_PFS, UNW_REG_PSP, UNW_REG_PR, 68.178 + UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR 68.179 + }, 68.180 + .preg_index = { 68.181 + offsetof(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_GR */ 68.182 + offsetof(struct unw_frame_info, pri_unat_loc)/8, /* PRI_UNAT_MEM */ 68.183 + offsetof(struct unw_frame_info, bsp_loc)/8, 68.184 + offsetof(struct unw_frame_info, bspstore_loc)/8, 68.185 + offsetof(struct unw_frame_info, pfs_loc)/8, 68.186 + offsetof(struct unw_frame_info, rnat_loc)/8, 68.187 + offsetof(struct unw_frame_info, psp)/8, 68.188 + offsetof(struct unw_frame_info, rp_loc)/8, 68.189 + offsetof(struct unw_frame_info, r4)/8, 68.190 + offsetof(struct unw_frame_info, r5)/8, 68.191 + offsetof(struct unw_frame_info, r6)/8, 68.192 + offsetof(struct unw_frame_info, r7)/8, 68.193 + offsetof(struct unw_frame_info, unat_loc)/8, 68.194 + offsetof(struct unw_frame_info, pr_loc)/8, 68.195 + offsetof(struct unw_frame_info, lc_loc)/8, 68.196 + offsetof(struct unw_frame_info, fpsr_loc)/8, 68.197 + offsetof(struct unw_frame_info, b1_loc)/8, 68.198 + offsetof(struct unw_frame_info, b2_loc)/8, 68.199 + offsetof(struct unw_frame_info, b3_loc)/8, 68.200 + offsetof(struct unw_frame_info, b4_loc)/8, 68.201 + offsetof(struct unw_frame_info, b5_loc)/8, 68.202 + offsetof(struct unw_frame_info, f2_loc)/8, 68.203 + offsetof(struct unw_frame_info, f3_loc)/8, 68.204 + offsetof(struct unw_frame_info, f4_loc)/8, 68.205 + offsetof(struct unw_frame_info, f5_loc)/8, 68.206 + offsetof(struct unw_frame_info, fr_loc[16 - 16])/8, 68.207 + offsetof(struct unw_frame_info, fr_loc[17 - 16])/8, 68.208 + offsetof(struct unw_frame_info, fr_loc[18 - 16])/8, 68.209 + offsetof(struct unw_frame_info, fr_loc[19 - 16])/8, 68.210 + offsetof(struct unw_frame_info, fr_loc[20 - 16])/8, 68.211 + offsetof(struct unw_frame_info, fr_loc[21 - 16])/8, 68.212 + offsetof(struct unw_frame_info, fr_loc[22 - 16])/8, 68.213 + offsetof(struct unw_frame_info, fr_loc[23 - 16])/8, 68.214 + offsetof(struct unw_frame_info, fr_loc[24 - 16])/8, 68.215 + offsetof(struct unw_frame_info, fr_loc[25 - 16])/8, 68.216 + offsetof(struct unw_frame_info, fr_loc[26 - 16])/8, 68.217 + offsetof(struct unw_frame_info, fr_loc[27 - 16])/8, 68.218 + offsetof(struct unw_frame_info, fr_loc[28 - 16])/8, 68.219 + offsetof(struct unw_frame_info, fr_loc[29 - 16])/8, 68.220 + offsetof(struct unw_frame_info, fr_loc[30 - 16])/8, 68.221 + offsetof(struct unw_frame_info, fr_loc[31 - 16])/8, 68.222 + }, 68.223 + .pt_regs_offsets = { 68.224 + [0] = -1, 68.225 + offsetof(struct pt_regs, r1), 68.226 + offsetof(struct pt_regs, r2), 68.227 + offsetof(struct pt_regs, r3), 68.228 + [4] = -1, [5] = -1, [6] = -1, [7] = -1, 68.229 + offsetof(struct pt_regs, r8), 68.230 + offsetof(struct pt_regs, r9), 68.231 + offsetof(struct pt_regs, r10), 68.232 + offsetof(struct pt_regs, r11), 68.233 + offsetof(struct pt_regs, r12), 68.234 + offsetof(struct pt_regs, r13), 68.235 + offsetof(struct pt_regs, r14), 68.236 + offsetof(struct pt_regs, r15), 68.237 + offsetof(struct pt_regs, r16), 68.238 + offsetof(struct pt_regs, r17), 68.239 + offsetof(struct pt_regs, r18), 68.240 + offsetof(struct pt_regs, r19), 68.241 + offsetof(struct pt_regs, r20), 68.242 + offsetof(struct pt_regs, r21), 68.243 + offsetof(struct pt_regs, r22), 68.244 + offsetof(struct pt_regs, r23), 68.245 + offsetof(struct pt_regs, r24), 68.246 + offsetof(struct pt_regs, r25), 68.247 + offsetof(struct pt_regs, r26), 68.248 + offsetof(struct pt_regs, r27), 68.249 + offsetof(struct pt_regs, r28), 68.250 + offsetof(struct pt_regs, r29), 68.251 + offsetof(struct pt_regs, r30), 68.252 + offsetof(struct pt_regs, r31), 68.253 + }, 68.254 + .hash = { [0 ... UNW_HASH_SIZE - 1] = -1 }, 68.255 +#ifdef UNW_DEBUG 68.256 + .preg_name = { 68.257 + "pri_unat_gr", "pri_unat_mem", "bsp", "bspstore", "ar.pfs", "ar.rnat", "psp", "rp", 68.258 + "r4", "r5", "r6", "r7", 68.259 + "ar.unat", "pr", "ar.lc", "ar.fpsr", 68.260 + "b1", "b2", "b3", "b4", "b5", 68.261 + "f2", "f3", "f4", "f5", 68.262 + "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", 68.263 + "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" 68.264 + } 68.265 +#endif 68.266 +}; 68.267 + 68.268 +static inline int 68.269 +read_only (void *addr) 68.270 +{ 68.271 + return (unsigned long) ((char *) addr - (char *) &unw.r0) < sizeof(unw.r0); 68.272 +} 68.273 + 68.274 +/* 68.275 + * Returns offset of rREG in struct pt_regs. 68.276 + */ 68.277 +static inline unsigned long 68.278 +pt_regs_off (unsigned long reg) 68.279 +{ 68.280 + short off = -1; 68.281 + 68.282 + if (reg < ARRAY_SIZE(unw.pt_regs_offsets)) 68.283 + off = unw.pt_regs_offsets[reg]; 68.284 + 68.285 + if (off < 0) { 68.286 + UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg); 68.287 + off = 0; 68.288 + } 68.289 + return (unsigned long) off; 68.290 +} 68.291 + 68.292 +static inline struct pt_regs * 68.293 +get_scratch_regs (struct unw_frame_info *info) 68.294 +{ 68.295 + if (!info->pt) { 68.296 + /* This should not happen with valid unwind info. */ 68.297 + UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __FUNCTION__); 68.298 + if (info->flags & UNW_FLAG_INTERRUPT_FRAME) 68.299 + info->pt = (unsigned long) ((struct pt_regs *) info->psp - 1); 68.300 + else 68.301 + info->pt = info->sp - 16; 68.302 + } 68.303 + UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __FUNCTION__, info->sp, info->pt); 68.304 + return (struct pt_regs *) info->pt; 68.305 +} 68.306 + 68.307 +/* Unwind accessors. */ 68.308 + 68.309 +int 68.310 +unw_access_gr (struct unw_frame_info *info, int regnum, unsigned long *val, char *nat, int write) 68.311 +{ 68.312 + unsigned long *addr, *nat_addr, nat_mask = 0, dummy_nat; 68.313 + struct unw_ireg *ireg; 68.314 + struct pt_regs *pt; 68.315 + 68.316 + if ((unsigned) regnum - 1 >= 127) { 68.317 + if (regnum == 0 && !write) { 68.318 + *val = 0; /* read r0 always returns 0 */ 68.319 + *nat = 0; 68.320 + return 0; 68.321 + } 68.322 + UNW_DPRINT(0, "unwind.%s: trying to access non-existent r%u\n", 68.323 + __FUNCTION__, regnum); 68.324 + return -1; 68.325 + } 68.326 + 68.327 + if (regnum < 32) { 68.328 + if (regnum >= 4 && regnum <= 7) { 68.329 + /* access a preserved register */ 68.330 + ireg = &info->r4 + (regnum - 4); 68.331 + addr = ireg->loc; 68.332 + if (addr) { 68.333 + nat_addr = addr + ireg->nat.off; 68.334 + switch (ireg->nat.type) { 68.335 + case UNW_NAT_VAL: 68.336 + /* simulate getf.sig/setf.sig */ 68.337 + if (write) { 68.338 + if (*nat) { 68.339 + /* write NaTVal and be done with it */ 68.340 + addr[0] = 0; 68.341 + addr[1] = 0x1fffe; 68.342 + return 0; 68.343 + } 68.344 + addr[1] = 0x1003e; 68.345 + } else { 68.346 + if (addr[0] == 0 && addr[1] == 0x1ffe) { 68.347 + /* return NaT and be done with it */ 68.348 + *val = 0; 68.349 + *nat = 1; 68.350 + return 0; 68.351 + } 68.352 + } 68.353 + /* fall through */ 68.354 + case UNW_NAT_NONE: 68.355 + dummy_nat = 0; 68.356 + nat_addr = &dummy_nat; 68.357 + break; 68.358 + 68.359 + case UNW_NAT_MEMSTK: 68.360 + nat_mask = (1UL << ((long) addr & 0x1f8)/8); 68.361 + break; 68.362 + 68.363 + case UNW_NAT_REGSTK: 68.364 + nat_addr = ia64_rse_rnat_addr(addr); 68.365 + if ((unsigned long) addr < info->regstk.limit 68.366 + || (unsigned long) addr >= info->regstk.top) 68.367 + { 68.368 + UNW_DPRINT(0, "unwind.%s: %p outside of regstk " 68.369 + "[0x%lx-0x%lx)\n", 68.370 + __FUNCTION__, (void *) addr, 68.371 + info->regstk.limit, 68.372 + info->regstk.top); 68.373 + return -1; 68.374 + } 68.375 + if ((unsigned long) nat_addr >= info->regstk.top) 68.376 + nat_addr = &info->sw->ar_rnat; 68.377 + nat_mask = (1UL << ia64_rse_slot_num(addr)); 68.378 + break; 68.379 + } 68.380 + } else { 68.381 + addr = &info->sw->r4 + (regnum - 4); 68.382 + nat_addr = &info->sw->ar_unat; 68.383 + nat_mask = (1UL << ((long) addr & 0x1f8)/8); 68.384 + } 68.385 + } else { 68.386 + /* access a scratch register */ 68.387 + pt = get_scratch_regs(info); 68.388 + addr = (unsigned long *) ((unsigned long)pt + pt_regs_off(regnum)); 68.389 + if (info->pri_unat_loc) 68.390 + nat_addr = info->pri_unat_loc; 68.391 + else 68.392 + nat_addr = &info->sw->caller_unat; 68.393 + nat_mask = (1UL << ((long) addr & 0x1f8)/8); 68.394 + } 68.395 + } else { 68.396 + /* access a stacked register */ 68.397 + addr = ia64_rse_skip_regs((unsigned long *) info->bsp, regnum - 32); 68.398 + nat_addr = ia64_rse_rnat_addr(addr); 68.399 + if ((unsigned long) addr < info->regstk.limit 68.400 + || (unsigned long) addr >= info->regstk.top) 68.401 + { 68.402 + UNW_DPRINT(0, "unwind.%s: ignoring attempt to access register outside " 68.403 + "of rbs\n", __FUNCTION__); 68.404 + return -1; 68.405 + } 68.406 + if ((unsigned long) nat_addr >= info->regstk.top) 68.407 + nat_addr = &info->sw->ar_rnat; 68.408 + nat_mask = (1UL << ia64_rse_slot_num(addr)); 68.409 + } 68.410 + 68.411 + if (write) { 68.412 + if (read_only(addr)) { 68.413 + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", 68.414 + __FUNCTION__); 68.415 + } else { 68.416 + *addr = *val; 68.417 + if (*nat) 68.418 + *nat_addr |= nat_mask; 68.419 + else 68.420 + *nat_addr &= ~nat_mask; 68.421 + } 68.422 + } else { 68.423 + if ((*nat_addr & nat_mask) == 0) { 68.424 + *val = *addr; 68.425 + *nat = 0; 68.426 + } else { 68.427 + *val = 0; /* if register is a NaT, *addr may contain kernel data! */ 68.428 + *nat = 1; 68.429 + } 68.430 + } 68.431 + return 0; 68.432 +} 68.433 +EXPORT_SYMBOL(unw_access_gr); 68.434 + 68.435 +int 68.436 +unw_access_br (struct unw_frame_info *info, int regnum, unsigned long *val, int write) 68.437 +{ 68.438 + unsigned long *addr; 68.439 + struct pt_regs *pt; 68.440 + 68.441 + switch (regnum) { 68.442 + /* scratch: */ 68.443 + case 0: pt = get_scratch_regs(info); addr = &pt->b0; break; 68.444 + case 6: pt = get_scratch_regs(info); addr = &pt->b6; break; 68.445 + case 7: pt = get_scratch_regs(info); addr = &pt->b7; break; 68.446 + 68.447 + /* preserved: */ 68.448 + case 1: case 2: case 3: case 4: case 5: 68.449 + addr = *(&info->b1_loc + (regnum - 1)); 68.450 + if (!addr) 68.451 + addr = &info->sw->b1 + (regnum - 1); 68.452 + break; 68.453 + 68.454 + default: 68.455 + UNW_DPRINT(0, "unwind.%s: trying to access non-existent b%u\n", 68.456 + __FUNCTION__, regnum); 68.457 + return -1; 68.458 + } 68.459 + if (write) 68.460 + if (read_only(addr)) { 68.461 + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", 68.462 + __FUNCTION__); 68.463 + } else 68.464 + *addr = *val; 68.465 + else 68.466 + *val = *addr; 68.467 + return 0; 68.468 +} 68.469 +EXPORT_SYMBOL(unw_access_br); 68.470 + 68.471 +int 68.472 +unw_access_fr (struct unw_frame_info *info, int regnum, struct ia64_fpreg *val, int write) 68.473 +{ 68.474 + struct ia64_fpreg *addr = NULL; 68.475 + struct pt_regs *pt; 68.476 + 68.477 + if ((unsigned) (regnum - 2) >= 126) { 68.478 + UNW_DPRINT(0, "unwind.%s: trying to access non-existent f%u\n", 68.479 + __FUNCTION__, regnum); 68.480 + return -1; 68.481 + } 68.482 + 68.483 + if (regnum <= 5) { 68.484 + addr = *(&info->f2_loc + (regnum - 2)); 68.485 + if (!addr) 68.486 + addr = &info->sw->f2 + (regnum - 2); 68.487 + } else if (regnum <= 15) { 68.488 + if (regnum <= 11) { 68.489 + pt = get_scratch_regs(info); 68.490 + addr = &pt->f6 + (regnum - 6); 68.491 + } 68.492 + else 68.493 + addr = &info->sw->f12 + (regnum - 12); 68.494 + } else if (regnum <= 31) { 68.495 + addr = info->fr_loc[regnum - 16]; 68.496 + if (!addr) 68.497 + addr = &info->sw->f16 + (regnum - 16); 68.498 + } else { 68.499 + struct task_struct *t = info->task; 68.500 + 68.501 + if (write) 68.502 + ia64_sync_fph(t); 68.503 + else 68.504 + ia64_flush_fph(t); 68.505 +#ifdef XEN 68.506 + addr = t->arch._thread.fph + (regnum - 32); 68.507 +#else 68.508 + addr = t->thread.fph + (regnum - 32); 68.509 +#endif 68.510 + } 68.511 + 68.512 + if (write) 68.513 + if (read_only(addr)) { 68.514 + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", 68.515 + __FUNCTION__); 68.516 + } else 68.517 + *addr = *val; 68.518 + else 68.519 + *val = *addr; 68.520 + return 0; 68.521 +} 68.522 +EXPORT_SYMBOL(unw_access_fr); 68.523 + 68.524 +int 68.525 +unw_access_ar (struct unw_frame_info *info, int regnum, unsigned long *val, int write) 68.526 +{ 68.527 + unsigned long *addr; 68.528 + struct pt_regs *pt; 68.529 + 68.530 + switch (regnum) { 68.531 + case UNW_AR_BSP: 68.532 + addr = info->bsp_loc; 68.533 + if (!addr) 68.534 + addr = &info->sw->ar_bspstore; 68.535 + break; 68.536 + 68.537 + case UNW_AR_BSPSTORE: 68.538 + addr = info->bspstore_loc; 68.539 + if (!addr) 68.540 + addr = &info->sw->ar_bspstore; 68.541 + break; 68.542 + 68.543 + case UNW_AR_PFS: 68.544 + addr = info->pfs_loc; 68.545 + if (!addr) 68.546 + addr = &info->sw->ar_pfs; 68.547 + break; 68.548 + 68.549 + case UNW_AR_RNAT: 68.550 + addr = info->rnat_loc; 68.551 + if (!addr) 68.552 + addr = &info->sw->ar_rnat; 68.553 + break; 68.554 + 68.555 + case UNW_AR_UNAT: 68.556 + addr = info->unat_loc; 68.557 + if (!addr) 68.558 + addr = &info->sw->caller_unat; 68.559 + break; 68.560 + 68.561 + case UNW_AR_LC: 68.562 + addr = info->lc_loc; 68.563 + if (!addr) 68.564 + addr = &info->sw->ar_lc; 68.565 + break; 68.566 + 68.567 + case UNW_AR_EC: 68.568 + if (!info->cfm_loc) 68.569 + return -1; 68.570 + if (write) 68.571 + *info->cfm_loc = 68.572 + (*info->cfm_loc & ~(0x3fUL << 52)) | ((*val & 0x3f) << 52); 68.573 + else 68.574 + *val = (*info->cfm_loc >> 52) & 0x3f; 68.575 + return 0; 68.576 + 68.577 + case UNW_AR_FPSR: 68.578 + addr = info->fpsr_loc; 68.579 + if (!addr) 68.580 + addr = &info->sw->ar_fpsr; 68.581 + break; 68.582 + 68.583 + case UNW_AR_RSC: 68.584 + pt = get_scratch_regs(info); 68.585 + addr = &pt->ar_rsc; 68.586 + break; 68.587 + 68.588 + case UNW_AR_CCV: 68.589 + pt = get_scratch_regs(info); 68.590 + addr = &pt->ar_ccv; 68.591 + break; 68.592 + 68.593 + case UNW_AR_CSD: 68.594 + pt = get_scratch_regs(info); 68.595 + addr = &pt->ar_csd; 68.596 + break; 68.597 + 68.598 + case UNW_AR_SSD: 68.599 + pt = get_scratch_regs(info); 68.600 + addr = &pt->ar_ssd; 68.601 + break; 68.602 + 68.603 + default: 68.604 + UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n", 68.605 + __FUNCTION__, regnum); 68.606 + return -1; 68.607 + } 68.608 + 68.609 + if (write) { 68.610 + if (read_only(addr)) { 68.611 + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", 68.612 + __FUNCTION__); 68.613 + } else 68.614 + *addr = *val; 68.615 + } else 68.616 + *val = *addr; 68.617 + return 0; 68.618 +} 68.619 +EXPORT_SYMBOL(unw_access_ar); 68.620 + 68.621 +int 68.622 +unw_access_pr (struct unw_frame_info *info, unsigned long *val, int write) 68.623 +{ 68.624 + unsigned long *addr; 68.625 + 68.626 + addr = info->pr_loc; 68.627 + if (!addr) 68.628 + addr = &info->sw->pr; 68.629 + 68.630 + if (write) { 68.631 + if (read_only(addr)) { 68.632 + UNW_DPRINT(0, "unwind.%s: ignoring attempt to write read-only location\n", 68.633 + __FUNCTION__); 68.634 + } else 68.635 + *addr = *val; 68.636 + } else 68.637 + *val = *addr; 68.638 + return 0; 68.639 +} 68.640 +EXPORT_SYMBOL(unw_access_pr); 68.641 + 68.642 + 68.643 +/* Routines to manipulate the state stack. */ 68.644 + 68.645 +static inline void 68.646 +push (struct unw_state_record *sr) 68.647 +{ 68.648 + struct unw_reg_state *rs; 68.649 + 68.650 + rs = alloc_reg_state(); 68.651 + if (!rs) { 68.652 + printk(KERN_ERR "unwind: cannot stack reg state!\n"); 68.653 + return; 68.654 + } 68.655 + memcpy(rs, &sr->curr, sizeof(*rs)); 68.656 + sr->curr.next = rs; 68.657 +} 68.658 + 68.659 +static void 68.660 +pop (struct unw_state_record *sr) 68.661 +{ 68.662 + struct unw_reg_state *rs = sr->curr.next; 68.663 + 68.664 + if (!rs) { 68.665 + printk(KERN_ERR "unwind: stack underflow!\n"); 68.666 + return; 68.667 + } 68.668 + memcpy(&sr->curr, rs, sizeof(*rs)); 68.669 + free_reg_state(rs); 68.670 +} 68.671 + 68.672 +/* Make a copy of the state stack. Non-recursive to avoid stack overflows. */ 68.673 +static struct unw_reg_state * 68.674 +dup_state_stack (struct unw_reg_state *rs) 68.675 +{ 68.676 + struct unw_reg_state *copy, *prev = NULL, *first = NULL; 68.677 + 68.678 + while (rs) { 68.679 + copy = alloc_reg_state(); 68.680 + if (!copy) { 68.681 + printk(KERN_ERR "unwind.dup_state_stack: out of memory\n"); 68.682 + return NULL; 68.683 + } 68.684 + memcpy(copy, rs, sizeof(*copy)); 68.685 + if (first) 68.686 + prev->next = copy; 68.687 + else 68.688 + first = copy; 68.689 + rs = rs->next; 68.690 + prev = copy; 68.691 + } 68.692 + return first; 68.693 +} 68.694 + 68.695 +/* Free all stacked register states (but not RS itself). */ 68.696 +static void 68.697 +free_state_stack (struct unw_reg_state *rs) 68.698 +{ 68.699 + struct unw_reg_state *p, *next; 68.700 + 68.701 + for (p = rs->next; p != NULL; p = next) { 68.702 + next = p->next; 68.703 + free_reg_state(p); 68.704 + } 68.705 + rs->next = NULL; 68.706 +} 68.707 + 68.708 +/* Unwind decoder routines */ 68.709 + 68.710 +static enum unw_register_index __attribute_const__ 68.711 +decode_abreg (unsigned char abreg, int memory) 68.712 +{ 68.713 + switch (abreg) { 68.714 + case 0x04 ... 0x07: return UNW_REG_R4 + (abreg - 0x04); 68.715 + case 0x22 ... 0x25: return UNW_REG_F2 + (abreg - 0x22); 68.716 + case 0x30 ... 0x3f: return UNW_REG_F16 + (abreg - 0x30); 68.717 + case 0x41 ... 0x45: return UNW_REG_B1 + (abreg - 0x41); 68.718 + case 0x60: return UNW_REG_PR; 68.719 + case 0x61: return UNW_REG_PSP; 68.720 + case 0x62: return memory ? UNW_REG_PRI_UNAT_MEM : UNW_REG_PRI_UNAT_GR; 68.721 + case 0x63: return UNW_REG_RP; 68.722 + case 0x64: return UNW_REG_BSP; 68.723 + case 0x65: return UNW_REG_BSPSTORE; 68.724 + case 0x66: return UNW_REG_RNAT; 68.725 + case 0x67: return UNW_REG_UNAT; 68.726 + case 0x68: return UNW_REG_FPSR; 68.727 + case 0x69: return UNW_REG_PFS; 68.728 + case 0x6a: return UNW_REG_LC; 68.729 + default: 68.730 + break; 68.731 + } 68.732 + UNW_DPRINT(0, "unwind.%s: bad abreg=0x%x\n", __FUNCTION__, abreg); 68.733 + return UNW_REG_LC; 68.734 +} 68.735 + 68.736 +static void 68.737 +set_reg (struct unw_reg_info *reg, enum unw_where where, int when, unsigned long val) 68.738 +{ 68.739 + reg->val = val; 68.740 + reg->where = where; 68.741 + if (reg->when == UNW_WHEN_NEVER) 68.742 + reg->when = when; 68.743 +} 68.744 + 68.745 +static void 68.746 +alloc_spill_area (unsigned long *offp, unsigned long regsize, 68.747 + struct unw_reg_info *lo, struct unw_reg_info *hi) 68.748 +{ 68.749 + struct unw_reg_info *reg; 68.750 + 68.751 + for (reg = hi; reg >= lo; --reg) { 68.752 + if (reg->where == UNW_WHERE_SPILL_HOME) { 68.753 + reg->where = UNW_WHERE_PSPREL; 68.754 + *offp -= regsize; 68.755 + reg->val = *offp; 68.756 + } 68.757 + } 68.758 +} 68.759 + 68.760 +static inline void 68.761 +spill_next_when (struct unw_reg_info **regp, struct unw_reg_info *lim, unw_word t) 68.762 +{ 68.763 + struct unw_reg_info *reg; 68.764 + 68.765 + for (reg = *regp; reg <= lim; ++reg) { 68.766 + if (reg->where == UNW_WHERE_SPILL_HOME) { 68.767 + reg->when = t; 68.768 + *regp = reg + 1; 68.769 + return; 68.770 + } 68.771 + } 68.772 + UNW_DPRINT(0, "unwind.%s: excess spill!\n", __FUNCTION__); 68.773 +} 68.774 + 68.775 +static inline void 68.776 +finish_prologue (struct unw_state_record *sr) 68.777 +{ 68.778 + struct unw_reg_info *reg; 68.779 + unsigned long off; 68.780 + int i; 68.781 + 68.782 + /* 68.783 + * First, resolve implicit register save locations (see Section "11.4.2.3 Rules 68.784 + * for Using Unwind Descriptors", rule 3): 68.785 + */ 68.786 + for (i = 0; i < (int) ARRAY_SIZE(unw.save_order); ++i) { 68.787 + reg = sr->curr.reg + unw.save_order[i]; 68.788 + if (reg->where == UNW_WHERE_GR_SAVE) { 68.789 + reg->where = UNW_WHERE_GR; 68.790 + reg->val = sr->gr_save_loc++; 68.791 + } 68.792 + } 68.793 + 68.794 + /* 68.795 + * Next, compute when the fp, general, and branch registers get 68.796 + * saved. This must come before alloc_spill_area() because 68.797 + * we need to know which registers are spilled to their home 68.798 + * locations. 68.799 + */ 68.800 + if (sr->imask) { 68.801 + unsigned char kind, mask = 0, *cp = sr->imask; 68.802 + int t; 68.803 + static const unsigned char limit[3] = { 68.804 + UNW_REG_F31, UNW_REG_R7, UNW_REG_B5 68.805 + }; 68.806 + struct unw_reg_info *(regs[3]); 68.807 + 68.808 + regs[0] = sr->curr.reg + UNW_REG_F2; 68.809 + regs[1] = sr->curr.reg + UNW_REG_R4; 68.810 + regs[2] = sr->curr.reg + UNW_REG_B1; 68.811 + 68.812 + for (t = 0; t < sr->region_len; ++t) { 68.813 + if ((t & 3) == 0) 68.814 + mask = *cp++; 68.815 + kind = (mask >> 2*(3-(t & 3))) & 3; 68.816 + if (kind > 0) 68.817 + spill_next_when(®s[kind - 1], sr->curr.reg + limit[kind - 1], 68.818 + sr->region_start + t); 68.819 + } 68.820 + } 68.821 + /* 68.822 + * Next, lay out the memory stack spill area: 68.823 + */ 68.824 + if (sr->any_spills) { 68.825 + off = sr->spill_offset; 68.826 + alloc_spill_area(&off, 16, sr->curr.reg + UNW_REG_F2, sr->curr.reg + UNW_REG_F31); 68.827 + alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_B1, sr->curr.reg + UNW_REG_B5); 68.828 + alloc_spill_area(&off, 8, sr->curr.reg + UNW_REG_R4, sr->curr.reg + UNW_REG_R7); 68.829 + } 68.830 +} 68.831 + 68.832 +/* 68.833 + * Region header descriptors. 68.834 + */ 68.835 + 68.836 +static void 68.837 +desc_prologue (int body, unw_word rlen, unsigned char mask, unsigned char grsave, 68.838 + struct unw_state_record *sr) 68.839 +{ 68.840 + int i, region_start; 68.841 + 68.842 + if (!(sr->in_body || sr->first_region)) 68.843 + finish_prologue(sr); 68.844 + sr->first_region = 0; 68.845 + 68.846 + /* check if we're done: */ 68.847 + if (sr->when_target < sr->region_start + sr->region_len) { 68.848 + sr->done = 1; 68.849 + return; 68.850 + } 68.851 + 68.852 + region_start = sr->region_start + sr->region_len; 68.853 + 68.854 + for (i = 0; i < sr->epilogue_count; ++i) 68.855 + pop(sr); 68.856 + sr->epilogue_count = 0; 68.857 + sr->epilogue_start = UNW_WHEN_NEVER; 68.858 + 68.859 + sr->region_start = region_start; 68.860 + sr->region_len = rlen; 68.861 + sr->in_body = body; 68.862 + 68.863 + if (!body) { 68.864 + push(sr); 68.865 + 68.866 + for (i = 0; i < 4; ++i) { 68.867 + if (mask & 0x8) 68.868 + set_reg(sr->curr.reg + unw.save_order[i], UNW_WHERE_GR, 68.869 + sr->region_start + sr->region_len - 1, grsave++); 68.870 + mask <<= 1; 68.871 + } 68.872 + sr->gr_save_loc = grsave; 68.873 + sr->any_spills = 0; 68.874 + sr->imask = NULL; 68.875 + sr->spill_offset = 0x10; /* default to psp+16 */ 68.876 + } 68.877 +} 68.878 + 68.879 +/* 68.880 + * Prologue descriptors. 68.881 + */ 68.882 + 68.883 +static inline void 68.884 +desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr) 68.885 +{ 68.886 + if (abi == 3 && context == 'i') { 68.887 + sr->flags |= UNW_FLAG_INTERRUPT_FRAME; 68.888 + UNW_DPRINT(3, "unwind.%s: interrupt frame\n", __FUNCTION__); 68.889 + } 68.890 + else 68.891 + UNW_DPRINT(0, "unwind%s: ignoring unwabi(abi=0x%x,context=0x%x)\n", 68.892 + __FUNCTION__, abi, context); 68.893 +} 68.894 + 68.895 +static inline void 68.896 +desc_br_gr (unsigned char brmask, unsigned char gr, struct unw_state_record *sr) 68.897 +{ 68.898 + int i; 68.899 + 68.900 + for (i = 0; i < 5; ++i) { 68.901 + if (brmask & 1) 68.902 + set_reg(sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_GR, 68.903 + sr->region_start + sr->region_len - 1, gr++); 68.904 + brmask >>= 1; 68.905 + } 68.906 +} 68.907 + 68.908 +static inline void 68.909 +desc_br_mem (unsigned char brmask, struct unw_state_record *sr) 68.910 +{ 68.911 + int i; 68.912 + 68.913 + for (i = 0; i < 5; ++i) { 68.914 + if (brmask & 1) { 68.915 + set_reg(sr->curr.reg + UNW_REG_B1 + i, UNW_WHERE_SPILL_HOME, 68.916 + sr->region_start + sr->region_len - 1, 0); 68.917 + sr->any_spills = 1; 68.918 + } 68.919 + brmask >>= 1; 68.920 + } 68.921 +} 68.922 + 68.923 +static inline void 68.924 +desc_frgr_mem (unsigned char grmask, unw_word frmask, struct unw_state_record *sr) 68.925 +{ 68.926 + int i; 68.927 + 68.928 + for (i = 0; i < 4; ++i) { 68.929 + if ((grmask & 1) != 0) { 68.930 + set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME, 68.931 + sr->region_start + sr->region_len - 1, 0); 68.932 + sr->any_spills = 1; 68.933 + } 68.934 + grmask >>= 1; 68.935 + } 68.936 + for (i = 0; i < 20; ++i) { 68.937 + if ((frmask & 1) != 0) { 68.938 + int base = (i < 4) ? UNW_REG_F2 : UNW_REG_F16 - 4; 68.939 + set_reg(sr->curr.reg + base + i, UNW_WHERE_SPILL_HOME, 68.940 + sr->region_start + sr->region_len - 1, 0); 68.941 + sr->any_spills = 1; 68.942 + } 68.943 + frmask >>= 1; 68.944 + } 68.945 +} 68.946 + 68.947 +static inline void 68.948 +desc_fr_mem (unsigned char frmask, struct unw_state_record *sr) 68.949 +{ 68.950 + int i; 68.951 + 68.952 + for (i = 0; i < 4; ++i) { 68.953 + if ((frmask & 1) != 0) { 68.954 + set_reg(sr->curr.reg + UNW_REG_F2 + i, UNW_WHERE_SPILL_HOME, 68.955 + sr->region_start + sr->region_len - 1, 0); 68.956 + sr->any_spills = 1; 68.957 + } 68.958 + frmask >>= 1; 68.959 + } 68.960 +} 68.961 + 68.962 +static inline void 68.963 +desc_gr_gr (unsigned char grmask, unsigned char gr, struct unw_state_record *sr) 68.964 +{ 68.965 + int i; 68.966 + 68.967 + for (i = 0; i < 4; ++i) { 68.968 + if ((grmask & 1) != 0) 68.969 + set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_GR, 68.970 + sr->region_start + sr->region_len - 1, gr++); 68.971 + grmask >>= 1; 68.972 + } 68.973 +} 68.974 + 68.975 +static inline void 68.976 +desc_gr_mem (unsigned char grmask, struct unw_state_record *sr) 68.977 +{ 68.978 + int i; 68.979 + 68.980 + for (i = 0; i < 4; ++i) { 68.981 + if ((grmask & 1) != 0) { 68.982 + set_reg(sr->curr.reg + UNW_REG_R4 + i, UNW_WHERE_SPILL_HOME, 68.983 + sr->region_start + sr->region_len - 1, 0); 68.984 + sr->any_spills = 1; 68.985 + } 68.986 + grmask >>= 1; 68.987 + } 68.988 +} 68.989 + 68.990 +static inline void 68.991 +desc_mem_stack_f (unw_word t, unw_word size, struct unw_state_record *sr) 68.992 +{ 68.993 + set_reg(sr->curr.reg + UNW_REG_PSP, UNW_WHERE_NONE, 68.994 + sr->region_start + min_t(int, t, sr->region_len - 1), 16*size); 68.995 +} 68.996 + 68.997 +static inline void 68.998 +desc_mem_stack_v (unw_word t, struct unw_state_record *sr) 68.999 +{ 68.1000 + sr->curr.reg[UNW_REG_PSP].when = sr->region_start + min_t(int, t, sr->region_len - 1); 68.1001 +} 68.1002 + 68.1003 +static inline void 68.1004 +desc_reg_gr (unsigned char reg, unsigned char dst, struct unw_state_record *sr) 68.1005 +{ 68.1006 + set_reg(sr->curr.reg + reg, UNW_WHERE_GR, sr->region_start + sr->region_len - 1, dst); 68.1007 +} 68.1008 + 68.1009 +static inline void 68.1010 +desc_reg_psprel (unsigned char reg, unw_word pspoff, struct unw_state_record *sr) 68.1011 +{ 68.1012 + set_reg(sr->curr.reg + reg, UNW_WHERE_PSPREL, sr->region_start + sr->region_len - 1, 68.1013 + 0x10 - 4*pspoff); 68.1014 +} 68.1015 + 68.1016 +static inline void 68.1017 +desc_reg_sprel (unsigned char reg, unw_word spoff, struct unw_state_record *sr) 68.1018 +{ 68.1019 + set_reg(sr->curr.reg + reg, UNW_WHERE_SPREL, sr->region_start + sr->region_len - 1, 68.1020 + 4*spoff); 68.1021 +} 68.1022 + 68.1023 +static inline void 68.1024 +desc_rp_br (unsigned char dst, struct unw_state_record *sr) 68.1025 +{ 68.1026 + sr->return_link_reg = dst; 68.1027 +} 68.1028 + 68.1029 +static inline void 68.1030 +desc_reg_when (unsigned char regnum, unw_word t, struct unw_state_record *sr) 68.1031 +{ 68.1032 + struct unw_reg_info *reg = sr->curr.reg + regnum; 68.1033 + 68.1034 + if (reg->where == UNW_WHERE_NONE) 68.1035 + reg->where = UNW_WHERE_GR_SAVE; 68.1036 + reg->when = sr->region_start + min_t(int, t, sr->region_len - 1); 68.1037 +} 68.1038 + 68.1039 +static inline void 68.1040 +desc_spill_base (unw_word pspoff, struct unw_state_record *sr) 68.1041 +{ 68.1042 + sr->spill_offset = 0x10 - 4*pspoff; 68.1043 +} 68.1044 + 68.1045 +static inline unsigned char * 68.1046 +desc_spill_mask (unsigned char *imaskp, struct unw_state_record *sr) 68.1047 +{ 68.1048 + sr->imask = imaskp; 68.1049 + return imaskp + (2*sr->region_len + 7)/8; 68.1050 +} 68.1051 + 68.1052 +/* 68.1053 + * Body descriptors. 68.1054 + */ 68.1055 +static inline void 68.1056 +desc_epilogue (unw_word t, unw_word ecount, struct unw_state_record *sr) 68.1057 +{ 68.1058 + sr->epilogue_start = sr->region_start + sr->region_len - 1 - t; 68.1059 + sr->epilogue_count = ecount + 1; 68.1060 +} 68.1061 + 68.1062 +static inline void 68.1063 +desc_copy_state (unw_word label, struct unw_state_record *sr) 68.1064 +{ 68.1065 + struct unw_labeled_state *ls; 68.1066 + 68.1067 + for (ls = sr->labeled_states; ls; ls = ls->next) { 68.1068 + if (ls->label == label) { 68.1069 + free_state_stack(&sr->curr); 68.1070 + memcpy(&sr->curr, &ls->saved_state, sizeof(sr->curr)); 68.1071 + sr->curr.next = dup_state_stack(ls->saved_state.next); 68.1072 + return; 68.1073 + } 68.1074 + } 68.1075 + printk(KERN_ERR "unwind: failed to find state labeled 0x%lx\n", label); 68.1076 +} 68.1077 + 68.1078 +static inline void 68.1079 +desc_label_state (unw_word label, struct unw_state_record *sr) 68.1080 +{ 68.1081 + struct unw_labeled_state *ls; 68.1082 + 68.1083 + ls = alloc_labeled_state(); 68.1084 + if (!ls) { 68.1085 + printk(KERN_ERR "unwind.desc_label_state(): out of memory\n"); 68.1086 + return; 68.1087 + } 68.1088 + ls->label = label; 68.1089 + memcpy(&ls->saved_state, &sr->curr, sizeof(ls->saved_state)); 68.1090 + ls->saved_state.next = dup_state_stack(sr->curr.next); 68.1091 + 68.1092 + /* insert into list of labeled states: */ 68.1093 + ls->next = sr->labeled_states; 68.1094 + sr->labeled_states = ls; 68.1095 +} 68.1096 + 68.1097 +/* 68.1098 + * General descriptors. 68.1099 + */ 68.1100 + 68.1101 +static inline int 68.1102 +desc_is_active (unsigned char qp, unw_word t, struct unw_state_record *sr) 68.1103 +{ 68.1104 + if (sr->when_target <= sr->region_start + min_t(int, t, sr->region_len - 1)) 68.1105 + return 0; 68.1106 + if (qp > 0) { 68.1107 + if ((sr->pr_val & (1UL << qp)) == 0) 68.1108 + return 0; 68.1109 + sr->pr_mask |= (1UL << qp); 68.1110 + } 68.1111 + return 1; 68.1112 +} 68.1113 + 68.1114 +static inline void 68.1115 +desc_restore_p (unsigned char qp, unw_word t, unsigned char abreg, struct unw_state_record *sr) 68.1116 +{ 68.1117 + struct unw_reg_info *r; 68.1118 + 68.1119 + if (!desc_is_active(qp, t, sr)) 68.1120 + return; 68.1121 + 68.1122 + r = sr->curr.reg + decode_abreg(abreg, 0); 68.1123 + r->where = UNW_WHERE_NONE; 68.1124 + r->when = UNW_WHEN_NEVER; 68.1125 + r->val = 0; 68.1126 +} 68.1127 + 68.1128 +static inline void 68.1129 +desc_spill_reg_p (unsigned char qp, unw_word t, unsigned char abreg, unsigned char x, 68.1130 + unsigned char ytreg, struct unw_state_record *sr) 68.1131 +{ 68.1132 + enum unw_where where = UNW_WHERE_GR; 68.1133 + struct unw_reg_info *r; 68.1134 + 68.1135 + if (!desc_is_active(qp, t, sr)) 68.1136 + return; 68.1137 + 68.1138 + if (x) 68.1139 + where = UNW_WHERE_BR; 68.1140 + else if (ytreg & 0x80) 68.1141 + where = UNW_WHERE_FR; 68.1142 + 68.1143 + r = sr->curr.reg + decode_abreg(abreg, 0); 68.1144 + r->where = where; 68.1145 + r->when = sr->region_start + min_t(int, t, sr->region_len - 1); 68.1146 + r->val = (ytreg & 0x7f); 68.1147 +} 68.1148 + 68.1149 +static inline void 68.1150 +desc_spill_psprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word pspoff, 68.1151 + struct unw_state_record *sr) 68.1152 +{ 68.1153 + struct unw_reg_info *r; 68.1154 + 68.1155 + if (!desc_is_active(qp, t, sr)) 68.1156 + return; 68.1157 + 68.1158 + r = sr->curr.reg + decode_abreg(abreg, 1); 68.1159 + r->where = UNW_WHERE_PSPREL; 68.1160 + r->when = sr->region_start + min_t(int, t, sr->region_len - 1); 68.1161 + r->val = 0x10 - 4*pspoff; 68.1162 +} 68.1163 + 68.1164 +static inline void 68.1165 +desc_spill_sprel_p (unsigned char qp, unw_word t, unsigned char abreg, unw_word spoff, 68.1166 + struct unw_state_record *sr) 68.1167 +{ 68.1168 + struct unw_reg_info *r; 68.1169 + 68.1170 + if (!desc_is_active(qp, t, sr)) 68.1171 + return; 68.1172 + 68.1173 + r = sr->curr.reg + decode_abreg(abreg, 1); 68.1174 + r->where = UNW_WHERE_SPREL; 68.1175 + r->when = sr->region_start + min_t(int, t, sr->region_len - 1); 68.1176 + r->val = 4*spoff; 68.1177 +} 68.1178 + 68.1179 +#define UNW_DEC_BAD_CODE(code) printk(KERN_ERR "unwind: unknown code 0x%02x\n", \ 68.1180 + code); 68.1181 + 68.1182 +/* 68.1183 + * region headers: 68.1184 + */ 68.1185 +#define UNW_DEC_PROLOGUE_GR(fmt,r,m,gr,arg) desc_prologue(0,r,m,gr,arg) 68.1186 +#define UNW_DEC_PROLOGUE(fmt,b,r,arg) desc_prologue(b,r,0,32,arg) 68.1187 +/* 68.1188 + * prologue descriptors: 68.1189 + */ 68.1190 +#define UNW_DEC_ABI(fmt,a,c,arg) desc_abi(a,c,arg) 68.1191 +#define UNW_DEC_BR_GR(fmt,b,g,arg) desc_br_gr(b,g,arg) 68.1192 +#define UNW_DEC_BR_MEM(fmt,b,arg) desc_br_mem(b,arg) 68.1193 +#define UNW_DEC_FRGR_MEM(fmt,g,f,arg) desc_frgr_mem(g,f,arg) 68.1194 +#define UNW_DEC_FR_MEM(fmt,f,arg) desc_fr_mem(f,arg) 68.1195 +#define UNW_DEC_GR_GR(fmt,m,g,arg) desc_gr_gr(m,g,arg) 68.1196 +#define UNW_DEC_GR_MEM(fmt,m,arg) desc_gr_mem(m,arg) 68.1197 +#define UNW_DEC_MEM_STACK_F(fmt,t,s,arg) desc_mem_stack_f(t,s,arg) 68.1198 +#define UNW_DEC_MEM_STACK_V(fmt,t,arg) desc_mem_stack_v(t,arg) 68.1199 +#define UNW_DEC_REG_GR(fmt,r,d,arg) desc_reg_gr(r,d,arg) 68.1200 +#define UNW_DEC_REG_PSPREL(fmt,r,o,arg) desc_reg_psprel(r,o,arg) 68.1201 +#define UNW_DEC_REG_SPREL(fmt,r,o,arg) desc_reg_sprel(r,o,arg) 68.1202 +#define UNW_DEC_REG_WHEN(fmt,r,t,arg) desc_reg_when(r,t,arg) 68.1203 +#define UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_GR,t,arg) 68.1204 +#define UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) desc_reg_when(UNW_REG_PRI_UNAT_MEM,t,arg) 68.1205 +#define UNW_DEC_PRIUNAT_GR(fmt,r,arg) desc_reg_gr(UNW_REG_PRI_UNAT_GR,r,arg) 68.1206 +#define UNW_DEC_PRIUNAT_PSPREL(fmt,o,arg) desc_reg_psprel(UNW_REG_PRI_UNAT_MEM,o,arg) 68.1207 +#define UNW_DEC_PRIUNAT_SPREL(fmt,o,arg) desc_reg_sprel(UNW_REG_PRI_UNAT_MEM,o,arg) 68.1208 +#define UNW_DEC_RP_BR(fmt,d,arg) desc_rp_br(d,arg) 68.1209 +#define UNW_DEC_SPILL_BASE(fmt,o,arg) desc_spill_base(o,arg) 68.1210 +#define UNW_DEC_SPILL_MASK(fmt,m,arg) (m = desc_spill_mask(m,arg)) 68.1211 +/* 68.1212 + * body descriptors: 68.1213 + */ 68.1214 +#define UNW_DEC_EPILOGUE(fmt,t,c,arg) desc_epilogue(t,c,arg) 68.1215 +#define UNW_DEC_COPY_STATE(fmt,l,arg) desc_copy_state(l,arg) 68.1216 +#define UNW_DEC_LABEL_STATE(fmt,l,arg) desc_label_state(l,arg) 68.1217 +/* 68.1218 + * general unwind descriptors: 68.1219 + */ 68.1220 +#define UNW_DEC_SPILL_REG_P(f,p,t,a,x,y,arg) desc_spill_reg_p(p,t,a,x,y,arg) 68.1221 +#define UNW_DEC_SPILL_REG(f,t,a,x,y,arg) desc_spill_reg_p(0,t,a,x,y,arg) 68.1222 +#define UNW_DEC_SPILL_PSPREL_P(f,p,t,a,o,arg) desc_spill_psprel_p(p,t,a,o,arg) 68.1223 +#define UNW_DEC_SPILL_PSPREL(f,t,a,o,arg) desc_spill_psprel_p(0,t,a,o,arg) 68.1224 +#define UNW_DEC_SPILL_SPREL_P(f,p,t,a,o,arg) desc_spill_sprel_p(p,t,a,o,arg) 68.1225 +#define UNW_DEC_SPILL_SPREL(f,t,a,o,arg) desc_spill_sprel_p(0,t,a,o,arg) 68.1226 +#define UNW_DEC_RESTORE_P(f,p,t,a,arg) desc_restore_p(p,t,a,arg) 68.1227 +#define UNW_DEC_RESTORE(f,t,a,arg) desc_restore_p(0,t,a,arg) 68.1228 + 68.1229 +#include "unwind_decoder.c" 68.1230 + 68.1231 + 68.1232 +/* Unwind scripts. */ 68.1233 + 68.1234 +static inline unw_hash_index_t 68.1235 +hash (unsigned long ip) 68.1236 +{ 68.1237 +# define hashmagic 0x9e3779b97f4a7c16UL /* based on (sqrt(5)/2-1)*2^64 */ 68.1238 + 68.1239 + return (ip >> 4)*hashmagic >> (64 - UNW_LOG_HASH_SIZE); 68.1240 +#undef hashmagic 68.1241 +} 68.1242 + 68.1243 +static inline long 68.1244 +cache_match (struct unw_script *script, unsigned long ip, unsigned long pr) 68.1245 +{ 68.1246 + read_lock(&script->lock); 68.1247 + if (ip == script->ip && ((pr ^ script->pr_val) & script->pr_mask) == 0) 68.1248 + /* keep the read lock... */ 68.1249 + return 1; 68.1250 + read_unlock(&script->lock); 68.1251 + return 0; 68.1252 +} 68.1253 + 68.1254 +static inline struct unw_script * 68.1255 +script_lookup (struct unw_frame_info *info) 68.1256 +{ 68.1257 + struct unw_script *script = unw.cache + info->hint; 68.1258 + unsigned short index; 68.1259 + unsigned long ip, pr; 68.1260 + 68.1261 + if (UNW_DEBUG_ON(0)) 68.1262 + return NULL; /* Always regenerate scripts in debug mode */ 68.1263 + 68.1264 + STAT(++unw.stat.cache.lookups); 68.1265 + 68.1266 + ip = info->ip; 68.1267 + pr = info->pr; 68.1268 + 68.1269 + if (cache_match(script, ip, pr)) { 68.1270 + STAT(++unw.stat.cache.hinted_hits); 68.1271 + return script; 68.1272 + } 68.1273 + 68.1274 + index = unw.hash[hash(ip)]; 68.1275 + if (index >= UNW_CACHE_SIZE) 68.1276 + return NULL; 68.1277 + 68.1278 + script = unw.cache + index; 68.1279 + while (1) { 68.1280 + if (cache_match(script, ip, pr)) { 68.1281 + /* update hint; no locking required as single-word writes are atomic */ 68.1282 + STAT(++unw.stat.cache.normal_hits); 68.1283 + unw.cache[info->prev_script].hint = script - unw.cache; 68.1284 + return script; 68.1285 + } 68.1286 + if (script->coll_chain >= UNW_HASH_SIZE) 68.1287 + return NULL; 68.1288 + script = unw.cache + script->coll_chain; 68.1289 + STAT(++unw.stat.cache.collision_chain_traversals); 68.1290 + } 68.1291 +} 68.1292 + 68.1293 +/* 68.1294 + * On returning, a write lock for the SCRIPT is still being held. 68.1295 + */ 68.1296 +static inline struct unw_script * 68.1297 +script_new (unsigned long ip) 68.1298 +{ 68.1299 + struct unw_script *script, *prev, *tmp; 68.1300 + unw_hash_index_t index; 68.1301 + unsigned short head; 68.1302 + 68.1303 + STAT(++unw.stat.script.news); 68.1304 + 68.1305 + /* 68.1306 + * Can't (easily) use cmpxchg() here because of ABA problem 68.1307 + * that is intrinsic in cmpxchg()... 68.1308 + */ 68.1309 + head = unw.lru_head; 68.1310 + script = unw.cache + head; 68.1311 + unw.lru_head = script->lru_chain; 68.1312 + 68.1313 + /* 68.1314 + * We'd deadlock here if we interrupted a thread that is holding a read lock on 68.1315 + * script->lock. Thus, if the write_trylock() fails, we simply bail out. The 68.1316 + * alternative would be to disable interrupts whenever we hold a read-lock, but 68.1317 + * that seems silly. 68.1318 + */ 68.1319 + if (!write_trylock(&script->lock)) 68.1320 + return NULL; 68.1321 + 68.1322 + /* re-insert script at the tail of the LRU chain: */ 68.1323 + unw.cache[unw.lru_tail].lru_chain = head; 68.1324 + unw.lru_tail = head; 68.1325 + 68.1326 + /* remove the old script from the hash table (if it's there): */ 68.1327 + if (script->ip) { 68.1328 + index = hash(script->ip); 68.1329 + tmp = unw.cache + unw.hash[index]; 68.1330 + prev = NULL; 68.1331 + while (1) { 68.1332 + if (tmp == script) { 68.1333 + if (prev) 68.1334 + prev->coll_chain = tmp->coll_chain; 68.1335 + else 68.1336 + unw.hash[index] = tmp->coll_chain; 68.1337 + break; 68.1338 + } else 68.1339 + prev = tmp; 68.1340 + if (tmp->coll_chain >= UNW_CACHE_SIZE) 68.1341 + /* old script wasn't in the hash-table */ 68.1342 + break; 68.1343 + tmp = unw.cache + tmp->coll_chain; 68.1344 + } 68.1345 + } 68.1346 + 68.1347 + /* enter new script in the hash table */ 68.1348 + index = hash(ip); 68.1349 + script->coll_chain = unw.hash[index]; 68.1350 + unw.hash[index] = script - unw.cache; 68.1351 + 68.1352 + script->ip = ip; /* set new IP while we're holding the locks */ 68.1353 + 68.1354 + STAT(if (script->coll_chain < UNW_CACHE_SIZE) ++unw.stat.script.collisions); 68.1355 + 68.1356 + script->flags = 0; 68.1357 + script->hint = 0; 68.1358 + script->count = 0; 68.1359 + return script; 68.1360 +} 68.1361 + 68.1362 +static void 68.1363 +script_finalize (struct unw_script *script, struct unw_state_record *sr) 68.1364 +{ 68.1365 + script->pr_mask = sr->pr_mask; 68.1366 + script->pr_val = sr->pr_val; 68.1367 + /* 68.1368 + * We could down-grade our write-lock on script->lock here but 68.1369 + * the rwlock API doesn't offer atomic lock downgrading, so 68.1370 + * we'll just keep the write-lock and release it later when 68.1371 + * we're done using the script. 68.1372 + */ 68.1373 +} 68.1374 + 68.1375 +static inline void 68.1376 +script_emit (struct unw_script *script, struct unw_insn insn) 68.1377 +{ 68.1378 + if (script->count >= UNW_MAX_SCRIPT_LEN) { 68.1379 + UNW_DPRINT(0, "unwind.%s: script exceeds maximum size of %u instructions!\n", 68.1380 + __FUNCTION__, UNW_MAX_SCRIPT_LEN); 68.1381 + return; 68.1382 + } 68.1383 + script->insn[script->count++] = insn; 68.1384 +} 68.1385 + 68.1386 +static inline void 68.1387 +emit_nat_info (struct unw_state_record *sr, int i, struct unw_script *script) 68.1388 +{ 68.1389 + struct unw_reg_info *r = sr->curr.reg + i; 68.1390 + enum unw_insn_opcode opc; 68.1391 + struct unw_insn insn; 68.1392 + unsigned long val = 0; 68.1393 + 68.1394 + switch (r->where) { 68.1395 + case UNW_WHERE_GR: 68.1396 + if (r->val >= 32) { 68.1397 + /* register got spilled to a stacked register */ 68.1398 + opc = UNW_INSN_SETNAT_TYPE; 68.1399 + val = UNW_NAT_REGSTK; 68.1400 + } else 68.1401 + /* register got spilled to a scratch register */ 68.1402 + opc = UNW_INSN_SETNAT_MEMSTK; 68.1403 + break; 68.1404 + 68.1405 + case UNW_WHERE_FR: 68.1406 + opc = UNW_INSN_SETNAT_TYPE; 68.1407 + val = UNW_NAT_VAL; 68.1408 + break; 68.1409 + 68.1410 + case UNW_WHERE_BR: 68.1411 + opc = UNW_INSN_SETNAT_TYPE; 68.1412 + val = UNW_NAT_NONE; 68.1413 + break; 68.1414 + 68.1415 + case UNW_WHERE_PSPREL: 68.1416 + case UNW_WHERE_SPREL: 68.1417 + opc = UNW_INSN_SETNAT_MEMSTK; 68.1418 + break; 68.1419 + 68.1420 + default: 68.1421 + UNW_DPRINT(0, "unwind.%s: don't know how to emit nat info for where = %u\n", 68.1422 + __FUNCTION__, r->where); 68.1423 + return; 68.1424 + } 68.1425 + insn.opc = opc; 68.1426 + insn.dst = unw.preg_index[i]; 68.1427 + insn.val = val; 68.1428 + script_emit(script, insn); 68.1429 +} 68.1430 + 68.1431 +static void 68.1432 +compile_reg (struct unw_state_record *sr, int i, struct unw_script *script) 68.1433 +{ 68.1434 + struct unw_reg_info *r = sr->curr.reg + i; 68.1435 + enum unw_insn_opcode opc; 68.1436 + unsigned long val, rval; 68.1437 + struct unw_insn insn; 68.1438 + long need_nat_info; 68.1439 + 68.1440 + if (r->where == UNW_WHERE_NONE || r->when >= sr->when_target) 68.1441 + return; 68.1442 + 68.1443 + opc = UNW_INSN_MOVE; 68.1444 + val = rval = r->val; 68.1445 + need_nat_info = (i >= UNW_REG_R4 && i <= UNW_REG_R7); 68.1446 + 68.1447 + switch (r->where) { 68.1448 + case UNW_WHERE_GR: 68.1449 + if (rval >= 32) { 68.1450 + opc = UNW_INSN_MOVE_STACKED; 68.1451 + val = rval - 32; 68.1452 + } else if (rval >= 4 && rval <= 7) { 68.1453 + if (need_nat_info) { 68.1454 + opc = UNW_INSN_MOVE2; 68.1455 + need_nat_info = 0; 68.1456 + } 68.1457 + val = unw.preg_index[UNW_REG_R4 + (rval - 4)]; 68.1458 + } else if (rval == 0) { 68.1459 + opc = UNW_INSN_MOVE_CONST; 68.1460 + val = 0; 68.1461 + } else { 68.1462 + /* register got spilled to a scratch register */ 68.1463 + opc = UNW_INSN_MOVE_SCRATCH; 68.1464 + val = pt_regs_off(rval); 68.1465 + } 68.1466 + break; 68.1467 + 68.1468 + case UNW_WHERE_FR: 68.1469 + if (rval <= 5) 68.1470 + val = unw.preg_index[UNW_REG_F2 + (rval - 2)]; 68.1471 + else if (rval >= 16 && rval <= 31) 68.1472 + val = unw.preg_index[UNW_REG_F16 + (rval - 16)]; 68.1473 + else { 68.1474 + opc = UNW_INSN_MOVE_SCRATCH; 68.1475 + if (rval <= 11) 68.1476 + val = offsetof(struct pt_regs, f6) + 16*(rval - 6); 68.1477 + else 68.1478 + UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n", 68.1479 + __FUNCTION__, rval); 68.1480 + } 68.1481 + break; 68.1482 + 68.1483 + case UNW_WHERE_BR: 68.1484 + if (rval >= 1 && rval <= 5) 68.1485 + val = unw.preg_index[UNW_REG_B1 + (rval - 1)]; 68.1486 + else { 68.1487 + opc = UNW_INSN_MOVE_SCRATCH; 68.1488 + if (rval == 0) 68.1489 + val = offsetof(struct pt_regs, b0); 68.1490 + else if (rval == 6) 68.1491 + val = offsetof(struct pt_regs, b6); 68.1492 + else 68.1493 + val = offsetof(struct pt_regs, b7); 68.1494 + } 68.1495 + break; 68.1496 + 68.1497 + case UNW_WHERE_SPREL: 68.1498 + opc = UNW_INSN_ADD_SP; 68.1499 + break; 68.1500 + 68.1501 + case UNW_WHERE_PSPREL: 68.1502 + opc = UNW_INSN_ADD_PSP; 68.1503 + break; 68.1504 + 68.1505 + default: 68.1506 + UNW_DPRINT(0, "unwind%s: register %u has unexpected `where' value of %u\n", 68.1507 + __FUNCTION__, i, r->where); 68.1508 + break; 68.1509 + } 68.1510 + insn.opc = opc; 68.1511 + insn.dst = unw.preg_index[i]; 68.1512 + insn.val = val; 68.1513 + script_emit(script, insn); 68.1514 + if (need_nat_info) 68.1515 + emit_nat_info(sr, i, script); 68.1516 + 68.1517 + if (i == UNW_REG_PSP) { 68.1518 + /* 68.1519 + * info->psp must contain the _value_ of the previous 68.1520 + * sp, not it's save location. We get this by 68.1521 + * dereferencing the value we just stored in 68.1522 + * info->psp: 68.1523 + */ 68.1524 + insn.opc = UNW_INSN_LOAD; 68.1525 + insn.dst = insn.val = unw.preg_index[UNW_REG_PSP]; 68.1526 + script_emit(script, insn); 68.1527 + } 68.1528 +} 68.1529 + 68.1530 +static inline const struct unw_table_entry * 68.1531 +lookup (struct unw_table *table, unsigned long rel_ip) 68.1532 +{ 68.1533 + const struct unw_table_entry *e = NULL; 68.1534 + unsigned long lo, hi, mid; 68.1535 + 68.1536 + /* do a binary search for right entry: */ 68.1537 + for (lo = 0, hi = table->length; lo < hi; ) { 68.1538 + mid = (lo + hi) / 2; 68.1539 + e = &table->array[mid]; 68.1540 + if (rel_ip < e->start_offset) 68.1541 + hi = mid; 68.1542 + else if (rel_ip >= e->end_offset) 68.1543 + lo = mid + 1; 68.1544 + else 68.1545 + break; 68.1546 + } 68.1547 + if (rel_ip < e->start_offset || rel_ip >= e->end_offset) 68.1548 + return NULL; 68.1549 + return e; 68.1550 +} 68.1551 + 68.1552 +/* 68.1553 + * Build an unwind script that unwinds from state OLD_STATE to the 68.1554 + * entrypoint of the function that called OLD_STATE. 68.1555 + */ 68.1556 +static inline struct unw_script * 68.1557 +build_script (struct unw_frame_info *info) 68.1558 +{ 68.1559 + const struct unw_table_entry *e = NULL; 68.1560 + struct unw_script *script = NULL; 68.1561 + struct unw_labeled_state *ls, *next; 68.1562 + unsigned long ip = info->ip; 68.1563 + struct unw_state_record sr; 68.1564 + struct unw_table *table; 68.1565 + struct unw_reg_info *r; 68.1566 + struct unw_insn insn; 68.1567 + u8 *dp, *desc_end; 68.1568 + u64 hdr; 68.1569 + int i; 68.1570 + STAT(unsigned long start, parse_start;) 68.1571 + 68.1572 + STAT(++unw.stat.script.builds; start = ia64_get_itc()); 68.1573 + 68.1574 + /* build state record */ 68.1575 + memset(&sr, 0, sizeof(sr)); 68.1576 + for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) 68.1577 + r->when = UNW_WHEN_NEVER; 68.1578 + sr.pr_val = info->pr; 68.1579 + 68.1580 + UNW_DPRINT(3, "unwind.%s: ip 0x%lx\n", __FUNCTION__, ip); 68.1581 + script = script_new(ip); 68.1582 + if (!script) { 68.1583 + UNW_DPRINT(0, "unwind.%s: failed to create unwind script\n", __FUNCTION__); 68.1584 + STAT(unw.stat.script.build_time += ia64_get_itc() - start); 68.1585 + return NULL; 68.1586 + } 68.1587 + unw.cache[info->prev_script].hint = script - unw.cache; 68.1588 + 68.1589 + /* search the kernels and the modules' unwind tables for IP: */ 68.1590 + 68.1591 + STAT(parse_start = ia64_get_itc()); 68.1592 + 68.1593 + for (table = unw.tables; table; table = table->next) { 68.1594 + if (ip >= table->start && ip < table->end) { 68.1595 + e = lookup(table, ip - table->segment_base); 68.1596 + break; 68.1597 + } 68.1598 + } 68.1599 + if (!e) { 68.1600 + /* no info, return default unwinder (leaf proc, no mem stack, no saved regs) */ 68.1601 + UNW_DPRINT(1, "unwind.%s: no unwind info for ip=0x%lx (prev ip=0x%lx)\n", 68.1602 + __FUNCTION__, ip, unw.cache[info->prev_script].ip); 68.1603 + sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; 68.1604 + sr.curr.reg[UNW_REG_RP].when = -1; 68.1605 + sr.curr.reg[UNW_REG_RP].val = 0; 68.1606 + compile_reg(&sr, UNW_REG_RP, script); 68.1607 + script_finalize(script, &sr); 68.1608 + STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start); 68.1609 + STAT(unw.stat.script.build_time += ia64_get_itc() - start); 68.1610 + return script; 68.1611 + } 68.1612 + 68.1613 + sr.when_target = (3*((ip & ~0xfUL) - (table->segment_base + e->start_offset))/16 68.1614 + + (ip & 0xfUL)); 68.1615 + hdr = *(u64 *) (table->segment_base + e->info_offset); 68.1616 + dp = (u8 *) (table->segment_base + e->info_offset + 8); 68.1617 + desc_end = dp + 8*UNW_LENGTH(hdr); 68.1618 + 68.1619 + while (!sr.done && dp < desc_end) 68.1620 + dp = unw_decode(dp, sr.in_body, &sr); 68.1621 + 68.1622 + if (sr.when_target > sr.epilogue_start) { 68.1623 + /* 68.1624 + * sp has been restored and all values on the memory stack below 68.1625 + * psp also have been restored. 68.1626 + */ 68.1627 + sr.curr.reg[UNW_REG_PSP].val = 0; 68.1628 + sr.curr.reg[UNW_REG_PSP].where = UNW_WHERE_NONE; 68.1629 + sr.curr.reg[UNW_REG_PSP].when = UNW_WHEN_NEVER; 68.1630 + for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) 68.1631 + if ((r->where == UNW_WHERE_PSPREL && r->val <= 0x10) 68.1632 + || r->where == UNW_WHERE_SPREL) 68.1633 + { 68.1634 + r->val = 0; 68.1635 + r->where = UNW_WHERE_NONE; 68.1636 + r->when = UNW_WHEN_NEVER; 68.1637 + } 68.1638 + } 68.1639 + 68.1640 + script->flags = sr.flags; 68.1641 + 68.1642 + /* 68.1643 + * If RP did't get saved, generate entry for the return link 68.1644 + * register. 68.1645 + */ 68.1646 + if (sr.curr.reg[UNW_REG_RP].when >= sr.when_target) { 68.1647 + sr.curr.reg[UNW_REG_RP].where = UNW_WHERE_BR; 68.1648 + sr.curr.reg[UNW_REG_RP].when = -1; 68.1649 + sr.curr.reg[UNW_REG_RP].val = sr.return_link_reg; 68.1650 + UNW_DPRINT(1, "unwind.%s: using default for rp at ip=0x%lx where=%d val=0x%lx\n", 68.1651 + __FUNCTION__, ip, sr.curr.reg[UNW_REG_RP].where, 68.1652 + sr.curr.reg[UNW_REG_RP].val); 68.1653 + } 68.1654 + 68.1655 +#ifdef UNW_DEBUG 68.1656 + UNW_DPRINT(1, "unwind.%s: state record for func 0x%lx, t=%u:\n", 68.1657 + __FUNCTION__, table->segment_base + e->start_offset, sr.when_target); 68.1658 + for (r = sr.curr.reg; r < sr.curr.reg + UNW_NUM_REGS; ++r) { 68.1659 + if (r->where != UNW_WHERE_NONE || r->when != UNW_WHEN_NEVER) { 68.1660 + UNW_DPRINT(1, " %s <- ", unw.preg_name[r - sr.curr.reg]); 68.1661 + switch (r->where) { 68.1662 + case UNW_WHERE_GR: UNW_DPRINT(1, "r%lu", r->val); break; 68.1663 + case UNW_WHERE_FR: UNW_DPRINT(1, "f%lu", r->val); break; 68.1664 + case UNW_WHERE_BR: UNW_DPRINT(1, "b%lu", r->val); break; 68.1665 + case UNW_WHERE_SPREL: UNW_DPRINT(1, "[sp+0x%lx]", r->val); break; 68.1666 + case UNW_WHERE_PSPREL: UNW_DPRINT(1, "[psp+0x%lx]", r->val); break; 68.1667 + case UNW_WHERE_NONE: 68.1668 + UNW_DPRINT(1, "%s+0x%lx", unw.preg_name[r - sr.curr.reg], r->val); 68.1669 + break; 68.1670 + 68.1671 + default: 68.1672 + UNW_DPRINT(1, "BADWHERE(%d)", r->where); 68.1673 + break; 68.1674 + } 68.1675 + UNW_DPRINT(1, "\t\t%d\n", r->when); 68.1676 + } 68.1677 + } 68.1678 +#endif 68.1679 + 68.1680 + STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start); 68.1681 + 68.1682 + /* translate state record into unwinder instructions: */ 68.1683 + 68.1684 + /* 68.1685 + * First, set psp if we're dealing with a fixed-size frame; 68.1686 + * subsequent instructions may depend on this value. 68.1687 + */ 68.1688 + if (sr.when_target > sr.curr.reg[UNW_REG_PSP].when 68.1689 + && (sr.curr.reg[UNW_REG_PSP].where == UNW_WHERE_NONE) 68.1690 + && sr.curr.reg[UNW_REG_PSP].val != 0) { 68.1691 + /* new psp is sp plus frame size */ 68.1692 + insn.opc = UNW_INSN_ADD; 68.1693 + insn.dst = offsetof(struct unw_frame_info, psp)/8; 68.1694 + insn.val = sr.curr.reg[UNW_REG_PSP].val; /* frame size */ 68.1695 + script_emit(script, insn); 68.1696 + } 68.1697 + 68.1698 + /* determine where the primary UNaT is: */ 68.1699 + if (sr.when_target < sr.curr.reg[UNW_REG_PRI_UNAT_GR].when) 68.1700 + i = UNW_REG_PRI_UNAT_MEM; 68.1701 + else if (sr.when_target < sr.curr.reg[UNW_REG_PRI_UNAT_MEM].when) 68.1702 + i = UNW_REG_PRI_UNAT_GR; 68.1703 + else if (sr.curr.reg[UNW_REG_PRI_UNAT_MEM].when > sr.curr.reg[UNW_REG_PRI_UNAT_GR].when) 68.1704 + i = UNW_REG_PRI_UNAT_MEM; 68.1705 + else 68.1706 + i = UNW_REG_PRI_UNAT_GR; 68.1707 + 68.1708 + compile_reg(&sr, i, script); 68.1709 + 68.1710 + for (i = UNW_REG_BSP; i < UNW_NUM_REGS; ++i) 68.1711 + compile_reg(&sr, i, script); 68.1712 + 68.1713 + /* free labeled register states & stack: */ 68.1714 + 68.1715 + STAT(parse_start = ia64_get_itc()); 68.1716 + for (ls = sr.labeled_states; ls; ls = next) { 68.1717 + next = ls->next; 68.1718 + free_state_stack(&ls->saved_state); 68.1719 + free_labeled_state(ls); 68.1720 + } 68.1721 + free_state_stack(&sr.curr); 68.1722 + STAT(unw.stat.script.parse_time += ia64_get_itc() - parse_start); 68.1723 + 68.1724 + script_finalize(script, &sr); 68.1725 + STAT(unw.stat.script.build_time += ia64_get_itc() - start); 68.1726 + return script; 68.1727 +} 68.1728 + 68.1729 +/* 68.1730 + * Apply the unwinding actions represented by OPS and update SR to 68.1731 + * reflect the state that existed upon entry to the function that this 68.1732 + * unwinder represents. 68.1733 + */ 68.1734 +static inline void 68.1735 +run_script (struct unw_script *script, struct unw_frame_info *state) 68.1736 +{ 68.1737 + struct unw_insn *ip, *limit, next_insn; 68.1738 + unsigned long opc, dst, val, off; 68.1739 + unsigned long *s = (unsigned long *) state; 68.1740 + STAT(unsigned long start;) 68.1741 + 68.1742 + STAT(++unw.stat.script.runs; start = ia64_get_itc()); 68.1743 + state->flags = script->flags; 68.1744 + ip = script->insn; 68.1745 + limit = script->insn + script->count; 68.1746 + next_insn = *ip; 68.1747 + 68.1748 + while (ip++ < limit) { 68.1749 + opc = next_insn.opc; 68.1750 + dst = next_insn.dst; 68.1751 + val = next_insn.val; 68.1752 + next_insn = *ip; 68.1753 + 68.1754 + redo: 68.1755 + switch (opc) { 68.1756 + case UNW_INSN_ADD: 68.1757 + s[dst] += val; 68.1758 + break; 68.1759 + 68.1760 + case UNW_INSN_MOVE2: 68.1761 + if (!s[val]) 68.1762 + goto lazy_init; 68.1763 + s[dst+1] = s[val+1]; 68.1764 + s[dst] = s[val]; 68.1765 + break; 68.1766 + 68.1767 + case UNW_INSN_MOVE: 68.1768 + if (!s[val]) 68.1769 + goto lazy_init; 68.1770 + s[dst] = s[val]; 68.1771 + break; 68.1772 + 68.1773 + case UNW_INSN_MOVE_SCRATCH: 68.1774 + if (state->pt) { 68.1775 + s[dst] = (unsigned long) get_scratch_regs(state) + val; 68.1776 + } else { 68.1777 + s[dst] = 0; 68.1778 + UNW_DPRINT(0, "unwind.%s: no state->pt, dst=%ld, val=%ld\n", 68.1779 + __FUNCTION__, dst, val); 68.1780 + } 68.1781 + break; 68.1782 + 68.1783 + case UNW_INSN_MOVE_CONST: 68.1784 + if (val == 0) 68.1785 + s[dst] = (unsigned long) &unw.r0; 68.1786 + else { 68.1787 + s[dst] = 0; 68.1788 + UNW_DPRINT(0, "unwind.%s: UNW_INSN_MOVE_CONST bad val=%ld\n", 68.1789 + __FUNCTION__, val); 68.1790 + } 68.1791 + break; 68.1792 + 68.1793 + 68.1794 + case UNW_INSN_MOVE_STACKED: 68.1795 + s[dst] = (unsigned long) ia64_rse_skip_regs((unsigned long *)state->bsp, 68.1796 + val); 68.1797 + break; 68.1798 + 68.1799 + case UNW_INSN_ADD_PSP: 68.1800 + s[dst] = state->psp + val; 68.1801 + break; 68.1802 + 68.1803 + case UNW_INSN_ADD_SP: 68.1804 + s[dst] = state->sp + val; 68.1805 + break; 68.1806 + 68.1807 + case UNW_INSN_SETNAT_MEMSTK: 68.1808 + if (!state->pri_unat_loc) 68.1809 + state->pri_unat_loc = &state->sw->caller_unat; 68.1810 + /* register off. is a multiple of 8, so the least 3 bits (type) are 0 */ 68.1811 + s[dst+1] = ((unsigned long) state->pri_unat_loc - s[dst]) | UNW_NAT_MEMSTK; 68.1812 + break; 68.1813 + 68.1814 + case UNW_INSN_SETNAT_TYPE: 68.1815 + s[dst+1] = val; 68.1816 + break; 68.1817 + 68.1818 + case UNW_INSN_LOAD: 68.1819 +#ifdef UNW_DEBUG 68.1820 + if ((s[val] & (local_cpu_data->unimpl_va_mask | 0x7)) != 0 68.1821 +#ifndef XEN 68.1822 + || s[val] < TASK_SIZE 68.1823 +#endif 68.1824 + ) 68.1825 + { 68.1826 + UNW_DPRINT(0, "unwind.%s: rejecting bad psp=0x%lx\n", 68.1827 + __FUNCTION__, s[val]); 68.1828 + break; 68.1829 + } 68.1830 +#endif 68.1831 + s[dst] = *(unsigned long *) s[val]; 68.1832 + break; 68.1833 + } 68.1834 + } 68.1835 + STAT(unw.stat.script.run_time += ia64_get_itc() - start); 68.1836 + return; 68.1837 + 68.1838 + lazy_init: 68.1839 + off = unw.sw_off[val]; 68.1840 + s[val] = (unsigned long) state->sw + off; 68.1841 + if (off >= offsetof(struct switch_stack, r4) && off <= offsetof(struct switch_stack, r7)) 68.1842 + /* 68.1843 + * We're initializing a general register: init NaT info, too. Note that 68.1844 + * the offset is a multiple of 8 which gives us the 3 bits needed for 68.1845 + * the type field. 68.1846 + */ 68.1847 + s[val+1] = (offsetof(struct switch_stack, ar_unat) - off) | UNW_NAT_MEMSTK; 68.1848 + goto redo; 68.1849 +} 68.1850 + 68.1851 +static int 68.1852 +find_save_locs (struct unw_frame_info *info) 68.1853 +{ 68.1854 + int have_write_lock = 0; 68.1855 + struct unw_script *scr; 68.1856 + unsigned long flags = 0; 68.1857 + 68.1858 + if ((info->ip & (local_cpu_data->unimpl_va_mask | 0xf)) 68.1859 +#ifndef XEN 68.1860 + || info->ip < TASK_SIZE 68.1861 +#endif 68.1862 + ) { 68.1863 + /* don't let obviously bad addresses pollute the cache */ 68.1864 + /* FIXME: should really be level 0 but it occurs too often. KAO */ 68.1865 + UNW_DPRINT(1, "unwind.%s: rejecting bad ip=0x%lx\n", __FUNCTION__, info->ip); 68.1866 + info->rp_loc = NULL; 68.1867 + return -1; 68.1868 + } 68.1869 + 68.1870 + scr = script_lookup(info); 68.1871 + if (!scr) { 68.1872 + spin_lock_irqsave(&unw.lock, flags); 68.1873 + scr = build_script(info); 68.1874 + if (!scr) { 68.1875 + spin_unlock_irqrestore(&unw.lock, flags); 68.1876 + UNW_DPRINT(0, 68.1877 + "unwind.%s: failed to locate/build unwind script for ip %lx\n", 68.1878 + __FUNCTION__, info->ip); 68.1879 + return -1; 68.1880 + } 68.1881 + have_write_lock = 1; 68.1882 + } 68.1883 + info->hint = scr->hint; 68.1884 + info->prev_script = scr - unw.cache; 68.1885 + 68.1886 + run_script(scr, info); 68.1887 + 68.1888 + if (have_write_lock) { 68.1889 + write_unlock(&scr->lock); 68.1890 + spin_unlock_irqrestore(&unw.lock, flags); 68.1891 + } else 68.1892 + read_unlock(&scr->lock); 68.1893 + return 0; 68.1894 +} 68.1895 + 68.1896 +int 68.1897 +unw_unwind (struct unw_frame_info *info) 68.1898 +{ 68.1899 + unsigned long prev_ip, prev_sp, prev_bsp; 68.1900 + unsigned long ip, pr, num_regs; 68.1901 + STAT(unsigned long start, flags;) 68.1902 + int retval; 68.1903 + 68.1904 + STAT(local_irq_save(flags); ++unw.stat.api.unwinds; start = ia64_get_itc()); 68.1905 + 68.1906 + prev_ip = info->ip; 68.1907 + prev_sp = info->sp; 68.1908 + prev_bsp = info->bsp; 68.1909 + 68.1910 + /* restore the ip */ 68.1911 + if (!info->rp_loc) { 68.1912 + /* FIXME: should really be level 0 but it occurs too often. KAO */ 68.1913 + UNW_DPRINT(1, "unwind.%s: failed to locate return link (ip=0x%lx)!\n", 68.1914 + __FUNCTION__, info->ip); 68.1915 + STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); 68.1916 + return -1; 68.1917 + } 68.1918 + ip = info->ip = *info->rp_loc; 68.1919 + if (ip < GATE_ADDR) { 68.1920 + UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip); 68.1921 + STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); 68.1922 + return -1; 68.1923 + } 68.1924 + 68.1925 + /* restore the cfm: */ 68.1926 + if (!info->pfs_loc) { 68.1927 + UNW_DPRINT(0, "unwind.%s: failed to locate ar.pfs!\n", __FUNCTION__); 68.1928 + STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); 68.1929 + return -1; 68.1930 + } 68.1931 + info->cfm_loc = info->pfs_loc; 68.1932 + 68.1933 + /* restore the bsp: */ 68.1934 + pr = info->pr; 68.1935 + num_regs = 0; 68.1936 + if ((info->flags & UNW_FLAG_INTERRUPT_FRAME)) { 68.1937 + info->pt = info->sp + 16; 68.1938 + if ((pr & (1UL << PRED_NON_SYSCALL)) != 0) 68.1939 + num_regs = *info->cfm_loc & 0x7f; /* size of frame */ 68.1940 + info->pfs_loc = 68.1941 + (unsigned long *) (info->pt + offsetof(struct pt_regs, ar_pfs)); 68.1942 + UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __FUNCTION__, info->pt); 68.1943 + } else 68.1944 + num_regs = (*info->cfm_loc >> 7) & 0x7f; /* size of locals */ 68.1945 + info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->bsp, -num_regs); 68.1946 + if (info->bsp < info->regstk.limit || info->bsp > info->regstk.top) { 68.1947 + UNW_DPRINT(0, "unwind.%s: bsp (0x%lx) out of range [0x%lx-0x%lx]\n", 68.1948 + __FUNCTION__, info->bsp, info->regstk.limit, info->regstk.top); 68.1949 + STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); 68.1950 + return -1; 68.1951 + } 68.1952 + 68.1953 + /* restore the sp: */ 68.1954 + info->sp = info->psp; 68.1955 + if (info->sp < info->memstk.top || info->sp > info->memstk.limit) { 68.1956 + UNW_DPRINT(0, "unwind.%s: sp (0x%lx) out of range [0x%lx-0x%lx]\n", 68.1957 + __FUNCTION__, info->sp, info->memstk.top, info->memstk.limit); 68.1958 + STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); 68.1959 + return -1; 68.1960 + } 68.1961 + 68.1962 + if (info->ip == prev_ip && info->sp == prev_sp && info->bsp == prev_bsp) { 68.1963 + UNW_DPRINT(0, "unwind.%s: ip, sp, bsp unchanged; stopping here (ip=0x%lx)\n", 68.1964 + __FUNCTION__, ip); 68.1965 + STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); 68.1966 + return -1; 68.1967 + } 68.1968 + 68.1969 + /* as we unwind, the saved ar.unat becomes the primary unat: */ 68.1970 + info->pri_unat_loc = info->unat_loc; 68.1971 + 68.1972 + /* finally, restore the predicates: */ 68.1973 + unw_get_pr(info, &info->pr); 68.1974 + 68.1975 + retval = find_save_locs(info); 68.1976 + STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags)); 68.1977 + return retval; 68.1978 +} 68.1979 +EXPORT_SYMBOL(unw_unwind); 68.1980 + 68.1981 +int 68.1982 +unw_unwind_to_user (struct unw_frame_info *info) 68.1983 +{ 68.1984 + unsigned long ip, sp, pr = 0; 68.1985 + 68.1986 + while (unw_unwind(info) >= 0) { 68.1987 + unw_get_sp(info, &sp); 68.1988 + if ((long)((unsigned long)info->task + IA64_STK_OFFSET - sp) 68.1989 + < IA64_PT_REGS_SIZE) { 68.1990 + UNW_DPRINT(0, "unwind.%s: ran off the top of the kernel stack\n", 68.1991 + __FUNCTION__); 68.1992 + break; 68.1993 + } 68.1994 + if (unw_is_intr_frame(info) && 68.1995 + (pr & (1UL << PRED_USER_STACK))) 68.1996 + return 0; 68.1997 + if (unw_get_pr (info, &pr) < 0) { 68.1998 + unw_get_rp(info, &ip); 68.1999 + UNW_DPRINT(0, "unwind.%s: failed to read " 68.2000 + "predicate register (ip=0x%lx)\n", 68.2001 + __FUNCTION__, ip); 68.2002 + return -1; 68.2003 + } 68.2004 + } 68.2005 + unw_get_ip(info, &ip); 68.2006 + UNW_DPRINT(0, "unwind.%s: failed to unwind to user-level (ip=0x%lx)\n", 68.2007 + __FUNCTION__, ip); 68.2008 + return -1; 68.2009 +} 68.2010 +EXPORT_SYMBOL(unw_unwind_to_user); 68.2011 + 68.2012 +static void 68.2013 +init_frame_info (struct unw_frame_info *info, struct task_struct *t, 68.2014 + struct switch_stack *sw, unsigned long stktop) 68.2015 +{ 68.2016 + unsigned long rbslimit, rbstop, stklimit; 68.2017 + STAT(unsigned long start, flags;) 68.2018 + 68.2019 + STAT(local_irq_save(flags); ++unw.stat.api.inits; start = ia64_get_itc()); 68.2020 + 68.2021 + /* 68.2022 + * Subtle stuff here: we _could_ unwind through the switch_stack frame but we 68.2023 + * don't want to do that because it would be slow as each preserved register would 68.2024 + * have to be processed. Instead, what we do here is zero out the frame info and 68.2025 + * start the unwind process at the function that created the switch_stack frame. 68.2026 + * When a preserved value in switch_stack needs to be accessed, run_script() will 68.2027 + * initialize the appropriate pointer on demand. 68.2028 + */ 68.2029 + memset(info, 0, sizeof(*info)); 68.2030 + 68.2031 + rbslimit = (unsigned long) t + IA64_RBS_OFFSET; 68.2032 + rbstop = sw->ar_bspstore; 68.2033 + if (rbstop - (unsigned long) t >= IA64_STK_OFFSET) 68.2034 + rbstop = rbslimit; 68.2035 + 68.2036 + stklimit = (unsigned long) t + IA64_STK_OFFSET; 68.2037 + if (stktop <= rbstop) 68.2038 + stktop = rbstop; 68.2039 + 68.2040 + info->regstk.limit = rbslimit; 68.2041 + info->regstk.top = rbstop; 68.2042 + info->memstk.limit = stklimit; 68.2043 + info->memstk.top = stktop; 68.2044 + info->task = t; 68.2045 + info->sw = sw; 68.2046 + info->sp = info->psp = stktop; 68.2047 + info->pr = sw->pr; 68.2048 + UNW_DPRINT(3, "unwind.%s:\n" 68.2049 + " task 0x%lx\n" 68.2050 + " rbs = [0x%lx-0x%lx)\n" 68.2051 + " stk = [0x%lx-0x%lx)\n" 68.2052 + " pr 0x%lx\n" 68.2053 + " sw 0x%lx\n" 68.2054 + " sp 0x%lx\n", 68.2055 + __FUNCTION__, (unsigned long) t, rbslimit, rbstop, stktop, stklimit, 68.2056 + info->pr, (unsigned long) info->sw, info->sp); 68.2057 + STAT(unw.stat.api.init_time += ia64_get_itc() - start; local_irq_restore(flags)); 68.2058 +} 68.2059 + 68.2060 +void 68.2061 +unw_init_frame_info (struct unw_frame_info *info, struct task_struct *t, struct switch_stack *sw) 68.2062 +{ 68.2063 + unsigned long sol; 68.2064 + 68.2065 + init_frame_info(info, t, sw, (unsigned long) (sw + 1) - 16); 68.2066 + info->cfm_loc = &sw->ar_pfs; 68.2067 + sol = (*info->cfm_loc >> 7) & 0x7f; 68.2068 + info->bsp = (unsigned long) ia64_rse_skip_regs((unsigned long *) info->regstk.top, -sol); 68.2069 + info->ip = sw->b0; 68.2070 + UNW_DPRINT(3, "unwind.%s:\n" 68.2071 + " bsp 0x%lx\n" 68.2072 + " sol 0x%lx\n" 68.2073 + " ip 0x%lx\n", 68.2074 + __FUNCTION__, info->bsp, sol, info->ip); 68.2075 + find_save_locs(info); 68.2076 +} 68.2077 + 68.2078 +EXPORT_SYMBOL(unw_init_frame_info); 68.2079 + 68.2080 +void 68.2081 +unw_init_from_blocked_task (struct unw_frame_info *info, struct task_struct *t) 68.2082 +{ 68.2083 +#ifdef XEN 68.2084 + struct switch_stack *sw = (struct switch_stack *) (t->arch._thread.ksp + 16); 68.2085 +#else 68.2086 + struct switch_stack *sw = (struct switch_stack *) (t->thread.ksp + 16); 68.2087 +#endif 68.2088 + 68.2089 + UNW_DPRINT(1, "unwind.%s\n", __FUNCTION__); 68.2090 + unw_init_frame_info(info, t, sw); 68.2091 +} 68.2092 +EXPORT_SYMBOL(unw_init_from_blocked_task); 68.2093 + 68.2094 +static void 68.2095 +init_unwind_table (struct unw_table *table, const char *name, unsigned long segment_base, 68.2096 + unsigned long gp, const void *table_start, const void *table_end) 68.2097 +{ 68.2098 + const struct unw_table_entry *start = table_start, *end = table_end; 68.2099 + 68.2100 + table->name = name; 68.2101 + table->segment_base = segment_base; 68.2102 + table->gp = gp; 68.2103 + table->start = segment_base + start[0].start_offset; 68.2104 + table->end = segment_base + end[-1].end_offset; 68.2105 + table->array = start; 68.2106 + table->length = end - start; 68.2107 +} 68.2108 + 68.2109 +#ifndef XEN 68.2110 +void * 68.2111 +unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned long gp, 68.2112 + const void *table_start, const void *table_end) 68.2113 +{ 68.2114 + const struct unw_table_entry *start = table_start, *end = table_end; 68.2115 + struct unw_table *table; 68.2116 + unsigned long flags; 68.2117 + 68.2118 + if (end - start <= 0) { 68.2119 + UNW_DPRINT(0, "unwind.%s: ignoring attempt to insert empty unwind table\n", 68.2120 + __FUNCTION__); 68.2121 + return NULL; 68.2122 + } 68.2123 + 68.2124 + table = kmalloc(sizeof(*table), GFP_USER); 68.2125 + if (!table) 68.2126 + return NULL; 68.2127 + 68.2128 + init_unwind_table(table, name, segment_base, gp, table_start, table_end); 68.2129 + 68.2130 + spin_lock_irqsave(&unw.lock, flags); 68.2131 + { 68.2132 + /* keep kernel unwind table at the front (it's searched most commonly): */ 68.2133 + table->next = unw.tables->next; 68.2134 + unw.tables->next = table; 68.2135 + } 68.2136 + spin_unlock_irqrestore(&unw.lock, flags); 68.2137 + 68.2138 + return table; 68.2139 +} 68.2140 + 68.2141 +void 68.2142 +unw_remove_unwind_table (void *handle) 68.2143 +{ 68.2144 + struct unw_table *table, *prev; 68.2145 + struct unw_script *tmp; 68.2146 + unsigned long flags; 68.2147 + long index; 68.2148 + 68.2149 + if (!handle) { 68.2150 + UNW_DPRINT(0, "unwind.%s: ignoring attempt to remove non-existent unwind table\n", 68.2151 + __FUNCTION__); 68.2152 + return; 68.2153 + } 68.2154 + 68.2155 + table = handle; 68.2156 + if (table == &unw.kernel_table) { 68.2157 + UNW_DPRINT(0, "unwind.%s: sorry, freeing the kernel's unwind table is a " 68.2158 + "no-can-do!\n", __FUNCTION__); 68.2159 + return; 68.2160 + } 68.2161 + 68.2162 + spin_lock_irqsave(&unw.lock, flags); 68.2163 + { 68.2164 + /* first, delete the table: */ 68.2165 + 68.2166 + for (prev = (struct unw_table *) &unw.tables; prev; prev = prev->next) 68.2167 + if (prev->next == table) 68.2168 + break; 68.2169 + if (!prev) { 68.2170 + UNW_DPRINT(0, "unwind.%s: failed to find unwind table %p\n", 68.2171 + __FUNCTION__, (void *) table); 68.2172 + spin_unlock_irqrestore(&unw.lock, flags); 68.2173 + return; 68.2174 + } 68.2175 + prev->next = table->next; 68.2176 + } 68.2177 + spin_unlock_irqrestore(&unw.lock, flags); 68.2178 + 68.2179 + /* next, remove hash table entries for this table */ 68.2180 + 68.2181 + for (index = 0; index <= UNW_HASH_SIZE; ++index) { 68.2182 + tmp = unw.cache + unw.hash[index]; 68.2183 + if (unw.hash[index] >= UNW_CACHE_SIZE 68.2184 + || tmp->ip < table->start || tmp->ip >= table->end) 68.2185 + continue; 68.2186 + 68.2187 + write_lock(&tmp->lock); 68.2188 + { 68.2189 + if (tmp->ip >= table->start && tmp->ip < table->end) { 68.2190 + unw.hash[index] = tmp->coll_chain; 68.2191 + tmp->ip = 0; 68.2192 + } 68.2193 + } 68.2194 + write_unlock(&tmp->lock); 68.2195 + } 68.2196 + 68.2197 + kfree(table); 68.2198 +} 68.2199 + 68.2200 +static int __init 68.2201 +create_gate_table (void) 68.2202 +{ 68.2203 + const struct unw_table_entry *entry, *start, *end; 68.2204 + unsigned long *lp, segbase = GATE_ADDR; 68.2205 + size_t info_size, size; 68.2206 + char *info; 68.2207 + Elf64_Phdr *punw = NULL, *phdr = (Elf64_Phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); 68.2208 + int i; 68.2209 + 68.2210 + for (i = 0; i < GATE_EHDR->e_phnum; ++i, ++phdr) 68.2211 + if (phdr->p_type == PT_IA_64_UNWIND) { 68.2212 + punw = phdr; 68.2213 + break; 68.2214 + } 68.2215 + 68.2216 + if (!punw) { 68.2217 + printk("%s: failed to find gate DSO's unwind table!\n", __FUNCTION__); 68.2218 + return 0; 68.2219 + } 68.2220 + 68.2221 + start = (const struct unw_table_entry *) punw->p_vaddr; 68.2222 + end = (struct unw_table_entry *) ((char *) start + punw->p_memsz); 68.2223 + size = 0; 68.2224 + 68.2225 + unw_add_unwind_table("linux-gate.so", segbase, 0, start, end); 68.2226 + 68.2227 + for (entry = start; entry < end; ++entry) 68.2228 + size += 3*8 + 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset)); 68.2229 + size += 8; /* reserve space for "end of table" marker */ 68.2230 + 68.2231 + unw.gate_table = kmalloc(size, GFP_KERNEL); 68.2232 + if (!unw.gate_table) { 68.2233 + unw.gate_table_size = 0; 68.2234 + printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __FUNCTION__); 68.2235 + return 0; 68.2236 + } 68.2237 + unw.gate_table_size = size; 68.2238 + 68.2239 + lp = unw.gate_table; 68.2240 + info = (char *) unw.gate_table + size; 68.2241 + 68.2242 + for (entry = start; entry < end; ++entry, lp += 3) { 68.2243 + info_size = 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset)); 68.2244 + info -= info_size; 68.2245 + memcpy(info, (char *) segbase + entry->info_offset, info_size); 68.2246 + 68.2247 + lp[0] = segbase + entry->start_offset; /* start */ 68.2248 + lp[1] = segbase + entry->end_offset; /* end */ 68.2249 + lp[2] = info - (char *) unw.gate_table; /* info */ 68.2250 + } 68.2251 + *lp = 0; /* end-of-table marker */ 68.2252 + return 0; 68.2253 +} 68.2254 + 68.2255 +__initcall(create_gate_table); 68.2256 +#endif // !XEN 68.2257 + 68.2258 +void __init 68.2259 +unw_init (void) 68.2260 +{ 68.2261 + extern char __gp[]; 68.2262 + extern void unw_hash_index_t_is_too_narrow (void); 68.2263 + long i, off; 68.2264 + 68.2265 + if (8*sizeof(unw_hash_index_t) < UNW_LOG_HASH_SIZE) 68.2266 + unw_hash_index_t_is_too_narrow(); 68.2267 + 68.2268 + unw.sw_off[unw.preg_index[UNW_REG_PRI_UNAT_GR]] = SW(CALLER_UNAT); 68.2269 + unw.sw_off[unw.preg_index[UNW_REG_BSPSTORE]] = SW(AR_BSPSTORE); 68.2270 + unw.sw_off[unw.preg_index[UNW_REG_PFS]] = SW(AR_PFS); 68.2271 + unw.sw_off[unw.preg_index[UNW_REG_RP]] = SW(B0); 68.2272 + unw.sw_off[unw.preg_index[UNW_REG_UNAT]] = SW(CALLER_UNAT); 68.2273 + unw.sw_off[unw.preg_index[UNW_REG_PR]] = SW(PR); 68.2274 + unw.sw_off[unw.preg_index[UNW_REG_LC]] = SW(AR_LC); 68.2275 + unw.sw_off[unw.preg_index[UNW_REG_FPSR]] = SW(AR_FPSR); 68.2276 + for (i = UNW_REG_R4, off = SW(R4); i <= UNW_REG_R7; ++i, off += 8) 68.2277 + unw.sw_off[unw.preg_index[i]] = off; 68.2278 + for (i = UNW_REG_B1, off = SW(B1); i <= UNW_REG_B5; ++i, off += 8) 68.2279 + unw.sw_off[unw.preg_index[i]] = off; 68.2280 + for (i = UNW_REG_F2, off = SW(F2); i <= UNW_REG_F5; ++i, off += 16) 68.2281 + unw.sw_off[unw.preg_index[i]] = off; 68.2282 + for (i = UNW_REG_F16, off = SW(F16); i <= UNW_REG_F31; ++i, off += 16) 68.2283 + unw.sw_off[unw.preg_index[i]] = off; 68.2284 + 68.2285 + for (i = 0; i < UNW_CACHE_SIZE; ++i) { 68.2286 + if (i > 0) 68.2287 + unw.cache[i].lru_chain = (i - 1); 68.2288 + unw.cache[i].coll_chain = -1; 68.2289 + rwlock_init(&unw.cache[i].lock); 68.2290 + } 68.2291 + unw.lru_head = UNW_CACHE_SIZE - 1; 68.2292 + unw.lru_tail = 0; 68.2293 + 68.2294 + init_unwind_table(&unw.kernel_table, "kernel", KERNEL_START, (unsigned long) __gp, 68.2295 + __start_unwind, __end_unwind); 68.2296 +} 68.2297 + 68.2298 +/* 68.2299 + * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED 68.2300 + * 68.2301 + * This system call has been deprecated. The new and improved way to get 68.2302 + * at the kernel's unwind info is via the gate DSO. The address of the 68.2303 + * ELF header for this DSO is passed to user-level via AT_SYSINFO_EHDR. 68.2304 + * 68.2305 + * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED 68.2306 + * 68.2307 + * This system call copies the unwind data into the buffer pointed to by BUF and returns 68.2308 + * the size of the unwind data. If BUF_SIZE is smaller than the size of the unwind data 68.2309 + * or if BUF is NULL, nothing is copied, but the system call still returns the size of the 68.2310 + * unwind data. 68.2311 + * 68.2312 + * The first portion of the unwind data contains an unwind table and rest contains the 68.2313 + * associated unwind info (in no particular order). The unwind table consists of a table 68.2314 + * of entries of the form: 68.2315 + * 68.2316 + * u64 start; (64-bit address of start of function) 68.2317 + * u64 end; (64-bit address of start of function) 68.2318 + * u64 info; (BUF-relative offset to unwind info) 68.2319 + * 68.2320 + * The end of the unwind table is indicated by an entry with a START address of zero. 68.2321 + * 68.2322 + * Please see the IA-64 Software Conventions and Runtime Architecture manual for details 68.2323 + * on the format of the unwind info. 68.2324 + * 68.2325 + * ERRORS 68.2326 + * EFAULT BUF points outside your accessible address space. 68.2327 + */ 68.2328 +asmlinkage long 68.2329 +sys_getunwind (void __user *buf, size_t buf_size) 68.2330 +{ 68.2331 + if (buf && buf_size >= unw.gate_table_size) 68.2332 + if (copy_to_user(buf, unw.gate_table, unw.gate_table_size) != 0) 68.2333 + return -EFAULT; 68.2334 + return unw.gate_table_size; 68.2335 +}
69.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 69.2 +++ b/xen/arch/ia64/linux-xen/unwind_decoder.c Mon Jan 09 11:22:17 2006 +0000 69.3 @@ -0,0 +1,459 @@ 69.4 +/* 69.5 + * Copyright (C) 2000 Hewlett-Packard Co 69.6 + * Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com> 69.7 + * 69.8 + * Generic IA-64 unwind info decoder. 69.9 + * 69.10 + * This file is used both by the Linux kernel and objdump. Please keep 69.11 + * the two copies of this file in sync. 69.12 + * 69.13 + * You need to customize the decoder by defining the following 69.14 + * macros/constants before including this file: 69.15 + * 69.16 + * Types: 69.17 + * unw_word Unsigned integer type with at least 64 bits 69.18 + * 69.19 + * Register names: 69.20 + * UNW_REG_BSP 69.21 + * UNW_REG_BSPSTORE 69.22 + * UNW_REG_FPSR 69.23 + * UNW_REG_LC 69.24 + * UNW_REG_PFS 69.25 + * UNW_REG_PR 69.26 + * UNW_REG_RNAT 69.27 + * UNW_REG_PSP 69.28 + * UNW_REG_RP 69.29 + * UNW_REG_UNAT 69.30 + * 69.31 + * Decoder action macros: 69.32 + * UNW_DEC_BAD_CODE(code) 69.33 + * UNW_DEC_ABI(fmt,abi,context,arg) 69.34 + * UNW_DEC_BR_GR(fmt,brmask,gr,arg) 69.35 + * UNW_DEC_BR_MEM(fmt,brmask,arg) 69.36 + * UNW_DEC_COPY_STATE(fmt,label,arg) 69.37 + * UNW_DEC_EPILOGUE(fmt,t,ecount,arg) 69.38 + * UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg) 69.39 + * UNW_DEC_FR_MEM(fmt,frmask,arg) 69.40 + * UNW_DEC_GR_GR(fmt,grmask,gr,arg) 69.41 + * UNW_DEC_GR_MEM(fmt,grmask,arg) 69.42 + * UNW_DEC_LABEL_STATE(fmt,label,arg) 69.43 + * UNW_DEC_MEM_STACK_F(fmt,t,size,arg) 69.44 + * UNW_DEC_MEM_STACK_V(fmt,t,arg) 69.45 + * UNW_DEC_PRIUNAT_GR(fmt,r,arg) 69.46 + * UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg) 69.47 + * UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg) 69.48 + * UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg) 69.49 + * UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg) 69.50 + * UNW_DEC_PROLOGUE(fmt,body,rlen,arg) 69.51 + * UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg) 69.52 + * UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg) 69.53 + * UNW_DEC_REG_REG(fmt,src,dst,arg) 69.54 + * UNW_DEC_REG_SPREL(fmt,reg,spoff,arg) 69.55 + * UNW_DEC_REG_WHEN(fmt,reg,t,arg) 69.56 + * UNW_DEC_RESTORE(fmt,t,abreg,arg) 69.57 + * UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg) 69.58 + * UNW_DEC_SPILL_BASE(fmt,pspoff,arg) 69.59 + * UNW_DEC_SPILL_MASK(fmt,imaskp,arg) 69.60 + * UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg) 69.61 + * UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg) 69.62 + * UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg) 69.63 + * UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg) 69.64 + * UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg) 69.65 + * UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg) 69.66 + */ 69.67 + 69.68 +static unw_word 69.69 +unw_decode_uleb128 (unsigned char **dpp) 69.70 +{ 69.71 + unsigned shift = 0; 69.72 + unw_word byte, result = 0; 69.73 + unsigned char *bp = *dpp; 69.74 + 69.75 + while (1) 69.76 + { 69.77 + byte = *bp++; 69.78 + result |= (byte & 0x7f) << shift; 69.79 + if ((byte & 0x80) == 0) 69.80 + break; 69.81 + shift += 7; 69.82 + } 69.83 + *dpp = bp; 69.84 + return result; 69.85 +} 69.86 + 69.87 +static unsigned char * 69.88 +unw_decode_x1 (unsigned char *dp, unsigned char code, void *arg) 69.89 +{ 69.90 + unsigned char byte1, abreg; 69.91 + unw_word t, off; 69.92 + 69.93 + byte1 = *dp++; 69.94 + t = unw_decode_uleb128 (&dp); 69.95 + off = unw_decode_uleb128 (&dp); 69.96 + abreg = (byte1 & 0x7f); 69.97 + if (byte1 & 0x80) 69.98 + UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg); 69.99 + else 69.100 + UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg); 69.101 + return dp; 69.102 +} 69.103 + 69.104 +static unsigned char * 69.105 +unw_decode_x2 (unsigned char *dp, unsigned char code, void *arg) 69.106 +{ 69.107 + unsigned char byte1, byte2, abreg, x, ytreg; 69.108 + unw_word t; 69.109 + 69.110 + byte1 = *dp++; byte2 = *dp++; 69.111 + t = unw_decode_uleb128 (&dp); 69.112 + abreg = (byte1 & 0x7f); 69.113 + ytreg = byte2; 69.114 + x = (byte1 >> 7) & 1; 69.115 + if ((byte1 & 0x80) == 0 && ytreg == 0) 69.116 + UNW_DEC_RESTORE(X2, t, abreg, arg); 69.117 + else 69.118 + UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg); 69.119 + return dp; 69.120 +} 69.121 + 69.122 +static unsigned char * 69.123 +unw_decode_x3 (unsigned char *dp, unsigned char code, void *arg) 69.124 +{ 69.125 + unsigned char byte1, byte2, abreg, qp; 69.126 + unw_word t, off; 69.127 + 69.128 + byte1 = *dp++; byte2 = *dp++; 69.129 + t = unw_decode_uleb128 (&dp); 69.130 + off = unw_decode_uleb128 (&dp); 69.131 + 69.132 + qp = (byte1 & 0x3f); 69.133 + abreg = (byte2 & 0x7f); 69.134 + 69.135 + if (byte1 & 0x80) 69.136 + UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg); 69.137 + else 69.138 + UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg); 69.139 + return dp; 69.140 +} 69.141 + 69.142 +static unsigned char * 69.143 +unw_decode_x4 (unsigned char *dp, unsigned char code, void *arg) 69.144 +{ 69.145 + unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg; 69.146 + unw_word t; 69.147 + 69.148 + byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; 69.149 + t = unw_decode_uleb128 (&dp); 69.150 + 69.151 + qp = (byte1 & 0x3f); 69.152 + abreg = (byte2 & 0x7f); 69.153 + x = (byte2 >> 7) & 1; 69.154 + ytreg = byte3; 69.155 + 69.156 + if ((byte2 & 0x80) == 0 && byte3 == 0) 69.157 + UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg); 69.158 + else 69.159 + UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg); 69.160 + return dp; 69.161 +} 69.162 + 69.163 +static unsigned char * 69.164 +unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg) 69.165 +{ 69.166 + int body = (code & 0x20) != 0; 69.167 + unw_word rlen; 69.168 + 69.169 + rlen = (code & 0x1f); 69.170 + UNW_DEC_PROLOGUE(R1, body, rlen, arg); 69.171 + return dp; 69.172 +} 69.173 + 69.174 +static unsigned char * 69.175 +unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg) 69.176 +{ 69.177 + unsigned char byte1, mask, grsave; 69.178 + unw_word rlen; 69.179 + 69.180 + byte1 = *dp++; 69.181 + 69.182 + mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); 69.183 + grsave = (byte1 & 0x7f); 69.184 + rlen = unw_decode_uleb128 (&dp); 69.185 + UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg); 69.186 + return dp; 69.187 +} 69.188 + 69.189 +static unsigned char * 69.190 +unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg) 69.191 +{ 69.192 + unw_word rlen; 69.193 + 69.194 + rlen = unw_decode_uleb128 (&dp); 69.195 + UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg); 69.196 + return dp; 69.197 +} 69.198 + 69.199 +static unsigned char * 69.200 +unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg) 69.201 +{ 69.202 + unsigned char brmask = (code & 0x1f); 69.203 + 69.204 + UNW_DEC_BR_MEM(P1, brmask, arg); 69.205 + return dp; 69.206 +} 69.207 + 69.208 +static unsigned char * 69.209 +unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg) 69.210 +{ 69.211 + if ((code & 0x10) == 0) 69.212 + { 69.213 + unsigned char byte1 = *dp++; 69.214 + 69.215 + UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1), 69.216 + (byte1 & 0x7f), arg); 69.217 + } 69.218 + else if ((code & 0x08) == 0) 69.219 + { 69.220 + unsigned char byte1 = *dp++, r, dst; 69.221 + 69.222 + r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1); 69.223 + dst = (byte1 & 0x7f); 69.224 + switch (r) 69.225 + { 69.226 + case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break; 69.227 + case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break; 69.228 + case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break; 69.229 + case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break; 69.230 + case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break; 69.231 + case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break; 69.232 + case 6: UNW_DEC_RP_BR(P3, dst, arg); break; 69.233 + case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break; 69.234 + case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break; 69.235 + case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break; 69.236 + case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break; 69.237 + case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break; 69.238 + default: UNW_DEC_BAD_CODE(r); break; 69.239 + } 69.240 + } 69.241 + else if ((code & 0x7) == 0) 69.242 + UNW_DEC_SPILL_MASK(P4, dp, arg); 69.243 + else if ((code & 0x7) == 1) 69.244 + { 69.245 + unw_word grmask, frmask, byte1, byte2, byte3; 69.246 + 69.247 + byte1 = *dp++; byte2 = *dp++; byte3 = *dp++; 69.248 + grmask = ((byte1 >> 4) & 0xf); 69.249 + frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3; 69.250 + UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg); 69.251 + } 69.252 + else 69.253 + UNW_DEC_BAD_CODE(code); 69.254 + return dp; 69.255 +} 69.256 + 69.257 +static unsigned char * 69.258 +unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg) 69.259 +{ 69.260 + int gregs = (code & 0x10) != 0; 69.261 + unsigned char mask = (code & 0x0f); 69.262 + 69.263 + if (gregs) 69.264 + UNW_DEC_GR_MEM(P6, mask, arg); 69.265 + else 69.266 + UNW_DEC_FR_MEM(P6, mask, arg); 69.267 + return dp; 69.268 +} 69.269 + 69.270 +static unsigned char * 69.271 +unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg) 69.272 +{ 69.273 + unsigned char r, byte1, byte2; 69.274 + unw_word t, size; 69.275 + 69.276 + if ((code & 0x10) == 0) 69.277 + { 69.278 + r = (code & 0xf); 69.279 + t = unw_decode_uleb128 (&dp); 69.280 + switch (r) 69.281 + { 69.282 + case 0: 69.283 + size = unw_decode_uleb128 (&dp); 69.284 + UNW_DEC_MEM_STACK_F(P7, t, size, arg); 69.285 + break; 69.286 + 69.287 + case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break; 69.288 + case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break; 69.289 + case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break; 69.290 + case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break; 69.291 + case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break; 69.292 + case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break; 69.293 + case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break; 69.294 + case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break; 69.295 + case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break; 69.296 + case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break; 69.297 + case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break; 69.298 + case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break; 69.299 + case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break; 69.300 + case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break; 69.301 + case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break; 69.302 + default: UNW_DEC_BAD_CODE(r); break; 69.303 + } 69.304 + } 69.305 + else 69.306 + { 69.307 + switch (code & 0xf) 69.308 + { 69.309 + case 0x0: /* p8 */ 69.310 + { 69.311 + r = *dp++; 69.312 + t = unw_decode_uleb128 (&dp); 69.313 + switch (r) 69.314 + { 69.315 + case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break; 69.316 + case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break; 69.317 + case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break; 69.318 + case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break; 69.319 + case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break; 69.320 + case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break; 69.321 + case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break; 69.322 + case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break; 69.323 + case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break; 69.324 + case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break; 69.325 + case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break; 69.326 + case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break; 69.327 + case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break; 69.328 + case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break; 69.329 + case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break; 69.330 + case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break; 69.331 + case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break; 69.332 + case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break; 69.333 + case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break; 69.334 + default: UNW_DEC_BAD_CODE(r); break; 69.335 + } 69.336 + } 69.337 + break; 69.338 + 69.339 + case 0x1: 69.340 + byte1 = *dp++; byte2 = *dp++; 69.341 + UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg); 69.342 + break; 69.343 + 69.344 + case 0xf: /* p10 */ 69.345 + byte1 = *dp++; byte2 = *dp++; 69.346 + UNW_DEC_ABI(P10, byte1, byte2, arg); 69.347 + break; 69.348 + 69.349 + case 0x9: 69.350 + return unw_decode_x1 (dp, code, arg); 69.351 + 69.352 + case 0xa: 69.353 + return unw_decode_x2 (dp, code, arg); 69.354 + 69.355 + case 0xb: 69.356 + return unw_decode_x3 (dp, code, arg); 69.357 + 69.358 + case 0xc: 69.359 + return unw_decode_x4 (dp, code, arg); 69.360 + 69.361 + default: 69.362 + UNW_DEC_BAD_CODE(code); 69.363 + break; 69.364 + } 69.365 + } 69.366 + return dp; 69.367 +} 69.368 + 69.369 +static unsigned char * 69.370 +unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg) 69.371 +{ 69.372 + unw_word label = (code & 0x1f); 69.373 + 69.374 + if ((code & 0x20) != 0) 69.375 + UNW_DEC_COPY_STATE(B1, label, arg); 69.376 + else 69.377 + UNW_DEC_LABEL_STATE(B1, label, arg); 69.378 + return dp; 69.379 +} 69.380 + 69.381 +static unsigned char * 69.382 +unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg) 69.383 +{ 69.384 + unw_word t; 69.385 + 69.386 + t = unw_decode_uleb128 (&dp); 69.387 + UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg); 69.388 + return dp; 69.389 +} 69.390 + 69.391 +static unsigned char * 69.392 +unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg) 69.393 +{ 69.394 + unw_word t, ecount, label; 69.395 + 69.396 + if ((code & 0x10) == 0) 69.397 + { 69.398 + t = unw_decode_uleb128 (&dp); 69.399 + ecount = unw_decode_uleb128 (&dp); 69.400 + UNW_DEC_EPILOGUE(B3, t, ecount, arg); 69.401 + } 69.402 + else if ((code & 0x07) == 0) 69.403 + { 69.404 + label = unw_decode_uleb128 (&dp); 69.405 + if ((code & 0x08) != 0) 69.406 + UNW_DEC_COPY_STATE(B4, label, arg); 69.407 + else 69.408 + UNW_DEC_LABEL_STATE(B4, label, arg); 69.409 + } 69.410 + else 69.411 + switch (code & 0x7) 69.412 + { 69.413 + case 1: return unw_decode_x1 (dp, code, arg); 69.414 + case 2: return unw_decode_x2 (dp, code, arg); 69.415 + case 3: return unw_decode_x3 (dp, code, arg); 69.416 + case 4: return unw_decode_x4 (dp, code, arg); 69.417 + default: UNW_DEC_BAD_CODE(code); break; 69.418 + } 69.419 + return dp; 69.420 +} 69.421 + 69.422 +typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *); 69.423 + 69.424 +static unw_decoder unw_decode_table[2][8] = 69.425 +{ 69.426 + /* prologue table: */ 69.427 + { 69.428 + unw_decode_r1, /* 0 */ 69.429 + unw_decode_r1, 69.430 + unw_decode_r2, 69.431 + unw_decode_r3, 69.432 + unw_decode_p1, /* 4 */ 69.433 + unw_decode_p2_p5, 69.434 + unw_decode_p6, 69.435 + unw_decode_p7_p10 69.436 + }, 69.437 + { 69.438 + unw_decode_r1, /* 0 */ 69.439 + unw_decode_r1, 69.440 + unw_decode_r2, 69.441 + unw_decode_r3, 69.442 + unw_decode_b1, /* 4 */ 69.443 + unw_decode_b1, 69.444 + unw_decode_b2, 69.445 + unw_decode_b3_x4 69.446 + } 69.447 +}; 69.448 + 69.449 +/* 69.450 + * Decode one descriptor and return address of next descriptor. 69.451 + */ 69.452 +static inline unsigned char * 69.453 +unw_decode (unsigned char *dp, int inside_body, void *arg) 69.454 +{ 69.455 + unw_decoder decoder; 69.456 + unsigned char code; 69.457 + 69.458 + code = *dp++; 69.459 + decoder = unw_decode_table[inside_body][code >> 5]; 69.460 + dp = (*decoder) (dp, code, arg); 69.461 + return dp; 69.462 +}
70.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 70.2 +++ b/xen/arch/ia64/linux-xen/unwind_i.h Mon Jan 09 11:22:17 2006 +0000 70.3 @@ -0,0 +1,164 @@ 70.4 +/* 70.5 + * Copyright (C) 2000, 2002-2003 Hewlett-Packard Co 70.6 + * David Mosberger-Tang <davidm@hpl.hp.com> 70.7 + * 70.8 + * Kernel unwind support. 70.9 + */ 70.10 + 70.11 +#define UNW_VER(x) ((x) >> 48) 70.12 +#define UNW_FLAG_MASK 0x0000ffff00000000 70.13 +#define UNW_FLAG_OSMASK 0x0000f00000000000 70.14 +#define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L) 70.15 +#define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L) 70.16 +#define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL) 70.17 + 70.18 +enum unw_register_index { 70.19 + /* primary unat: */ 70.20 + UNW_REG_PRI_UNAT_GR, 70.21 + UNW_REG_PRI_UNAT_MEM, 70.22 + 70.23 + /* register stack */ 70.24 + UNW_REG_BSP, /* register stack pointer */ 70.25 + UNW_REG_BSPSTORE, 70.26 + UNW_REG_PFS, /* previous function state */ 70.27 + UNW_REG_RNAT, 70.28 + /* memory stack */ 70.29 + UNW_REG_PSP, /* previous memory stack pointer */ 70.30 + /* return pointer: */ 70.31 + UNW_REG_RP, 70.32 + 70.33 + /* preserved registers: */ 70.34 + UNW_REG_R4, UNW_REG_R5, UNW_REG_R6, UNW_REG_R7, 70.35 + UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR, 70.36 + UNW_REG_B1, UNW_REG_B2, UNW_REG_B3, UNW_REG_B4, UNW_REG_B5, 70.37 + UNW_REG_F2, UNW_REG_F3, UNW_REG_F4, UNW_REG_F5, 70.38 + UNW_REG_F16, UNW_REG_F17, UNW_REG_F18, UNW_REG_F19, 70.39 + UNW_REG_F20, UNW_REG_F21, UNW_REG_F22, UNW_REG_F23, 70.40 + UNW_REG_F24, UNW_REG_F25, UNW_REG_F26, UNW_REG_F27, 70.41 + UNW_REG_F28, UNW_REG_F29, UNW_REG_F30, UNW_REG_F31, 70.42 + UNW_NUM_REGS 70.43 +}; 70.44 + 70.45 +struct unw_info_block { 70.46 + u64 header; 70.47 + u64 desc[0]; /* unwind descriptors */ 70.48 + /* personality routine and language-specific data follow behind descriptors */ 70.49 +}; 70.50 + 70.51 +struct unw_table { 70.52 + struct unw_table *next; /* must be first member! */ 70.53 + const char *name; 70.54 + unsigned long gp; /* global pointer for this load-module */ 70.55 + unsigned long segment_base; /* base for offsets in the unwind table entries */ 70.56 + unsigned long start; 70.57 + unsigned long end; 70.58 + const struct unw_table_entry *array; 70.59 + unsigned long length; 70.60 +}; 70.61 + 70.62 +enum unw_where { 70.63 + UNW_WHERE_NONE, /* register isn't saved at all */ 70.64 + UNW_WHERE_GR, /* register is saved in a general register */ 70.65 + UNW_WHERE_FR, /* register is saved in a floating-point register */ 70.66 + UNW_WHERE_BR, /* register is saved in a branch register */ 70.67 + UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */ 70.68 + UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */ 70.69 + /* 70.70 + * At the end of each prologue these locations get resolved to 70.71 + * UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively: 70.72 + */ 70.73 + UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */ 70.74 + UNW_WHERE_GR_SAVE /* register is saved in next general register */ 70.75 +}; 70.76 + 70.77 +#define UNW_WHEN_NEVER 0x7fffffff 70.78 + 70.79 +struct unw_reg_info { 70.80 + unsigned long val; /* save location: register number or offset */ 70.81 + enum unw_where where; /* where the register gets saved */ 70.82 + int when; /* when the register gets saved */ 70.83 +}; 70.84 + 70.85 +struct unw_reg_state { 70.86 + struct unw_reg_state *next; /* next (outer) element on state stack */ 70.87 + struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */ 70.88 +}; 70.89 + 70.90 +struct unw_labeled_state { 70.91 + struct unw_labeled_state *next; /* next labeled state (or NULL) */ 70.92 + unsigned long label; /* label for this state */ 70.93 + struct unw_reg_state saved_state; 70.94 +}; 70.95 + 70.96 +struct unw_state_record { 70.97 + unsigned int first_region : 1; /* is this the first region? */ 70.98 + unsigned int done : 1; /* are we done scanning descriptors? */ 70.99 + unsigned int any_spills : 1; /* got any register spills? */ 70.100 + unsigned int in_body : 1; /* are we inside a body (as opposed to a prologue)? */ 70.101 + unsigned long flags; /* see UNW_FLAG_* in unwind.h */ 70.102 + 70.103 + u8 *imask; /* imask of spill_mask record or NULL */ 70.104 + unsigned long pr_val; /* predicate values */ 70.105 + unsigned long pr_mask; /* predicate mask */ 70.106 + long spill_offset; /* psp-relative offset for spill base */ 70.107 + int region_start; 70.108 + int region_len; 70.109 + int epilogue_start; 70.110 + int epilogue_count; 70.111 + int when_target; 70.112 + 70.113 + u8 gr_save_loc; /* next general register to use for saving a register */ 70.114 + u8 return_link_reg; /* branch register in which the return link is passed */ 70.115 + 70.116 + struct unw_labeled_state *labeled_states; /* list of all labeled states */ 70.117 + struct unw_reg_state curr; /* current state */ 70.118 +}; 70.119 + 70.120 +enum unw_nat_type { 70.121 + UNW_NAT_NONE, /* NaT not represented */ 70.122 + UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */ 70.123 + UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */ 70.124 + UNW_NAT_REGSTK /* NaT is in rnat */ 70.125 +}; 70.126 + 70.127 +enum unw_insn_opcode { 70.128 + UNW_INSN_ADD, /* s[dst] += val */ 70.129 + UNW_INSN_ADD_PSP, /* s[dst] = (s.psp + val) */ 70.130 + UNW_INSN_ADD_SP, /* s[dst] = (s.sp + val) */ 70.131 + UNW_INSN_MOVE, /* s[dst] = s[val] */ 70.132 + UNW_INSN_MOVE2, /* s[dst] = s[val]; s[dst+1] = s[val+1] */ 70.133 + UNW_INSN_MOVE_STACKED, /* s[dst] = ia64_rse_skip(*s.bsp, val) */ 70.134 + UNW_INSN_SETNAT_MEMSTK, /* s[dst+1].nat.type = MEMSTK; 70.135 + s[dst+1].nat.off = *s.pri_unat - s[dst] */ 70.136 + UNW_INSN_SETNAT_TYPE, /* s[dst+1].nat.type = val */ 70.137 + UNW_INSN_LOAD, /* s[dst] = *s[val] */ 70.138 + UNW_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */ 70.139 + UNW_INSN_MOVE_CONST, /* s[dst] = constant reg "val" */ 70.140 +}; 70.141 + 70.142 +struct unw_insn { 70.143 + unsigned int opc : 4; 70.144 + unsigned int dst : 9; 70.145 + signed int val : 19; 70.146 +}; 70.147 + 70.148 +/* 70.149 + * Preserved general static registers (r4-r7) give rise to two script 70.150 + * instructions; everything else yields at most one instruction; at 70.151 + * the end of the script, the psp gets popped, accounting for one more 70.152 + * instruction. 70.153 + */ 70.154 +#define UNW_MAX_SCRIPT_LEN (UNW_NUM_REGS + 5) 70.155 + 70.156 +struct unw_script { 70.157 + unsigned long ip; /* ip this script is for */ 70.158 + unsigned long pr_mask; /* mask of predicates script depends on */ 70.159 + unsigned long pr_val; /* predicate values this script is for */ 70.160 + rwlock_t lock; 70.161 + unsigned int flags; /* see UNW_FLAG_* in unwind.h */ 70.162 + unsigned short lru_chain; /* used for least-recently-used chain */ 70.163 + unsigned short coll_chain; /* used for hash collisions */ 70.164 + unsigned short hint; /* hint for next script to try (or -1) */ 70.165 + unsigned short count; /* number of instructions in script */ 70.166 + struct unw_insn insn[UNW_MAX_SCRIPT_LEN]; 70.167 +};
71.1 --- a/xen/arch/ia64/vmx/mmio.c Mon Jan 09 11:19:55 2006 +0000 71.2 +++ b/xen/arch/ia64/vmx/mmio.c Mon Jan 09 11:22:17 2006 +0000 71.3 @@ -29,7 +29,7 @@ 71.4 #include <asm/vmx_vcpu.h> 71.5 #include <asm/privop.h> 71.6 #include <asm/types.h> 71.7 -#include <public/io/ioreq.h> 71.8 +#include <public/hvm/ioreq.h> 71.9 #include <asm/mm.h> 71.10 #include <asm/vmx.h> 71.11
72.1 --- a/xen/arch/ia64/vmx/vlsapic.c Mon Jan 09 11:19:55 2006 +0000 72.2 +++ b/xen/arch/ia64/vmx/vlsapic.c Mon Jan 09 11:22:17 2006 +0000 72.3 @@ -218,7 +218,7 @@ void vtm_interruption_update(VCPU *vcpu, 72.4 */ 72.5 void vtm_domain_out(VCPU *vcpu) 72.6 { 72.7 - if(!is_idle_task(vcpu->domain)) 72.8 + if(!is_idle_domain(vcpu->domain)) 72.9 rem_ac_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer); 72.10 } 72.11 72.12 @@ -230,7 +230,7 @@ void vtm_domain_in(VCPU *vcpu) 72.13 { 72.14 vtime_t *vtm; 72.15 72.16 - if(!is_idle_task(vcpu->domain)) { 72.17 + if(!is_idle_domain(vcpu->domain)) { 72.18 vtm=&(vcpu->arch.arch_vmx.vtm); 72.19 vtm_interruption_update(vcpu, vtm); 72.20 }
73.1 --- a/xen/arch/ia64/vmx/vmx_init.c Mon Jan 09 11:19:55 2006 +0000 73.2 +++ b/xen/arch/ia64/vmx/vmx_init.c Mon Jan 09 11:22:17 2006 +0000 73.3 @@ -42,7 +42,7 @@ 73.4 #include <xen/lib.h> 73.5 #include <asm/vmmu.h> 73.6 #include <public/arch-ia64.h> 73.7 -#include <public/io/ioreq.h> 73.8 +#include <public/hvm/ioreq.h> 73.9 #include <asm/vmx_phy_mode.h> 73.10 #include <asm/processor.h> 73.11 #include <asm/vmx.h>
74.1 --- a/xen/arch/ia64/vmx/vmx_process.c Mon Jan 09 11:19:55 2006 +0000 74.2 +++ b/xen/arch/ia64/vmx/vmx_process.c Mon Jan 09 11:22:17 2006 +0000 74.3 @@ -53,6 +53,7 @@ 74.4 #define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034 74.5 74.6 74.7 +extern void die_if_kernel(char *str, struct pt_regs *regs, long err); 74.8 extern void rnat_consumption (VCPU *vcpu); 74.9 #define DOMN_PAL_REQUEST 0x110000 74.10 74.11 @@ -185,8 +186,11 @@ vmx_ia64_handle_break (unsigned long ifa 74.12 }else if(iim == DOMN_PAL_REQUEST){ 74.13 pal_emul(current); 74.14 vmx_vcpu_increment_iip(current); 74.15 - } else 74.16 + } else { 74.17 + if (iim == 0) 74.18 + die_if_kernel("bug check", regs, iim); 74.19 vmx_reflect_interruption(ifa,isr,iim,11,regs); 74.20 + } 74.21 } 74.22 74.23 74.24 @@ -227,7 +231,7 @@ void leave_hypervisor_tail(struct pt_reg 74.25 struct domain *d = current->domain; 74.26 struct vcpu *v = current; 74.27 // FIXME: Will this work properly if doing an RFI??? 74.28 - if (!is_idle_task(d) ) { // always comes from guest 74.29 + if (!is_idle_domain(d) ) { // always comes from guest 74.30 extern void vmx_dorfirfi(void); 74.31 struct pt_regs *user_regs = vcpu_regs(current); 74.32 if (local_softirq_pending())
75.1 --- a/xen/arch/ia64/vmx/vmx_support.c Mon Jan 09 11:19:55 2006 +0000 75.2 +++ b/xen/arch/ia64/vmx/vmx_support.c Mon Jan 09 11:22:17 2006 +0000 75.3 @@ -21,7 +21,7 @@ 75.4 */ 75.5 #include <xen/config.h> 75.6 #include <xen/sched.h> 75.7 -#include <public/io/ioreq.h> 75.8 +#include <public/hvm/ioreq.h> 75.9 #include <asm/vmx.h> 75.10 #include <asm/vmx_vcpu.h> 75.11
76.1 --- a/xen/arch/ia64/xen/dom_fw.c Mon Jan 09 11:19:55 2006 +0000 76.2 +++ b/xen/arch/ia64/xen/dom_fw.c Mon Jan 09 11:22:17 2006 +0000 76.3 @@ -861,12 +861,16 @@ dom_fw_init (struct domain *d, char *arg 76.4 bp->console_info.orig_x = 0; 76.5 bp->console_info.orig_y = 24; 76.6 bp->fpswa = 0; 76.7 - bp->initrd_start = (dom0_start+dom0_size) - 76.8 - (PAGE_ALIGN(ia64_boot_param->initrd_size) + 4*1024*1024); 76.9 - bp->initrd_size = ia64_boot_param->initrd_size; 76.10 - printf(" initrd start %0xlx", bp->initrd_start); 76.11 - printf(" initrd size %0xlx", bp->initrd_size); 76.12 - 76.13 - 76.14 + if (d == dom0) { 76.15 + bp->initrd_start = (dom0_start+dom0_size) - 76.16 + (PAGE_ALIGN(ia64_boot_param->initrd_size) + 4*1024*1024); 76.17 + bp->initrd_size = ia64_boot_param->initrd_size; 76.18 + } 76.19 + else { 76.20 + bp->initrd_start = d->arch.initrd_start; 76.21 + bp->initrd_size = d->arch.initrd_len; 76.22 + } 76.23 + printf(" initrd start %0xlx", bp->initrd_start); 76.24 + printf(" initrd size %0xlx", bp->initrd_size); 76.25 return bp; 76.26 }
77.1 --- a/xen/arch/ia64/xen/domain.c Mon Jan 09 11:19:55 2006 +0000 77.2 +++ b/xen/arch/ia64/xen/domain.c Mon Jan 09 11:22:17 2006 +0000 77.3 @@ -19,6 +19,7 @@ 77.4 #include <xen/delay.h> 77.5 #include <xen/softirq.h> 77.6 #include <xen/mm.h> 77.7 +#include <xen/iocap.h> 77.8 #include <asm/ptrace.h> 77.9 #include <asm/system.h> 77.10 #include <asm/io.h> 77.11 @@ -45,7 +46,7 @@ 77.12 #include <asm/vmx_vcpu.h> 77.13 #include <asm/vmx_vpd.h> 77.14 #include <asm/pal.h> 77.15 -#include <public/io/ioreq.h> 77.16 +#include <public/hvm/ioreq.h> 77.17 77.18 #define CONFIG_DOMAIN0_CONTIGUOUS 77.19 unsigned long dom0_start = -1L; 77.20 @@ -181,7 +182,7 @@ static void init_switch_stack(struct vcp 77.21 memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96); 77.22 } 77.23 77.24 -void arch_do_createdomain(struct vcpu *v) 77.25 +int arch_do_createdomain(struct vcpu *v) 77.26 { 77.27 struct domain *d = v->domain; 77.28 struct thread_info *ti = alloc_thread_info(v); 77.29 @@ -248,7 +249,9 @@ void arch_do_createdomain(struct vcpu *v 77.30 } 77.31 } else 77.32 d->arch.mm = NULL; 77.33 - printf ("arch_do_create_domain: domain=%p\n", d); 77.34 + printf ("arch_do_create_domain: domain=%p\n", d); 77.35 + 77.36 + return 0; 77.37 } 77.38 77.39 void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c) 77.40 @@ -291,16 +294,7 @@ int arch_set_info_guest(struct vcpu *v, 77.41 d->arch.cmdline = c->cmdline; 77.42 new_thread(v, regs->cr_iip, 0, 0); 77.43 77.44 -#ifdef CONFIG_IA64_SPLIT_CACHE 77.45 - /* Sync d/i cache conservatively */ 77.46 - if (!running_on_sim) { 77.47 - ret = ia64_pal_cache_flush(4, 0, &progress, NULL); 77.48 - if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED)) 77.49 - printk("PAL CACHE FLUSH failed for dom0.\n"); 77.50 - else 77.51 - printk("Sync i/d cache for guest SUCC\n"); 77.52 - } 77.53 -#endif 77.54 + sync_split_caches(); 77.55 v->vcpu_info->arch.evtchn_vector = c->vcpu.evtchn_vector; 77.56 if ( c->vcpu.privregs && copy_from_user(v->arch.privregs, 77.57 c->vcpu.privregs, sizeof(mapped_regs_t))) { 77.58 @@ -428,7 +422,7 @@ extern unsigned long vhpt_paddr, vhpt_pe 77.59 { 77.60 p = alloc_domheap_page(d); 77.61 // zero out pages for security reasons 77.62 - memset(__va(page_to_phys(p)),0,PAGE_SIZE); 77.63 + if (p) memset(__va(page_to_phys(p)),0,PAGE_SIZE); 77.64 } 77.65 if (unlikely(!p)) { 77.66 printf("map_new_domain_page: Can't alloc!!!! Aaaargh!\n"); 77.67 @@ -763,7 +757,10 @@ void alloc_dom0(void) 77.68 */ 77.69 void physdev_init_dom0(struct domain *d) 77.70 { 77.71 - set_bit(_DOMF_physdev_access, &d->domain_flags); 77.72 + if (iomem_permit_access(d, 0UL, ~0UL)) 77.73 + BUG(); 77.74 + if (irqs_permit_access(d, 0, NR_PIRQS-1)) 77.75 + BUG(); 77.76 } 77.77 77.78 unsigned int vmx_dom0 = 0; 77.79 @@ -912,9 +909,9 @@ int construct_dom0(struct domain *d, 77.80 memset(si, 0, PAGE_SIZE); 77.81 d->shared_info->arch.start_info_pfn = __pa(si) >> PAGE_SHIFT; 77.82 sprintf(si->magic, "xen-%i.%i-ia64", XEN_VERSION, XEN_SUBVERSION); 77.83 + si->nr_pages = d->tot_pages; 77.84 77.85 #if 0 77.86 - si->nr_pages = d->tot_pages; 77.87 si->shared_info = virt_to_phys(d->shared_info); 77.88 si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN; 77.89 //si->pt_base = vpt_start; 77.90 @@ -959,16 +956,7 @@ int construct_dom0(struct domain *d, 77.91 77.92 new_thread(v, pkern_entry, 0, 0); 77.93 physdev_init_dom0(d); 77.94 -#ifdef CONFIG_IA64_SPLIT_CACHE 77.95 - /* Sync d/i cache conservatively */ 77.96 - if (!running_on_sim) { 77.97 - ret = ia64_pal_cache_flush(4, 0, &progress, NULL); 77.98 - if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED)) 77.99 - printk("PAL CACHE FLUSH failed for dom0.\n"); 77.100 - else 77.101 - printk("Sync i/d cache for guest SUCC\n"); 77.102 - } 77.103 -#endif 77.104 + sync_split_caches(); 77.105 77.106 // FIXME: Hack for keyboard input 77.107 #ifdef CLONE_DOMAIN0 77.108 @@ -1027,16 +1015,7 @@ int construct_domU(struct domain *d, 77.109 #endif 77.110 new_thread(v, pkern_entry, 0, 0); 77.111 printk("new_thread returns\n"); 77.112 -#ifdef CONFIG_IA64_SPLIT_CACHE 77.113 - /* Sync d/i cache conservatively */ 77.114 - if (!running_on_sim) { 77.115 - ret = ia64_pal_cache_flush(4, 0, &progress, NULL); 77.116 - if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED)) 77.117 - printk("PAL CACHE FLUSH failed for dom0.\n"); 77.118 - else 77.119 - printk("Sync i/d cache for guest SUCC\n"); 77.120 - } 77.121 -#endif 77.122 + sync_split_caches(); 77.123 __set_bit(0x30, VCPU(v, delivery_mask)); 77.124 77.125 return 0; 77.126 @@ -1050,16 +1029,7 @@ void reconstruct_domU(struct vcpu *v) 77.127 v->domain->domain_id); 77.128 loaddomainelfimage(v->domain,v->domain->arch.image_start); 77.129 new_thread(v, v->domain->arch.entry, 0, 0); 77.130 -#ifdef CONFIG_IA64_SPLIT_CACHE 77.131 - /* Sync d/i cache conservatively */ 77.132 - if (!running_on_sim) { 77.133 - ret = ia64_pal_cache_flush(4, 0, &progress, NULL); 77.134 - if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED)) 77.135 - printk("PAL CACHE FLUSH failed for dom0.\n"); 77.136 - else 77.137 - printk("Sync i/d cache for guest SUCC\n"); 77.138 - } 77.139 -#endif 77.140 + sync_split_caches(); 77.141 } 77.142 #endif 77.143 77.144 @@ -1100,15 +1070,6 @@ void domain_pend_keyboard_interrupt(int 77.145 vcpu_pend_interrupt(dom0->vcpu[0],irq); 77.146 } 77.147 77.148 -void vcpu_migrate_cpu(struct vcpu *v, int newcpu) 77.149 -{ 77.150 - if ( v->processor == newcpu ) 77.151 - return; 77.152 - 77.153 - set_bit(_VCPUF_cpu_migrated, &v->vcpu_flags); 77.154 - v->processor = newcpu; 77.155 -} 77.156 - 77.157 void sync_vcpu_execstate(struct vcpu *v) 77.158 { 77.159 ia64_save_fpu(v->arch._thread.fph);
78.1 --- a/xen/arch/ia64/xen/hyperprivop.S Mon Jan 09 11:19:55 2006 +0000 78.2 +++ b/xen/arch/ia64/xen/hyperprivop.S Mon Jan 09 11:22:17 2006 +0000 78.3 @@ -543,6 +543,13 @@ GLOBAL_ENTRY(fast_break_reflect) 78.4 extr.u r21=r30,IA64_PSR_PP_BIT,1 ;; 78.5 cmp.ne p7,p0=r21,r0 ;; 78.6 (p7) br.spnt.few dispatch_break_fault ;; 78.7 + movl r20=IA64_PSR_CPL ;; 78.8 + and r22=r20,r30 ;; 78.9 + cmp.ne p7,p0=r22,r0 78.10 +(p7) br.spnt.many 1f ;; 78.11 + cmp.eq p7,p0=r17,r0 78.12 +(p7) br.spnt.few dispatch_break_fault ;; 78.13 +1: 78.14 #if 1 /* special handling in case running on simulator */ 78.15 movl r20=first_break;; 78.16 ld4 r23=[r20];;
79.1 --- a/xen/arch/ia64/xen/irq.c Mon Jan 09 11:19:55 2006 +0000 79.2 +++ b/xen/arch/ia64/xen/irq.c Mon Jan 09 11:22:17 2006 +0000 79.3 @@ -1378,9 +1378,6 @@ int pirq_guest_bind(struct vcpu *d, int 79.4 unsigned long flags; 79.5 int rc = 0; 79.6 79.7 - if ( !IS_CAPABLE_PHYSDEV(d->domain) ) 79.8 - return -EPERM; 79.9 - 79.10 spin_lock_irqsave(&desc->lock, flags); 79.11 79.12 action = (irq_guest_action_t *)desc->action;
80.1 --- a/xen/arch/ia64/xen/ivt.S Mon Jan 09 11:19:55 2006 +0000 80.2 +++ b/xen/arch/ia64/xen/ivt.S Mon Jan 09 11:22:17 2006 +0000 80.3 @@ -839,6 +839,8 @@ ENTRY(break_fault) 80.4 mov r17=cr.iim 80.5 mov r31=pr 80.6 ;; 80.7 + cmp.eq p7,p0=r17,r0 80.8 +(p7) br.spnt.few dispatch_break_fault ;; 80.9 movl r18=XSI_PSR_IC 80.10 ;; 80.11 ld8 r19=[r18]
81.1 --- a/xen/arch/ia64/xen/process.c Mon Jan 09 11:19:55 2006 +0000 81.2 +++ b/xen/arch/ia64/xen/process.c Mon Jan 09 11:22:17 2006 +0000 81.3 @@ -33,6 +33,7 @@ 81.4 #include <xen/multicall.h> 81.5 81.6 extern unsigned long vcpu_get_itir_on_fault(struct vcpu *, UINT64); 81.7 +extern void die_if_kernel(char *str, struct pt_regs *regs, long err); 81.8 81.9 extern unsigned long dom0_start, dom0_size; 81.10 81.11 @@ -64,26 +65,16 @@ long do_iopl(domid_t domain, unsigned in 81.12 81.13 extern struct schedule_data schedule_data[NR_CPUS]; 81.14 81.15 -void schedule_tail(struct vcpu *next) 81.16 +void schedule_tail(struct vcpu *prev) 81.17 { 81.18 - unsigned long rr7; 81.19 - //printk("current=%lx,shared_info=%lx\n",current,current->vcpu_info); 81.20 - //printk("next=%lx,shared_info=%lx\n",next,next->vcpu_info); 81.21 + context_saved(prev); 81.22 81.23 - // TG: Real HACK FIXME. 81.24 - // This is currently necessary because when a new domain is started, 81.25 - // the context_switch function of xen/common/schedule.c(__enter_scheduler) 81.26 - // never returns. Therefore, the lock must be released. 81.27 - // schedule_tail is only called when a domain is started. 81.28 - spin_unlock_irq(&schedule_data[current->processor].schedule_lock); 81.29 - 81.30 - /* rr7 will be postponed to last point when resuming back to guest */ 81.31 - if(VMX_DOMAIN(current)){ 81.32 - vmx_load_all_rr(current); 81.33 - }else{ 81.34 - load_region_regs(current); 81.35 - vcpu_load_kernel_regs(current); 81.36 - } 81.37 + if (VMX_DOMAIN(current)) { 81.38 + vmx_load_all_rr(current); 81.39 + } else { 81.40 + load_region_regs(current); 81.41 + vcpu_load_kernel_regs(current); 81.42 + } 81.43 } 81.44 81.45 void tdpfoo(void) { } 81.46 @@ -251,7 +242,7 @@ void deliver_pending_interrupt(struct pt 81.47 struct domain *d = current->domain; 81.48 struct vcpu *v = current; 81.49 // FIXME: Will this work properly if doing an RFI??? 81.50 - if (!is_idle_task(d) && user_mode(regs)) { 81.51 + if (!is_idle_domain(d) && user_mode(regs)) { 81.52 //vcpu_poke_timer(v); 81.53 if (vcpu_deliverable_interrupts(v)) 81.54 reflect_extint(regs); 81.55 @@ -686,6 +677,8 @@ ia64_handle_break (unsigned long ifa, st 81.56 vcpu_increment_iip(current); 81.57 } 81.58 else { 81.59 + if (iim == 0) 81.60 + die_if_kernel("bug check", regs, iim); 81.61 PSCB(v,iim) = iim; 81.62 reflect_interruption(isr,regs,IA64_BREAK_VECTOR); 81.63 }
82.1 --- a/xen/arch/ia64/xen/vcpu.c Mon Jan 09 11:19:55 2006 +0000 82.2 +++ b/xen/arch/ia64/xen/vcpu.c Mon Jan 09 11:22:17 2006 +0000 82.3 @@ -1085,7 +1085,7 @@ void vcpu_set_next_timer(VCPU *vcpu) 82.4 /* gloss over the wraparound problem for now... we know it exists 82.5 * but it doesn't matter right now */ 82.6 82.7 - if (is_idle_task(vcpu->domain)) { 82.8 + if (is_idle_domain(vcpu->domain)) { 82.9 // printf("****** vcpu_set_next_timer called during idle!!\n"); 82.10 vcpu_safe_set_itm(s); 82.11 return;
83.1 --- a/xen/arch/ia64/xen/xenmisc.c Mon Jan 09 11:19:55 2006 +0000 83.2 +++ b/xen/arch/ia64/xen/xenmisc.c Mon Jan 09 11:22:17 2006 +0000 83.3 @@ -25,7 +25,6 @@ unsigned long wait_init_idle; 83.4 int phys_proc_id[NR_CPUS]; 83.5 unsigned long loops_per_jiffy = (1<<12); // from linux/init/main.c 83.6 83.7 -void unw_init(void) { printf("unw_init() skipped (NEED FOR KERNEL UNWIND)\n"); } 83.8 void ia64_mca_init(void) { printf("ia64_mca_init() skipped (Machine check abort handling)\n"); } 83.9 void ia64_mca_cpu_init(void *x) { } 83.10 void ia64_patch_mckinley_e9(unsigned long a, unsigned long b) { } 83.11 @@ -180,11 +179,6 @@ void pgtable_quicklist_free(void *pgtabl 83.12 // from arch/ia64/traps.c 83.13 /////////////////////////////// 83.14 83.15 -void show_registers(struct pt_regs *regs) 83.16 -{ 83.17 - printf("*** ADD REGISTER DUMP HERE FOR DEBUGGING\n"); 83.18 -} 83.19 - 83.20 int is_kernel_text(unsigned long addr) 83.21 { 83.22 extern char _stext[], _etext[]; 83.23 @@ -236,7 +230,13 @@ void sys_exit(void) 83.24 83.25 void die_if_kernel(char *str, struct pt_regs *regs, long err) /* __attribute__ ((noreturn)) */ 83.26 { 83.27 - printk("die_if_kernel: called, not implemented\n"); 83.28 + if (user_mode(regs)) 83.29 + return; 83.30 + 83.31 + printk("%s: %s %ld\n", __func__, str, err); 83.32 + debugtrace_dump(); 83.33 + show_registers(regs); 83.34 + domain_crash_synchronous(); 83.35 } 83.36 83.37 long 83.38 @@ -320,18 +320,15 @@ if (!i--) { printk("+",id); i = 1000000; 83.39 ia64_set_iva(&ia64_ivt); 83.40 ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) | 83.41 VHPT_ENABLED); 83.42 - if (!is_idle_task(current->domain)) { 83.43 + if (!is_idle_domain(current->domain)) { 83.44 load_region_regs(current); 83.45 vcpu_load_kernel_regs(current); 83.46 if (vcpu_timer_expired(current)) vcpu_pend_timer(current); 83.47 } 83.48 if (vcpu_timer_expired(current)) vcpu_pend_timer(current); 83.49 } 83.50 -} 83.51 83.52 -void context_switch_finalise(struct vcpu *next) 83.53 -{ 83.54 - /* nothing to do */ 83.55 + context_saved(prev); 83.56 } 83.57 83.58 void continue_running(struct vcpu *same) 83.59 @@ -368,3 +365,23 @@ loop: 83.60 goto loop; 83.61 } 83.62 } 83.63 + 83.64 +/* FIXME: for the forseeable future, all cpu's that enable VTi have split 83.65 + * caches and all cpu's that have split caches enable VTi. This may 83.66 + * eventually be untrue though. */ 83.67 +#define cpu_has_split_cache vmx_enabled 83.68 +extern unsigned int vmx_enabled; 83.69 + 83.70 +void sync_split_caches(void) 83.71 +{ 83.72 + unsigned long ret, progress = 0; 83.73 + 83.74 + if (cpu_has_split_cache) { 83.75 + /* Sync d/i cache conservatively */ 83.76 + ret = ia64_pal_cache_flush(4, 0, &progress, NULL); 83.77 + if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED)) 83.78 + printk("PAL CACHE FLUSH failed\n"); 83.79 + else printk("Sync i/d cache for guest SUCC\n"); 83.80 + } 83.81 + else printk("sync_split_caches ignored for CPU with no split cache\n"); 83.82 +}
84.1 --- a/xen/arch/ia64/xen/xensetup.c Mon Jan 09 11:19:55 2006 +0000 84.2 +++ b/xen/arch/ia64/xen/xensetup.c Mon Jan 09 11:22:17 2006 +0000 84.3 @@ -26,7 +26,7 @@ unsigned long xenheap_phys_end; 84.4 84.5 char saved_command_line[COMMAND_LINE_SIZE]; 84.6 84.7 -struct vcpu *idle_task[NR_CPUS] = { &idle0_vcpu }; 84.8 +struct vcpu *idle_domain[NR_CPUS] = { &idle0_vcpu }; 84.9 84.10 cpumask_t cpu_present_map; 84.11 84.12 @@ -382,8 +382,7 @@ printk("About to call do_createdomain()\ 84.13 panic("Could not set up DOM0 guest OS\n"); 84.14 84.15 /* PIN domain0 on CPU 0. */ 84.16 - dom0->vcpu[0]->cpumap=1; 84.17 - set_bit(_VCPUF_cpu_pinned, &dom0->vcpu[0]->vcpu_flags); 84.18 + dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0); 84.19 84.20 #ifdef CLONE_DOMAIN0 84.21 {
85.1 --- a/xen/arch/ia64/xen/xentime.c Mon Jan 09 11:19:55 2006 +0000 85.2 +++ b/xen/arch/ia64/xen/xentime.c Mon Jan 09 11:22:17 2006 +0000 85.3 @@ -127,7 +127,7 @@ xen_timer_interrupt (int irq, void *dev_ 85.4 vcpu_wake(dom0->vcpu[0]); 85.5 } 85.6 } 85.7 - if (!is_idle_task(current->domain)) { 85.8 + if (!is_idle_domain(current->domain)) { 85.9 if (vcpu_timer_expired(current)) { 85.10 vcpu_pend_timer(current); 85.11 // ensure another timer interrupt happens even if domain doesn't
86.1 --- a/xen/arch/x86/Makefile Mon Jan 09 11:19:55 2006 +0000 86.2 +++ b/xen/arch/x86/Makefile Mon Jan 09 11:22:17 2006 +0000 86.3 @@ -29,6 +29,7 @@ ifeq ($(TARGET_SUBARCH),x86_32) 86.4 endif 86.5 86.6 OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS)) 86.7 +OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS)) 86.8 86.9 ifneq ($(crash_debug),y) 86.10 OBJS := $(patsubst cdb%.o,,$(OBJS)) 86.11 @@ -43,22 +44,25 @@ default: $(TARGET) 86.12 $(CURDIR)/arch.o: $(OBJS) 86.13 $(LD) $(LDFLAGS) -r -o $@ $(OBJS) 86.14 86.15 -$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(TARGET_SUBARCH)/xen.lds 86.16 - $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \ 86.17 +$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) xen.lds 86.18 + $(LD) $(LDFLAGS) -T xen.lds -N \ 86.19 boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $@ 86.20 $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S 86.21 $(MAKE) $(BASEDIR)/xen-syms.o 86.22 - $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \ 86.23 + $(LD) $(LDFLAGS) -T xen.lds -N \ 86.24 boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@ 86.25 $(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S 86.26 $(MAKE) $(BASEDIR)/xen-syms.o 86.27 - $(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \ 86.28 + $(LD) $(LDFLAGS) -T xen.lds -N \ 86.29 boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@ 86.30 rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o 86.31 86.32 asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS) 86.33 $(CC) $(CFLAGS) -S -o $@ $< 86.34 86.35 +xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(HDRS) 86.36 + $(CC) $(CFLAGS) -P -E -Ui386 -D__ASSEMBLY__ -o $@ $< 86.37 + 86.38 boot/mkelf32: boot/mkelf32.c 86.39 $(HOSTCC) $(HOSTCFLAGS) -o $@ $< 86.40 86.41 @@ -73,5 +77,6 @@ clean: 86.42 rm -f dm/*.o dm/*~ dm/core 86.43 rm -f genapic/*.o genapic/*~ genapic/core 86.44 rm -f cpu/*.o cpu/*~ cpu/core 86.45 + rm -f xen.lds 86.46 86.47 .PHONY: default clean
87.1 --- a/xen/arch/x86/boot/x86_32.S Mon Jan 09 11:19:55 2006 +0000 87.2 +++ b/xen/arch/x86/boot/x86_32.S Mon Jan 09 11:22:17 2006 +0000 87.3 @@ -1,5 +1,6 @@ 87.4 #include <xen/config.h> 87.5 #include <public/xen.h> 87.6 +#include <asm/asm_defns.h> 87.7 #include <asm/desc.h> 87.8 #include <asm/page.h> 87.9 #include <asm/msr.h> 87.10 @@ -53,6 +54,7 @@ 3: in %dx,%al 87.11 mov %ecx,%gs 87.12 ljmp $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET 87.13 1: lss stack_start-__PAGE_OFFSET,%esp 87.14 + add $(STACK_SIZE-CPUINFO_sizeof-__PAGE_OFFSET),%esp 87.15 87.16 /* Reset EFLAGS (subsumes CLI and CLD). */ 87.17 pushl $0 87.18 @@ -98,7 +100,7 @@ 1: mov %eax,__PAGE_OFFSET>>18(% 87.19 1: stosl /* low mappings cover as much physmem as possible */ 87.20 add $4,%edi 87.21 add $(1<<L2_PAGETABLE_SHIFT),%eax 87.22 - cmp $__HYPERVISOR_VIRT_START+0xe3,%eax 87.23 + cmp $HYPERVISOR_VIRT_START+0xe3,%eax 87.24 jne 1b 87.25 #else 87.26 /* Initialize low and high mappings of all memory with 4MB pages */ 87.27 @@ -111,7 +113,7 @@ 1: mov %eax,__PAGE_OFFSET>>20(% 87.28 jne 1b 87.29 1: stosl /* low mappings cover as much physmem as possible */ 87.30 add $(1<<L2_PAGETABLE_SHIFT),%eax 87.31 - cmp $__HYPERVISOR_VIRT_START+0xe3,%eax 87.32 + cmp $HYPERVISOR_VIRT_START+0xe3,%eax 87.33 jne 1b 87.34 #endif 87.35 87.36 @@ -189,7 +191,7 @@ 1: jmp 1b 87.37 /*** STACK LOCATION ***/ 87.38 87.39 ENTRY(stack_start) 87.40 - .long cpu0_stack + STACK_SIZE - 200 - __PAGE_OFFSET 87.41 + .long cpu0_stack 87.42 .long __HYPERVISOR_DS 87.43 87.44 /*** DESCRIPTOR TABLES ***/ 87.45 @@ -256,10 +258,6 @@ ENTRY(idle_pg_table_l2) 87.46 .fill 1*PAGE_SIZE,1,0 87.47 #endif 87.48 87.49 -#if (STACK_ORDER == 0) 87.50 -.section ".bss.page_aligned","w" 87.51 -#else 87.52 -.section ".bss.twopage_aligned","w" 87.53 -#endif 87.54 +.section ".bss.stack_aligned","w" 87.55 ENTRY(cpu0_stack) 87.56 .fill STACK_SIZE,1,0
88.1 --- a/xen/arch/x86/boot/x86_64.S Mon Jan 09 11:19:55 2006 +0000 88.2 +++ b/xen/arch/x86/boot/x86_64.S Mon Jan 09 11:22:17 2006 +0000 88.3 @@ -1,5 +1,6 @@ 88.4 #include <xen/config.h> 88.5 #include <public/xen.h> 88.6 +#include <asm/asm_defns.h> 88.7 #include <asm/desc.h> 88.8 #include <asm/page.h> 88.9 #include <asm/msr.h> 88.10 @@ -121,7 +122,8 @@ 1: /* Now in compatibility mode. Lo 88.11 mov %rcx,%cr4 88.12 88.13 mov stack_start(%rip),%rsp 88.14 - 88.15 + or $(STACK_SIZE-CPUINFO_sizeof),%rsp 88.16 + 88.17 /* Reset EFLAGS (subsumes CLI and CLD). */ 88.18 pushq $0 88.19 popf 88.20 @@ -140,7 +142,7 @@ 1: /* Now in compatibility mode. Lo 88.21 mov %ecx,%ss 88.22 88.23 lidt idt_descr(%rip) 88.24 - 88.25 + 88.26 cmp $(SECONDARY_CPU_FLAG),%ebx 88.27 je start_secondary 88.28 88.29 @@ -219,7 +221,7 @@ idt: 88.30 .quad idt_table 88.31 88.32 ENTRY(stack_start) 88.33 - .quad cpu0_stack + STACK_SIZE - 200 88.34 + .quad cpu0_stack 88.35 88.36 high_start: 88.37 .quad __high_start 88.38 @@ -265,10 +267,6 @@ ENTRY(idle_pg_table_l2) 88.39 .org 0x4000 + PAGE_SIZE 88.40 .code64 88.41 88.42 -#if (STACK_ORDER == 0) 88.43 -.section ".bss.page_aligned","w" 88.44 -#else 88.45 -.section ".bss.twopage_aligned","w" 88.46 -#endif 88.47 +.section ".bss.stack_aligned","w" 88.48 ENTRY(cpu0_stack) 88.49 .fill STACK_SIZE,1,0
89.1 --- a/xen/arch/x86/dm/i8259.c Mon Jan 09 11:19:55 2006 +0000 89.2 +++ b/xen/arch/x86/dm/i8259.c Mon Jan 09 11:22:17 2006 +0000 89.3 @@ -29,7 +29,7 @@ 89.4 #include <xen/lib.h> 89.5 #include <xen/errno.h> 89.6 #include <xen/sched.h> 89.7 -#include <public/io/ioreq.h> 89.8 +#include <public/hvm/ioreq.h> 89.9 #include <asm/vmx.h> 89.10 #include <asm/vmx_vpic.h> 89.11 #include <asm/current.h>
90.1 --- a/xen/arch/x86/dm/vmx_vioapic.c Mon Jan 09 11:19:55 2006 +0000 90.2 +++ b/xen/arch/x86/dm/vmx_vioapic.c Mon Jan 09 11:22:17 2006 +0000 90.3 @@ -37,7 +37,7 @@ 90.4 #include <xen/lib.h> 90.5 #include <xen/errno.h> 90.6 #include <xen/sched.h> 90.7 -#include <public/io/ioreq.h> 90.8 +#include <public/hvm/ioreq.h> 90.9 #include <asm/vmx.h> 90.10 #include <asm/vmx_vpic.h> 90.11 #include <asm/current.h>
91.1 --- a/xen/arch/x86/dom0_ops.c Mon Jan 09 11:19:55 2006 +0000 91.2 +++ b/xen/arch/x86/dom0_ops.c Mon Jan 09 11:22:17 2006 +0000 91.3 @@ -17,6 +17,7 @@ 91.4 #include <asm/msr.h> 91.5 #include <xen/trace.h> 91.6 #include <xen/console.h> 91.7 +#include <xen/iocap.h> 91.8 #include <asm/shadow.h> 91.9 #include <asm/irq.h> 91.10 #include <asm/processor.h> 91.11 @@ -35,13 +36,13 @@ static unsigned long msr_hi; 91.12 91.13 static void write_msr_for(void *unused) 91.14 { 91.15 - if ( ((1 << current->processor) & msr_cpu_mask) ) 91.16 + if ( ((1 << smp_processor_id()) & msr_cpu_mask) ) 91.17 (void)wrmsr_user(msr_addr, msr_lo, msr_hi); 91.18 } 91.19 91.20 static void read_msr_for(void *unused) 91.21 { 91.22 - if ( ((1 << current->processor) & msr_cpu_mask) ) 91.23 + if ( ((1 << smp_processor_id()) & msr_cpu_mask) ) 91.24 (void)rdmsr_user(msr_addr, msr_lo, msr_hi); 91.25 } 91.26 91.27 @@ -102,12 +103,27 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 91.28 op->u.add_memtype.nr_pfns, 91.29 op->u.add_memtype.type, 91.30 1); 91.31 + if (ret > 0) 91.32 + { 91.33 + (void)__put_user(0, &u_dom0_op->u.add_memtype.handle); 91.34 + (void)__put_user(ret, &u_dom0_op->u.add_memtype.reg); 91.35 + ret = 0; 91.36 + } 91.37 } 91.38 break; 91.39 91.40 case DOM0_DEL_MEMTYPE: 91.41 { 91.42 - ret = mtrr_del_page(op->u.del_memtype.reg, 0, 0); 91.43 + if (op->u.del_memtype.handle == 0 91.44 + /* mtrr/main.c otherwise does a lookup */ 91.45 + && (int)op->u.del_memtype.reg >= 0) 91.46 + { 91.47 + ret = mtrr_del_page(op->u.del_memtype.reg, 0, 0); 91.48 + if (ret > 0) 91.49 + ret = 0; 91.50 + } 91.51 + else 91.52 + ret = -EINVAL; 91.53 } 91.54 break; 91.55 91.56 @@ -141,7 +157,6 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 91.57 struct domain *d; 91.58 unsigned int fp = op->u.ioport_permission.first_port; 91.59 unsigned int np = op->u.ioport_permission.nr_ports; 91.60 - unsigned int p; 91.61 91.62 ret = -EINVAL; 91.63 if ( (fp + np) > 65536 ) 91.64 @@ -152,26 +167,12 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 91.65 op->u.ioport_permission.domain)) == NULL) ) 91.66 break; 91.67 91.68 - ret = -ENOMEM; 91.69 - if ( d->arch.iobmp_mask != NULL ) 91.70 - { 91.71 - if ( (d->arch.iobmp_mask = xmalloc_array( 91.72 - u8, IOBMP_BYTES)) == NULL ) 91.73 - { 91.74 - put_domain(d); 91.75 - break; 91.76 - } 91.77 - memset(d->arch.iobmp_mask, 0xFF, IOBMP_BYTES); 91.78 - } 91.79 - 91.80 - ret = 0; 91.81 - for ( p = fp; p < (fp + np); p++ ) 91.82 - { 91.83 - if ( op->u.ioport_permission.allow_access ) 91.84 - clear_bit(p, d->arch.iobmp_mask); 91.85 - else 91.86 - set_bit(p, d->arch.iobmp_mask); 91.87 - } 91.88 + if ( np == 0 ) 91.89 + ret = 0; 91.90 + else if ( op->u.ioport_permission.allow_access ) 91.91 + ret = ioports_permit_access(d, fp, fp + np - 1); 91.92 + else 91.93 + ret = ioports_deny_access(d, fp, fp + np - 1); 91.94 91.95 put_domain(d); 91.96 } 91.97 @@ -193,7 +194,7 @@ long arch_do_dom0_op(dom0_op_t *op, dom0 91.98 memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4); 91.99 ret = 0; 91.100 if ( copy_to_user(u_dom0_op, op, sizeof(*op)) ) 91.101 - ret = -EFAULT; 91.102 + ret = -EFAULT; 91.103 } 91.104 break; 91.105
92.1 --- a/xen/arch/x86/domain.c Mon Jan 09 11:19:55 2006 +0000 92.2 +++ b/xen/arch/x86/domain.c Mon Jan 09 11:22:17 2006 +0000 92.3 @@ -20,6 +20,7 @@ 92.4 #include <xen/delay.h> 92.5 #include <xen/softirq.h> 92.6 #include <xen/grant_table.h> 92.7 +#include <xen/iocap.h> 92.8 #include <asm/regs.h> 92.9 #include <asm/mc146818rtc.h> 92.10 #include <asm/system.h> 92.11 @@ -35,9 +36,7 @@ 92.12 #include <xen/console.h> 92.13 #include <xen/elf.h> 92.14 #include <asm/vmx.h> 92.15 -#include <asm/vmx_vmcs.h> 92.16 #include <asm/msr.h> 92.17 -#include <asm/physdev.h> 92.18 #include <xen/kernel.h> 92.19 #include <xen/multicall.h> 92.20 92.21 @@ -47,17 +46,16 @@ boolean_param("noreboot", opt_noreboot); 92.22 92.23 struct percpu_ctxt { 92.24 struct vcpu *curr_vcpu; 92.25 - unsigned int context_not_finalised; 92.26 unsigned int dirty_segment_mask; 92.27 } __cacheline_aligned; 92.28 static struct percpu_ctxt percpu_ctxt[NR_CPUS]; 92.29 92.30 -static void continue_idle_task(struct vcpu *v) 92.31 +static void continue_idle_domain(struct vcpu *v) 92.32 { 92.33 reset_stack_and_jump(idle_loop); 92.34 } 92.35 92.36 -static void continue_nonidle_task(struct vcpu *v) 92.37 +static void continue_nonidle_domain(struct vcpu *v) 92.38 { 92.39 reset_stack_and_jump(ret_from_intr); 92.40 } 92.41 @@ -93,12 +91,13 @@ void startup_cpu_idle_loop(void) 92.42 { 92.43 struct vcpu *v = current; 92.44 92.45 - ASSERT(is_idle_task(v->domain)); 92.46 + ASSERT(is_idle_domain(v->domain)); 92.47 percpu_ctxt[smp_processor_id()].curr_vcpu = v; 92.48 - cpu_set(smp_processor_id(), v->domain->cpumask); 92.49 - v->arch.schedule_tail = continue_idle_task; 92.50 + cpu_set(smp_processor_id(), v->domain->domain_dirty_cpumask); 92.51 + cpu_set(smp_processor_id(), v->vcpu_dirty_cpumask); 92.52 + v->arch.schedule_tail = continue_idle_domain; 92.53 92.54 - idle_loop(); 92.55 + reset_stack_and_jump(idle_loop); 92.56 } 92.57 92.58 static long no_idt[2]; 92.59 @@ -185,11 +184,17 @@ void dump_pageframe_info(struct domain * 92.60 { 92.61 struct pfn_info *page; 92.62 92.63 - if ( d->tot_pages < 10 ) 92.64 + printk("Memory pages belonging to domain %u:\n", d->domain_id); 92.65 + 92.66 + if ( d->tot_pages >= 10 ) 92.67 + { 92.68 + printk(" DomPage list too long to display\n"); 92.69 + } 92.70 + else 92.71 { 92.72 list_for_each_entry ( page, &d->page_list, list ) 92.73 { 92.74 - printk("Page %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n", 92.75 + printk(" DomPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n", 92.76 _p(page_to_phys(page)), _p(page_to_pfn(page)), 92.77 page->count_info, page->u.inuse.type_info); 92.78 } 92.79 @@ -197,15 +202,10 @@ void dump_pageframe_info(struct domain * 92.80 92.81 list_for_each_entry ( page, &d->xenpage_list, list ) 92.82 { 92.83 - printk("XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n", 92.84 + printk(" XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n", 92.85 _p(page_to_phys(page)), _p(page_to_pfn(page)), 92.86 page->count_info, page->u.inuse.type_info); 92.87 } 92.88 - 92.89 - page = virt_to_page(d->shared_info); 92.90 - printk("Shared_info@%p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n", 92.91 - _p(page_to_phys(page)), _p(page_to_pfn(page)), page->count_info, 92.92 - page->u.inuse.type_info); 92.93 } 92.94 92.95 struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id) 92.96 @@ -250,24 +250,36 @@ void free_perdomain_pt(struct domain *d) 92.97 #endif 92.98 } 92.99 92.100 -void arch_do_createdomain(struct vcpu *v) 92.101 +int arch_do_createdomain(struct vcpu *v) 92.102 { 92.103 struct domain *d = v->domain; 92.104 l1_pgentry_t gdt_l1e; 92.105 - int vcpuid, pdpt_order; 92.106 + int vcpuid, pdpt_order, rc; 92.107 #ifdef __x86_64__ 92.108 int i; 92.109 #endif 92.110 92.111 - if ( is_idle_task(d) ) 92.112 - return; 92.113 + if ( is_idle_domain(d) ) 92.114 + return 0; 92.115 + 92.116 + d->arch.ioport_caps = 92.117 + rangeset_new(d, "I/O Ports", RANGESETF_prettyprint_hex); 92.118 + if ( d->arch.ioport_caps == NULL ) 92.119 + return -ENOMEM; 92.120 92.121 - v->arch.schedule_tail = continue_nonidle_task; 92.122 + if ( (d->shared_info = alloc_xenheap_page()) == NULL ) 92.123 + return -ENOMEM; 92.124 92.125 - d->shared_info = alloc_xenheap_page(); 92.126 + if ( (rc = ptwr_init(d)) != 0 ) 92.127 + { 92.128 + free_xenheap_page(d->shared_info); 92.129 + return rc; 92.130 + } 92.131 + 92.132 + v->arch.schedule_tail = continue_nonidle_domain; 92.133 + 92.134 memset(d->shared_info, 0, PAGE_SIZE); 92.135 v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id]; 92.136 - v->cpumap = CPUMAP_RUNANYWHERE; 92.137 SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d); 92.138 92.139 pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t)); 92.140 @@ -308,25 +320,10 @@ void arch_do_createdomain(struct vcpu *v 92.141 __PAGE_HYPERVISOR); 92.142 #endif 92.143 92.144 - (void)ptwr_init(d); 92.145 - 92.146 shadow_lock_init(d); 92.147 INIT_LIST_HEAD(&d->arch.free_shadow_frames); 92.148 -} 92.149 92.150 -void vcpu_migrate_cpu(struct vcpu *v, int newcpu) 92.151 -{ 92.152 - if ( v->processor == newcpu ) 92.153 - return; 92.154 - 92.155 - set_bit(_VCPUF_cpu_migrated, &v->vcpu_flags); 92.156 - v->processor = newcpu; 92.157 - 92.158 - if ( VMX_DOMAIN(v) ) 92.159 - { 92.160 - __vmpclear(virt_to_phys(v->arch.arch_vmx.vmcs)); 92.161 - v->arch.schedule_tail = arch_vmx_do_relaunch; 92.162 - } 92.163 + return 0; 92.164 } 92.165 92.166 /* This is called by arch_final_setup_guest and do_boot_vcpu */ 92.167 @@ -348,6 +345,8 @@ int arch_set_info_guest( 92.168 ((c->user_regs.ss & 3) == 0) ) 92.169 return -EINVAL; 92.170 } 92.171 + else if ( !hvm_enabled ) 92.172 + return -EINVAL; 92.173 92.174 clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags); 92.175 if ( c->flags & VGCF_I387_VALID ) 92.176 @@ -690,7 +689,7 @@ static void __context_switch(void) 92.177 struct vcpu *p = percpu_ctxt[cpu].curr_vcpu; 92.178 struct vcpu *n = current; 92.179 92.180 - if ( !is_idle_task(p->domain) ) 92.181 + if ( !is_idle_domain(p->domain) ) 92.182 { 92.183 memcpy(&p->arch.guest_context.user_regs, 92.184 stack_regs, 92.185 @@ -699,7 +698,7 @@ static void __context_switch(void) 92.186 save_segments(p); 92.187 } 92.188 92.189 - if ( !is_idle_task(n->domain) ) 92.190 + if ( !is_idle_domain(n->domain) ) 92.191 { 92.192 memcpy(stack_regs, 92.193 &n->arch.guest_context.user_regs, 92.194 @@ -725,7 +724,8 @@ static void __context_switch(void) 92.195 } 92.196 92.197 if ( p->domain != n->domain ) 92.198 - cpu_set(cpu, n->domain->cpumask); 92.199 + cpu_set(cpu, n->domain->domain_dirty_cpumask); 92.200 + cpu_set(cpu, n->vcpu_dirty_cpumask); 92.201 92.202 write_ptbase(n); 92.203 92.204 @@ -738,7 +738,8 @@ static void __context_switch(void) 92.205 } 92.206 92.207 if ( p->domain != n->domain ) 92.208 - cpu_clear(cpu, p->domain->cpumask); 92.209 + cpu_clear(cpu, p->domain->domain_dirty_cpumask); 92.210 + cpu_clear(cpu, p->vcpu_dirty_cpumask); 92.211 92.212 percpu_ctxt[cpu].curr_vcpu = n; 92.213 } 92.214 @@ -748,28 +749,24 @@ void context_switch(struct vcpu *prev, s 92.215 { 92.216 unsigned int cpu = smp_processor_id(); 92.217 92.218 - ASSERT(!local_irq_is_enabled()); 92.219 + ASSERT(local_irq_is_enabled()); 92.220 92.221 set_current(next); 92.222 92.223 - if ( (percpu_ctxt[cpu].curr_vcpu != next) && !is_idle_task(next->domain) ) 92.224 + if ( (percpu_ctxt[cpu].curr_vcpu != next) && 92.225 + !is_idle_domain(next->domain) ) 92.226 { 92.227 - __context_switch(); 92.228 - percpu_ctxt[cpu].context_not_finalised = 1; 92.229 - } 92.230 -} 92.231 + /* This may happen if next has been migrated by the scheduler. */ 92.232 + if ( unlikely(!cpus_empty(next->vcpu_dirty_cpumask)) ) 92.233 + { 92.234 + ASSERT(!cpu_isset(cpu, next->vcpu_dirty_cpumask)); 92.235 + sync_vcpu_execstate(next); 92.236 + ASSERT(cpus_empty(next->vcpu_dirty_cpumask)); 92.237 + } 92.238 92.239 -void context_switch_finalise(struct vcpu *next) 92.240 -{ 92.241 - unsigned int cpu = smp_processor_id(); 92.242 - 92.243 - ASSERT(local_irq_is_enabled()); 92.244 - 92.245 - if ( percpu_ctxt[cpu].context_not_finalised ) 92.246 - { 92.247 - percpu_ctxt[cpu].context_not_finalised = 0; 92.248 - 92.249 - BUG_ON(percpu_ctxt[cpu].curr_vcpu != next); 92.250 + local_irq_disable(); 92.251 + __context_switch(); 92.252 + local_irq_enable(); 92.253 92.254 if ( VMX_DOMAIN(next) ) 92.255 { 92.256 @@ -783,6 +780,8 @@ void context_switch_finalise(struct vcpu 92.257 } 92.258 } 92.259 92.260 + context_saved(prev); 92.261 + 92.262 schedule_tail(next); 92.263 BUG(); 92.264 } 92.265 @@ -812,20 +811,11 @@ int __sync_lazy_execstate(void) 92.266 92.267 void sync_vcpu_execstate(struct vcpu *v) 92.268 { 92.269 - unsigned int cpu = v->processor; 92.270 - 92.271 - if ( !cpu_isset(cpu, v->domain->cpumask) ) 92.272 - return; 92.273 + if ( cpu_isset(smp_processor_id(), v->vcpu_dirty_cpumask) ) 92.274 + (void)__sync_lazy_execstate(); 92.275 92.276 - if ( cpu == smp_processor_id() ) 92.277 - { 92.278 - (void)__sync_lazy_execstate(); 92.279 - } 92.280 - else 92.281 - { 92.282 - /* Other cpus call __sync_lazy_execstate from flush ipi handler. */ 92.283 - flush_tlb_mask(cpumask_of_cpu(cpu)); 92.284 - } 92.285 + /* Other cpus call __sync_lazy_execstate from flush ipi handler. */ 92.286 + flush_tlb_mask(v->vcpu_dirty_cpumask); 92.287 } 92.288 92.289 unsigned long __hypercall_create_continuation( 92.290 @@ -951,9 +941,7 @@ void domain_relinquish_resources(struct 92.291 struct vcpu *v; 92.292 unsigned long pfn; 92.293 92.294 - BUG_ON(!cpus_empty(d->cpumask)); 92.295 - 92.296 - physdev_destroy_state(d); 92.297 + BUG_ON(!cpus_empty(d->domain_dirty_cpumask)); 92.298 92.299 ptwr_destroy(d); 92.300
93.1 --- a/xen/arch/x86/domain_build.c Mon Jan 09 11:19:55 2006 +0000 93.2 +++ b/xen/arch/x86/domain_build.c Mon Jan 09 11:22:17 2006 +0000 93.3 @@ -16,13 +16,13 @@ 93.4 #include <xen/kernel.h> 93.5 #include <xen/domain.h> 93.6 #include <xen/compile.h> 93.7 +#include <xen/iocap.h> 93.8 #include <asm/regs.h> 93.9 #include <asm/system.h> 93.10 #include <asm/io.h> 93.11 #include <asm/processor.h> 93.12 #include <asm/desc.h> 93.13 #include <asm/i387.h> 93.14 -#include <asm/physdev.h> 93.15 #include <asm/shadow.h> 93.16 93.17 static long dom0_nrpages; 93.18 @@ -94,9 +94,9 @@ static struct pfn_info *alloc_chunk(stru 93.19 return page; 93.20 } 93.21 93.22 -static void process_dom0_ioports_disable() 93.23 +static void process_dom0_ioports_disable(void) 93.24 { 93.25 - unsigned long io_from, io_to, io_nr; 93.26 + unsigned long io_from, io_to; 93.27 char *t, *u, *s = opt_dom0_ioports_disable; 93.28 93.29 if ( *s == '\0' ) 93.30 @@ -126,8 +126,8 @@ static void process_dom0_ioports_disable 93.31 printk("Disabling dom0 access to ioport range %04lx-%04lx\n", 93.32 io_from, io_to); 93.33 93.34 - io_nr = io_to - io_from + 1; 93.35 - physdev_modify_ioport_access_range(dom0, 0, io_from, io_nr); 93.36 + if ( ioports_deny_access(dom0, io_from, io_to) != 0 ) 93.37 + BUG(); 93.38 } 93.39 } 93.40 93.41 @@ -183,7 +183,6 @@ int construct_dom0(struct domain *d, 93.42 /* Machine address of next candidate page-table page. */ 93.43 unsigned long mpt_alloc; 93.44 93.45 - extern void physdev_init_dom0(struct domain *); 93.46 extern void translate_l2pgtable( 93.47 struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn); 93.48 93.49 @@ -692,9 +691,6 @@ int construct_dom0(struct domain *d, 93.50 zap_low_mappings(l2start); 93.51 zap_low_mappings(idle_pg_table_l2); 93.52 #endif 93.53 - 93.54 - /* DOM0 gets access to everything. */ 93.55 - physdev_init_dom0(d); 93.56 93.57 init_domain_time(d); 93.58 93.59 @@ -746,20 +742,29 @@ int construct_dom0(struct domain *d, 93.60 printk("dom0: shadow setup done\n"); 93.61 } 93.62 93.63 + i = 0; 93.64 + 93.65 + /* DOM0 is permitted full I/O capabilities. */ 93.66 + i |= ioports_permit_access(dom0, 0, 0xFFFF); 93.67 + i |= iomem_permit_access(dom0, 0UL, ~0UL); 93.68 + i |= irqs_permit_access(dom0, 0, NR_PIRQS-1); 93.69 + 93.70 /* 93.71 * Modify I/O port access permissions. 93.72 */ 93.73 /* Master Interrupt Controller (PIC). */ 93.74 - physdev_modify_ioport_access_range(dom0, 0, 0x20, 2); 93.75 + i |= ioports_deny_access(dom0, 0x20, 0x21); 93.76 /* Slave Interrupt Controller (PIC). */ 93.77 - physdev_modify_ioport_access_range(dom0, 0, 0xA0, 2); 93.78 + i |= ioports_deny_access(dom0, 0xA0, 0xA1); 93.79 /* Interval Timer (PIT). */ 93.80 - physdev_modify_ioport_access_range(dom0, 0, 0x40, 4); 93.81 + i |= ioports_deny_access(dom0, 0x40, 0x43); 93.82 /* PIT Channel 2 / PC Speaker Control. */ 93.83 - physdev_modify_ioport_access_range(dom0, 0, 0x61, 1); 93.84 - /* Command-line passed i/o ranges */ 93.85 + i |= ioports_deny_access(dom0, 0x61, 0x61); 93.86 + /* Command-line I/O ranges. */ 93.87 process_dom0_ioports_disable(); 93.88 93.89 + BUG_ON(i != 0); 93.90 + 93.91 return 0; 93.92 } 93.93
94.1 --- a/xen/arch/x86/idle0_task.c Mon Jan 09 11:19:55 2006 +0000 94.2 +++ b/xen/arch/x86/idle0_task.c Mon Jan 09 11:22:17 2006 +0000 94.3 @@ -11,6 +11,7 @@ struct domain idle0_domain = { 94.4 94.5 struct vcpu idle0_vcpu = { 94.6 processor: 0, 94.7 + cpu_affinity:CPU_MASK_CPU0, 94.8 domain: &idle0_domain 94.9 }; 94.10
95.1 --- a/xen/arch/x86/io_apic.c Mon Jan 09 11:19:55 2006 +0000 95.2 +++ b/xen/arch/x86/io_apic.c Mon Jan 09 11:22:17 2006 +0000 95.3 @@ -1807,3 +1807,47 @@ int ioapic_guest_write(int apicid, int a 95.4 95.5 return 0; 95.6 } 95.7 + 95.8 +void dump_ioapic_irq_info(void) 95.9 +{ 95.10 + struct irq_pin_list *entry; 95.11 + struct IO_APIC_route_entry rte; 95.12 + unsigned int irq, pin, printed = 0; 95.13 + unsigned long flags; 95.14 + 95.15 + for ( irq = 0; irq < NR_IRQS; irq++ ) 95.16 + { 95.17 + entry = &irq_2_pin[irq]; 95.18 + if ( entry->pin == -1 ) 95.19 + continue; 95.20 + 95.21 + if ( !printed++ ) 95.22 + printk("IO-APIC interrupt information:\n"); 95.23 + 95.24 + printk(" IRQ%3d Vec%3d:\n", irq, irq_to_vector(irq)); 95.25 + 95.26 + for ( ; ; ) 95.27 + { 95.28 + pin = entry->pin; 95.29 + 95.30 + printk(" Apic 0x%02x, Pin %2d: ", entry->apic, pin); 95.31 + 95.32 + spin_lock_irqsave(&ioapic_lock, flags); 95.33 + *(((int *)&rte) + 0) = io_apic_read(entry->apic, 0x10 + 2 * pin); 95.34 + *(((int *)&rte) + 1) = io_apic_read(entry->apic, 0x11 + 2 * pin); 95.35 + spin_unlock_irqrestore(&ioapic_lock, flags); 95.36 + 95.37 + printk("vector=%u, delivery_mode=%u, dest_mode=%s, " 95.38 + "delivery_status=%d, polarity=%d, irr=%d, " 95.39 + "trigger=%s, mask=%d\n", 95.40 + rte.vector, rte.delivery_mode, 95.41 + rte.dest_mode ? "logical" : "physical", 95.42 + rte.delivery_status, rte.polarity, rte.irr, 95.43 + rte.trigger ? "level" : "edge", rte.mask); 95.44 + 95.45 + if ( entry->next == 0 ) 95.46 + break; 95.47 + entry = &irq_2_pin[entry->next]; 95.48 + } 95.49 + } 95.50 +}
96.1 --- a/xen/arch/x86/irq.c Mon Jan 09 11:19:55 2006 +0000 96.2 +++ b/xen/arch/x86/irq.c Mon Jan 09 11:22:17 2006 +0000 96.3 @@ -12,6 +12,7 @@ 96.4 #include <xen/irq.h> 96.5 #include <xen/perfc.h> 96.6 #include <xen/sched.h> 96.7 +#include <xen/keyhandler.h> 96.8 #include <asm/current.h> 96.9 #include <asm/smpboot.h> 96.10 96.11 @@ -198,19 +199,21 @@ int pirq_guest_unmask(struct domain *d) 96.12 96.13 int pirq_guest_bind(struct vcpu *v, int irq, int will_share) 96.14 { 96.15 - unsigned int vector = irq_to_vector(irq); 96.16 - struct domain *d = v->domain; 96.17 - irq_desc_t *desc = &irq_desc[vector]; 96.18 + unsigned int vector; 96.19 + irq_desc_t *desc; 96.20 irq_guest_action_t *action; 96.21 unsigned long flags; 96.22 int rc = 0; 96.23 cpumask_t cpumask = CPU_MASK_NONE; 96.24 96.25 - if ( !IS_CAPABLE_PHYSDEV(d) ) 96.26 - return -EPERM; 96.27 + if ( (irq < 0) || (irq >= NR_IRQS) ) 96.28 + return -EINVAL; 96.29 96.30 + vector = irq_to_vector(irq); 96.31 if ( vector == 0 ) 96.32 - return -EBUSY; 96.33 + return -EINVAL; 96.34 + 96.35 + desc = &irq_desc[vector]; 96.36 96.37 spin_lock_irqsave(&desc->lock, flags); 96.38 96.39 @@ -309,3 +312,71 @@ int pirq_guest_unbind(struct domain *d, 96.40 spin_unlock_irqrestore(&desc->lock, flags); 96.41 return 0; 96.42 } 96.43 + 96.44 +extern void dump_ioapic_irq_info(void); 96.45 + 96.46 +static void dump_irqs(unsigned char key) 96.47 +{ 96.48 + int i, irq, vector; 96.49 + irq_desc_t *desc; 96.50 + irq_guest_action_t *action; 96.51 + struct domain *d; 96.52 + unsigned long flags; 96.53 + 96.54 + printk("Guest interrupt information:\n"); 96.55 + 96.56 + for ( irq = 0; irq < NR_IRQS; irq++ ) 96.57 + { 96.58 + vector = irq_to_vector(irq); 96.59 + if ( vector == 0 ) 96.60 + continue; 96.61 + 96.62 + desc = &irq_desc[vector]; 96.63 + 96.64 + spin_lock_irqsave(&desc->lock, flags); 96.65 + 96.66 + if ( desc->status & IRQ_GUEST ) 96.67 + { 96.68 + action = (irq_guest_action_t *)desc->action; 96.69 + 96.70 + printk(" IRQ%3d Vec%3d: type=%-15s status=%08x " 96.71 + "in-flight=%d domain-list=", 96.72 + irq, vector, desc->handler->typename, 96.73 + desc->status, action->in_flight); 96.74 + 96.75 + for ( i = 0; i < action->nr_guests; i++ ) 96.76 + { 96.77 + d = action->guest[i]; 96.78 + printk("%u(%c%c%c%c)", 96.79 + d->domain_id, 96.80 + (test_bit(d->pirq_to_evtchn[irq], 96.81 + &d->shared_info->evtchn_pending[0]) ? 96.82 + 'P' : '-'), 96.83 + (test_bit(d->pirq_to_evtchn[irq]/BITS_PER_LONG, 96.84 + &d->shared_info->vcpu_info[0]. 96.85 + evtchn_pending_sel) ? 96.86 + 'S' : '-'), 96.87 + (test_bit(d->pirq_to_evtchn[irq], 96.88 + &d->shared_info->evtchn_mask[0]) ? 96.89 + 'M' : '-'), 96.90 + (test_bit(irq, &d->pirq_mask) ? 96.91 + 'M' : '-')); 96.92 + if ( i != action->nr_guests ) 96.93 + printk(","); 96.94 + } 96.95 + 96.96 + printk("\n"); 96.97 + } 96.98 + 96.99 + spin_unlock_irqrestore(&desc->lock, flags); 96.100 + } 96.101 + 96.102 + dump_ioapic_irq_info(); 96.103 +} 96.104 + 96.105 +static int __init setup_dump_irqs(void) 96.106 +{ 96.107 + register_keyhandler('i', dump_irqs, "dump interrupt bindings"); 96.108 + return 0; 96.109 +} 96.110 +__initcall(setup_dump_irqs);
97.1 --- a/xen/arch/x86/mm.c Mon Jan 09 11:19:55 2006 +0000 97.2 +++ b/xen/arch/x86/mm.c Mon Jan 09 11:22:17 2006 +0000 97.3 @@ -96,6 +96,7 @@ 97.4 #include <xen/softirq.h> 97.5 #include <xen/domain_page.h> 97.6 #include <xen/event.h> 97.7 +#include <xen/iocap.h> 97.8 #include <asm/shadow.h> 97.9 #include <asm/page.h> 97.10 #include <asm/flushtlb.h> 97.11 @@ -437,7 +438,6 @@ get_page_from_l1e( 97.12 unsigned long mfn = l1e_get_pfn(l1e); 97.13 struct pfn_info *page = pfn_to_page(mfn); 97.14 int okay; 97.15 - extern int domain_iomem_in_pfn(struct domain *d, unsigned long pfn); 97.16 97.17 if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) ) 97.18 return 1; 97.19 @@ -455,8 +455,7 @@ get_page_from_l1e( 97.20 if ( d == dom_io ) 97.21 d = current->domain; 97.22 97.23 - if ( (!IS_PRIV(d)) && 97.24 - (!IS_CAPABLE_PHYSDEV(d) || !domain_iomem_in_pfn(d, mfn)) ) 97.25 + if ( !iomem_access_permitted(d, mfn, mfn) ) 97.26 { 97.27 MEM_LOG("Non-privileged attempt to map I/O space %08lx", mfn); 97.28 return 0; 97.29 @@ -1458,7 +1457,8 @@ int get_page_type(struct pfn_info *page, 97.30 * was GDT/LDT) but those circumstances should be 97.31 * very rare. 97.32 */ 97.33 - cpumask_t mask = page_get_owner(page)->cpumask; 97.34 + cpumask_t mask = 97.35 + page_get_owner(page)->domain_dirty_cpumask; 97.36 tlbflush_filter(mask, page->tlbflush_timestamp); 97.37 97.38 if ( unlikely(!cpus_empty(mask)) ) 97.39 @@ -1620,7 +1620,7 @@ static void process_deferred_ops(unsigne 97.40 if ( shadow_mode_enabled(d) ) 97.41 shadow_sync_all(d); 97.42 if ( deferred_ops & DOP_FLUSH_ALL_TLBS ) 97.43 - flush_tlb_mask(d->cpumask); 97.44 + flush_tlb_mask(d->domain_dirty_cpumask); 97.45 else 97.46 local_flush_tlb(); 97.47 } 97.48 @@ -1692,7 +1692,7 @@ static inline cpumask_t vcpumask_to_pcpu 97.49 struct domain *d, unsigned long vmask) 97.50 { 97.51 unsigned int vcpu_id; 97.52 - cpumask_t pmask; 97.53 + cpumask_t pmask = CPU_MASK_NONE; 97.54 struct vcpu *v; 97.55 97.56 while ( vmask != 0 ) 97.57 @@ -1701,7 +1701,7 @@ static inline cpumask_t vcpumask_to_pcpu 97.58 vmask &= ~(1UL << vcpu_id); 97.59 if ( (vcpu_id < MAX_VIRT_CPUS) && 97.60 ((v = d->vcpu[vcpu_id]) != NULL) ) 97.61 - cpu_set(v->processor, pmask); 97.62 + cpus_or(pmask, pmask, v->vcpu_dirty_cpumask); 97.63 } 97.64 97.65 return pmask; 97.66 @@ -1870,7 +1870,6 @@ int do_mmuext_op( 97.67 break; 97.68 } 97.69 pmask = vcpumask_to_pcpumask(d, vmask); 97.70 - cpus_and(pmask, pmask, d->cpumask); 97.71 if ( op.cmd == MMUEXT_TLB_FLUSH_MULTI ) 97.72 flush_tlb_mask(pmask); 97.73 else 97.74 @@ -1879,15 +1878,15 @@ int do_mmuext_op( 97.75 } 97.76 97.77 case MMUEXT_TLB_FLUSH_ALL: 97.78 - flush_tlb_mask(d->cpumask); 97.79 + flush_tlb_mask(d->domain_dirty_cpumask); 97.80 break; 97.81 97.82 case MMUEXT_INVLPG_ALL: 97.83 - flush_tlb_one_mask(d->cpumask, op.arg1.linear_addr); 97.84 + flush_tlb_one_mask(d->domain_dirty_cpumask, op.arg1.linear_addr); 97.85 break; 97.86 97.87 case MMUEXT_FLUSH_CACHE: 97.88 - if ( unlikely(!IS_CAPABLE_PHYSDEV(d)) ) 97.89 + if ( unlikely(!cache_flush_permitted(d)) ) 97.90 { 97.91 MEM_LOG("Non-physdev domain tried to FLUSH_CACHE."); 97.92 okay = 0; 97.93 @@ -2498,7 +2497,7 @@ int do_update_va_mapping(unsigned long v 97.94 l1_pgentry_t val = l1e_from_intpte(val64); 97.95 struct vcpu *v = current; 97.96 struct domain *d = v->domain; 97.97 - unsigned int cpu = v->processor; 97.98 + unsigned int cpu = smp_processor_id(); 97.99 unsigned long vmask, bmap_ptr; 97.100 cpumask_t pmask; 97.101 int rc = 0; 97.102 @@ -2549,13 +2548,12 @@ int do_update_va_mapping(unsigned long v 97.103 local_flush_tlb(); 97.104 break; 97.105 case UVMF_ALL: 97.106 - flush_tlb_mask(d->cpumask); 97.107 + flush_tlb_mask(d->domain_dirty_cpumask); 97.108 break; 97.109 default: 97.110 if ( unlikely(get_user(vmask, (unsigned long *)bmap_ptr)) ) 97.111 rc = -EFAULT; 97.112 pmask = vcpumask_to_pcpumask(d, vmask); 97.113 - cpus_and(pmask, pmask, d->cpumask); 97.114 flush_tlb_mask(pmask); 97.115 break; 97.116 } 97.117 @@ -2570,13 +2568,12 @@ int do_update_va_mapping(unsigned long v 97.118 local_flush_tlb_one(va); 97.119 break; 97.120 case UVMF_ALL: 97.121 - flush_tlb_one_mask(d->cpumask, va); 97.122 + flush_tlb_one_mask(d->domain_dirty_cpumask, va); 97.123 break; 97.124 default: 97.125 if ( unlikely(get_user(vmask, (unsigned long *)bmap_ptr)) ) 97.126 rc = -EFAULT; 97.127 pmask = vcpumask_to_pcpumask(d, vmask); 97.128 - cpus_and(pmask, pmask, d->cpumask); 97.129 flush_tlb_one_mask(pmask, va); 97.130 break; 97.131 } 97.132 @@ -3019,7 +3016,7 @@ void ptwr_flush(struct domain *d, const 97.133 97.134 /* Ensure that there are no stale writable mappings in any TLB. */ 97.135 /* NB. INVLPG is a serialising instruction: flushes pending updates. */ 97.136 - flush_tlb_one_mask(d->cpumask, l1va); 97.137 + flush_tlb_one_mask(d->domain_dirty_cpumask, l1va); 97.138 PTWR_PRINTK("[%c] disconnected_l1va at %p now %"PRIpte"\n", 97.139 PTWR_PRINT_WHICH, ptep, pte.l1); 97.140 97.141 @@ -3343,7 +3340,7 @@ int ptwr_do_page_fault(struct domain *d, 97.142 if ( which == PTWR_PT_ACTIVE ) 97.143 { 97.144 l2e_remove_flags(*pl2e, _PAGE_PRESENT); 97.145 - flush_tlb_mask(d->cpumask); 97.146 + flush_tlb_mask(d->domain_dirty_cpumask); 97.147 } 97.148 97.149 /* Temporarily map the L1 page, and make a copy of it. */ 97.150 @@ -3370,7 +3367,7 @@ int ptwr_do_page_fault(struct domain *d, 97.151 97.152 emulate: 97.153 if ( x86_emulate_memop(guest_cpu_user_regs(), addr, 97.154 - &ptwr_mem_emulator, BITS_PER_LONG/8) ) 97.155 + &ptwr_mem_emulator, X86EMUL_MODE_HOST) ) 97.156 return 0; 97.157 perfc_incrc(ptwr_emulations); 97.158 return EXCRET_fault_fixed;
98.1 --- a/xen/arch/x86/physdev.c Mon Jan 09 11:19:55 2006 +0000 98.2 +++ b/xen/arch/x86/physdev.c Mon Jan 09 11:22:17 2006 +0000 98.3 @@ -14,27 +14,6 @@ 98.4 extern int ioapic_guest_read(int apicid, int address, u32 *pval); 98.5 extern int ioapic_guest_write(int apicid, int address, u32 pval); 98.6 98.7 -void physdev_modify_ioport_access_range( 98.8 - struct domain *d, int enable, int port, int num) 98.9 -{ 98.10 - int i; 98.11 - for ( i = port; i < (port + num); i++ ) 98.12 - (enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask); 98.13 -} 98.14 - 98.15 -void physdev_destroy_state(struct domain *d) 98.16 -{ 98.17 - xfree(d->arch.iobmp_mask); 98.18 - d->arch.iobmp_mask = NULL; 98.19 -} 98.20 - 98.21 -/* Check if a domain controls a device with IO memory within frame @pfn. 98.22 - * Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise. */ 98.23 -int domain_iomem_in_pfn(struct domain *p, unsigned long pfn) 98.24 -{ 98.25 - return 0; 98.26 -} 98.27 - 98.28 /* 98.29 * Demuxing hypercall. 98.30 */ 98.31 @@ -120,18 +99,6 @@ long do_physdev_op(physdev_op_t *uop) 98.32 return ret; 98.33 } 98.34 98.35 -/* Domain 0 has read access to all devices. */ 98.36 -void physdev_init_dom0(struct domain *d) 98.37 -{ 98.38 - /* Access to all I/O ports. */ 98.39 - d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES); 98.40 - BUG_ON(d->arch.iobmp_mask == NULL); 98.41 - memset(d->arch.iobmp_mask, 0, IOBMP_BYTES); 98.42 - 98.43 - set_bit(_DOMF_physdev_access, &d->domain_flags); 98.44 -} 98.45 - 98.46 - 98.47 /* 98.48 * Local variables: 98.49 * mode: C
99.1 --- a/xen/arch/x86/setup.c Mon Jan 09 11:19:55 2006 +0000 99.2 +++ b/xen/arch/x86/setup.c Mon Jan 09 11:22:17 2006 +0000 99.3 @@ -92,7 +92,7 @@ unsigned long mmu_cr4_features = X86_CR4 99.4 #endif 99.5 EXPORT_SYMBOL(mmu_cr4_features); 99.6 99.7 -struct vcpu *idle_task[NR_CPUS] = { &idle0_vcpu }; 99.8 +struct vcpu *idle_domain[NR_CPUS] = { &idle0_vcpu }; 99.9 99.10 int acpi_disabled; 99.11 99.12 @@ -138,131 +138,19 @@ static void __init do_initcalls(void) 99.13 (*call)(); 99.14 } 99.15 99.16 -static void __init start_of_day(void) 99.17 -{ 99.18 - int i; 99.19 - unsigned long vgdt, gdt_pfn; 99.20 - 99.21 - early_cpu_init(); 99.22 - 99.23 - paging_init(); 99.24 - 99.25 - /* Unmap the first page of CPU0's stack. */ 99.26 - memguard_guard_stack(cpu0_stack); 99.27 - 99.28 - open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period); 99.29 - 99.30 - if ( opt_watchdog ) 99.31 - nmi_watchdog = NMI_LOCAL_APIC; 99.32 - 99.33 - sort_exception_tables(); 99.34 - 99.35 - arch_do_createdomain(current); 99.36 - 99.37 - /* 99.38 - * Map default GDT into its final positions in the idle page table. As 99.39 - * noted in arch_do_createdomain(), we must map for every possible VCPU#. 99.40 - */ 99.41 - vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE; 99.42 - gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT; 99.43 - for ( i = 0; i < MAX_VIRT_CPUS; i++ ) 99.44 - { 99.45 - map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR); 99.46 - vgdt += 1 << PDPT_VCPU_VA_SHIFT; 99.47 - } 99.48 - 99.49 - find_smp_config(); 99.50 - 99.51 - smp_alloc_memory(); 99.52 - 99.53 - dmi_scan_machine(); 99.54 - 99.55 - generic_apic_probe(); 99.56 - 99.57 - acpi_boot_table_init(); 99.58 - acpi_boot_init(); 99.59 - 99.60 - if ( smp_found_config ) 99.61 - get_smp_config(); 99.62 - 99.63 - init_apic_mappings(); 99.64 - 99.65 - init_IRQ(); 99.66 - 99.67 - trap_init(); 99.68 - 99.69 - ac_timer_init(); 99.70 - 99.71 - early_time_init(); 99.72 - 99.73 - arch_init_memory(); 99.74 - 99.75 - scheduler_init(); 99.76 - 99.77 - identify_cpu(&boot_cpu_data); 99.78 - if ( cpu_has_fxsr ) 99.79 - set_in_cr4(X86_CR4_OSFXSR); 99.80 - if ( cpu_has_xmm ) 99.81 - set_in_cr4(X86_CR4_OSXMMEXCPT); 99.82 - 99.83 - if ( opt_nosmp ) 99.84 - { 99.85 - max_cpus = 0; 99.86 - smp_num_siblings = 1; 99.87 - boot_cpu_data.x86_num_cores = 1; 99.88 - } 99.89 - 99.90 - smp_prepare_cpus(max_cpus); 99.91 - 99.92 - /* We aren't hotplug-capable yet. */ 99.93 - BUG_ON(!cpus_empty(cpu_present_map)); 99.94 - for_each_cpu ( i ) 99.95 - cpu_set(i, cpu_present_map); 99.96 - 99.97 - /* 99.98 - * Initialise higher-level timer functions. We do this fairly late 99.99 - * (post-SMP) because the time bases and scale factors need to be updated 99.100 - * regularly, and SMP initialisation can cause a long delay with 99.101 - * interrupts not yet enabled. 99.102 - */ 99.103 - init_xen_time(); 99.104 - 99.105 - initialize_keytable(); 99.106 - 99.107 - serial_init_postirq(); 99.108 - 99.109 - BUG_ON(!local_irq_is_enabled()); 99.110 - 99.111 - for_each_present_cpu ( i ) 99.112 - { 99.113 - if ( num_online_cpus() >= max_cpus ) 99.114 - break; 99.115 - if ( !cpu_online(i) ) 99.116 - __cpu_up(i); 99.117 - } 99.118 - 99.119 - printk("Brought up %ld CPUs\n", (long)num_online_cpus()); 99.120 - smp_cpus_done(max_cpus); 99.121 - 99.122 - do_initcalls(); 99.123 - 99.124 - schedulers_start(); 99.125 - 99.126 - watchdog_enable(); 99.127 -} 99.128 - 99.129 #define EARLY_FAIL() for ( ; ; ) __asm__ __volatile__ ( "hlt" ) 99.130 99.131 static struct e820entry e820_raw[E820MAX]; 99.132 99.133 void __init __start_xen(multiboot_info_t *mbi) 99.134 { 99.135 + unsigned long vgdt, gdt_pfn; 99.136 char *cmdline; 99.137 + unsigned long _initrd_start = 0, _initrd_len = 0; 99.138 + unsigned int initrdidx = 1; 99.139 module_t *mod = (module_t *)__va(mbi->mods_addr); 99.140 unsigned long nr_pages, modules_length; 99.141 unsigned long initial_images_start, initial_images_end; 99.142 - unsigned long _initrd_start = 0, _initrd_len = 0; 99.143 - unsigned int initrdidx = 1; 99.144 physaddr_t s, e; 99.145 int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0; 99.146 struct ns16550_defaults ns16550 = { 99.147 @@ -455,6 +343,12 @@ void __init __start_xen(multiboot_info_t 99.148 BUG_ON(sizeof(shared_info_t) > PAGE_SIZE); 99.149 BUG_ON(sizeof(vcpu_info_t) != 64); 99.150 99.151 + /* __foo are defined in public headers. Check they match internal defs. */ 99.152 + BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START); 99.153 +#ifdef HYPERVISOR_VIRT_END 99.154 + BUG_ON(__HYPERVISOR_VIRT_END != HYPERVISOR_VIRT_END); 99.155 +#endif 99.156 + 99.157 init_frametable(); 99.158 99.159 end_boot_allocator(); 99.160 @@ -486,7 +380,113 @@ void __init __start_xen(multiboot_info_t 99.161 99.162 early_boot = 0; 99.163 99.164 - start_of_day(); 99.165 + early_cpu_init(); 99.166 + 99.167 + paging_init(); 99.168 + 99.169 + /* Unmap the first page of CPU0's stack. */ 99.170 + memguard_guard_stack(cpu0_stack); 99.171 + 99.172 + open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period); 99.173 + 99.174 + if ( opt_watchdog ) 99.175 + nmi_watchdog = NMI_LOCAL_APIC; 99.176 + 99.177 + sort_exception_tables(); 99.178 + 99.179 + if ( arch_do_createdomain(current) != 0 ) 99.180 + BUG(); 99.181 + 99.182 + /* 99.183 + * Map default GDT into its final positions in the idle page table. As 99.184 + * noted in arch_do_createdomain(), we must map for every possible VCPU#. 99.185 + */ 99.186 + vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE; 99.187 + gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT; 99.188 + for ( i = 0; i < MAX_VIRT_CPUS; i++ ) 99.189 + { 99.190 + map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR); 99.191 + vgdt += 1 << PDPT_VCPU_VA_SHIFT; 99.192 + } 99.193 + 99.194 + find_smp_config(); 99.195 + 99.196 + smp_alloc_memory(); 99.197 + 99.198 + dmi_scan_machine(); 99.199 + 99.200 + generic_apic_probe(); 99.201 + 99.202 + acpi_boot_table_init(); 99.203 + acpi_boot_init(); 99.204 + 99.205 + if ( smp_found_config ) 99.206 + get_smp_config(); 99.207 + 99.208 + init_apic_mappings(); 99.209 + 99.210 + init_IRQ(); 99.211 + 99.212 + trap_init(); 99.213 + 99.214 + ac_timer_init(); 99.215 + 99.216 + early_time_init(); 99.217 + 99.218 + arch_init_memory(); 99.219 + 99.220 + scheduler_init(); 99.221 + 99.222 + identify_cpu(&boot_cpu_data); 99.223 + if ( cpu_has_fxsr ) 99.224 + set_in_cr4(X86_CR4_OSFXSR); 99.225 + if ( cpu_has_xmm ) 99.226 + set_in_cr4(X86_CR4_OSXMMEXCPT); 99.227 + 99.228 + if ( opt_nosmp ) 99.229 + { 99.230 + max_cpus = 0; 99.231 + smp_num_siblings = 1; 99.232 + boot_cpu_data.x86_num_cores = 1; 99.233 + } 99.234 + 99.235 + smp_prepare_cpus(max_cpus); 99.236 + 99.237 + /* We aren't hotplug-capable yet. */ 99.238 + BUG_ON(!cpus_empty(cpu_present_map)); 99.239 + for_each_cpu ( i ) 99.240 + cpu_set(i, cpu_present_map); 99.241 + 99.242 + /* 99.243 + * Initialise higher-level timer functions. We do this fairly late 99.244 + * (post-SMP) because the time bases and scale factors need to be updated 99.245 + * regularly, and SMP initialisation can cause a long delay with 99.246 + * interrupts not yet enabled. 99.247 + */ 99.248 + init_xen_time(); 99.249 + 99.250 + initialize_keytable(); 99.251 + 99.252 + serial_init_postirq(); 99.253 + 99.254 + BUG_ON(!local_irq_is_enabled()); 99.255 + 99.256 + for_each_present_cpu ( i ) 99.257 + { 99.258 + if ( num_online_cpus() >= max_cpus ) 99.259 + break; 99.260 + if ( !cpu_online(i) ) 99.261 + __cpu_up(i); 99.262 + } 99.263 + 99.264 + printk("Brought up %ld CPUs\n", (long)num_online_cpus()); 99.265 + smp_cpus_done(max_cpus); 99.266 + 99.267 + do_initcalls(); 99.268 + 99.269 + schedulers_start(); 99.270 + 99.271 + watchdog_enable(); 99.272 99.273 shadow_mode_init(); 99.274
100.1 --- a/xen/arch/x86/shadow.c Mon Jan 09 11:19:55 2006 +0000 100.2 +++ b/xen/arch/x86/shadow.c Mon Jan 09 11:22:17 2006 +0000 100.3 @@ -1800,7 +1800,7 @@ static void sync_all(struct domain *d) 100.4 } 100.5 100.6 /* Other VCPUs mustn't use the revoked writable mappings. */ 100.7 - other_vcpus_mask = d->cpumask; 100.8 + other_vcpus_mask = d->domain_dirty_cpumask; 100.9 cpu_clear(smp_processor_id(), other_vcpus_mask); 100.10 flush_tlb_mask(other_vcpus_mask); 100.11
101.1 --- a/xen/arch/x86/shadow32.c Mon Jan 09 11:19:55 2006 +0000 101.2 +++ b/xen/arch/x86/shadow32.c Mon Jan 09 11:22:17 2006 +0000 101.3 @@ -2586,7 +2586,7 @@ void __shadow_sync_all(struct domain *d) 101.4 } 101.5 101.6 /* Other VCPUs mustn't use the revoked writable mappings. */ 101.7 - other_vcpus_mask = d->cpumask; 101.8 + other_vcpus_mask = d->domain_dirty_cpumask; 101.9 cpu_clear(smp_processor_id(), other_vcpus_mask); 101.10 flush_tlb_mask(other_vcpus_mask); 101.11
102.1 --- a/xen/arch/x86/smpboot.c Mon Jan 09 11:19:55 2006 +0000 102.2 +++ b/xen/arch/x86/smpboot.c Mon Jan 09 11:22:17 2006 +0000 102.3 @@ -435,7 +435,7 @@ void __init start_secondary(void *unused 102.4 102.5 extern void percpu_traps_init(void); 102.6 102.7 - set_current(idle_task[cpu]); 102.8 + set_current(idle_domain[cpu]); 102.9 set_processor_id(cpu); 102.10 102.11 percpu_traps_init(); 102.12 @@ -763,7 +763,6 @@ static int __init do_boot_cpu(int apicid 102.13 { 102.14 struct domain *idle; 102.15 struct vcpu *v; 102.16 - void *stack; 102.17 unsigned long boot_error; 102.18 int timeout, cpu; 102.19 unsigned long start_eip; 102.20 @@ -774,7 +773,7 @@ static int __init do_boot_cpu(int apicid 102.21 if ( (idle = do_createdomain(IDLE_DOMAIN_ID, cpu)) == NULL ) 102.22 panic("failed 'createdomain' for CPU %d", cpu); 102.23 102.24 - v = idle_task[cpu] = idle->vcpu[0]; 102.25 + v = idle_domain[cpu] = idle->vcpu[0]; 102.26 102.27 set_bit(_DOMF_idle_domain, &idle->domain_flags); 102.28 102.29 @@ -786,16 +785,10 @@ static int __init do_boot_cpu(int apicid 102.30 /* So we see what's up */ 102.31 printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); 102.32 102.33 - stack = alloc_xenheap_pages(STACK_ORDER); 102.34 -#if defined(__i386__) 102.35 - stack_start.esp = (void *)__pa(stack); 102.36 -#elif defined(__x86_64__) 102.37 - stack_start.esp = stack; 102.38 -#endif 102.39 - stack_start.esp += STACK_SIZE - sizeof(struct cpu_info); 102.40 + stack_start.esp = alloc_xenheap_pages(STACK_ORDER); 102.41 102.42 /* Debug build: detect stack overflow by setting up a guard page. */ 102.43 - memguard_guard_stack(stack); 102.44 + memguard_guard_stack(stack_start.esp); 102.45 102.46 /* 102.47 * This grunge runs the startup process for
103.1 --- a/xen/arch/x86/traps.c Mon Jan 09 11:19:55 2006 +0000 103.2 +++ b/xen/arch/x86/traps.c Mon Jan 09 11:22:17 2006 +0000 103.3 @@ -41,6 +41,7 @@ 103.4 #include <xen/softirq.h> 103.5 #include <xen/domain_page.h> 103.6 #include <xen/symbols.h> 103.7 +#include <xen/iocap.h> 103.8 #include <asm/shadow.h> 103.9 #include <asm/system.h> 103.10 #include <asm/io.h> 103.11 @@ -192,7 +193,8 @@ static void show_trace(struct cpu_user_r 103.12 103.13 /* Bounds for range of valid frame pointer. */ 103.14 low = (unsigned long)(ESP_BEFORE_EXCEPTION(regs) - 2); 103.15 - high = (low & ~(STACK_SIZE - 1)) + (STACK_SIZE - sizeof(struct cpu_info)); 103.16 + high = (low & ~(STACK_SIZE - 1)) + 103.17 + (STACK_SIZE - sizeof(struct cpu_info) - 2*sizeof(unsigned long)); 103.18 103.19 /* The initial frame pointer. */ 103.20 next = regs->ebp; 103.21 @@ -200,14 +202,14 @@ static void show_trace(struct cpu_user_r 103.22 for ( ; ; ) 103.23 { 103.24 /* Valid frame pointer? */ 103.25 - if ( (next < low) || (next > high) ) 103.26 + if ( (next < low) || (next >= high) ) 103.27 { 103.28 /* 103.29 * Exception stack frames have a different layout, denoted by an 103.30 * inverted frame pointer. 103.31 */ 103.32 next = ~next; 103.33 - if ( (next < low) || (next > high) ) 103.34 + if ( (next < low) || (next >= high) ) 103.35 break; 103.36 frame = (unsigned long *)next; 103.37 next = frame[0]; 103.38 @@ -621,17 +623,7 @@ static inline int admin_io_okay( 103.39 unsigned int port, unsigned int bytes, 103.40 struct vcpu *v, struct cpu_user_regs *regs) 103.41 { 103.42 - struct domain *d = v->domain; 103.43 - u16 x; 103.44 - 103.45 - if ( d->arch.iobmp_mask != NULL ) 103.46 - { 103.47 - x = *(u16 *)(d->arch.iobmp_mask + (port >> 3)); 103.48 - if ( (x & (((1<<bytes)-1) << (port&7))) == 0 ) 103.49 - return 1; 103.50 - } 103.51 - 103.52 - return 0; 103.53 + return ioports_access_permitted(v->domain, port, port + bytes - 1); 103.54 } 103.55 103.56 /* Check admin limits. Silently fail the access if it is disallowed. */ 103.57 @@ -871,7 +863,7 @@ static int emulate_privileged_op(struct 103.58 103.59 case 0x09: /* WBINVD */ 103.60 /* Ignore the instruction if unprivileged. */ 103.61 - if ( !IS_CAPABLE_PHYSDEV(v->domain) ) 103.62 + if ( !cache_flush_permitted(v->domain) ) 103.63 DPRINTK("Non-physdev domain attempted WBINVD.\n"); 103.64 else 103.65 wbinvd(); 103.66 @@ -885,7 +877,8 @@ static int emulate_privileged_op(struct 103.67 switch ( modrm_reg ) 103.68 { 103.69 case 0: /* Read CR0 */ 103.70 - *reg = v->arch.guest_context.ctrlreg[0]; 103.71 + *reg = (read_cr0() & ~X86_CR0_TS) | 103.72 + v->arch.guest_context.ctrlreg[0]; 103.73 break; 103.74 103.75 case 2: /* Read CR2 */ 103.76 @@ -927,6 +920,11 @@ static int emulate_privileged_op(struct 103.77 switch ( modrm_reg ) 103.78 { 103.79 case 0: /* Write CR0 */ 103.80 + if ( (*reg ^ read_cr0()) & ~X86_CR0_TS ) 103.81 + { 103.82 + DPRINTK("Attempt to change unmodifiable CR0 flags.\n"); 103.83 + goto fail; 103.84 + } 103.85 (void)do_fpu_taskswitch(!!(*reg & X86_CR0_TS)); 103.86 break; 103.87 103.88 @@ -941,6 +939,14 @@ static int emulate_privileged_op(struct 103.89 UNLOCK_BIGLOCK(v->domain); 103.90 break; 103.91 103.92 + case 4: 103.93 + if ( *reg != (read_cr4() & ~(X86_CR4_PGE|X86_CR4_PSE)) ) 103.94 + { 103.95 + DPRINTK("Attempt to change CR4 flags.\n"); 103.96 + goto fail; 103.97 + } 103.98 + break; 103.99 + 103.100 default: 103.101 goto fail; 103.102 }
104.1 --- a/xen/arch/x86/vmx.c Mon Jan 09 11:19:55 2006 +0000 104.2 +++ b/xen/arch/x86/vmx.c Mon Jan 09 11:22:17 2006 +0000 104.3 @@ -42,7 +42,7 @@ 104.4 #include <asm/shadow_64.h> 104.5 #endif 104.6 #include <public/sched.h> 104.7 -#include <public/io/ioreq.h> 104.8 +#include <public/hvm/ioreq.h> 104.9 #include <asm/vmx_vpic.h> 104.10 #include <asm/vmx_vlapic.h> 104.11 104.12 @@ -53,7 +53,7 @@ unsigned int opt_vmx_debug_level = 0; 104.13 integer_param("vmx_debug", opt_vmx_debug_level); 104.14 104.15 static unsigned long trace_values[NR_CPUS][4]; 104.16 -#define TRACE_VMEXIT(index,value) trace_values[current->processor][index]=value 104.17 +#define TRACE_VMEXIT(index,value) trace_values[smp_processor_id()][index]=value 104.18 104.19 static int vmx_switch_on; 104.20 104.21 @@ -66,11 +66,6 @@ void vmx_final_setup_guest(struct vcpu * 104.22 struct domain *d = v->domain; 104.23 struct vcpu *vc; 104.24 104.25 - d->arch.vmx_platform.lapic_enable = v->arch.guest_context.user_regs.ecx; 104.26 - v->arch.guest_context.user_regs.ecx = 0; 104.27 - VMX_DBG_LOG(DBG_LEVEL_VLAPIC, "lapic enable is %d.\n", 104.28 - d->arch.vmx_platform.lapic_enable); 104.29 - 104.30 /* Initialize monitor page table */ 104.31 for_each_vcpu(d, vc) 104.32 vc->arch.monitor_table = mk_pagetable(0); 104.33 @@ -95,7 +90,7 @@ void vmx_final_setup_guest(struct vcpu * 104.34 void vmx_relinquish_resources(struct vcpu *v) 104.35 { 104.36 struct vmx_virpit *vpit; 104.37 - 104.38 + 104.39 if ( !VMX_DOMAIN(v) ) 104.40 return; 104.41 104.42 @@ -1955,9 +1950,12 @@ asmlinkage void load_cr2(void) 104.43 104.44 asmlinkage void trace_vmentry (void) 104.45 { 104.46 - TRACE_5D(TRC_VMENTRY,trace_values[current->processor][0], 104.47 - trace_values[current->processor][1],trace_values[current->processor][2], 104.48 - trace_values[current->processor][3],trace_values[current->processor][4]); 104.49 + TRACE_5D(TRC_VMENTRY, 104.50 + trace_values[smp_processor_id()][0], 104.51 + trace_values[smp_processor_id()][1], 104.52 + trace_values[smp_processor_id()][2], 104.53 + trace_values[smp_processor_id()][3], 104.54 + trace_values[smp_processor_id()][4]); 104.55 TRACE_VMEXIT(0,9); 104.56 TRACE_VMEXIT(1,9); 104.57 TRACE_VMEXIT(2,9);
105.1 --- a/xen/arch/x86/vmx_intercept.c Mon Jan 09 11:19:55 2006 +0000 105.2 +++ b/xen/arch/x86/vmx_intercept.c Mon Jan 09 11:22:17 2006 +0000 105.3 @@ -24,7 +24,7 @@ 105.4 #include <asm/vmx_vpit.h> 105.5 #include <asm/vmx_intercept.h> 105.6 #include <asm/vmx_vlapic.h> 105.7 -#include <public/io/ioreq.h> 105.8 +#include <public/hvm/ioreq.h> 105.9 #include <xen/lib.h> 105.10 #include <xen/sched.h> 105.11 #include <asm/current.h>
106.1 --- a/xen/arch/x86/vmx_io.c Mon Jan 09 11:19:55 2006 +0000 106.2 +++ b/xen/arch/x86/vmx_io.c Mon Jan 09 11:22:17 2006 +0000 106.3 @@ -37,7 +37,7 @@ 106.4 #include <asm/shadow.h> 106.5 #include <asm/vmx_vpic.h> 106.6 #include <asm/vmx_vlapic.h> 106.7 -#include <public/io/ioreq.h> 106.8 +#include <public/hvm/ioreq.h> 106.9 106.10 #ifdef CONFIG_VMX 106.11 #if defined (__i386__)
107.1 --- a/xen/arch/x86/vmx_platform.c Mon Jan 09 11:19:55 2006 +0000 107.2 +++ b/xen/arch/x86/vmx_platform.c Mon Jan 09 11:22:17 2006 +0000 107.3 @@ -27,7 +27,7 @@ 107.4 #include <xen/trace.h> 107.5 #include <asm/vmx.h> 107.6 #include <asm/vmx_platform.h> 107.7 -#include <public/io/ioreq.h> 107.8 +#include <public/hvm/ioreq.h> 107.9 107.10 #include <xen/lib.h> 107.11 #include <xen/sched.h>
108.1 --- a/xen/arch/x86/vmx_vlapic.c Mon Jan 09 11:19:55 2006 +0000 108.2 +++ b/xen/arch/x86/vmx_vlapic.c Mon Jan 09 11:22:17 2006 +0000 108.3 @@ -32,7 +32,7 @@ 108.4 #include <xen/lib.h> 108.5 #include <xen/sched.h> 108.6 #include <asm/current.h> 108.7 -#include <public/io/ioreq.h> 108.8 +#include <public/hvm/ioreq.h> 108.9 108.10 #ifdef CONFIG_VMX 108.11 108.12 @@ -62,7 +62,7 @@ int vlapic_find_highest_irr(struct vlapi 108.13 108.14 int vmx_apic_support(struct domain *d) 108.15 { 108.16 - return d->arch.vmx_platform.lapic_enable; 108.17 + return d->arch.vmx_platform.apic_enabled; 108.18 } 108.19 108.20 s_time_t get_apictime_scheduled(struct vcpu *v)
109.1 --- a/xen/arch/x86/vmx_vmcs.c Mon Jan 09 11:19:55 2006 +0000 109.2 +++ b/xen/arch/x86/vmx_vmcs.c Mon Jan 09 11:22:17 2006 +0000 109.3 @@ -32,7 +32,7 @@ 109.4 #include <asm/flushtlb.h> 109.5 #include <xen/event.h> 109.6 #include <xen/kernel.h> 109.7 -#include <public/io/ioreq.h> 109.8 +#include <public/hvm/hvm_info_table.h> 109.9 #if CONFIG_PAGING_LEVELS >= 4 109.10 #include <asm/shadow_64.h> 109.11 #endif 109.12 @@ -206,36 +206,56 @@ static void vmx_map_io_shared_page(struc 109.13 &d->shared_info->evtchn_mask[0]); 109.14 } 109.15 109.16 -#define VCPU_NR_PAGE 0x0009F000 109.17 -#define VCPU_NR_OFFSET 0x00000800 109.18 -#define VCPU_MAGIC 0x76637075 /* "vcpu" */ 109.19 +static int validate_hvm_info(struct hvm_info_table *t) 109.20 +{ 109.21 + char signature[] = "HVM INFO"; 109.22 + uint8_t *ptr = (uint8_t *)t; 109.23 + uint8_t sum = 0; 109.24 + int i; 109.25 109.26 -static void vmx_set_vcpu_nr(struct domain *d) 109.27 + /* strncmp(t->signature, "HVM INFO", 8) */ 109.28 + for ( i = 0; i < 8; i++ ) { 109.29 + if ( signature[i] != t->signature[i] ) { 109.30 + printk("Bad hvm info signature\n"); 109.31 + return 0; 109.32 + } 109.33 + } 109.34 + 109.35 + for ( i = 0; i < t->length; i++ ) 109.36 + sum += ptr[i]; 109.37 + 109.38 + return (sum == 0); 109.39 +} 109.40 + 109.41 +static void vmx_get_hvm_info(struct domain *d) 109.42 { 109.43 unsigned char *p; 109.44 unsigned long mpfn; 109.45 - unsigned int *vcpus; 109.46 + struct hvm_info_table *t; 109.47 109.48 - mpfn = get_mfn_from_pfn(VCPU_NR_PAGE >> PAGE_SHIFT); 109.49 - if (mpfn == INVALID_MFN) { 109.50 - printk("Can not get vcpu number page mfn for VMX domain.\n"); 109.51 + mpfn = get_mfn_from_pfn(HVM_INFO_PFN); 109.52 + if ( mpfn == INVALID_MFN ) { 109.53 + printk("Can not get hvm info page mfn for VMX domain.\n"); 109.54 domain_crash_synchronous(); 109.55 } 109.56 109.57 p = map_domain_page(mpfn); 109.58 - if (p == NULL) { 109.59 - printk("Can not map vcpu number page for VMX domain.\n"); 109.60 + if ( p == NULL ) { 109.61 + printk("Can not map hvm info page for VMX domain.\n"); 109.62 domain_crash_synchronous(); 109.63 } 109.64 109.65 - vcpus = (unsigned int *)(p + VCPU_NR_OFFSET); 109.66 - if (vcpus[0] != VCPU_MAGIC) { 109.67 - printk("Bad vcpus magic, set vcpu number to 1 by default.\n"); 109.68 - d->arch.vmx_platform.nr_vcpu = 1; 109.69 + t = (struct hvm_info_table *)(p + HVM_INFO_OFFSET); 109.70 + 109.71 + if ( validate_hvm_info(t) ) { 109.72 + d->arch.vmx_platform.nr_vcpus = t->nr_vcpus; 109.73 + d->arch.vmx_platform.apic_enabled = t->apic_enabled; 109.74 + } else { 109.75 + printk("Bad hvm info table\n"); 109.76 + d->arch.vmx_platform.nr_vcpus = 1; 109.77 + d->arch.vmx_platform.apic_enabled = 0; 109.78 } 109.79 109.80 - d->arch.vmx_platform.nr_vcpu = vcpus[1]; 109.81 - 109.82 unmap_domain_page(p); 109.83 } 109.84 109.85 @@ -244,10 +264,10 @@ static void vmx_setup_platform(struct do 109.86 struct vmx_platform *platform; 109.87 109.88 vmx_map_io_shared_page(d); 109.89 - vmx_set_vcpu_nr(d); 109.90 + vmx_get_hvm_info(d); 109.91 109.92 platform = &d->arch.vmx_platform; 109.93 - pic_init(&platform->vmx_pic, pic_irq_request, 109.94 + pic_init(&platform->vmx_pic, pic_irq_request, 109.95 &platform->interrupt_request); 109.96 register_pic_io_hook(); 109.97 109.98 @@ -335,6 +355,8 @@ static void vmx_do_launch(struct vcpu *v 109.99 __vmwrite(HOST_RSP, (unsigned long)get_stack_bottom()); 109.100 109.101 v->arch.schedule_tail = arch_vmx_do_resume; 109.102 + v->arch.arch_vmx.launch_cpu = smp_processor_id(); 109.103 + 109.104 /* init guest tsc to start from 0 */ 109.105 rdtscll(host_tsc); 109.106 v->arch.arch_vmx.tsc_offset = 0 - host_tsc; 109.107 @@ -617,11 +639,21 @@ void vm_resume_fail(unsigned long eflags 109.108 109.109 void arch_vmx_do_resume(struct vcpu *v) 109.110 { 109.111 - u64 vmcs_phys_ptr = (u64) virt_to_phys(v->arch.arch_vmx.vmcs); 109.112 - 109.113 - load_vmcs(&v->arch.arch_vmx, vmcs_phys_ptr); 109.114 - vmx_do_resume(v); 109.115 - reset_stack_and_jump(vmx_asm_do_resume); 109.116 + if ( v->arch.arch_vmx.launch_cpu == smp_processor_id() ) 109.117 + { 109.118 + load_vmcs(&v->arch.arch_vmx, virt_to_phys(v->arch.arch_vmx.vmcs)); 109.119 + vmx_do_resume(v); 109.120 + reset_stack_and_jump(vmx_asm_do_resume); 109.121 + } 109.122 + else 109.123 + { 109.124 + __vmpclear(virt_to_phys(v->arch.arch_vmx.vmcs)); 109.125 + load_vmcs(&v->arch.arch_vmx, virt_to_phys(v->arch.arch_vmx.vmcs)); 109.126 + vmx_do_resume(v); 109.127 + vmx_set_host_env(v); 109.128 + v->arch.arch_vmx.launch_cpu = smp_processor_id(); 109.129 + reset_stack_and_jump(vmx_asm_do_relaunch); 109.130 + } 109.131 } 109.132 109.133 void arch_vmx_do_launch(struct vcpu *v) 109.134 @@ -643,18 +675,6 @@ void arch_vmx_do_launch(struct vcpu *v) 109.135 reset_stack_and_jump(vmx_asm_do_launch); 109.136 } 109.137 109.138 -void arch_vmx_do_relaunch(struct vcpu *v) 109.139 -{ 109.140 - u64 vmcs_phys_ptr = (u64) virt_to_phys(v->arch.arch_vmx.vmcs); 109.141 - 109.142 - load_vmcs(&v->arch.arch_vmx, vmcs_phys_ptr); 109.143 - vmx_do_resume(v); 109.144 - vmx_set_host_env(v); 109.145 - v->arch.schedule_tail = arch_vmx_do_resume; 109.146 - 109.147 - reset_stack_and_jump(vmx_asm_do_relaunch); 109.148 -} 109.149 - 109.150 #endif /* CONFIG_VMX */ 109.151 109.152 /*
110.1 --- a/xen/arch/x86/x86_32/xen.lds Mon Jan 09 11:19:55 2006 +0000 110.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 110.3 @@ -1,79 +0,0 @@ 110.4 -/* ld script to make i386 Linux kernel 110.5 - * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> 110.6 - * Modified for i386 Xen by Keir Fraser 110.7 - */ 110.8 -OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") 110.9 -OUTPUT_ARCH(i386) 110.10 -ENTRY(start) 110.11 -PHDRS 110.12 -{ 110.13 - text PT_LOAD ; 110.14 -} 110.15 -SECTIONS 110.16 -{ 110.17 - . = 0xFF000000 + 0x100000; 110.18 - _text = .; /* Text and read-only data */ 110.19 - .text : { 110.20 - *(.text) 110.21 - *(.fixup) 110.22 - *(.gnu.warning) 110.23 - } :text =0x9090 110.24 - .text.lock : { *(.text.lock) } :text /* out-of-line lock text */ 110.25 - 110.26 - _etext = .; /* End of text section */ 110.27 - 110.28 - .rodata : { *(.rodata) *(.rodata.*) } :text 110.29 - 110.30 - . = ALIGN(32); /* Exception table */ 110.31 - __start___ex_table = .; 110.32 - __ex_table : { *(__ex_table) } :text 110.33 - __stop___ex_table = .; 110.34 - 110.35 - . = ALIGN(32); /* Pre-exception table */ 110.36 - __start___pre_ex_table = .; 110.37 - __pre_ex_table : { *(__pre_ex_table) } :text 110.38 - __stop___pre_ex_table = .; 110.39 - 110.40 - .data : { /* Data */ 110.41 - *(.data) 110.42 - CONSTRUCTORS 110.43 - } :text 110.44 - 110.45 - . = ALIGN(4096); /* Init code and data */ 110.46 - __init_begin = .; 110.47 - .text.init : { *(.text.init) } :text 110.48 - .data.init : { *(.data.init) } :text 110.49 - . = ALIGN(32); 110.50 - __setup_start = .; 110.51 - .setup.init : { *(.setup.init) } :text 110.52 - __setup_end = .; 110.53 - __initcall_start = .; 110.54 - .initcall.init : { *(.initcall.init) } :text 110.55 - __initcall_end = .; 110.56 - . = ALIGN(8192); 110.57 - __init_end = .; 110.58 - 110.59 - __bss_start = .; /* BSS */ 110.60 - .bss : { 110.61 - *(.bss.twopage_aligned) 110.62 - *(.bss.page_aligned) 110.63 - *(.bss) 110.64 - } :text 110.65 - _end = . ; 110.66 - 110.67 - /* Sections to be discarded */ 110.68 - /DISCARD/ : { 110.69 - *(.text.exit) 110.70 - *(.data.exit) 110.71 - *(.exitcall.exit) 110.72 - } 110.73 - 110.74 - /* Stabs debugging sections. */ 110.75 - .stab 0 : { *(.stab) } 110.76 - .stabstr 0 : { *(.stabstr) } 110.77 - .stab.excl 0 : { *(.stab.excl) } 110.78 - .stab.exclstr 0 : { *(.stab.exclstr) } 110.79 - .stab.index 0 : { *(.stab.index) } 110.80 - .stab.indexstr 0 : { *(.stab.indexstr) } 110.81 - .comment 0 : { *(.comment) } 110.82 -}
111.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 111.2 +++ b/xen/arch/x86/x86_32/xen.lds.S Mon Jan 09 11:22:17 2006 +0000 111.3 @@ -0,0 +1,85 @@ 111.4 +/* ld script to make i386 Linux kernel 111.5 + * Written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> 111.6 + * Modified for i386 Xen by Keir Fraser 111.7 + */ 111.8 + 111.9 +#include <xen/config.h> 111.10 +#include <asm/page.h> 111.11 +#undef ENTRY 111.12 +#undef ALIGN 111.13 + 111.14 +OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") 111.15 +OUTPUT_ARCH(i386) 111.16 +ENTRY(start) 111.17 +PHDRS 111.18 +{ 111.19 + text PT_LOAD ; 111.20 +} 111.21 +SECTIONS 111.22 +{ 111.23 + . = 0xFF000000 + 0x100000; 111.24 + _text = .; /* Text and read-only data */ 111.25 + .text : { 111.26 + *(.text) 111.27 + *(.fixup) 111.28 + *(.gnu.warning) 111.29 + } :text =0x9090 111.30 + .text.lock : { *(.text.lock) } :text /* out-of-line lock text */ 111.31 + 111.32 + _etext = .; /* End of text section */ 111.33 + 111.34 + .rodata : { *(.rodata) *(.rodata.*) } :text 111.35 + 111.36 + . = ALIGN(32); /* Exception table */ 111.37 + __start___ex_table = .; 111.38 + __ex_table : { *(__ex_table) } :text 111.39 + __stop___ex_table = .; 111.40 + 111.41 + . = ALIGN(32); /* Pre-exception table */ 111.42 + __start___pre_ex_table = .; 111.43 + __pre_ex_table : { *(__pre_ex_table) } :text 111.44 + __stop___pre_ex_table = .; 111.45 + 111.46 + .data : { /* Data */ 111.47 + *(.data) 111.48 + CONSTRUCTORS 111.49 + } :text 111.50 + 111.51 + . = ALIGN(4096); /* Init code and data */ 111.52 + __init_begin = .; 111.53 + .text.init : { *(.text.init) } :text 111.54 + .data.init : { *(.data.init) } :text 111.55 + . = ALIGN(32); 111.56 + __setup_start = .; 111.57 + .setup.init : { *(.setup.init) } :text 111.58 + __setup_end = .; 111.59 + __initcall_start = .; 111.60 + .initcall.init : { *(.initcall.init) } :text 111.61 + __initcall_end = .; 111.62 + . = ALIGN(STACK_SIZE); 111.63 + __init_end = .; 111.64 + 111.65 + __bss_start = .; /* BSS */ 111.66 + .bss : { 111.67 + *(.bss.stack_aligned) 111.68 + *(.bss.page_aligned) 111.69 + *(.bss) 111.70 + } :text 111.71 + _end = . ; 111.72 + 111.73 + /* Sections to be discarded */ 111.74 + /DISCARD/ : { 111.75 + *(.text.exit) 111.76 + *(.data.exit) 111.77 + *(.exitcall.exit) 111.78 + } 111.79 + 111.80 + /* Stabs debugging sections. */ 111.81 + .stab 0 : { *(.stab) } 111.82 + .stabstr 0 : { *(.stabstr) } 111.83 + .stab.excl 0 : { *(.stab.excl) } 111.84 + .stab.exclstr 0 : { *(.stab.exclstr) } 111.85 + .stab.index 0 : { *(.stab.index) } 111.86 + .stab.indexstr 0 : { *(.stab.indexstr) } 111.87 + .comment 0 : { *(.comment) } 111.88 +}
112.1 --- a/xen/arch/x86/x86_64/xen.lds Mon Jan 09 11:19:55 2006 +0000 112.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 112.3 @@ -1,77 +0,0 @@ 112.4 -/* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */ 112.5 -/* Modified for x86-64 Xen by Keir Fraser */ 112.6 -OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") 112.7 -OUTPUT_ARCH(i386:x86-64) 112.8 -ENTRY(start) 112.9 -PHDRS 112.10 -{ 112.11 - text PT_LOAD ; 112.12 -} 112.13 -SECTIONS 112.14 -{ 112.15 - . = 0xFFFF830000100000; 112.16 - _text = .; /* Text and read-only data */ 112.17 - .text : { 112.18 - *(.text) 112.19 - *(.fixup) 112.20 - *(.gnu.warning) 112.21 - } :text = 0x9090 112.22 - .text.lock : { *(.text.lock) } :text /* out-of-line lock text */ 112.23 - 112.24 - _etext = .; /* End of text section */ 112.25 - 112.26 - .rodata : { *(.rodata) *(.rodata.*) } :text 112.27 - 112.28 - . = ALIGN(32); /* Exception table */ 112.29 - __start___ex_table = .; 112.30 - __ex_table : { *(__ex_table) } :text 112.31 - __stop___ex_table = .; 112.32 - 112.33 - . = ALIGN(32); /* Pre-exception table */ 112.34 - __start___pre_ex_table = .; 112.35 - __pre_ex_table : { *(__pre_ex_table) } :text 112.36 - __stop___pre_ex_table = .; 112.37 - 112.38 - .data : { /* Data */ 112.39 - *(.data) 112.40 - CONSTRUCTORS 112.41 - } :text 112.42 - 112.43 - . = ALIGN(4096); /* Init code and data */ 112.44 - __init_begin = .; 112.45 - .text.init : { *(.text.init) } :text 112.46 - .data.init : { *(.data.init) } :text 112.47 - . = ALIGN(32); 112.48 - __setup_start = .; 112.49 - .setup.init : { *(.setup.init) } :text 112.50 - __setup_end = .; 112.51 - __initcall_start = .; 112.52 - .initcall.init : { *(.initcall.init) } :text 112.53 - __initcall_end = .; 112.54 - . = ALIGN(8192); 112.55 - __init_end = .; 112.56 - 112.57 - __bss_start = .; /* BSS */ 112.58 - .bss : { 112.59 - *(.bss.twopage_aligned) 112.60 - *(.bss.page_aligned) 112.61 - *(.bss) 112.62 - } :text 112.63 - _end = . ; 112.64 - 112.65 - /* Sections to be discarded */ 112.66 - /DISCARD/ : { 112.67 - *(.text.exit) 112.68 - *(.data.exit) 112.69 - *(.exitcall.exit) 112.70 - } 112.71 - 112.72 - /* Stabs debugging sections. */ 112.73 - .stab 0 : { *(.stab) } 112.74 - .stabstr 0 : { *(.stabstr) } 112.75 - .stab.excl 0 : { *(.stab.excl) } 112.76 - .stab.exclstr 0 : { *(.stab.exclstr) } 112.77 - .stab.index 0 : { *(.stab.index) } 112.78 - .stab.indexstr 0 : { *(.stab.indexstr) } 112.79 - .comment 0 : { *(.comment) } 112.80 -}
113.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 113.2 +++ b/xen/arch/x86/x86_64/xen.lds.S Mon Jan 09 11:22:17 2006 +0000 113.3 @@ -0,0 +1,83 @@ 113.4 +/* Excerpts written by Martin Mares <mj@atrey.karlin.mff.cuni.cz> */ 113.5 +/* Modified for x86-64 Xen by Keir Fraser */ 113.6 + 113.7 +#include <xen/config.h> 113.8 +#include <asm/page.h> 113.9 +#undef ENTRY 113.10 +#undef ALIGN 113.11 + 113.12 +OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64") 113.13 +OUTPUT_ARCH(i386:x86-64) 113.14 +ENTRY(start) 113.15 +PHDRS 113.16 +{ 113.17 + text PT_LOAD ; 113.18 +} 113.19 +SECTIONS 113.20 +{ 113.21 + . = 0xFFFF830000100000; 113.22 + _text = .; /* Text and read-only data */ 113.23 + .text : { 113.24 + *(.text) 113.25 + *(.fixup) 113.26 + *(.gnu.warning) 113.27 + } :text = 0x9090 113.28 + .text.lock : { *(.text.lock) } :text /* out-of-line lock text */ 113.29 + 113.30 + _etext = .; /* End of text section */ 113.31 + 113.32 + .rodata : { *(.rodata) *(.rodata.*) } :text 113.33 + 113.34 + . = ALIGN(32); /* Exception table */ 113.35 + __start___ex_table = .; 113.36 + __ex_table : { *(__ex_table) } :text 113.37 + __stop___ex_table = .; 113.38 + 113.39 + . = ALIGN(32); /* Pre-exception table */ 113.40 + __start___pre_ex_table = .; 113.41 + __pre_ex_table : { *(__pre_ex_table) } :text 113.42 + __stop___pre_ex_table = .; 113.43 + 113.44 + .data : { /* Data */ 113.45 + *(.data) 113.46 + CONSTRUCTORS 113.47 + } :text 113.48 + 113.49 + . = ALIGN(4096); /* Init code and data */ 113.50 + __init_begin = .; 113.51 + .text.init : { *(.text.init) } :text 113.52 + .data.init : { *(.data.init) } :text 113.53 + . = ALIGN(32); 113.54 + __setup_start = .; 113.55 + .setup.init : { *(.setup.init) } :text 113.56 + __setup_end = .; 113.57 + __initcall_start = .; 113.58 + .initcall.init : { *(.initcall.init) } :text 113.59 + __initcall_end = .; 113.60 + . = ALIGN(STACK_SIZE); 113.61 + __init_end = .; 113.62 + 113.63 + __bss_start = .; /* BSS */ 113.64 + .bss : { 113.65 + *(.bss.stack_aligned) 113.66 + *(.bss.page_aligned) 113.67 + *(.bss) 113.68 + } :text 113.69 + _end = . ; 113.70 + 113.71 + /* Sections to be discarded */ 113.72 + /DISCARD/ : { 113.73 + *(.text.exit) 113.74 + *(.data.exit) 113.75 + *(.exitcall.exit) 113.76 + } 113.77 + 113.78 + /* Stabs debugging sections. */ 113.79 + .stab 0 : { *(.stab) } 113.80 + .stabstr 0 : { *(.stabstr) } 113.81 + .stab.excl 0 : { *(.stab.excl) } 113.82 + .stab.exclstr 0 : { *(.stab.exclstr) } 113.83 + .stab.index 0 : { *(.stab.index) } 113.84 + .stab.indexstr 0 : { *(.stab.indexstr) } 113.85 + .comment 0 : { *(.comment) } 113.86 +}
114.1 --- a/xen/arch/x86/x86_emulate.c Mon Jan 09 11:19:55 2006 +0000 114.2 +++ b/xen/arch/x86/x86_emulate.c Mon Jan 09 11:22:17 2006 +0000 114.3 @@ -371,6 +371,21 @@ do{ __asm__ __volatile__ ( 114.4 (_type)_x; \ 114.5 }) 114.6 114.7 +/* Access/update address held in a register, based on addressing mode. */ 114.8 +#define register_address(sel, reg) \ 114.9 + ((ad_bytes == sizeof(unsigned long)) ? (reg) : \ 114.10 + ((mode == X86EMUL_MODE_REAL) ? /* implies ad_bytes == 2 */ \ 114.11 + (((unsigned long)(sel) << 4) + ((reg) & 0xffff)) : \ 114.12 + ((reg) & ((1UL << (ad_bytes << 3)) - 1)))) 114.13 +#define register_address_increment(reg, inc) \ 114.14 +do { \ 114.15 + if ( ad_bytes == sizeof(unsigned long) ) \ 114.16 + (reg) += (inc); \ 114.17 + else \ 114.18 + (reg) = ((reg) & ~((1UL << (ad_bytes << 3)) - 1)) | \ 114.19 + (((reg) + (inc)) & ((1UL << (ad_bytes << 3)) - 1)); \ 114.20 +} while (0) 114.21 + 114.22 void * 114.23 decode_register( 114.24 uint8_t modrm_reg, struct cpu_user_regs *regs, int highbyte_regs) 114.25 @@ -420,32 +435,64 @@ x86_emulate_memop( 114.26 { 114.27 uint8_t b, d, sib, twobyte = 0, rex_prefix = 0; 114.28 uint8_t modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; 114.29 - unsigned int op_bytes = (mode == 8) ? 4 : mode, ad_bytes = mode; 114.30 - unsigned int lock_prefix = 0, rep_prefix = 0, i; 114.31 + uint16_t *seg = NULL; /* override segment */ 114.32 + unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; 114.33 int rc = 0; 114.34 struct operand src, dst; 114.35 114.36 /* Shadow copy of register state. Committed on successful emulation. */ 114.37 struct cpu_user_regs _regs = *regs; 114.38 114.39 + switch ( mode ) 114.40 + { 114.41 + case X86EMUL_MODE_REAL: 114.42 + case X86EMUL_MODE_PROT16: 114.43 + op_bytes = ad_bytes = 2; 114.44 + break; 114.45 + case X86EMUL_MODE_PROT32: 114.46 + op_bytes = ad_bytes = 4; 114.47 + break; 114.48 +#ifdef __x86_64__ 114.49 + case X86EMUL_MODE_PROT64: 114.50 + op_bytes = 4; 114.51 + ad_bytes = 8; 114.52 + break; 114.53 +#endif 114.54 + default: 114.55 + return -1; 114.56 + } 114.57 + 114.58 /* Legacy prefixes. */ 114.59 for ( i = 0; i < 8; i++ ) 114.60 { 114.61 switch ( b = insn_fetch(uint8_t, 1, _regs.eip) ) 114.62 { 114.63 case 0x66: /* operand-size override */ 114.64 - op_bytes ^= 6; /* switch between 2/4 bytes */ 114.65 + op_bytes ^= 6; /* switch between 2/4 bytes */ 114.66 break; 114.67 case 0x67: /* address-size override */ 114.68 - ad_bytes ^= (mode == 8) ? 12 : 6; /* switch between 2/4/8 bytes */ 114.69 + if ( mode == X86EMUL_MODE_PROT64 ) 114.70 + ad_bytes ^= 12; /* switch between 4/8 bytes */ 114.71 + else 114.72 + ad_bytes ^= 6; /* switch between 2/4 bytes */ 114.73 break; 114.74 case 0x2e: /* CS override */ 114.75 + seg = &_regs.cs; 114.76 + break; 114.77 case 0x3e: /* DS override */ 114.78 + seg = &_regs.ds; 114.79 + break; 114.80 case 0x26: /* ES override */ 114.81 + seg = &_regs.es; 114.82 + break; 114.83 case 0x64: /* FS override */ 114.84 + seg = &_regs.fs; 114.85 + break; 114.86 case 0x65: /* GS override */ 114.87 + seg = &_regs.gs; 114.88 + break; 114.89 case 0x36: /* SS override */ 114.90 - DPRINTF("Warning: ignoring a segment override.\n"); 114.91 + seg = &_regs.ss; 114.92 break; 114.93 case 0xf0: /* LOCK */ 114.94 lock_prefix = 1; 114.95 @@ -461,8 +508,12 @@ x86_emulate_memop( 114.96 } 114.97 done_prefixes: 114.98 114.99 + /* Note quite the same as 80386 real mode, but hopefully good enough. */ 114.100 + if ( (mode == X86EMUL_MODE_REAL) && (ad_bytes != 2) ) 114.101 + goto cannot_emulate; 114.102 + 114.103 /* REX prefix. */ 114.104 - if ( (mode == 8) && ((b & 0xf0) == 0x40) ) 114.105 + if ( (mode == X86EMUL_MODE_PROT64) && ((b & 0xf0) == 0x40) ) 114.106 { 114.107 rex_prefix = b; 114.108 if ( b & 8 ) 114.109 @@ -674,7 +725,7 @@ x86_emulate_memop( 114.110 emulate_2op_SrcV("cmp", src, dst, _regs.eflags); 114.111 break; 114.112 case 0x63: /* movsxd */ 114.113 - if ( mode != 8 ) /* x86/64 long mode only */ 114.114 + if ( mode != X86EMUL_MODE_PROT64 ) 114.115 goto cannot_emulate; 114.116 dst.val = (int32_t)src.val; 114.117 break; 114.118 @@ -721,12 +772,13 @@ x86_emulate_memop( 114.119 dst.val = src.val; 114.120 break; 114.121 case 0x8f: /* pop (sole member of Grp1a) */ 114.122 - /* 64-bit mode: POP defaults to 64-bit operands. */ 114.123 - if ( (mode == 8) && (dst.bytes == 4) ) 114.124 + /* 64-bit mode: POP always pops a 64-bit operand. */ 114.125 + if ( mode == X86EMUL_MODE_PROT64 ) 114.126 dst.bytes = 8; 114.127 - if ( (rc = ops->read_std(_regs.esp, &dst.val, dst.bytes)) != 0 ) 114.128 + if ( (rc = ops->read_std(register_address(_regs.ss, _regs.esp), 114.129 + &dst.val, dst.bytes)) != 0 ) 114.130 goto done; 114.131 - _regs.esp += dst.bytes; 114.132 + register_address_increment(_regs.esp, dst.bytes); 114.133 break; 114.134 case 0xc0 ... 0xc1: grp2: /* Grp2 */ 114.135 switch ( modrm_reg ) 114.136 @@ -797,16 +849,17 @@ x86_emulate_memop( 114.137 emulate_1op("dec", dst, _regs.eflags); 114.138 break; 114.139 case 6: /* push */ 114.140 - /* 64-bit mode: PUSH defaults to 64-bit operands. */ 114.141 - if ( (mode == 8) && (dst.bytes == 4) ) 114.142 + /* 64-bit mode: PUSH always pushes a 64-bit operand. */ 114.143 + if ( mode == X86EMUL_MODE_PROT64 ) 114.144 { 114.145 dst.bytes = 8; 114.146 if ( (rc = ops->read_std((unsigned long)dst.ptr, 114.147 &dst.val, 8)) != 0 ) 114.148 goto done; 114.149 } 114.150 - _regs.esp -= dst.bytes; 114.151 - if ( (rc = ops->write_std(_regs.esp, dst.val, dst.bytes)) != 0 ) 114.152 + register_address_increment(_regs.esp, -dst.bytes); 114.153 + if ( (rc = ops->write_std(register_address(_regs.ss, _regs.esp), 114.154 + dst.val, dst.bytes)) != 0 ) 114.155 goto done; 114.156 dst.val = dst.orig_val; /* skanky: disable writeback */ 114.157 break; 114.158 @@ -873,19 +926,22 @@ x86_emulate_memop( 114.159 { 114.160 /* Write fault: destination is special memory. */ 114.161 dst.ptr = (unsigned long *)cr2; 114.162 - if ( (rc = ops->read_std(_regs.esi - _regs.edi + cr2, 114.163 + if ( (rc = ops->read_std(register_address(seg ? *seg : _regs.ds, 114.164 + _regs.esi), 114.165 &dst.val, dst.bytes)) != 0 ) 114.166 goto done; 114.167 } 114.168 else 114.169 { 114.170 /* Read fault: source is special memory. */ 114.171 - dst.ptr = (unsigned long *)(_regs.edi - _regs.esi + cr2); 114.172 + dst.ptr = (unsigned long *)register_address(_regs.es, _regs.edi); 114.173 if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 ) 114.174 goto done; 114.175 } 114.176 - _regs.esi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes; 114.177 - _regs.edi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes; 114.178 + register_address_increment( 114.179 + _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); 114.180 + register_address_increment( 114.181 + _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); 114.182 break; 114.183 case 0xa6 ... 0xa7: /* cmps */ 114.184 DPRINTF("Urk! I don't handle CMPS.\n"); 114.185 @@ -895,7 +951,8 @@ x86_emulate_memop( 114.186 dst.bytes = (d & ByteOp) ? 1 : op_bytes; 114.187 dst.ptr = (unsigned long *)cr2; 114.188 dst.val = _regs.eax; 114.189 - _regs.edi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes; 114.190 + register_address_increment( 114.191 + _regs.edi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); 114.192 break; 114.193 case 0xac ... 0xad: /* lods */ 114.194 dst.type = OP_REG; 114.195 @@ -903,7 +960,8 @@ x86_emulate_memop( 114.196 dst.ptr = (unsigned long *)&_regs.eax; 114.197 if ( (rc = ops->read_emulated(cr2, &dst.val, dst.bytes)) != 0 ) 114.198 goto done; 114.199 - _regs.esi += (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes; 114.200 + register_address_increment( 114.201 + _regs.esi, (_regs.eflags & EFLG_DF) ? -dst.bytes : dst.bytes); 114.202 break; 114.203 case 0xae ... 0xaf: /* scas */ 114.204 DPRINTF("Urk! I don't handle SCAS.\n");
115.1 --- a/xen/common/bitmap.c Mon Jan 09 11:19:55 2006 +0000 115.2 +++ b/xen/common/bitmap.c Mon Jan 09 11:22:17 2006 +0000 115.3 @@ -282,6 +282,111 @@ int __bitmap_weight(const unsigned long 115.4 #endif 115.5 EXPORT_SYMBOL(__bitmap_weight); 115.6 115.7 +/* 115.8 + * Bitmap printing & parsing functions: first version by Bill Irwin, 115.9 + * second version by Paul Jackson, third by Joe Korty. 115.10 + */ 115.11 + 115.12 +#define CHUNKSZ 32 115.13 +#define nbits_to_hold_value(val) fls(val) 115.14 +#define roundup_power2(val,modulus) (((val) + (modulus) - 1) & ~((modulus) - 1)) 115.15 +#define unhex(c) (isdigit(c) ? (c - '0') : (toupper(c) - 'A' + 10)) 115.16 +#define BASEDEC 10 /* fancier cpuset lists input in decimal */ 115.17 + 115.18 +/** 115.19 + * bitmap_scnprintf - convert bitmap to an ASCII hex string. 115.20 + * @buf: byte buffer into which string is placed 115.21 + * @buflen: reserved size of @buf, in bytes 115.22 + * @maskp: pointer to bitmap to convert 115.23 + * @nmaskbits: size of bitmap, in bits 115.24 + * 115.25 + * Exactly @nmaskbits bits are displayed. Hex digits are grouped into 115.26 + * comma-separated sets of eight digits per set. 115.27 + */ 115.28 +int bitmap_scnprintf(char *buf, unsigned int buflen, 115.29 + const unsigned long *maskp, int nmaskbits) 115.30 +{ 115.31 + int i, word, bit, len = 0; 115.32 + unsigned long val; 115.33 + const char *sep = ""; 115.34 + int chunksz; 115.35 + u32 chunkmask; 115.36 + 115.37 + chunksz = nmaskbits & (CHUNKSZ - 1); 115.38 + if (chunksz == 0) 115.39 + chunksz = CHUNKSZ; 115.40 + 115.41 + i = roundup_power2(nmaskbits, CHUNKSZ) - CHUNKSZ; 115.42 + for (; i >= 0; i -= CHUNKSZ) { 115.43 + chunkmask = ((1ULL << chunksz) - 1); 115.44 + word = i / BITS_PER_LONG; 115.45 + bit = i % BITS_PER_LONG; 115.46 + val = (maskp[word] >> bit) & chunkmask; 115.47 + len += scnprintf(buf+len, buflen-len, "%s%0*lx", sep, 115.48 + (chunksz+3)/4, val); 115.49 + chunksz = CHUNKSZ; 115.50 + sep = ","; 115.51 + } 115.52 + return len; 115.53 +} 115.54 +EXPORT_SYMBOL(bitmap_scnprintf); 115.55 + 115.56 +/* 115.57 + * bscnl_emit(buf, buflen, rbot, rtop, bp) 115.58 + * 115.59 + * Helper routine for bitmap_scnlistprintf(). Write decimal number 115.60 + * or range to buf, suppressing output past buf+buflen, with optional 115.61 + * comma-prefix. Return len of what would be written to buf, if it 115.62 + * all fit. 115.63 + */ 115.64 +static inline int bscnl_emit(char *buf, int buflen, int rbot, int rtop, int len) 115.65 +{ 115.66 + if (len > 0) 115.67 + len += scnprintf(buf + len, buflen - len, ","); 115.68 + if (rbot == rtop) 115.69 + len += scnprintf(buf + len, buflen - len, "%d", rbot); 115.70 + else 115.71 + len += scnprintf(buf + len, buflen - len, "%d-%d", rbot, rtop); 115.72 + return len; 115.73 +} 115.74 + 115.75 +/** 115.76 + * bitmap_scnlistprintf - convert bitmap to list format ASCII string 115.77 + * @buf: byte buffer into which string is placed 115.78 + * @buflen: reserved size of @buf, in bytes 115.79 + * @maskp: pointer to bitmap to convert 115.80 + * @nmaskbits: size of bitmap, in bits 115.81 + * 115.82 + * Output format is a comma-separated list of decimal numbers and 115.83 + * ranges. Consecutively set bits are shown as two hyphen-separated 115.84 + * decimal numbers, the smallest and largest bit numbers set in 115.85 + * the range. Output format is compatible with the format 115.86 + * accepted as input by bitmap_parselist(). 115.87 + * 115.88 + * The return value is the number of characters which would be 115.89 + * generated for the given input, excluding the trailing '\0', as 115.90 + * per ISO C99. 115.91 + */ 115.92 +int bitmap_scnlistprintf(char *buf, unsigned int buflen, 115.93 + const unsigned long *maskp, int nmaskbits) 115.94 +{ 115.95 + int len = 0; 115.96 + /* current bit is 'cur', most recently seen range is [rbot, rtop] */ 115.97 + int cur, rbot, rtop; 115.98 + 115.99 + rbot = cur = find_first_bit(maskp, nmaskbits); 115.100 + while (cur < nmaskbits) { 115.101 + rtop = cur; 115.102 + cur = find_next_bit(maskp, nmaskbits, cur+1); 115.103 + if (cur >= nmaskbits || cur > rtop + 1) { 115.104 + len = bscnl_emit(buf, buflen, rbot, rtop, len); 115.105 + rbot = cur; 115.106 + } 115.107 + } 115.108 + return len; 115.109 +} 115.110 +EXPORT_SYMBOL(bitmap_scnlistprintf); 115.111 + 115.112 /** 115.113 * bitmap_find_free_region - find a contiguous aligned mem region 115.114 * @bitmap: an array of unsigned longs corresponding to the bitmap
116.1 --- a/xen/common/dom0_ops.c Mon Jan 09 11:19:55 2006 +0000 116.2 +++ b/xen/common/dom0_ops.c Mon Jan 09 11:22:17 2006 +0000 116.3 @@ -16,6 +16,7 @@ 116.4 #include <xen/domain_page.h> 116.5 #include <xen/trace.h> 116.6 #include <xen/console.h> 116.7 +#include <xen/iocap.h> 116.8 #include <asm/current.h> 116.9 #include <public/dom0_ops.h> 116.10 #include <public/sched_ctl.h> 116.11 @@ -109,13 +110,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 116.12 switch ( op->cmd ) 116.13 { 116.14 116.15 - case DOM0_SETDOMAININFO: 116.16 + case DOM0_SETVCPUCONTEXT: 116.17 { 116.18 - struct domain *d = find_domain_by_id(op->u.setdomaininfo.domain); 116.19 + struct domain *d = find_domain_by_id(op->u.setvcpucontext.domain); 116.20 ret = -ESRCH; 116.21 if ( d != NULL ) 116.22 { 116.23 - ret = set_info_guest(d, &op->u.setdomaininfo); 116.24 + ret = set_info_guest(d, &op->u.setvcpucontext); 116.25 put_domain(d); 116.26 } 116.27 } 116.28 @@ -283,11 +284,12 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 116.29 } 116.30 break; 116.31 116.32 - case DOM0_PINCPUDOMAIN: 116.33 + case DOM0_SETVCPUAFFINITY: 116.34 { 116.35 - domid_t dom = op->u.pincpudomain.domain; 116.36 + domid_t dom = op->u.setvcpuaffinity.domain; 116.37 struct domain *d = find_domain_by_id(dom); 116.38 struct vcpu *v; 116.39 + cpumask_t new_affinity; 116.40 116.41 if ( d == NULL ) 116.42 { 116.43 @@ -295,15 +297,15 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 116.44 break; 116.45 } 116.46 116.47 - if ( (op->u.pincpudomain.vcpu >= MAX_VIRT_CPUS) || 116.48 - !d->vcpu[op->u.pincpudomain.vcpu] ) 116.49 + if ( (op->u.setvcpuaffinity.vcpu >= MAX_VIRT_CPUS) || 116.50 + !d->vcpu[op->u.setvcpuaffinity.vcpu] ) 116.51 { 116.52 ret = -EINVAL; 116.53 put_domain(d); 116.54 break; 116.55 } 116.56 116.57 - v = d->vcpu[op->u.pincpudomain.vcpu]; 116.58 + v = d->vcpu[op->u.setvcpuaffinity.vcpu]; 116.59 if ( v == NULL ) 116.60 { 116.61 ret = -ESRCH; 116.62 @@ -318,22 +320,13 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 116.63 break; 116.64 } 116.65 116.66 - v->cpumap = op->u.pincpudomain.cpumap; 116.67 + new_affinity = v->cpu_affinity; 116.68 + memcpy(cpus_addr(new_affinity), 116.69 + &op->u.setvcpuaffinity.cpumap, 116.70 + min((int)BITS_TO_LONGS(NR_CPUS), 116.71 + (int)sizeof(op->u.setvcpuaffinity.cpumap))); 116.72 116.73 - if ( v->cpumap == CPUMAP_RUNANYWHERE ) 116.74 - { 116.75 - clear_bit(_VCPUF_cpu_pinned, &v->vcpu_flags); 116.76 - } 116.77 - else 116.78 - { 116.79 - /* pick a new cpu from the usable map */ 116.80 - int new_cpu; 116.81 - new_cpu = (int)find_first_set_bit(v->cpumap) % num_online_cpus(); 116.82 - vcpu_pause(v); 116.83 - vcpu_migrate_cpu(v, new_cpu); 116.84 - set_bit(_VCPUF_cpu_pinned, &v->vcpu_flags); 116.85 - vcpu_unpause(v); 116.86 - } 116.87 + ret = vcpu_set_affinity(v, &new_affinity); 116.88 116.89 put_domain(d); 116.90 } 116.91 @@ -505,7 +498,11 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 116.92 op->u.getvcpuinfo.running = test_bit(_VCPUF_running, &v->vcpu_flags); 116.93 op->u.getvcpuinfo.cpu_time = v->cpu_time; 116.94 op->u.getvcpuinfo.cpu = v->processor; 116.95 - op->u.getvcpuinfo.cpumap = v->cpumap; 116.96 + op->u.getvcpuinfo.cpumap = 0; 116.97 + memcpy(&op->u.getvcpuinfo.cpumap, 116.98 + cpus_addr(v->cpu_affinity), 116.99 + min((int)BITS_TO_LONGS(NR_CPUS), 116.100 + (int)sizeof(op->u.getvcpuinfo.cpumap))); 116.101 ret = 0; 116.102 116.103 if ( copy_to_user(u_dom0_op, op, sizeof(*op)) ) 116.104 @@ -582,6 +579,7 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 116.105 } 116.106 } 116.107 break; 116.108 + 116.109 case DOM0_SETDEBUGGING: 116.110 { 116.111 struct domain *d; 116.112 @@ -599,6 +597,53 @@ long do_dom0_op(dom0_op_t *u_dom0_op) 116.113 } 116.114 break; 116.115 116.116 + case DOM0_IRQ_PERMISSION: 116.117 + { 116.118 + struct domain *d; 116.119 + unsigned int pirq = op->u.irq_permission.pirq; 116.120 + 116.121 + ret = -EINVAL; 116.122 + if ( pirq >= NR_PIRQS ) 116.123 + break; 116.124 + 116.125 + ret = -ESRCH; 116.126 + d = find_domain_by_id(op->u.irq_permission.domain); 116.127 + if ( d == NULL ) 116.128 + break; 116.129 + 116.130 + if ( op->u.irq_permission.allow_access ) 116.131 + ret = irq_permit_access(d, pirq); 116.132 + else 116.133 + ret = irq_deny_access(d, pirq); 116.134 + 116.135 + put_domain(d); 116.136 + } 116.137 + break; 116.138 + 116.139 + case DOM0_IOMEM_PERMISSION: 116.140 + { 116.141 + struct domain *d; 116.142 + unsigned long pfn = op->u.iomem_permission.first_pfn; 116.143 + unsigned long nr_pfns = op->u.iomem_permission.nr_pfns; 116.144 + 116.145 + ret = -EINVAL; 116.146 + if ( (pfn + nr_pfns - 1) < pfn ) /* wrap? */ 116.147 + break; 116.148 + 116.149 + ret = -ESRCH; 116.150 + d = find_domain_by_id(op->u.iomem_permission.domain); 116.151 + if ( d == NULL ) 116.152 + break; 116.153 + 116.154 + if ( op->u.iomem_permission.allow_access ) 116.155 + ret = iomem_permit_access(d, pfn, pfn + nr_pfns - 1); 116.156 + else 116.157 + ret = iomem_deny_access(d, pfn, pfn + nr_pfns - 1); 116.158 + 116.159 + put_domain(d); 116.160 + } 116.161 + break; 116.162 + 116.163 #ifdef PERF_COUNTERS 116.164 case DOM0_PERFCCONTROL: 116.165 {
117.1 --- a/xen/common/domain.c Mon Jan 09 11:19:55 2006 +0000 117.2 +++ b/xen/common/domain.c Mon Jan 09 11:22:17 2006 +0000 117.3 @@ -16,6 +16,7 @@ 117.4 #include <xen/console.h> 117.5 #include <xen/softirq.h> 117.6 #include <xen/domain_page.h> 117.7 +#include <xen/rangeset.h> 117.8 #include <asm/debugger.h> 117.9 #include <public/dom0_ops.h> 117.10 #include <public/sched.h> 117.11 @@ -50,25 +51,24 @@ struct domain *do_createdomain(domid_t d 117.12 else 117.13 set_bit(_DOMF_ctrl_pause, &d->domain_flags); 117.14 117.15 - if ( !is_idle_task(d) && 117.16 + if ( !is_idle_domain(d) && 117.17 ((evtchn_init(d) != 0) || (grant_table_create(d) != 0)) ) 117.18 - { 117.19 - evtchn_destroy(d); 117.20 - free_domain(d); 117.21 - return NULL; 117.22 - } 117.23 + goto fail1;