This commit is contained in:
emellor@leeni.uk.xensource.com committed 2006-01-09 11:22:17 +00:00
commit 1676162e17
162 files changed
+7271 -1638

No files matched your search

+1
View File
@@ -181,6 +181,7 @@
^xen/TAGS$
^xen/arch/x86/asm-offsets\.s$
^xen/arch/x86/boot/mkelf32$
^xen/arch/x86/xen\.lds$
^xen/ddb/.*$
^xen/include/asm$
^xen/include/asm-.*/asm-offsets\.h$
@@ -25,8 +25,9 @@ int xen_init(void)
xen_start_info = __va(s->arch.start_info_pfn << PAGE_SHIFT);
xen_start_info->flags = s->arch.flags;
printk("Running on Xen! start_info_pfn=0x%lx lags=0x%x\n",
s->arch.start_info_pfn, xen_start_info->flags);
printk("Running on Xen! start_info_pfn=0x%lx nr_pages=%d flags=0x%x\n",
s->arch.start_info_pfn, xen_start_info->nr_pages,
xen_start_info->flags);
evtchn_init();
initialized = 1;
-2
View File
@@ -77,8 +77,6 @@ install kernel_install:
install -m0664 .config $(INSTALL_PATH)/boot/config-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
install -m0664 System.map $(INSTALL_PATH)/boot/System.map-$(XINSTALL_NAME)$(INSTALL_SUFFIX)
ln -f -s vmlinuz-$(XINSTALL_NAME)$(INSTALL_SUFFIX) $(INSTALL_PATH)/boot/vmlinuz-$(VERSION).$(PATCHLEVEL)$(XENGUEST)$(INSTALL_SUFFIX)
mkdir -p $(INSTALL_PATH)/usr/include/xen/linux
install -m0644 $(srctree)/include/asm-xen/linux-public/*.h $(INSTALL_PATH)/usr/include/xen/linux
archclean:
@if [ -e arch/xen/arch ]; then $(MAKE) $(clean)=arch/xen/arch; fi;
@@ -40,8 +40,6 @@
#include <asm/fixmap.h>
#endif
void (*pm_power_off)(void) = NULL;
#ifdef CONFIG_X86_64
static inline void acpi_madt_oem_check(char *oem_id, char *oem_table_id) { }
@@ -67,8 +67,11 @@ int mtrr_add_page(unsigned long base, unsigned long size,
op.u.add_memtype.pfn = base;
op.u.add_memtype.nr_pfns = size;
op.u.add_memtype.type = type;
if ((error = HYPERVISOR_dom0_op(&op)))
error = HYPERVISOR_dom0_op(&op);
if (error) {
BUG_ON(error > 0);
return error;
}
if (increment)
++usage_table[op.u.add_memtype.reg];
@@ -121,8 +124,12 @@ int mtrr_del_page(int reg, unsigned long base, unsigned long size)
if (--usage_table[reg] < 1) {
op.cmd = DOM0_DEL_MEMTYPE;
op.u.del_memtype.handle = 0;
op.u.add_memtype.reg = reg;
(void)HYPERVISOR_dom0_op(&op);
op.u.del_memtype.reg = reg;
error = HYPERVISOR_dom0_op(&op);
if (error) {
BUG_ON(error > 0);
goto out;
}
}
error = reg;
out:
@@ -76,9 +76,7 @@ EXPORT_SYMBOL(ioremap_nocache);
EXPORT_SYMBOL(iounmap);
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(pm_idle);
#ifdef CONFIG_ACPI_BOOT
EXPORT_SYMBOL(pm_power_off);
#endif
EXPORT_SYMBOL(get_cmos_time);
EXPORT_SYMBOL(cpu_khz);
EXPORT_SYMBOL(apm_info);
+25 -19
View File
@@ -389,6 +389,30 @@ grant_write(struct file *file, const char __user *buffer, unsigned long count,
return -ENOSYS;
}
static int __init
gnttab_proc_init(void)
{
/*
* /proc/xen/grant : used by libxc to access grant tables
*/
if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
WPRINTK("Unable to create grant xen proc entry\n");
return -1;
}
grant_file_ops.read = grant_pde->proc_fops->read;
grant_file_ops.write = grant_pde->proc_fops->write;
grant_pde->proc_fops = &grant_file_ops;
grant_pde->read_proc = &grant_read;
grant_pde->write_proc = &grant_write;
return 0;
}
device_initcall(gnttab_proc_init);
#endif /* CONFIG_PROC_FS */
int
@@ -446,29 +470,11 @@ gnttab_init(void)
gnttab_free_count = NR_GRANT_ENTRIES - NR_RESERVED_ENTRIES;
gnttab_free_head = NR_RESERVED_ENTRIES;
#ifdef CONFIG_PROC_FS
/*
* /proc/xen/grant : used by libxc to access grant tables
*/
if ((grant_pde = create_xen_proc_entry("grant", 0600)) == NULL) {
WPRINTK("Unable to create grant xen proc entry\n");
return -1;
}
grant_file_ops.read = grant_pde->proc_fops->read;
grant_file_ops.write = grant_pde->proc_fops->write;
grant_pde->proc_fops = &grant_file_ops;
grant_pde->read_proc = &grant_read;
grant_pde->write_proc = &grant_write;
#endif
printk("Grant table initialized\n");
return 0;
}
__initcall(gnttab_init);
core_initcall(gnttab_init);
/*
* Local variables:
@@ -17,6 +17,13 @@
#include <linux/kthread.h>
#include <asm-xen/xencons.h>
#if defined(__i386__) || defined(__x86_64__)
/*
* Power off function, if any
*/
void (*pm_power_off)(void);
#endif
#define SHUTDOWN_INVALID -1
#define SHUTDOWN_POWEROFF 0
#define SHUTDOWN_REBOOT 1
@@ -59,9 +59,7 @@ EXPORT_SYMBOL(disable_irq_nosync);
EXPORT_SYMBOL(probe_irq_mask);
EXPORT_SYMBOL(kernel_thread);
EXPORT_SYMBOL(pm_idle);
#ifdef CONFIG_ACPI_BOOT
EXPORT_SYMBOL(pm_power_off);
#endif
EXPORT_SYMBOL(get_cmos_time);
EXPORT_SYMBOL(__down_failed);
@@ -540,6 +540,9 @@ static int __init blkif_init(void)
pending_vaddrs = kmalloc(sizeof(pending_vaddrs[0]) *
mmap_pages, GFP_KERNEL);
if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) {
kfree(pending_reqs);
kfree(pending_grant_handles);
kfree(pending_vaddrs);
printk("%s: out of memory\n", __FUNCTION__);
return -1;
}
@@ -331,7 +331,12 @@ static void connect(struct blkfront_info *info)
return;
}
xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
err = xlvbd_add(sectors, info->vdevice, binfo, sector_size, info);
if (err) {
xenbus_dev_fatal(info->xbdev, err, "xlvbd_add at %s",
info->xbdev->otherend);
return;
}
(void)xenbus_switch_state(info->xbdev, NULL, XenbusStateConnected);
@@ -208,7 +208,7 @@ static struct page *blktap_nopage(struct vm_area_struct *vma,
}
struct vm_operations_struct blktap_vm_ops = {
nopage: blktap_nopage,
.nopage = blktap_nopage,
};
/******************************************************************
@@ -225,7 +225,7 @@ static int blktap_open(struct inode *inode, struct file *filp)
/* Allocate the fe ring. */
sring = (blkif_sring_t *)get_zeroed_page(GFP_KERNEL);
if (sring == NULL)
goto fail_nomem;
return -ENOMEM;
SetPageReserved(virt_to_page(sring));
@@ -233,9 +233,6 @@ static int blktap_open(struct inode *inode, struct file *filp)
FRONT_RING_INIT(&blktap_ufe_ring, sring, PAGE_SIZE);
return 0;
fail_nomem:
return -ENOMEM;
}
static int blktap_release(struct inode *inode, struct file *filp)
@@ -391,12 +388,12 @@ void blktap_kick_user(void)
}
static struct file_operations blktap_fops = {
owner: THIS_MODULE,
poll: blktap_poll,
ioctl: blktap_ioctl,
open: blktap_open,
release: blktap_release,
mmap: blktap_mmap,
.owner = THIS_MODULE,
.poll = blktap_poll,
.ioctl = blktap_ioctl,
.open = blktap_open,
.release = blktap_release,
.mmap = blktap_mmap,
};
@@ -314,39 +314,31 @@ static void __xencons_tx_flush(void)
{
int sent, sz, work_done = 0;
if (xen_start_info->flags & SIF_INITDOMAIN) {
if (x_char) {
if (x_char) {
if (xen_start_info->flags & SIF_INITDOMAIN)
kcons_write_dom0(NULL, &x_char, 1);
x_char = 0;
work_done = 1;
}
else
while (x_char)
if (xencons_ring_send(&x_char, 1) == 1)
break;
x_char = 0;
work_done = 1;
}
while (wc != wp) {
sz = wp - wc;
if (sz > (wbuf_size - WBUF_MASK(wc)))
sz = wbuf_size - WBUF_MASK(wc);
while (wc != wp) {
sz = wp - wc;
if (sz > (wbuf_size - WBUF_MASK(wc)))
sz = wbuf_size - WBUF_MASK(wc);
if (xen_start_info->flags & SIF_INITDOMAIN) {
kcons_write_dom0(NULL, &wbuf[WBUF_MASK(wc)], sz);
wc += sz;
work_done = 1;
}
} else {
while (x_char) {
if (xencons_ring_send(&x_char, 1) == 1) {
x_char = 0;
work_done = 1;
}
}
while (wc != wp) {
sz = wp - wc;
if (sz > (wbuf_size - WBUF_MASK(wc)))
sz = wbuf_size - WBUF_MASK(wc);
} else {
sent = xencons_ring_send(&wbuf[WBUF_MASK(wc)], sz);
if (sent == 0)
break;
wc += sent;
work_done = 1;
}
work_done = 1;
}
if (work_done && (xencons_tty != NULL)) {
@@ -82,7 +82,7 @@ typedef struct netif_st {
#define NET_RX_RING_SIZE __RING_SIZE((netif_rx_sring_t *)0, PAGE_SIZE)
void netif_creditlimit(netif_t *netif);
int netif_disconnect(netif_t *netif);
void netif_disconnect(netif_t *netif);
netif_t *alloc_netif(domid_t domid, unsigned int handle, u8 be_mac[ETH_ALEN]);
void free_netif(netif_t *netif);
@@ -183,7 +183,7 @@ static void unmap_frontend_pages(netif_t *netif)
int netif_map(netif_t *netif, unsigned long tx_ring_ref,
unsigned long rx_ring_ref, unsigned int evtchn)
{
int err;
int err = -ENOMEM;
netif_tx_sring_t *txs;
netif_rx_sring_t *rxs;
evtchn_op_t op = {
@@ -196,24 +196,19 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
return 0;
netif->tx_comms_area = alloc_vm_area(PAGE_SIZE);
netif->rx_comms_area = alloc_vm_area(PAGE_SIZE);
if (netif->tx_comms_area == NULL || netif->rx_comms_area == NULL)
if (netif->tx_comms_area == NULL)
return -ENOMEM;
netif->rx_comms_area = alloc_vm_area(PAGE_SIZE);
if (netif->rx_comms_area == NULL)
goto err_rx;
err = map_frontend_pages(netif, tx_ring_ref, rx_ring_ref);
if (err) {
free_vm_area(netif->tx_comms_area);
free_vm_area(netif->rx_comms_area);
return err;
}
if (err)
goto err_map;
err = HYPERVISOR_event_channel_op(&op);
if (err) {
unmap_frontend_pages(netif);
free_vm_area(netif->tx_comms_area);
free_vm_area(netif->rx_comms_area);
return err;
}
if (err)
goto err_hypervisor;
netif->evtchn = op.u.bind_interdomain.local_port;
@@ -241,19 +236,22 @@ int netif_map(netif_t *netif, unsigned long tx_ring_ref,
rtnl_unlock();
return 0;
err_hypervisor:
unmap_frontend_pages(netif);
err_map:
free_vm_area(netif->rx_comms_area);
err_rx:
free_vm_area(netif->tx_comms_area);
return err;
}
static void free_netif_callback(void *arg)
{
netif_t *netif = (netif_t *)arg;
/* Already disconnected? */
if (!netif->irq)
return;
unbind_from_irqhandler(netif->irq, netif);
netif->irq = 0;
if (netif->irq)
unbind_from_irqhandler(netif->irq, netif);
unregister_netdev(netif->dev);
if (netif->tx.sring) {
@@ -290,10 +288,10 @@ void netif_creditlimit(netif_t *netif)
#endif
}
int netif_disconnect(netif_t *netif)
void netif_disconnect(netif_t *netif)
{
if (netif->status == CONNECTED) {
switch (netif->status) {
case CONNECTED:
rtnl_lock();
netif->status = DISCONNECTING;
wmb();
@@ -301,10 +299,14 @@ int netif_disconnect(netif_t *netif)
__netif_down(netif);
rtnl_unlock();
netif_put(netif);
return 0; /* Caller should not send response message. */
break;
case DISCONNECTED:
BUG_ON(atomic_read(&netif->refcnt) != 0);
free_netif(netif);
break;
default:
BUG();
}
return 1;
}
/*
@@ -14,6 +14,7 @@
#include <asm-xen/balloon.h>
#include <asm-xen/xen-public/memory.h>
/*#define NETBE_DEBUG_INTERRUPT*/
static void netif_idx_release(u16 pending_idx);
static void netif_page_release(struct page *page);
@@ -727,6 +728,7 @@ static int make_rx_response(netif_t *netif,
return notify;
}
#ifdef NETBE_DEBUG_INTERRUPT
static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs)
{
struct list_head *ent;
@@ -758,6 +760,7 @@ static irqreturn_t netif_be_dbg(int irq, void *dev_id, struct pt_regs *regs)
return IRQ_HANDLED;
}
#endif
static int __init netback_init(void)
{
@@ -794,6 +797,7 @@ static int __init netback_init(void)
netif_xenbus_init();
#ifdef NETBE_DEBUG_INTERRUPT
(void)bind_virq_to_irqhandler(
VIRQ_DEBUG,
0,
@@ -801,6 +805,7 @@ static int __init netback_init(void)
SA_SHIRQ,
"net-be-dbg",
&netif_be_dbg);
#endif
return 0;
}
@@ -117,6 +117,8 @@ struct netfront_info
int rx_min_target, rx_max_target, rx_target;
struct sk_buff_head rx_batch;
struct timer_list rx_refill_timer;
/*
* {tx,rx}_skbs store outstanding skbuffs. The first entry in each
* array is an index into a chain of free entries.
@@ -517,6 +519,13 @@ static void network_tx_buf_gc(struct net_device *dev)
}
static void rx_refill_timeout(unsigned long data)
{
struct net_device *dev = (struct net_device *)data;
netif_rx_schedule(dev);
}
static void network_alloc_rx_buffers(struct net_device *dev)
{
unsigned short id;
@@ -534,7 +543,7 @@ static void network_alloc_rx_buffers(struct net_device *dev)
* Allocate skbuffs greedily, even though we batch updates to the
* receive ring. This creates a less bursty demand on the memory
* allocator, so should reduce the chance of failed allocation requests
* both for ourself and for other kernel subsystems.
* both for ourself and for other kernel subsystems.
*/
batch_target = np->rx_target - (req_prod - np->rx.rsp_cons);
for (i = skb_queue_len(&np->rx_batch); i < batch_target; i++) {
@@ -545,8 +554,15 @@ static void network_alloc_rx_buffers(struct net_device *dev)
skb = alloc_xen_skb(
((PAGE_SIZE - sizeof(struct skb_shared_info)) &
(-SKB_DATA_ALIGN(1))) - 16);
if (skb == NULL)
break;
if (skb == NULL) {
/* Any skbuffs queued for refill? Force them out. */
if (i != 0)
goto refill;
/* Could not allocate any skbuffs. Try again later. */
mod_timer(&np->rx_refill_timer,
jiffies + (HZ/10));
return;
}
__skb_queue_tail(&np->rx_batch, skb);
}
@@ -554,6 +570,12 @@ static void network_alloc_rx_buffers(struct net_device *dev)
if (i < (np->rx_target/2))
return;
/* Adjust our fill target if we risked running out of buffers. */
if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
((np->rx_target *= 2) > np->rx_max_target))
np->rx_target = np->rx_max_target;
refill:
for (i = 0; ; i++) {
if ((skb = __skb_dequeue(&np->rx_batch)) == NULL)
break;
@@ -608,11 +630,6 @@ static void network_alloc_rx_buffers(struct net_device *dev)
/* Above is a suitable barrier to ensure backend will see requests. */
np->rx.req_prod_pvt = req_prod + i;
RING_PUSH_REQUESTS(&np->rx);
/* Adjust our fill target if we risked running out of buffers. */
if (((req_prod - np->rx.sring->rsp_prod) < (np->rx_target / 4)) &&
((np->rx_target *= 2) > np->rx_max_target))
np->rx_target = np->rx_max_target;
}
@@ -1077,6 +1094,10 @@ static int create_netdev(int handle, struct xenbus_device *dev,
np->rx_min_target = RX_MIN_TARGET;
np->rx_max_target = RX_MAX_TARGET;
init_timer(&np->rx_refill_timer);
np->rx_refill_timer.data = (unsigned long)netdev;
np->rx_refill_timer.function = rx_refill_timeout;
/* Initialise {tx,rx}_skbs as a free chain containing every entry. */
for (i = 0; i <= NET_TX_RING_SIZE; i++) {
np->tx_skbs[i] = (void *)((unsigned long) i+1);
@@ -1188,29 +1209,26 @@ static int netfront_remove(struct xenbus_device *dev)
DPRINTK("%s\n", dev->nodename);
netif_free(info);
kfree(info);
netif_disconnect_backend(info);
free_netdev(info->netdev);
return 0;
}
static void netif_free(struct netfront_info *info)
{
netif_disconnect_backend(info);
close_netdev(info);
}
static void close_netdev(struct netfront_info *info)
{
if (info->netdev) {
spin_lock_irq(&info->netdev->xmit_lock);
netif_stop_queue(info->netdev);
spin_unlock_irq(&info->netdev->xmit_lock);
#ifdef CONFIG_PROC_FS
xennet_proc_delif(info->netdev);
xennet_proc_delif(info->netdev);
#endif
unregister_netdev(info->netdev);
info->netdev = NULL;
}
del_timer_sync(&info->rx_refill_timer);
unregister_netdev(info->netdev);
}
@@ -1219,21 +1237,28 @@ static void netif_disconnect_backend(struct netfront_info *info)
/* Stop old i/f to prevent errors whilst we rebuild the state. */
spin_lock_irq(&info->tx_lock);
spin_lock(&info->rx_lock);
netif_stop_queue(info->netdev);
/* info->backend_state = BEST_DISCONNECTED; */
info->backend_state = BEST_DISCONNECTED;
spin_unlock(&info->rx_lock);
spin_unlock_irq(&info->tx_lock);
if (info->irq)
unbind_from_irqhandler(info->irq, info->netdev);
info->evtchn = info->irq = 0;
end_access(info->tx_ring_ref, info->tx.sring);
end_access(info->rx_ring_ref, info->rx.sring);
info->tx_ring_ref = GRANT_INVALID_REF;
info->rx_ring_ref = GRANT_INVALID_REF;
info->tx.sring = NULL;
info->rx.sring = NULL;
}
if (info->irq)
unbind_from_irqhandler(info->irq, info->netdev);
info->evtchn = info->irq = 0;
static void netif_free(struct netfront_info *info)
{
close_netdev(info);
netif_disconnect_backend(info);
free_netdev(info->netdev);
}
@@ -111,7 +111,6 @@ static ssize_t xenbus_dev_write(struct file *filp,
struct xenbus_dev_data *u = filp->private_data;
struct xenbus_dev_transaction *trans;
void *reply;
int err = 0;
if ((len + u->len) > sizeof(u->u.buffer))
return -EINVAL;
@@ -136,41 +135,36 @@ static ssize_t xenbus_dev_write(struct file *filp,
case XS_RM:
case XS_SET_PERMS:
reply = xenbus_dev_request_and_reply(&u->u.msg);
if (IS_ERR(reply)) {
err = PTR_ERR(reply);
} else {
if (u->u.msg.type == XS_TRANSACTION_START) {
trans = kmalloc(sizeof(*trans), GFP_KERNEL);
trans->handle = (struct xenbus_transaction *)
simple_strtoul(reply, NULL, 0);
list_add(&trans->list, &u->transactions);
} else if (u->u.msg.type == XS_TRANSACTION_END) {
list_for_each_entry(trans, &u->transactions,
list)
if ((unsigned long)trans->handle ==
(unsigned long)u->u.msg.tx_id)
break;
BUG_ON(&trans->list == &u->transactions);
list_del(&trans->list);
kfree(trans);
}
queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
queue_reply(u, (char *)reply, u->u.msg.len);
kfree(reply);
if (IS_ERR(reply))
return PTR_ERR(reply);
if (u->u.msg.type == XS_TRANSACTION_START) {
trans = kmalloc(sizeof(*trans), GFP_KERNEL);
if (!trans)
return -ENOMEM;
trans->handle = (struct xenbus_transaction *)
simple_strtoul(reply, NULL, 0);
list_add(&trans->list, &u->transactions);
} else if (u->u.msg.type == XS_TRANSACTION_END) {
list_for_each_entry(trans, &u->transactions, list)
if ((unsigned long)trans->handle ==
(unsigned long)u->u.msg.tx_id)
break;
BUG_ON(&trans->list == &u->transactions);
list_del(&trans->list);
kfree(trans);
}
queue_reply(u, (char *)&u->u.msg, sizeof(u->u.msg));
queue_reply(u, (char *)reply, u->u.msg.len);
kfree(reply);
break;
default:
err = -EINVAL;
break;
return -EINVAL;
}
if (err == 0) {
u->len = 0;
err = len;
}
return err;
u->len = 0;
return len;
}
static int xenbus_dev_open(struct inode *inode, struct file *filp)
@@ -542,14 +542,6 @@ static int xenbus_probe_node(struct xen_bus_type *bus,
const char *type,
const char *nodename)
{
#define CHECK_FAIL \
do { \
if (err) \
goto fail; \
} \
while (0) \
int err;
struct xenbus_device *xendev;
size_t stringlen;
@@ -584,19 +576,18 @@ static int xenbus_probe_node(struct xen_bus_type *bus,
xendev->dev.release = xenbus_dev_release;
err = bus->get_bus_id(xendev->dev.bus_id, xendev->nodename);
CHECK_FAIL;
if (err)
goto fail;
/* Register with generic device framework. */
err = device_register(&xendev->dev);
CHECK_FAIL;
if (err)
goto fail;
device_create_file(&xendev->dev, &dev_attr_nodename);
device_create_file(&xendev->dev, &dev_attr_devtype);
return 0;
#undef CHECK_FAIL
fail:
xenbus_dev_free(xendev);
return err;
@@ -372,7 +372,7 @@ HYPERVISOR_memory_op(
int ret;
__asm__ __volatile__ ( ";; mov r14=%2 ; mov r15=%3 ; mov r2=%1 ; break 0x1000 ;; mov %0=r8 ;;"
: "=r" (ret)
: "i" (__HYPERVISOR_console_io), "r"(cmd), "r"(arg)
: "i" (__HYPERVISOR_memory_op), "r"(cmd), "r"(arg)
: "r14","r15","r2","r8","memory" );
return ret;
}
+1
View File
@@ -12,6 +12,7 @@ SUBDIRS += firmware
SUBDIRS += security
SUBDIRS += console
SUBDIRS += xenmon
SUBDIRS += guest-headers
ifeq ($(VTPM_TOOLS),y)
SUBDIRS += vtpm_manager
SUBDIRS += vtpm
+2
View File
@@ -35,6 +35,8 @@ mk-symlinks: LINUX_ROOT=$(XEN_ROOT)/linux-2.6-xen-sparse
mk-symlinks:
mkdir -p xen
( cd xen && ln -sf ../$(XEN_ROOT)/xen/include/public/*.h . )
mkdir -p xen/hvm
( cd xen/hvm && ln -sf ../../$(XEN_ROOT)/xen/include/public/hvm/*.h . )
mkdir -p xen/io
( cd xen/io && ln -sf ../../$(XEN_ROOT)/xen/include/public/io/*.h . )
mkdir -p xen/linux
+6 -6
View File
@@ -119,8 +119,8 @@ xendebug_get_context (int xc_handle, uint32_t domid, uint32_t vcpu)
if ( !ctxt->valid[vcpu] )
{
if ( (rc = xc_domain_get_vcpu_context(xc_handle, domid, vcpu,
&ctxt->context[vcpu])) )
if ( (rc = xc_vcpu_getcontext(xc_handle, domid, vcpu,
&ctxt->context[vcpu])) )
return NULL;
ctxt->valid[vcpu] = true;
@@ -139,10 +139,10 @@ xendebug_set_context (int xc_handle, domain_context_p ctxt, uint32_t vcpu)
return -EINVAL;
op.interface_version = DOM0_INTERFACE_VERSION;
op.cmd = DOM0_SETDOMAININFO;
op.u.setdomaininfo.domain = ctxt->domid;
op.u.setdomaininfo.vcpu = vcpu;
op.u.setdomaininfo.ctxt = &ctxt->context[vcpu];
op.cmd = DOM0_SETVCPUCONTEXT;
op.u.setvcpucontext.domain = ctxt->domid;
op.u.setvcpucontext.vcpu = vcpu;
op.u.setvcpucontext.ctxt = &ctxt->context[vcpu];
if ( (rc = mlock(&ctxt->context[vcpu], sizeof(vcpu_guest_context_t))) )
return rc;
+7 -1
View File
@@ -28,7 +28,13 @@ name = "ExampleVMXDomain"
#-----------------------------------------------------------------------------
# the number of cpus guest platform has, default=1
vcpus=1
#vcpus=1
# enable/disalbe vmx guest ACPI, default=0 (disabled)
#acpi=0
# enable/disalbe vmx guest APIC, default=0 (disabled)
#apic=0
# List of which CPUS this domain is allowed to use, default Xen picks
#cpus = "" # leave to Xen to pick
+1 -1
View File
@@ -24,7 +24,7 @@ include $(XEN_ROOT)/tools/Rules.mk
# The emulator code lives in ROM space
TEXTADDR=0x000D0000
DEFINES=-DDEBUG -D_ACPI_ -DTEXTADDR=$(TEXTADDR)
DEFINES=-DDEBUG -DTEXTADDR=$(TEXTADDR)
XENINC=-I$(XEN_ROOT)/tools/libxc
LD = ld
+63 -20
View File
@@ -17,30 +17,73 @@
* this program; if not, write to the Free Software Foundation, Inc., 59 Temple
* Place - Suite 330, Boston, MA 02111-1307 USA.
*/
#include "../acpi/acpi2_0.h"
#include "../acpi/acpi_madt.h"
#include <xen/hvm/hvm_info_table.h>
#define NULL ((void*)0)
extern int puts(const char *s);
#define VCPU_NR_PAGE 0x0009F000
#define VCPU_NR_OFFSET 0x00000800
#define VCPU_MAGIC 0x76637075 /* "vcpu" */
static struct hvm_info_table *table = NULL;
/* xc_vmx_builder wrote vcpu block at 0x9F800. Return it. */
static int
get_vcpu_nr(void)
static int validate_hvm_info(struct hvm_info_table *t)
{
unsigned int *vcpus;
char signature[] = "HVM INFO";
uint8_t *ptr = (uint8_t *)t;
uint8_t sum = 0;
int i;
vcpus = (unsigned int *)(VCPU_NR_PAGE + VCPU_NR_OFFSET);
if (vcpus[0] != VCPU_MAGIC) {
puts("Bad vcpus magic, set vcpu number to 1 by default.\n");
return 1;
/* strncmp(t->signature, "HVM INFO", 8) */
for (i = 0; i < 8; i++) {
if (signature[i] != t->signature[i]) {
puts("Bad hvm info signature\n");
return 0;
}
}
return vcpus[1];
for (i = 0; i < t->length; i++)
sum += ptr[i];
return (sum == 0);
}
/* xc_vmx_builder wrote hvm info at 0x9F800. Return it. */
static struct hvm_info_table *
get_hvm_info_table(void)
{
struct hvm_info_table *t;
int i;
if (table != NULL)
return table;
t = (struct hvm_info_table *)HVM_INFO_PADDR;
if (!validate_hvm_info(t)) {
puts("Bad hvm info table\n");
return NULL;
}
table = t;
return table;
}
int
get_vcpu_nr(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->nr_vcpus : 1); /* default 1 vcpu */
}
int
get_acpi_enabled(void)
{
struct hvm_info_table *t = get_hvm_info_table();
return (t ? t->acpi_enabled : 0); /* default no acpi */
}
static void *
@@ -74,10 +117,10 @@ acpi_madt_get_madt(unsigned char *acpi_start)
return madt;
}
static void
static void
set_checksum(void *start, int checksum_offset, int len)
{
unsigned char sum = 0;
unsigned char sum = 0;
unsigned char *ptr;
ptr = start;
@@ -89,9 +132,9 @@ set_checksum(void *start, int checksum_offset, int len)
ptr[checksum_offset] = -sum;
}
static int
static int
acpi_madt_set_local_apics(
int nr_vcpu,
int nr_vcpu,
ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE *madt)
{
int i;
@@ -104,14 +147,14 @@ acpi_madt_set_local_apics(
madt->LocalApic[i].Length = sizeof (ACPI_LOCAL_APIC_STRUCTURE);
madt->LocalApic[i].AcpiProcessorId = i;
madt->LocalApic[i].ApicId = i;
madt->LocalApic[i].Flags = 1;
madt->LocalApic[i].Flags = 1;
}
madt->Header.Header.Length =
sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
sizeof(ACPI_MULTIPLE_APIC_DESCRIPTION_TABLE) -
(MAX_VIRT_CPUS - nr_vcpu)* sizeof(ACPI_LOCAL_APIC_STRUCTURE);
return 0;
return 0;
}
#define FIELD_OFFSET(TYPE,Field) ((unsigned int)(&(((TYPE *) 0)->Field)))
@@ -133,7 +176,7 @@ int acpi_madt_update(unsigned char *acpi_start)
madt, FIELD_OFFSET(ACPI_TABLE_HEADER, Checksum),
madt->Header.Header.Length);
return 0;
return 0;
}
/*
+1 -1
View File
@@ -24,7 +24,7 @@
#include <stdint.h>
#endif
#include <xen/vmx_assist.h>
#include <xen/hvm/vmx_assist.h>
#define NR_EXCEPTION_HANDLER 32
#define NR_INTERRUPT_HANDLERS 16
+10 -13
View File
@@ -24,12 +24,10 @@
#include "machine.h"
#include "roms.h"
#ifdef _ACPI_
#include "acpi.h"
#include "../acpi/acpi2_0.h" // for ACPI_PHYSICAL_ADDRESS
int acpi_madt_update(unsigned char* acpi_start);
#endif
int get_acpi_enabled(void);
/*
* C runtime start off
@@ -120,18 +118,17 @@ main(void)
memcpy((void *)0xC0000,
vgabios_stdvga, sizeof(vgabios_stdvga));
}
#ifdef _ACPI_
puts("Loading ACPI ...\n");
acpi_madt_update(acpi);
if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
/* make sure acpi table does not overlap rombios
* currently acpi less than 8K will be OK.
*/
memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
if (get_acpi_enabled() != 0) {
puts("Loading ACPI ...\n");
acpi_madt_update((unsigned char*)acpi);
if (ACPI_PHYSICAL_ADDRESS+sizeof(acpi) <= 0xF0000) {
/* make sure acpi table does not overlap rombios
* currently acpi less than 8K will be OK.
*/
memcpy((void *)ACPI_PHYSICAL_ADDRESS, acpi, sizeof(acpi));
}
}
#endif
puts("Loading VMXAssist ...\n");
memcpy((void *)TEXTADDR, vmxassist, sizeof(vmxassist));
+11
View File
@@ -0,0 +1,11 @@
XEN_ROOT=../..
linuxsparsetree = $(XEN_ROOT)/linux-2.6-xen-sparse
check:
install:
mkdir -p $(DESTDIR)/usr/include/xen/linux
install -m0644 $(linuxsparsetree)/include/asm-xen/linux-public/*.h $(DESTDIR)/usr/include/xen/linux
clean:
+1 -1
View File
@@ -23,7 +23,7 @@
*/
#include "vl.h"
#include <xenctrl.h>
#include <xen/io/ioreq.h>
#include <xen/hvm/ioreq.h>
//#define DEBUG_PIT
+1 -1
View File
@@ -23,7 +23,7 @@
*/
#include "vl.h"
#include <xenctrl.h>
#include <xen/io/ioreq.h>
#include <xen/hvm/ioreq.h>
/* debug PIC */
//#define DEBUG_PIC
+1 -1
View File
@@ -22,7 +22,7 @@
* THE SOFTWARE.
*/
#include "xenctrl.h"
#include <xen/io/ioreq.h>
#include <xen/hvm/ioreq.h>
#include <stdio.h>
#include "cpu.h"
#include "cpu-all.h"
+1 -1
View File
@@ -48,7 +48,7 @@
#include <sys/ioctl.h>
#include <xenctrl.h>
#include <xen/io/ioreq.h>
#include <xen/hvm/ioreq.h>
#include <xen/linux/evtchn.h>
#include "cpu.h"
+1
View File
@@ -2948,6 +2948,7 @@ int main(int argc, char **argv)
case QEMU_OPTION_vcpus:
vcpus = atoi(optarg);
fprintf(logfile, "qemu: the number of cpus is %d\n", vcpus);
break;
case QEMU_OPTION_pci:
pci_enabled = 1;
break;
+1 -1
View File
@@ -55,7 +55,7 @@ xc_domain_dumpcore(int xc_handle,
}
for (i = 0; i < info.max_vcpu_id; i++)
if (xc_domain_get_vcpu_context(xc_handle, domid,
if (xc_vcpu_getcontext(xc_handle, domid,
i, &ctxt[nr_vcpus]) == 0)
nr_vcpus++;
+53 -21
View File
@@ -58,16 +58,16 @@ int xc_domain_destroy(int xc_handle,
return do_dom0_op(xc_handle, &op);
}
int xc_domain_pincpu(int xc_handle,
uint32_t domid,
int vcpu,
cpumap_t cpumap)
int xc_vcpu_setaffinity(int xc_handle,
uint32_t domid,
int vcpu,
cpumap_t cpumap)
{
DECLARE_DOM0_OP;
op.cmd = DOM0_PINCPUDOMAIN;
op.u.pincpudomain.domain = (domid_t)domid;
op.u.pincpudomain.vcpu = vcpu;
op.u.pincpudomain.cpumap = cpumap;
op.cmd = DOM0_SETVCPUAFFINITY;
op.u.setvcpuaffinity.domain = (domid_t)domid;
op.u.setvcpuaffinity.vcpu = vcpu;
op.u.setvcpuaffinity.cpumap = cpumap;
return do_dom0_op(xc_handle, &op);
}
@@ -155,7 +155,7 @@ int xc_domain_getinfolist(int xc_handle,
return ret;
}
int xc_domain_get_vcpu_context(int xc_handle,
int xc_vcpu_getcontext(int xc_handle,
uint32_t domid,
uint32_t vcpu,
vcpu_guest_context_t *ctxt)
@@ -345,10 +345,10 @@ int xc_domain_sethandle(int xc_handle, uint32_t domid,
return do_dom0_op(xc_handle, &op);
}
int xc_domain_get_vcpu_info(int xc_handle,
uint32_t domid,
uint32_t vcpu,
xc_vcpuinfo_t *info)
int xc_vcpu_getinfo(int xc_handle,
uint32_t domid,
uint32_t vcpu,
xc_vcpuinfo_t *info)
{
int rc;
DECLARE_DOM0_OP;
@@ -380,18 +380,18 @@ int xc_domain_ioport_permission(int xc_handle,
return do_dom0_op(xc_handle, &op);
}
int xc_domain_setinfo(int xc_handle,
uint32_t domid,
uint32_t vcpu,
vcpu_guest_context_t *ctxt)
int xc_vcpu_setcontext(int xc_handle,
uint32_t domid,
uint32_t vcpu,
vcpu_guest_context_t *ctxt)
{
dom0_op_t op;
int rc;
op.cmd = DOM0_SETDOMAININFO;
op.u.setdomaininfo.domain = domid;
op.u.setdomaininfo.vcpu = vcpu;
op.u.setdomaininfo.ctxt = ctxt;
op.cmd = DOM0_SETVCPUCONTEXT;
op.u.setvcpucontext.domain = domid;
op.u.setvcpucontext.vcpu = vcpu;
op.u.setvcpucontext.ctxt = ctxt;
if ( (rc = mlock(ctxt, sizeof(*ctxt))) != 0 )
return rc;
@@ -404,6 +404,38 @@ int xc_domain_setinfo(int xc_handle,
}
int xc_domain_irq_permission(int xc_handle,
uint32_t domid,
uint8_t pirq,
uint8_t allow_access)
{
dom0_op_t op;
op.cmd = DOM0_IRQ_PERMISSION;
op.u.irq_permission.domain = domid;
op.u.irq_permission.pirq = pirq;
op.u.irq_permission.allow_access = allow_access;
return do_dom0_op(xc_handle, &op);
}
int xc_domain_iomem_permission(int xc_handle,
uint32_t domid,
unsigned long first_pfn,
unsigned long nr_pfns,
uint8_t allow_access)
{
dom0_op_t op;
op.cmd = DOM0_IOMEM_PERMISSION;
op.u.iomem_permission.domain = domid;
op.u.iomem_permission.first_pfn = first_pfn;
op.u.iomem_permission.nr_pfns = nr_pfns;
op.u.iomem_permission.allow_access = allow_access;
return do_dom0_op(xc_handle, &op);
}
/*
* Local variables:
* mode: C
+7 -6
View File
@@ -5,7 +5,7 @@
#include <stdlib.h>
#include <zlib.h>
#include "xen/arch-ia64.h"
#include <xen/io/ioreq.h>
#include <xen/hvm/ioreq.h>
/* this is a very ugly way of getting FPSR_DEFAULT. struct ia64_fpreg is
* mysteriously declared in two places: /usr/include/asm/fpu.h and
@@ -627,6 +627,7 @@ int xc_vmx_build(int xc_handle,
unsigned int control_evtchn,
unsigned int lapic,
unsigned int vcpus,
unsigned int acpi,
unsigned int store_evtchn,
unsigned long *store_mfn)
{
@@ -663,7 +664,7 @@ int xc_vmx_build(int xc_handle,
goto error_out;
}
if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) ){
if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) ){
PERROR("Could not get vcpu context");
goto error_out;
}
@@ -687,11 +688,11 @@ int xc_vmx_build(int xc_handle,
memset( &launch_op, 0, sizeof(launch_op) );
launch_op.u.setdomaininfo.domain = (domid_t)domid;
launch_op.u.setdomaininfo.vcpu = 0;
launch_op.u.setdomaininfo.ctxt = ctxt;
launch_op.u.setvcpucontext.domain = (domid_t)domid;
launch_op.u.setvcpucontext.vcpu = 0;
launch_op.u.setvcpucontext.ctxt = ctxt;
launch_op.cmd = DOM0_SETDOMAININFO;
launch_op.cmd = DOM0_SETVCPUCONTEXT;
rc = do_dom0_op(xc_handle, &launch_op);
return rc;
+9 -5
View File
@@ -393,10 +393,14 @@ static int setup_guest(int xc_handle,
start_info->store_evtchn = store_evtchn;
start_info->console_mfn = nr_pages - 1;
start_info->console_evtchn = console_evtchn;
start_info->nr_pages = nr_pages; // FIXME?: nr_pages - 2 ????
if ( initrd_len != 0 )
{
ctxt->initrd.start = vinitrd_start;
ctxt->initrd.size = initrd_len;
} else {
ctxt->initrd.start = 0;
ctxt->initrd.size = 0;
}
strncpy((char *)ctxt->cmdline, cmdline, IA64_COMMAND_LINE_SIZE);
ctxt->cmdline[IA64_COMMAND_LINE_SIZE-1] = '\0';
@@ -790,7 +794,7 @@ int xc_linux_build(int xc_handle,
goto error_out;
}
if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
{
PERROR("Could not get vcpu context");
goto error_out;
@@ -893,11 +897,11 @@ int xc_linux_build(int xc_handle,
memset( &launch_op, 0, sizeof(launch_op) );
launch_op.u.setdomaininfo.domain = (domid_t)domid;
launch_op.u.setdomaininfo.vcpu = 0;
launch_op.u.setdomaininfo.ctxt = ctxt;
launch_op.u.setvcpucontext.domain = (domid_t)domid;
launch_op.u.setvcpucontext.vcpu = 0;
launch_op.u.setvcpucontext.ctxt = ctxt;
launch_op.cmd = DOM0_SETDOMAININFO;
launch_op.cmd = DOM0_SETVCPUCONTEXT;
rc = xc_dom0_op(xc_handle, &launch_op);
return rc;
+5 -5
View File
@@ -171,7 +171,7 @@ int xc_linux_restore(int xc_handle, int io_fd,
/* Only have to worry about vcpu 0 even for SMP */
if (xc_domain_get_vcpu_context( xc_handle, dom, 0, &ctxt)) {
if (xc_vcpu_getcontext( xc_handle, dom, 0, &ctxt)) {
ERR("Could not get vcpu context");
goto out;
}
@@ -735,10 +735,10 @@ int xc_linux_restore(int xc_handle, int io_fd,
DPRINTF("Domain ready to be built.\n");
op.cmd = DOM0_SETDOMAININFO;
op.u.setdomaininfo.domain = (domid_t)dom;
op.u.setdomaininfo.vcpu = 0;
op.u.setdomaininfo.ctxt = &ctxt;
op.cmd = DOM0_SETVCPUCONTEXT;
op.u.setvcpucontext.domain = (domid_t)dom;
op.u.setvcpucontext.vcpu = 0;
op.u.setvcpucontext.ctxt = &ctxt;
rc = xc_dom0_op(xc_handle, &op);
if (rc != 0) {
+2 -2
View File
@@ -382,7 +382,7 @@ static int suspend_and_state(int xc_handle, int io_fd, int dom,
return -1;
}
if ( xc_domain_get_vcpu_context(xc_handle, dom, 0 /* XXX */, ctxt))
if ( xc_vcpu_getcontext(xc_handle, dom, 0 /* XXX */, ctxt))
ERR("Could not get vcpu context");
@@ -643,7 +643,7 @@ int xc_linux_save(int xc_handle, int io_fd, uint32_t dom, uint32_t max_iters,
}
/* Only have to worry about vcpu 0 even for SMP */
if (xc_domain_get_vcpu_context(xc_handle, dom, 0, &ctxt)) {
if (xc_vcpu_getcontext(xc_handle, dom, 0, &ctxt)) {
ERR("Could not get vcpu context");
goto out;
}
+1 -1
View File
@@ -74,7 +74,7 @@ unsigned long xc_translate_foreign_address(int xc_handle, uint32_t dom,
#define pt_levels 4
#endif
if (xc_domain_get_vcpu_context(xc_handle, dom, vcpu, &ctx) != 0) {
if (xc_vcpu_getcontext(xc_handle, dom, vcpu, &ctx) != 0) {
fprintf(stderr, "failed to retreive vcpu context\n");
goto out;
}
+6 -7
View File
@@ -33,7 +33,7 @@ fetch_regs(int xc_handle, int cpu, int *online)
if (online)
*online = 0;
if ( !(regs_valid & (1 << cpu)) ) {
retval = xc_domain_get_vcpu_context(xc_handle, current_domid,
retval = xc_vcpu_getcontext(xc_handle, current_domid,
cpu, &ctxt[cpu]);
if ( retval )
goto done;
@@ -43,8 +43,7 @@ fetch_regs(int xc_handle, int cpu, int *online)
if ( online == NULL )
goto done;
retval = xc_domain_get_vcpu_info(xc_handle, current_domid,
cpu, &info);
retval = xc_vcpu_getinfo(xc_handle, current_domid, cpu, &info);
*online = info.online;
done:
@@ -395,7 +394,7 @@ xc_ptrace(
case PTRACE_SETREGS:
SET_XC_REGS(((struct gdb_regs *)data), ctxt[cpu].user_regs);
retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]);
if (retval)
goto error_out;
break;
@@ -405,7 +404,7 @@ xc_ptrace(
* during single-stepping - but that just seems retarded
*/
ctxt[cpu].user_regs.eflags |= PSL_T;
retval = xc_domain_setinfo(xc_handle, current_domid, cpu, &ctxt[cpu]);
retval = xc_vcpu_setcontext(xc_handle, current_domid, cpu, &ctxt[cpu]);
if ( retval )
{
perror("dom0 op failed");
@@ -423,8 +422,8 @@ xc_ptrace(
/* Clear trace flag */
if ( ctxt[cpu].user_regs.eflags & PSL_T ) {
ctxt[cpu].user_regs.eflags &= ~PSL_T;
retval = xc_domain_setinfo(xc_handle, current_domid,
cpu, &ctxt[cpu]);
retval = xc_vcpu_setcontext(xc_handle, current_domid,
cpu, &ctxt[cpu]);
if ( retval ) {
perror("dom0 op failed");
goto error_out;
+78 -71
View File
@@ -9,7 +9,8 @@
#include <stdlib.h>
#include <unistd.h>
#include <zlib.h>
#include <xen/io/ioreq.h>
#include <xen/hvm/hvm_info_table.h>
#include <xen/hvm/ioreq.h>
#define VMX_LOADER_ENTR_ADDR 0x00100000
@@ -33,9 +34,6 @@
#define E820_MAP_NR_OFFSET 0x000001E8
#define E820_MAP_OFFSET 0x000002D0
#define VCPU_NR_PAGE 0x0009F000
#define VCPU_NR_OFFSET 0x00000800
struct e820entry {
uint64_t addr;
uint64_t size;
@@ -119,26 +117,50 @@ static unsigned char build_e820map(void *e820_page, unsigned long mem_size)
return (*(((unsigned char *)e820_page) + E820_MAP_NR_OFFSET) = nr_map);
}
/*
* Use E820 reserved memory 0x9F800 to pass number of vcpus to vmxloader
* vmxloader will use it to config ACPI MADT table
*/
#define VCPU_MAGIC 0x76637075 /* "vcpu" */
static int set_vcpu_nr(int xc_handle, uint32_t dom,
unsigned long *pfn_list, unsigned int vcpus)
static void
set_hvm_info_checksum(struct hvm_info_table *t)
{
char *va_map;
unsigned int *va_vcpus;
uint8_t *ptr = (uint8_t *)t, sum = 0;
unsigned int i;
va_map = xc_map_foreign_range(xc_handle, dom,
PAGE_SIZE, PROT_READ|PROT_WRITE,
pfn_list[VCPU_NR_PAGE >> PAGE_SHIFT]);
t->checksum = 0;
for (i = 0; i < t->length; i++)
sum += *ptr++;
t->checksum = -sum;
}
/*
* Use E820 reserved memory 0x9F800 to pass HVM info to vmxloader
* vmxloader will use this info to set BIOS accordingly
*/
static int set_hvm_info(int xc_handle, uint32_t dom,
unsigned long *pfn_list, unsigned int vcpus,
unsigned int acpi, unsigned int apic)
{
char *va_map;
struct hvm_info_table *va_hvm;
va_map = xc_map_foreign_range(
xc_handle,
dom,
PAGE_SIZE,
PROT_READ|PROT_WRITE,
pfn_list[HVM_INFO_PFN]);
if ( va_map == NULL )
return -1;
va_vcpus = (unsigned int *)(va_map + VCPU_NR_OFFSET);
va_vcpus[0] = VCPU_MAGIC;
va_vcpus[1] = vcpus;
va_hvm = (struct hvm_info_table *)(va_map + HVM_INFO_OFFSET);
memset(va_hvm, 0, sizeof(*va_hvm));
strncpy(va_hvm->signature, "HVM INFO", 8);
va_hvm->length = sizeof(struct hvm_info_table);
va_hvm->acpi_enabled = acpi;
va_hvm->apic_enabled = apic;
va_hvm->nr_vcpus = vcpus;
set_hvm_info_checksum(va_hvm);
munmap(va_map, PAGE_SIZE);
@@ -279,8 +301,9 @@ static int setup_guest(int xc_handle,
vcpu_guest_context_t *ctxt,
unsigned long shared_info_frame,
unsigned int control_evtchn,
unsigned int lapic,
unsigned int vcpus,
unsigned int acpi,
unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn)
{
@@ -490,20 +513,14 @@ static int setup_guest(int xc_handle,
goto error_out;
}
if (set_vcpu_nr(xc_handle, dom, page_array, vcpus)) {
fprintf(stderr, "Couldn't set vcpu number for VMX guest.\n");
if ( set_hvm_info(xc_handle, dom, page_array, vcpus, acpi, apic) ) {
fprintf(stderr, "Couldn't set hvm info for VMX guest.\n");
goto error_out;
}
*store_mfn = page_array[(v_end-2) >> PAGE_SHIFT];
if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
goto error_out;
shared_page_frame = (v_end - PAGE_SIZE) >> PAGE_SHIFT;
if ((e820_page = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0)
if ( (e820_page = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[E820_MAP_PAGE >> PAGE_SHIFT])) == 0 )
goto error_out;
memset(e820_page, 0, PAGE_SIZE);
e820_map_nr = build_e820map(e820_page, v_end);
@@ -518,26 +535,30 @@ static int setup_guest(int xc_handle,
munmap(e820_page, PAGE_SIZE);
/* shared_info page starts its life empty. */
if ((shared_info = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
shared_info_frame)) == 0)
if ( (shared_info = xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
shared_info_frame)) == 0 )
goto error_out;
memset(shared_info, 0, sizeof(shared_info_t));
/* Mask all upcalls... */
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
shared_info->vcpu_info[i].evtchn_upcall_mask = 1;
munmap(shared_info, PAGE_SIZE);
/* Populate the event channel port in the shared page */
if ((sp = (shared_iopage_t *) xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
page_array[shared_page_frame])) == 0)
shared_page_frame = page_array[(v_end >> PAGE_SHIFT) - 1];
if ( (sp = (shared_iopage_t *) xc_map_foreign_range(
xc_handle, dom, PAGE_SIZE, PROT_READ|PROT_WRITE,
shared_page_frame)) == 0 )
goto error_out;
memset(sp, 0, PAGE_SIZE);
sp->sp_global.eport = control_evtchn;
munmap(sp, PAGE_SIZE);
*store_mfn = page_array[(v_end >> PAGE_SHIFT) - 2];
if ( xc_clear_domain_page(xc_handle, dom, *store_mfn) )
goto error_out;
/* Send the page update requests down to the hypervisor. */
if ( xc_finish_mmu_updates(xc_handle, mmu) )
goto error_out;
@@ -559,7 +580,7 @@ static int setup_guest(int xc_handle,
ctxt->user_regs.eax = 0;
ctxt->user_regs.esp = 0;
ctxt->user_regs.ebx = 0; /* startup_32 expects this to be 0 to signal boot cpu */
ctxt->user_regs.ecx = lapic;
ctxt->user_regs.ecx = 0;
ctxt->user_regs.esi = 0;
ctxt->user_regs.edi = 0;
ctxt->user_regs.ebp = 0;
@@ -574,36 +595,14 @@ static int setup_guest(int xc_handle,
return -1;
}
#define VMX_FEATURE_FLAG 0x20
static int vmx_identify(void)
{
int eax, ecx;
__asm__ __volatile__ (
#if defined(__i386__)
"push %%ebx; cpuid; pop %%ebx"
#elif defined(__x86_64__)
"push %%rbx; cpuid; pop %%rbx"
#endif
: "=a" (eax), "=c" (ecx)
: "0" (1)
: "dx");
if (!(ecx & VMX_FEATURE_FLAG)) {
return -1;
}
return 0;
}
int xc_vmx_build(int xc_handle,
uint32_t domid,
int memsize,
const char *image_name,
unsigned int control_evtchn,
unsigned int lapic,
unsigned int vcpus,
unsigned int acpi,
unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn)
{
@@ -613,10 +612,18 @@ int xc_vmx_build(int xc_handle,
unsigned long nr_pages;
char *image = NULL;
unsigned long image_size;
xen_capabilities_info_t xen_caps;
if ( vmx_identify() < 0 )
if ( (rc = xc_version(xc_handle, XENVER_capabilities, &xen_caps)) != 0 )
{
PERROR("CPU doesn't support VMX Extensions");
PERROR("Failed to get xen version info");
goto error_out;
}
if ( !strstr(xen_caps, "hvm") )
{
PERROR("CPU doesn't support VMX Extensions or "
"CPU VMX Extensions are not turned on");
goto error_out;
}
@@ -644,7 +651,7 @@ int xc_vmx_build(int xc_handle,
goto error_out;
}
if ( xc_domain_get_vcpu_context(xc_handle, domid, 0, ctxt) )
if ( xc_vcpu_getcontext(xc_handle, domid, 0, ctxt) )
{
PERROR("Could not get vcpu context");
goto error_out;
@@ -659,7 +666,7 @@ int xc_vmx_build(int xc_handle,
if ( setup_guest(xc_handle, domid, memsize, image, image_size, nr_pages,
ctxt, op.u.getdomaininfo.shared_info_frame, control_evtchn,
lapic, vcpus, store_evtchn, store_mfn) < 0)
vcpus, acpi, apic, store_evtchn, store_mfn) < 0)
{
ERROR("Error constructing guest OS");
goto error_out;
@@ -701,11 +708,11 @@ int xc_vmx_build(int xc_handle,
memset( &launch_op, 0, sizeof(launch_op) );
launch_op.u.setdomaininfo.domain = (domid_t)domid;
launch_op.u.setdomaininfo.vcpu = 0;
launch_op.u.setdomaininfo.ctxt = ctxt;
launch_op.u.setvcpucontext.domain = (domid_t)domid;
launch_op.u.setvcpucontext.vcpu = 0;
launch_op.u.setvcpucontext.ctxt = ctxt;
launch_op.cmd = DOM0_SETDOMAININFO;
launch_op.cmd = DOM0_SETVCPUCONTEXT;
rc = xc_dom0_op(xc_handle, &launch_op);
return rc;
+26 -15
View File
@@ -181,10 +181,11 @@ int xc_domain_unpause(int xc_handle,
*/
int xc_domain_destroy(int xc_handle,
uint32_t domid);
int xc_domain_pincpu(int xc_handle,
uint32_t domid,
int vcpu,
cpumap_t cpumap);
int xc_vcpu_setaffinity(int xc_handle,
uint32_t domid,
int vcpu,
cpumap_t cpumap);
/**
* This function will return information about one or more domains. It is
@@ -208,7 +209,7 @@ int xc_domain_getinfo(int xc_handle,
/**
* This function will set the vcpu context for the specified domain.
* This function will set the execution context for the specified vcpu.
*
* @parm xc_handle a handle to an open hypervisor interface
* @parm domid the domain to set the vcpu context for
@@ -216,10 +217,10 @@ int xc_domain_getinfo(int xc_handle,
* @parm ctxt pointer to the the cpu context with the values to set
* @return the number of domains enumerated or -1 on error
*/
int xc_domain_setinfo(int xc_handle,
uint32_t domid,
uint32_t vcpu,
vcpu_guest_context_t *ctxt);
int xc_vcpu_setcontext(int xc_handle,
uint32_t domid,
uint32_t vcpu,
vcpu_guest_context_t *ctxt);
/**
* This function will return information about one or more domains, using a
* single hypercall. The domain information will be stored into the supplied
@@ -249,17 +250,16 @@ int xc_domain_getinfolist(int xc_handle,
* domain
* @return 0 on success, -1 on failure
*/
int xc_domain_get_vcpu_context(int xc_handle,
int xc_vcpu_getcontext(int xc_handle,
uint32_t domid,
uint32_t vcpu,
vcpu_guest_context_t *ctxt);
typedef dom0_getvcpuinfo_t xc_vcpuinfo_t;
int xc_domain_get_vcpu_info(int xc_handle,
uint32_t domid,
uint32_t vcpu,
xc_vcpuinfo_t *info);
int xc_vcpu_getinfo(int xc_handle,
uint32_t domid,
uint32_t vcpu,
xc_vcpuinfo_t *info);
int xc_domain_setcpuweight(int xc_handle,
uint32_t domid,
@@ -380,6 +380,17 @@ int xc_domain_ioport_permission(int xc_handle,
uint32_t nr_ports,
uint32_t allow_access);
int xc_domain_irq_permission(int xc_handle,
uint32_t domid,
uint8_t pirq,
uint8_t allow_access);
int xc_domain_iomem_permission(int xc_handle,
uint32_t domid,
unsigned long first_pfn,
unsigned long nr_pfns,
uint8_t allow_access);
unsigned long xc_make_page_below_4G(int xc_handle, uint32_t domid,
unsigned long mfn);
+2 -1
View File
@@ -56,8 +56,9 @@ int xc_vmx_build(int xc_handle,
int memsize,
const char *image_name,
unsigned int control_evtchn,
unsigned int lapic,
unsigned int vcpus,
unsigned int acpi,
unsigned int apic,
unsigned int store_evtchn,
unsigned long *store_mfn);
+80 -13
View File
@@ -135,9 +135,9 @@ static PyObject *pyxc_domain_destroy(XcObject *self, PyObject *args)
}
static PyObject *pyxc_domain_pincpu(XcObject *self,
PyObject *args,
PyObject *kwds)
static PyObject *pyxc_vcpu_setaffinity(XcObject *self,
PyObject *args,
PyObject *kwds)
{
uint32_t dom;
int vcpu = 0, i;
@@ -157,7 +157,7 @@ static PyObject *pyxc_domain_pincpu(XcObject *self,
cpumap |= (cpumap_t)1 << PyInt_AsLong(PyList_GetItem(cpulist, i));
}
if ( xc_domain_pincpu(self->xc_handle, dom, vcpu, cpumap) != 0 )
if ( xc_vcpu_setaffinity(self->xc_handle, dom, vcpu, cpumap) != 0 )
return PyErr_SetFromErrno(xc_error);
Py_INCREF(zero);
@@ -297,7 +297,7 @@ static PyObject *pyxc_vcpu_getinfo(XcObject *self,
&dom, &vcpu) )
return NULL;
rc = xc_domain_get_vcpu_info(self->xc_handle, dom, vcpu, &info);
rc = xc_vcpu_getinfo(self->xc_handle, dom, vcpu, &info);
if ( rc < 0 )
return PyErr_SetFromErrno(xc_error);
@@ -362,21 +362,23 @@ static PyObject *pyxc_vmx_build(XcObject *self,
uint32_t dom;
char *image;
int control_evtchn, store_evtchn;
int vcpus = 1;
int lapic = 0;
int memsize;
int vcpus = 1;
int acpi = 0;
int apic = 0;
unsigned long store_mfn = 0;
static char *kwd_list[] = { "dom", "control_evtchn", "store_evtchn",
"memsize", "image", "lapic", "vcpus", NULL };
"memsize", "image", "vcpus", "acpi", "apic",
NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisii", kwd_list,
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iiiisiii", kwd_list,
&dom, &control_evtchn, &store_evtchn,
&memsize, &image, &lapic, &vcpus) )
&memsize, &image, &vcpus, &acpi, &apic) )
return NULL;
if ( xc_vmx_build(self->xc_handle, dom, memsize, image, control_evtchn,
lapic, vcpus, store_evtchn, &store_mfn) != 0 )
vcpus, acpi, apic, store_evtchn, &store_mfn) != 0 )
return PyErr_SetFromErrno(xc_error);
return Py_BuildValue("{s:i}", "store_mfn", store_mfn);
@@ -774,6 +776,52 @@ static PyObject *pyxc_domain_ioport_permission(XcObject *self,
return zero;
}
static PyObject *pyxc_domain_irq_permission(PyObject *self,
PyObject *args,
PyObject *kwds)
{
XcObject *xc = (XcObject *)self;
uint32_t dom;
int pirq, allow_access, ret;
static char *kwd_list[] = { "dom", "pirq", "allow_access", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
&dom, &pirq, &allow_access) )
return NULL;
ret = xc_domain_irq_permission(
xc->xc_handle, dom, pirq, allow_access);
if ( ret != 0 )
return PyErr_SetFromErrno(xc_error);
Py_INCREF(zero);
return zero;
}
static PyObject *pyxc_domain_iomem_permission(PyObject *self,
PyObject *args,
PyObject *kwds)
{
XcObject *xc = (XcObject *)self;
uint32_t dom;
unsigned long first_pfn, nr_pfns, allow_access, ret;
static char *kwd_list[] = { "dom", "first_pfn", "nr_pfns", "allow_access", NULL };
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "illi", kwd_list,
&dom, &first_pfn, &nr_pfns, &allow_access) )
return NULL;
ret = xc_domain_iomem_permission(
xc->xc_handle, dom, first_pfn, nr_pfns, allow_access);
if ( ret != 0 )
return PyErr_SetFromErrno(xc_error);
Py_INCREF(zero);
return zero;
}
static PyObject *dom_op(XcObject *self, PyObject *args,
int (*fn)(int, uint32_t))
@@ -842,8 +890,8 @@ static PyMethodDef pyxc_methods[] = {
" dom [int]: Identifier of domain to be destroyed.\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "domain_pincpu",
(PyCFunction)pyxc_domain_pincpu,
{ "vcpu_setaffinity",
(PyCFunction)pyxc_vcpu_setaffinity,
METH_VARARGS | METH_KEYWORDS, "\n"
"Pin a VCPU to a specified set CPUs.\n"
" dom [int]: Identifier of domain to which VCPU belongs.\n"
@@ -1070,6 +1118,25 @@ static PyMethodDef pyxc_methods[] = {
" allow_access [int]: Non-zero means enable access; else disable access\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "domain_irq_permission",
(PyCFunction)pyxc_domain_irq_permission,
METH_VARARGS | METH_KEYWORDS, "\n"
"Allow a domain access to a physical IRQ\n"
" dom [int]: Identifier of domain to be allowed access.\n"
" pirq [int]: The Physical IRQ\n"
" allow_access [int]: Non-zero means enable access; else disable access\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "domain_iomem_permission",
(PyCFunction)pyxc_domain_iomem_permission,
METH_VARARGS | METH_KEYWORDS, "\n"
"Allow a domain access to a range of IO memory pages\n"
" dom [int]: Identifier of domain to be allowed access.\n"
" first_pfn [long]: First page of I/O Memory\n"
" nr_pfns [long]: Number of pages of I/O Memory (>0)\n"
" allow_access [int]: Non-zero means enable access; else disable access\n\n"
"Returns: [int] 0 on success; -1 on error.\n" },
{ "pages_to_kib",
(PyCFunction)pyxc_pages_to_kib,
METH_VARARGS, "\n"
+1 -1
View File
@@ -443,7 +443,7 @@ class XendDomain:
cpumap = map(lambda x: int(x),
cpumap.replace("[", "").replace("]", "").split(","))
try:
return xc.domain_pincpu(dominfo.getDomid(), vcpu, cpumap)
return xc.vcpu_setaffinity(dominfo.getDomid(), vcpu, cpumap)
except Exception, ex:
raise XendError(str(ex))
+1 -1
View File
@@ -1179,7 +1179,7 @@ class XendDomainInfo:
for v in range(0, self.info['max_vcpu_id']+1):
# pincpu takes a list of ints
cpu = [ int( cpus[v % len(cpus)] ) ]
xc.domain_pincpu(self.domid, v, cpu)
xc.vcpu_setaffinity(self.domid, v, cpu)
m = self.image.getDomainMemory(self.info['memory'] * 1024)
balloon.free(m)
+49 -43
View File
@@ -189,11 +189,16 @@ class VmxImageHandler(ImageHandler):
def configure(self, imageConfig, deviceConfig):
ImageHandler.configure(self, imageConfig, deviceConfig)
info = xc.xeninfo()
if not 'hvm' in info['xen_caps']:
raise VmError("vmx: not an Intel VT platform, we stop creating!")
self.dmargs = self.parseDeviceModelArgs(imageConfig, deviceConfig)
self.device_model = sxp.child_value(imageConfig, 'device_model')
if not self.device_model:
raise VmError("vmx: missing device model")
self.display = sxp.child_value(imageConfig, 'display')
self.xauthority = sxp.child_value(imageConfig, 'xauthority')
self.vm.storeVm(("image/dmargs", " ".join(self.dmargs)),
("image/device-model", self.device_model),
@@ -204,10 +209,8 @@ class VmxImageHandler(ImageHandler):
self.dmargs += self.configVNC(imageConfig)
self.lapic = 0
lapic = sxp.child_value(imageConfig, 'lapic')
if not lapic is None:
self.lapic = int(lapic)
self.acpi = int(sxp.child_value(imageConfig, 'acpi', 0))
self.apic = int(sxp.child_value(imageConfig, 'apic', 0))
def buildDomain(self):
# Create an event channel
@@ -222,17 +225,18 @@ class VmxImageHandler(ImageHandler):
log.debug("control_evtchn = %d", self.device_channel)
log.debug("store_evtchn = %d", store_evtchn)
log.debug("memsize = %d", self.vm.getMemoryTarget() / 1024)
log.debug("lapic = %d", self.lapic)
log.debug("vcpus = %d", self.vm.getVCpuCount())
log.debug("acpi = %d", self.acpi)
log.debug("apic = %d", self.apic)
return xc.vmx_build(dom = self.vm.getDomid(),
image = self.kernel,
control_evtchn = self.device_channel,
store_evtchn = store_evtchn,
memsize = self.vm.getMemoryTarget() / 1024,
lapic = self.lapic,
vcpus = self.vm.getVCpuCount())
vcpus = self.vm.getVCpuCount(),
acpi = self.acpi,
apic = self.apic)
# Return a list of cmd line args to the device models based on the
# xm config file
@@ -264,44 +268,44 @@ class VmxImageHandler(ImageHandler):
nics = 0
for (name, info) in deviceConfig:
if name == 'vbd':
uname = sxp.child_value(info, 'uname')
typedev = sxp.child_value(info, 'dev')
(_, vbdparam) = string.split(uname, ':', 1)
if re.match('^ioemu:', typedev):
(emtype, vbddev) = string.split(typedev, ':', 1)
else:
emtype = 'vbd'
vbddev = typedev
if emtype != 'ioemu':
continue;
vbddev_list = ['hda', 'hdb', 'hdc', 'hdd']
if vbddev not in vbddev_list:
raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd")
ret.append("-%s" % vbddev)
ret.append("%s" % vbdparam)
uname = sxp.child_value(info, 'uname')
typedev = sxp.child_value(info, 'dev')
(_, vbdparam) = string.split(uname, ':', 1)
if 'ioemu:' in typedev:
(emtype, vbddev) = string.split(typedev, ':', 1)
else:
emtype = 'vbd'
vbddev = typedev
if emtype == 'vbd':
continue;
vbddev_list = ['hda', 'hdb', 'hdc', 'hdd']
if vbddev not in vbddev_list:
raise VmError("vmx: for qemu vbd type=file&dev=hda~hdd")
ret.append("-%s" % vbddev)
ret.append("%s" % vbdparam)
if name == 'vif':
type = sxp.child_value(info, 'type')
if type != 'ioemu':
continue
nics += 1
if mac != None:
continue
mac = sxp.child_value(info, 'mac')
bridge = sxp.child_value(info, 'bridge')
if mac == None:
mac = randomMAC()
if bridge == None:
bridge = 'xenbr0'
ret.append("-macaddr")
ret.append("%s" % mac)
ret.append("-bridge")
ret.append("%s" % bridge)
type = sxp.child_value(info, 'type')
if type != 'ioemu':
continue
nics += 1
if mac != None:
continue
mac = sxp.child_value(info, 'mac')
bridge = sxp.child_value(info, 'bridge')
if mac == None:
mac = randomMAC()
if bridge == None:
bridge = 'xenbr0'
ret.append("-macaddr")
ret.append("%s" % mac)
ret.append("-bridge")
ret.append("%s" % bridge)
if name == 'vtpm':
instance = sxp.child_value(info, 'pref_instance')
ret.append("-instance")
ret.append("%s" % instance)
instance = sxp.child_value(info, 'pref_instance')
ret.append("-instance")
ret.append("%s" % instance)
ret.append("-nics")
ret.append("%d" % nics)
ret.append("%d" % nics)
return ret
def configVNC(self, config):
@@ -340,6 +344,8 @@ class VmxImageHandler(ImageHandler):
env = dict(os.environ)
if self.display:
env['DISPLAY'] = self.display
if self.xauthority:
env['XAUTHORITY'] = self.xauthority
log.info("spawning device models: %s %s", self.device_model, args)
self.pid = os.spawnve(os.P_NOWAIT, self.device_model, args, env)
log.info("device model pid: %d", self.pid)
+3 -3
View File
@@ -31,7 +31,7 @@ class BlkifController(DevController):
"""Block device interface controller. Handles all block devices
for a domain.
"""
def __init__(self, vm):
"""Create a block device controller.
"""
@@ -40,9 +40,9 @@ class BlkifController(DevController):
def getDeviceDetails(self, config):
"""@see DevController.getDeviceDetails"""
dev = sxp.child_value(config, 'dev')
if re.match('^ioemu:', dev):
if 'ioemu:' in dev:
return (None,{},{})
devid = blkif.blkdev_name_to_number(dev)
+15 -3
View File
@@ -160,9 +160,13 @@ gopts.var('cpus', val='CPUS',
fn=set_int, default=None,
use="CPUS to run the domain on.")
gopts.var('lapic', val='LAPIC',
gopts.var('acpi', val='ACPI',
fn=set_int, default=0,
use="Disable or enable local APIC of VMX domain.")
use="Disable or enable ACPI of VMX domain.")
gopts.var('apic', val='APIC',
fn=set_int, default=0,
use="Disable or enable APIC of VMX domain.")
gopts.var('vcpus', val='VCPUS',
fn=set_int, default=1,
@@ -388,6 +392,10 @@ gopts.var('display', val='DISPLAY',
fn=set_value, default=None,
use="X11 display to use")
gopts.var('xauthority', val='XAUTHORITY',
fn=set_value, default=None,
use="X11 Authority to use")
def err(msg):
"""Print an error to stderr and exit.
@@ -526,7 +534,8 @@ def configure_vmx(config_image, vals):
"""
args = [ 'device_model', 'vcpus', 'cdrom', 'boot', 'fda', 'fdb',
'localtime', 'serial', 'stdvga', 'isa', 'nographic', 'audio',
'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'lapic']
'vnc', 'vncviewer', 'sdl', 'display', 'ne2000', 'acpi', 'apic',
'xauthority' ]
for a in args:
if (vals.__dict__[a]):
config_image.append([a, vals.__dict__[a]])
@@ -801,6 +810,9 @@ def parseCommandLine(argv):
if not gopts.vals.display:
gopts.vals.display = os.getenv("DISPLAY")
if not gopts.vals.xauthority:
gopts.vals.xauthority = os.getenv("XAUTHORITY")
# Process remaining args as config variables.
for arg in args:
if '=' in arg:
+7 -1
View File
@@ -390,7 +390,6 @@ def xm_brief_list(doms):
def xm_vcpu_list(args):
print 'Name ID VCPU CPU State Time(s) CPU Affinity'
from xen.xend.XendClient import server
if args:
@@ -401,6 +400,8 @@ def xm_vcpu_list(args):
lambda x: server.xend_domain_vcpuinfo(sxp.child_value(x, 'name')),
doms)
print 'Name ID VCPU CPU State Time(s) CPU Affinity'
for dom in dominfo:
def get_info(n):
return sxp.child_value(dom, n)
@@ -625,6 +626,8 @@ def xm_sched_sedf(args):
server.xend_domain_cpu_sedf_set(dom, *v)
def xm_info(args):
arg_check(args, "info", 0)
from xen.xend.XendClient import server
info = server.xend_node()
@@ -645,9 +648,12 @@ def xm_console(args):
def xm_top(args):
arg_check(args, "top", 0)
os.execvp('xentop', ['xentop'])
def xm_dmesg(args):
arg_check(args, "dmesg", 0)
gopts = Opts(use="""[-c|--clear]
+12 -12
View File
@@ -92,7 +92,7 @@ int main(int argc, char **argv)
regs.ecx = 0x12345678;
cr2 = (unsigned long)&res;
res = 0x7FFFFFFF;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0x92345677) ||
(regs.eflags != 0xa94) ||
@@ -110,7 +110,7 @@ int main(int argc, char **argv)
regs.ecx = 0x12345678UL;
#endif
cr2 = (unsigned long)&res;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0x92345677) ||
(regs.ecx != 0x8000000FUL) ||
@@ -125,7 +125,7 @@ int main(int argc, char **argv)
regs.eax = 0x92345677UL;
regs.ecx = 0xAA;
cr2 = (unsigned long)&res;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0x923456AA) ||
(regs.eflags != 0x244) ||
@@ -141,7 +141,7 @@ int main(int argc, char **argv)
regs.eax = 0xAABBCC77UL;
regs.ecx = 0xFF;
cr2 = (unsigned long)&res;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0x923456AA) ||
((regs.eflags&0x240) != 0x200) ||
@@ -157,7 +157,7 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.ecx = 0x12345678;
cr2 = (unsigned long)&res;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0x12345678) ||
(regs.eflags != 0x200) ||
@@ -174,7 +174,7 @@ int main(int argc, char **argv)
regs.eax = 0x923456AAUL;
regs.ecx = 0xDDEEFF00L;
cr2 = (unsigned long)&res;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0xDDEEFF00) ||
(regs.eflags != 0x244) ||
@@ -193,7 +193,7 @@ int main(int argc, char **argv)
regs.edi = (unsigned long)&res + 2;
regs.error_code = 0; /* read fault */
cr2 = regs.esi;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0x44554455) ||
(regs.eflags != 0x200) ||
@@ -211,7 +211,7 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)&res;
cr2 = regs.edi;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0x2233445D) ||
((regs.eflags&0x201) != 0x201) ||
@@ -229,7 +229,7 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)cmpxchg8b_res;
cr2 = regs.edi;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(cmpxchg8b_res[0] != 0x9999AAAA) ||
(cmpxchg8b_res[1] != 0xCCCCFFFF) ||
@@ -243,7 +243,7 @@ int main(int argc, char **argv)
regs.eip = (unsigned long)&instr[0];
regs.edi = (unsigned long)cmpxchg8b_res;
cr2 = regs.edi;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(cmpxchg8b_res[0] != 0x9999AAAA) ||
(cmpxchg8b_res[1] != 0xCCCCFFFF) ||
@@ -260,7 +260,7 @@ int main(int argc, char **argv)
regs.ecx = 0x12345678;
cr2 = (unsigned long)&res;
res = 0x82;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0x82) ||
(regs.ecx != 0xFFFFFF82) ||
@@ -275,7 +275,7 @@ int main(int argc, char **argv)
regs.ecx = 0x12345678;
cr2 = (unsigned long)&res;
res = 0x1234aa82;
rc = x86_emulate_memop(&regs, cr2, &emulops, 4);
rc = x86_emulate_memop(&regs, cr2, &emulops, X86EMUL_MODE_PROT32);
if ( (rc != 0) ||
(res != 0x1234aa82) ||
(regs.ecx != 0xaa82) ||
-5
View File
@@ -53,11 +53,6 @@ DUMMY_BACKEND -> vtpm_manager listens on /tmp/in.fifo and
MANUAL_DM_LAUNCH -> Must manually launch & kill VTPMs
WELL_KNOWN_SRK_AUTH -> Rather than randomly generating the password for the SRK,
use a well known value. This is necessary for sharing use
of the SRK across applications. Such as VTPM and Dom0
measurement software.
WELL_KNOWN_OWNER_AUTH -> Rather than randomly generating the password for the owner,
use a well known value. This is useful for debugging and for
poor bios which do not support clearing TPM if OwnerAuth is
+1 -2
View File
@@ -56,8 +56,7 @@ CFLAGS += -DLOGGING_MODULES="(BITMASK(VTPM_LOG_TCS)|BITMASK(VTPM_LOG_VTSP)|BITMA
# Do not have manager launch DMs.
#CFLAGS += -DMANUAL_DM_LAUNCH
# Fixed SRK
CFLAGS += -DWELL_KNOWN_SRK_AUTH
# Fixed OwnerAuth
#CFLAGS += -DWELL_KNOWN_OWNER_AUTH
# TPM Hardware Device or TPM Simulator
+149 -84
View File
@@ -65,7 +65,7 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
UINT32 i;
struct pack_constbuf_t symkey_cipher32, data_cipher32;
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping[%d]: 0x", buffer_len(inbuf));
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Input[%d]: 0x", buffer_len(inbuf));
for (i=0; i< buffer_len(inbuf); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", inbuf->bytes[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
@@ -94,6 +94,12 @@ TPM_RESULT envelope_encrypt(const buffer_t *inbuf,
BSG_TPM_SIZE32_DATA, &data_cipher32);
vtpmloginfo(VTPM_LOG_VTPM, "Saved %d bytes of E(symkey) + %d bytes of E(data)\n", buffer_len(&symkey_cipher), buffer_len(&data_cipher));
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Enveloping Output[%d]: 0x", buffer_len(sealed_data));
for (i=0; i< buffer_len(sealed_data); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", sealed_data->bytes[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
goto egress;
abort_egress:
@@ -125,7 +131,7 @@ TPM_RESULT envelope_decrypt(const long cipher_size,
memset(&symkey, 0, sizeof(symkey_t));
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "envelope decrypting[%ld]: 0x", cipher_size);
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypt Input[%ld]: 0x", cipher_size);
for (i=0; i< cipher_size; i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", cipher[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
@@ -155,6 +161,11 @@ TPM_RESULT envelope_decrypt(const long cipher_size,
// Decrypt State
TPMTRY(TPM_DECRYPT_ERROR, Crypto_symcrypto_decrypt (&symkey, &data_cipher, unsealed_data) );
vtpmloginfo(VTPM_LOG_VTPM_DEEP, "Envelope Decrypte Output[%d]: 0x", buffer_len(unsealed_data));
for (i=0; i< buffer_len(unsealed_data); i++)
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "%x ", unsealed_data->bytes[i]);
vtpmloginfomore(VTPM_LOG_VTPM_DEEP, "\n");
goto egress;
@@ -291,124 +302,175 @@ TPM_RESULT VTPM_Handle_Load_NVM(VTPM_DMI_RESOURCE *myDMI,
return status;
}
TPM_RESULT VTPM_SaveService(void) {
TPM_RESULT status=TPM_SUCCESS;
int fh, dmis=-1;
BYTE *flat_global;
int flat_global_size, bytes_written;
BYTE *flat_boot_key, *flat_dmis, *flat_enc;
buffer_t clear_flat_global, enc_flat_global;
UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
struct pack_buf_t boot_key_pack = {bootKeySize, vtpm_globals->bootKeyWrap.bytes};
struct hashtable_itr *dmi_itr;
VTPM_DMI_RESOURCE *dmi_res;
UINT32 flat_global_full_size;
// Global Values needing to be saved
flat_global_full_size = 3*sizeof(TPM_DIGEST) + // Auths
sizeof(UINT32) + // storagekeysize
storageKeySize + // storage key
hashtable_count(vtpm_globals->dmi_map) * // num DMIS
(sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
flat_global = (BYTE *) malloc( flat_global_full_size);
flat_global_size = BSG_PackList(flat_global, 4,
BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
BSG_TPM_SIZE32_DATA, &storage_key_pack);
UINT32 boot_key_size, flat_dmis_size;
// Initially fill these with buffer sizes for each data type. Later fill
// in actual size, once flattened.
boot_key_size = sizeof(UINT32) + // bootkeysize
bootKeySize; // boot key
TPMTRYRETURN(buffer_init(&clear_flat_global, 3*sizeof(TPM_DIGEST) + // Auths
sizeof(UINT32) +// storagekeysize
storageKeySize, NULL) ); // storage key
flat_dmis_size = (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
(sizeof(UINT32) + 2*sizeof(TPM_DIGEST)); // Per DMI info
flat_boot_key = (BYTE *) malloc( boot_key_size );
flat_enc = (BYTE *) malloc( sizeof(UINT32) );
flat_dmis = (BYTE *) malloc( flat_dmis_size );
boot_key_size = BSG_PackList(flat_boot_key, 1,
BSG_TPM_SIZE32_DATA, &boot_key_pack);
BSG_PackList(clear_flat_global.bytes, 3,
BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
BSG_TPM_SIZE32_DATA, &storage_key_pack);
TPMTRYRETURN(envelope_encrypt(&clear_flat_global,
&vtpm_globals->bootKey,
&enc_flat_global) );
BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);
// Per DMI values to be saved
if (hashtable_count(vtpm_globals->dmi_map) > 0) {
dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
do {
dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
dmis++;
// No need to save dmi0.
if (dmi_res->dmi_id == 0)
continue;
flat_global_size += BSG_PackList( flat_global + flat_global_size, 3,
BSG_TYPE_UINT32, &dmi_res->dmi_id,
BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
if (dmi_res->dmi_id == 0)
continue;
flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 3,
BSG_TYPE_UINT32, &dmi_res->dmi_id,
BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
} while (hashtable_iterator_advance(dmi_itr));
}
//FIXME: Once we have a way to protect a TPM key, we should use it to
// encrypt this blob. BUT, unless there is a way to ensure the key is
// not used by other apps, this encryption is useless.
fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
if (fh == -1) {
vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", STATE_FILE);
status = TPM_IOERROR;
goto abort_egress;
}
if ( (bytes_written = write(fh, flat_global, flat_global_size)) != flat_global_size ) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to save service data. %d/%d bytes written.\n", bytes_written, flat_global_size);
if ( ( write(fh, flat_boot_key, boot_key_size) != boot_key_size ) ||
( write(fh, flat_enc, sizeof(UINT32)) != sizeof(UINT32) ) ||
( write(fh, enc_flat_global.bytes, buffer_len(&enc_flat_global)) != buffer_len(&enc_flat_global) ) ||
( write(fh, flat_dmis, flat_dmis_size) != flat_dmis_size ) ) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to completely write service data.\n");
status = TPM_IOERROR;
goto abort_egress;
}
vtpm_globals->DMI_table_dirty = FALSE;
}
vtpm_globals->DMI_table_dirty = FALSE;
goto egress;
abort_egress:
egress:
free(flat_global);
free(flat_boot_key);
free(flat_enc);
buffer_free(&enc_flat_global);
free(flat_dmis);
close(fh);
vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Service state (status = %d, dmis = %d)\n", (int) status, dmis);
return status;
}
TPM_RESULT VTPM_LoadService(void) {
TPM_RESULT status=TPM_SUCCESS;
int fh, stat_ret, dmis=0;
long fh_size = 0, step_size;
BYTE *flat_global=NULL;
struct pack_buf_t storage_key_pack;
UINT32 *dmi_id_key;
BYTE *flat_table=NULL;
buffer_t unsealed_data;
struct pack_buf_t storage_key_pack, boot_key_pack;
UINT32 *dmi_id_key, enc_size;
VTPM_DMI_RESOURCE *dmi_res;
struct stat file_stat;
TPM_HANDLE boot_key_handle;
TPM_AUTHDATA boot_usage_auth;
memset(&boot_usage_auth, 0, sizeof(TPM_AUTHDATA));
fh = open(STATE_FILE, O_RDONLY );
stat_ret = fstat(fh, &file_stat);
if (stat_ret == 0)
if (stat_ret == 0)
fh_size = file_stat.st_size;
else {
status = TPM_IOERROR;
goto abort_egress;
}
flat_global = (BYTE *) malloc(fh_size);
if ((long) read(fh, flat_global, fh_size) != fh_size ) {
flat_table = (BYTE *) malloc(fh_size);
if ((long) read(fh, flat_table, fh_size) != fh_size ) {
status = TPM_IOERROR;
goto abort_egress;
}
// Read Boot Key
step_size = BSG_UnpackList( flat_table, 2,
BSG_TPM_SIZE32_DATA, &boot_key_pack,
BSG_TYPE_UINT32, &enc_size);
TPMTRYRETURN(buffer_init(&vtpm_globals->bootKeyWrap, 0, 0) );
TPMTRYRETURN(buffer_append_raw(&vtpm_globals->bootKeyWrap, boot_key_pack.size, boot_key_pack.data) );
//Load Boot Key
TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
TPM_SRK_KEYHANDLE,
&vtpm_globals->bootKeyWrap,
&SRK_AUTH,
&boot_key_handle,
&vtpm_globals->keyAuth,
&vtpm_globals->bootKey,
FALSE) );
TPMTRYRETURN( envelope_decrypt(enc_size,
flat_table + step_size,
vtpm_globals->manager_tcs_handle,
boot_key_handle,
(const TPM_AUTHDATA*) &boot_usage_auth,
&unsealed_data) );
step_size += enc_size;
// Global Values needing to be saved
step_size = BSG_UnpackList( flat_global, 4,
BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
BSG_TPM_AUTHDATA, &vtpm_globals->srk_usage_auth,
BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
BSG_TPM_SIZE32_DATA, &storage_key_pack);
BSG_UnpackList( unsealed_data.bytes, 3,
BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
BSG_TPM_SECRET, &vtpm_globals->storage_key_usage_auth,
BSG_TPM_SIZE32_DATA, &storage_key_pack);
TPMTRYRETURN(buffer_init(&vtpm_globals->storageKeyWrap, 0, 0) );
TPMTRYRETURN(buffer_append_raw(&vtpm_globals->storageKeyWrap, storage_key_pack.size, storage_key_pack.data) );
// Per DMI values to be saved
while ( step_size < fh_size ){
if (fh_size - step_size < (long) (sizeof(UINT32) + 2*sizeof(TPM_DIGEST))) {
@@ -417,35 +479,38 @@ TPM_RESULT VTPM_LoadService(void) {
} else {
dmi_res = (VTPM_DMI_RESOURCE *) malloc(sizeof(VTPM_DMI_RESOURCE));
dmis++;
dmi_res->connected = FALSE;
step_size += BSG_UnpackList(flat_global + step_size, 3,
BSG_TYPE_UINT32, &dmi_res->dmi_id,
BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
step_size += BSG_UnpackList(flat_table + step_size, 3,
BSG_TYPE_UINT32, &dmi_res->dmi_id,
BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
BSG_TPM_DIGEST, &dmi_res->DMI_measurement);
// install into map
dmi_id_key = (UINT32 *) malloc (sizeof(UINT32));
*dmi_id_key = dmi_res->dmi_id;
if (!hashtable_insert(vtpm_globals->dmi_map, dmi_id_key, dmi_res)) {
status = TPM_FAIL;
goto abort_egress;
status = TPM_FAIL;
goto abort_egress;
}
}
}
vtpmloginfo(VTPM_LOG_VTPM, "Loaded saved state (dmis = %d).\n", dmis);
goto egress;
abort_egress:
vtpmlogerror(VTPM_LOG_VTPM, "Failed to load service data with error = %s\n", tpm_get_error_name(status));
egress:
free(flat_global);
free(flat_table);
close(fh);
// TODO: Could be nice and evict BootKey. (Need to add EvictKey to VTSP.
return status;
}
+66 -30
View File
@@ -74,16 +74,15 @@ VTPM_GLOBALS *vtpm_globals=NULL;
#endif
// --------------------------- Well Known Auths --------------------------
#ifdef WELL_KNOWN_SRK_AUTH
static BYTE FIXED_SRK_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
const TPM_AUTHDATA SRK_AUTH = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
#endif
#ifdef WELL_KNOWN_OWNER_AUTH
static BYTE FIXED_OWNER_AUTH[20] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
#endif
// -------------------------- Hash table functions --------------------
static unsigned int hashfunc32(void *ky) {
@@ -100,13 +99,7 @@ TPM_RESULT VTPM_Create_Service(){
TPM_RESULT status = TPM_SUCCESS;
// Generate Auth's for SRK & Owner
#ifdef WELL_KNOWN_SRK_AUTH
memcpy(vtpm_globals->srk_usage_auth, FIXED_SRK_AUTH, sizeof(TPM_AUTHDATA));
#else
Crypto_GetRandom(vtpm_globals->srk_usage_auth, sizeof(TPM_AUTHDATA) );
#endif
// Generate Auth for Owner
#ifdef WELL_KNOWN_OWNER_AUTH
memcpy(vtpm_globals->owner_usage_auth, FIXED_OWNER_AUTH, sizeof(TPM_AUTHDATA));
#else
@@ -116,14 +109,14 @@ TPM_RESULT VTPM_Create_Service(){
// Take Owership of TPM
CRYPTO_INFO ek_cryptoInfo;
vtpmloginfo(VTPM_LOG_VTPM, "Attempting Pubek Read. NOTE: Failure is ok.\n");
status = VTSP_ReadPubek(vtpm_globals->manager_tcs_handle, &ek_cryptoInfo);
// If we can read PubEK then there is no owner and we should take it.
if (status == TPM_SUCCESS) {
vtpmloginfo(VTPM_LOG_VTPM, "Failed to readEK meaning TPM has an owner. Creating Keys off existing SRK.\n");
TPMTRYRETURN(VTSP_TakeOwnership(vtpm_globals->manager_tcs_handle,
(const TPM_AUTHDATA*)&vtpm_globals->owner_usage_auth,
(const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
&SRK_AUTH,
&ek_cryptoInfo,
&vtpm_globals->keyAuth));
@@ -142,7 +135,7 @@ TPM_RESULT VTPM_Create_Service(){
TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
TPM_ET_KEYHANDLE,
TPM_SRK_KEYHANDLE,
(const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
&SRK_AUTH,
&sharedsecret,
&osap) );
@@ -157,8 +150,43 @@ TPM_RESULT VTPM_Create_Service(){
&vtpm_globals->storageKeyWrap,
&osap) );
vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
// Generate boot key's auth
Crypto_GetRandom( &vtpm_globals->storage_key_usage_auth,
sizeof(TPM_AUTHDATA) );
TPM_AUTHDATA bootKeyWrapAuth;
memset(&bootKeyWrapAuth, 0, sizeof(bootKeyWrapAuth));
TPMTRYRETURN( VTSP_OSAP(vtpm_globals->manager_tcs_handle,
TPM_ET_KEYHANDLE,
TPM_SRK_KEYHANDLE,
&SRK_AUTH,
&sharedsecret,
&osap) );
osap.fContinueAuthSession = FALSE;
// FIXME: This key protects the global secrets on disk. It should use TPM
// PCR bindings to limit its use to legit configurations.
// Current binds are open, implying a Trusted VM contains this code.
// If this VM is not Trusted, use measurement and PCR bindings.
TPMTRYRETURN( VTSP_CreateWrapKey( vtpm_globals->manager_tcs_handle,
TPM_KEY_BIND,
(const TPM_AUTHDATA*)&bootKeyWrapAuth,
TPM_SRK_KEYHANDLE,
(const TPM_AUTHDATA*)&sharedsecret,
&vtpm_globals->bootKeyWrap,
&osap) );
// Populate CRYPTO_INFO vtpm_globals->bootKey. This does not load it into the TPM
TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
TPM_SRK_KEYHANDLE,
&vtpm_globals->bootKeyWrap,
NULL,
NULL,
NULL,
&vtpm_globals->bootKey,
TRUE ) );
goto egress;
abort_egress:
@@ -278,24 +306,26 @@ void *VTPM_Service_Handler(void *threadTypePtr){
#endif
// Check status of rx_fh. If necessary attempt to re-open it.
char* s = NULL;
if (*rx_fh < 0) {
#ifdef VTPM_MULTI_VM
*rx_fh = open(VTPM_BE_DEV, O_RDWR);
s = VTPM_BE_DEV;
#else
if (threadType == BE_LISTENER_THREAD)
#ifdef DUMMY_BACKEND
*rx_fh = open("/tmp/in.fifo", O_RDWR);
s = "/tmp/in.fifo";
#else
*rx_fh = open(VTPM_BE_DEV, O_RDWR);
s = VTPM_BE_DEV;
#endif
else // DMI Listener
*rx_fh = open(VTPM_RX_FIFO, O_RDWR);
s = VTPM_RX_FIFO;
*rx_fh = open(s, O_RDWR);
#endif
}
// Respond to failures to open rx_fh
if (*rx_fh < 0) {
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh.\n");
vtpmhandlerlogerror(VTPM_LOG_VTPM, "Can't open inbound fh for %s.\n", s);
#ifdef VTPM_MULTI_VM
return TPM_IOERROR;
#else
@@ -713,7 +743,7 @@ void *VTPM_Service_Handler(void *threadTypePtr){
///////////////////////////////////////////////////////////////////////////////
TPM_RESULT VTPM_Init_Service() {
TPM_RESULT status = TPM_FAIL;
TPM_RESULT status = TPM_FAIL, serviceStatus;
BYTE *randomsead;
UINT32 randomsize;
@@ -737,7 +767,7 @@ TPM_RESULT VTPM_Init_Service() {
// Create new TCS Object
vtpm_globals->manager_tcs_handle = 0;
TPMTRYRETURN(TCS_create());
// Create TCS Context for service
@@ -756,17 +786,24 @@ TPM_RESULT VTPM_Init_Service() {
vtpm_globals->keyAuth.fContinueAuthSession = TRUE;
// If failed, create new Service.
if (VTPM_LoadService() != TPM_SUCCESS)
serviceStatus = VTPM_LoadService();
if (serviceStatus == TPM_IOERROR) {
vtpmloginfo(VTPM_LOG_VTPM, "Failed to read service file. Assuming first time initialization.\n");
TPMTRYRETURN( VTPM_Create_Service() );
} else if (serviceStatus != TPM_SUCCESS) {
vtpmlogerror(VTPM_LOG_VTPM, "Failed to read existing service file");
exit(1);
}
//Load Storage Key
TPMTRYRETURN( VTSP_LoadKey( vtpm_globals->manager_tcs_handle,
TPM_SRK_KEYHANDLE,
&vtpm_globals->storageKeyWrap,
(const TPM_AUTHDATA*)&vtpm_globals->srk_usage_auth,
&SRK_AUTH,
&vtpm_globals->storageKeyHandle,
&vtpm_globals->keyAuth,
&vtpm_globals->storageKey) );
&vtpm_globals->storageKey,
FALSE ) );
// Create entry for Dom0 for control messages
TPMTRYRETURN( VTPM_Handle_New_DMI(NULL) );
@@ -797,12 +834,11 @@ void VTPM_Stop_Service() {
free (dmi_itr);
}
TCS_CloseContext(vtpm_globals->manager_tcs_handle);
if ( (vtpm_globals->DMI_table_dirty) &&
(VTPM_SaveService() != TPM_SUCCESS) )
if ( (vtpm_globals->DMI_table_dirty) && (VTPM_SaveService() != TPM_SUCCESS) )
vtpmlogerror(VTPM_LOG_VTPM, "Unable to save manager data.\n");
TCS_CloseContext(vtpm_globals->manager_tcs_handle);
TCS_destroy();
hashtable_destroy(vtpm_globals->dmi_map, 1);
free(vtpm_globals);
+8 -5
View File
@@ -108,6 +108,7 @@ typedef struct tdVTPM_GLOBALS {
TCS_CONTEXT_HANDLE manager_tcs_handle; // TCS Handle used by manager
TPM_HANDLE storageKeyHandle; // Key used by persistent store
CRYPTO_INFO storageKey; // For software encryption
CRYPTO_INFO bootKey; // For saving table
TCS_AUTH keyAuth; // OIAP session for storageKey
BOOL DMI_table_dirty; // Indicates that a command
// has updated the DMI table
@@ -115,15 +116,17 @@ typedef struct tdVTPM_GLOBALS {
// Persistent Data
TPM_AUTHDATA owner_usage_auth; // OwnerAuth of real TPM
TPM_AUTHDATA srk_usage_auth; // SRK Auth of real TPM
buffer_t storageKeyWrap; // Wrapped copy of storageKey
TPM_AUTHDATA srk_usage_auth;
TPM_AUTHDATA storage_key_usage_auth;
buffer_t bootKeyWrap; // Wrapped copy of boot key
}VTPM_GLOBALS;
//Global dmi map
extern VTPM_GLOBALS *vtpm_globals;
// --------------------------- Global Values --------------------------
extern VTPM_GLOBALS *vtpm_globals; // Key info and DMI states
extern const TPM_AUTHDATA SRK_AUTH; // SRK Well Known Auth Value
// ********************** Command Handler Prototypes ***********************
TPM_RESULT VTPM_Handle_Load_NVM( VTPM_DMI_RESOURCE *myDMI,
+241 -50
View File
@@ -144,7 +144,10 @@ TPM_RESULT VerifyAuth( /*[IN]*/ const BYTE *outParamDigestText,
if (memcmp (&hm, &(auth->HMAC), sizeof(TPM_DIGEST)) == 0) // 0 indicates equality
return (TPM_SUCCESS);
else {
VTSP_OIAP( hContext, auth);
// If specified, reconnect the OIAP session.
// NOTE: This only works for TCS's that never have a 0 context.
if (hContext)
VTSP_OIAP( hContext, auth);
return (TPM_AUTHFAIL);
}
}
@@ -157,6 +160,10 @@ TPM_RESULT VTSP_OIAP(const TCS_CONTEXT_HANDLE hContext,
TPMTRYRETURN( TCSP_OIAP(hContext,
&auth->AuthHandle,
&auth->NonceEven) );
memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
auth->fContinueAuthSession = FALSE;
goto egress;
abort_egress:
@@ -195,6 +202,9 @@ TPM_RESULT VTSP_OSAP(const TCS_CONTEXT_HANDLE hContext,
BSG_TPM_NONCE, &nonceOddOSAP);
Crypto_HMAC(sharedSecretText, sizeof(sharedSecretText), (BYTE *) usageAuth, TPM_DIGEST_SIZE, (BYTE *) sharedSecret);
memset(&auth->HMAC, 0, sizeof(TPM_DIGEST));
auth->fContinueAuthSession = FALSE;
goto egress;
@@ -288,9 +298,6 @@ TPM_RESULT VTSP_TakeOwnership( const TCS_CONTEXT_HANDLE hContext,
struct pack_buf_t srkText;
// GenerateAuth new nonceOdd
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
//These values are accurate for an enc(AuthData).
struct pack_buf_t encOwnerAuth, encSrkAuth;
@@ -383,9 +390,6 @@ TPM_RESULT VTSP_DisablePubekRead( const TCS_CONTEXT_HANDLE hContext,
BYTE *paramText; // Digest to make Auth.
UINT32 paramTextSize;
// Generate HMAC
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
paramTextSize = BSG_PackList(paramText, 1,
@@ -504,9 +508,6 @@ TPM_RESULT VTSP_CreateWrapKey( const TCS_CONTEXT_HANDLE hContext,
newKeyText.data = flatKey;
newKeyText.size = flatKeySize;
// GenerateAuth new nonceOdd
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
// Generate HMAC
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
@@ -563,63 +564,66 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE hContext,
const TPM_AUTHDATA *parentAuth,
TPM_HANDLE *newKeyHandle,
TCS_AUTH *auth,
CRYPTO_INFO *cryptoinfo /*= NULL*/) {
CRYPTO_INFO *cryptoinfo,
const BOOL skipTPMLoad) {
vtpmloginfo(VTPM_LOG_VTSP, "Loading Key.\n%s","");
vtpmloginfo(VTPM_LOG_VTSP, "Loading Key %s.\n", (!skipTPMLoad ? "into TPM" : "only into memory"));
TPM_RESULT status = TPM_SUCCESS;
TPM_COMMAND_CODE command = TPM_ORD_LoadKey;
BYTE *paramText; // Digest to make Auth.
BYTE *paramText=NULL; // Digest to make Auth.
UINT32 paramTextSize;
// SkipTPMLoad stops key from being loaded into TPM, but still generates CRYPTO_INFO for it
if (! skipTPMLoad) {
if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) ||
(newKeyHandle==NULL) || (auth==NULL)) {
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
if ((rgbWrappedKeyBlob == NULL) || (parentAuth == NULL) ||
(newKeyHandle==NULL) || (auth==NULL)) {
status = TPM_BAD_PARAMETER;
goto abort_egress;
}
// Generate Extra TCS Parameters
TPM_HANDLE phKeyHMAC;
// Generate Extra TCS Parameters
TPM_HANDLE phKeyHMAC;
// Generate HMAC
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
paramTextSize = BSG_PackList(paramText, 1,
BSG_TPM_COMMAND_CODE, &command);
paramTextSize = BSG_PackList(paramText, 1,
BSG_TPM_COMMAND_CODE, &command);
memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
paramTextSize += buffer_len(rgbWrappedKeyBlob);
memcpy(paramText + paramTextSize, rgbWrappedKeyBlob->bytes, buffer_len(rgbWrappedKeyBlob));
paramTextSize += buffer_len(rgbWrappedKeyBlob);
TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
parentAuth, auth) );
// Call TCS
TPMTRYRETURN( TCSP_LoadKeyByBlob( hContext,
hUnwrappingKey,
buffer_len(rgbWrappedKeyBlob),
rgbWrappedKeyBlob->bytes,
auth,
newKeyHandle,
&phKeyHMAC) );
// Call TCS
TPMTRYRETURN( TCSP_LoadKeyByBlob( hContext,
hUnwrappingKey,
buffer_len(rgbWrappedKeyBlob),
rgbWrappedKeyBlob->bytes,
auth,
newKeyHandle,
&phKeyHMAC) );
// Verify Auth
paramTextSize = BSG_PackList(paramText, 3,
BSG_TPM_RESULT, &status,
BSG_TPM_COMMAND_CODE, &command,
BSG_TPM_HANDLE, newKeyHandle);
// Verify Auth
paramTextSize = BSG_PackList(paramText, 3,
BSG_TPM_RESULT, &status,
BSG_TPM_COMMAND_CODE, &command,
BSG_TPM_HANDLE, newKeyHandle);
TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
parentAuth, auth,
hContext) );
TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
parentAuth, auth,
hContext) );
}
// Unpack/return key structure
// Build cryptoinfo structure for software crypto function.
if (cryptoinfo != NULL) {
TPM_KEY newKey;
// Unpack/return key structure
BSG_Unpack(BSG_TPM_KEY, rgbWrappedKeyBlob->bytes , &newKey);
TPM_RSA_KEY_PARMS rsaKeyParms;
@@ -670,9 +674,6 @@ TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE hContext,
BYTE *clear_data_text;
UINT32 clear_data_size;
// Generate HMAC
Crypto_GetRandom(&auth->NonceOdd, sizeof(TPM_NONCE) );
struct pack_buf_t bound_data32 = {bound_data->size, bound_data->bytes};
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
@@ -781,6 +782,196 @@ TPM_RESULT VTSP_Bind( CRYPTO_INFO *cryptoInfo,
return TPM_SUCCESS;
}
TPM_RESULT VTSP_Seal(const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_HANDLE keyHandle,
const TPM_AUTHDATA *sealDataAuth,
const TPM_PCR_COMPOSITE *pcrComp,
const buffer_t *inData,
TPM_STORED_DATA *sealedData,
const TPM_SECRET *osapSharedSecret,
TCS_AUTH *auth) {
TPM_RESULT status = TPM_SUCCESS;
TPM_COMMAND_CODE command = TPM_ORD_Seal;
BYTE *paramText; // Digest to make Auth.
UINT32 paramTextSize;
// Generate PCR_Info Struct from Comp
TPM_PCR_INFO pcrInfo;
UINT32 pcrInfoSize, flatpcrSize;
BYTE flatpcr[3 + // PCR_Select = 3 1 byte banks
sizeof(UINT16) + // 2 byte UINT16
sizeof(UINT32) + // PCR_Comp = 4 byte UINT32
24 * sizeof(TPM_PCRVALUE) ]; // up to 24 PCRs
if (pcrComp != NULL) {
//printf("\n\tBinding to PCRs: ");
//for(int i = 0 ; i < pcrComp->select.sizeOfSelect ; i++)
//printf("%2.2x", pcrComp->select.pcrSelect[i]);
memcpy(&pcrInfo.pcrSelection, &pcrComp->select, sizeof(TPM_PCR_SELECTION));
flatpcrSize = BSG_Pack(BSG_TPM_PCR_COMPOSITE, (BYTE *) pcrComp, flatpcr);
Crypto_SHA1Full((BYTE *) flatpcr, flatpcrSize, (BYTE *) &(pcrInfo.digestAtRelease));
memset(&(pcrInfo.digestAtCreation), 0, sizeof(TPM_DIGEST));
pcrInfoSize = BSG_Pack(BSG_TPM_PCR_INFO, (BYTE *) &pcrInfo, flatpcr);
} else {
//printf("\n\tBinding to no PCRS.");
pcrInfoSize = 0;
}
// Calculate encUsageAuth
BYTE XORbuffer[sizeof(TPM_SECRET) + sizeof(TPM_NONCE)];
UINT32 XORbufferSize = sizeof(XORbuffer);
TPM_DIGEST XORKey;
TPM_ENCAUTH encAuth;
BSG_PackList( XORbuffer, 2,
BSG_TPM_SECRET, osapSharedSecret,
BSG_TPM_NONCE, &auth->NonceEven );
Crypto_SHA1Full(XORbuffer, XORbufferSize, (BYTE *) &XORKey);
int i;
for (i=0; i < TPM_DIGEST_SIZE; i++)
((BYTE *) &encAuth)[i] = ((BYTE *) &XORKey)[i] ^ ((BYTE *) sealDataAuth)[i];
// Generate Extra TCS Parameters
UINT32 inDataSize = buffer_len(inData);
struct pack_buf_t inData_pack = {inDataSize, inData->bytes};
struct pack_buf_t pcrInfo_pack = {pcrInfoSize, flatpcr};
UINT32 sealedDataSize;
BYTE *flatSealedData=NULL;
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
paramTextSize = BSG_PackList(paramText, 4,
BSG_TPM_COMMAND_CODE, &command,
BSG_TPM_ENCAUTH, &encAuth,
BSG_TPM_SIZE32_DATA, &pcrInfo_pack,
BSG_TPM_SIZE32_DATA, &inData_pack);
TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
osapSharedSecret, auth) );
// Call TCS
TPMTRYRETURN( TCSP_Seal( hContext,
keyHandle,
encAuth,
pcrInfoSize,
flatpcr,
inDataSize,
inData->bytes,
auth,
&sealedDataSize,
&flatSealedData) );
// Unpack/return key structure
BSG_Unpack( BSG_TPM_STORED_DATA, flatSealedData, sealedData );
paramTextSize = BSG_PackList(paramText, 3,
BSG_TPM_RESULT, &status,
BSG_TPM_COMMAND_CODE, &command,
BSG_TPM_STORED_DATA, sealedData);
TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
osapSharedSecret, auth,
0) );
goto egress;
abort_egress:
egress:
if (flatSealedData)
TCS_FreeMemory( hContext, flatSealedData);
free(paramText);
return status;
}
TPM_RESULT VTSP_Unseal(const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_HANDLE keyHandle,
const TPM_STORED_DATA *sealedData,
const TPM_AUTHDATA *key_usage_auth,
const TPM_AUTHDATA *data_usage_auth,
buffer_t *outData,
TCS_AUTH *auth,
TCS_AUTH *dataAuth) {
TPM_RESULT status = TPM_SUCCESS;
TPM_COMMAND_CODE command = TPM_ORD_Unseal;
BYTE *paramText; // Digest to make Auth.
UINT32 paramTextSize;
// Generate Extra TCS Parameters
UINT32 sealDataSize, clearDataSize;
BYTE *flatSealedData= (BYTE *) malloc(sizeof(TPM_VERSION) +
2 * sizeof(UINT32) +
sealedData->sealInfoSize +
sealedData->encDataSize),
*clearData=NULL;
sealDataSize = BSG_Pack(BSG_TPM_STORED_DATA, sealedData, flatSealedData );
paramText = (BYTE *) malloc(sizeof(BYTE) * TCPA_MAX_BUFFER_LENGTH);
paramTextSize = BSG_PackList(paramText, 2,
BSG_TPM_COMMAND_CODE, &command,
BSG_TPM_STORED_DATA, sealedData);
TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
key_usage_auth, auth) );
TPMTRYRETURN( GenerateAuth( paramText, paramTextSize,
data_usage_auth, dataAuth) );
// Call TCS
TPMTRYRETURN( TCSP_Unseal( hContext,
keyHandle,
sealDataSize,
flatSealedData,
auth,
dataAuth,
&clearDataSize,
&clearData) );
// Verify Auth
struct pack_buf_t clearData_pack = {clearDataSize, clearData};
paramTextSize = BSG_PackList(paramText, 3,
BSG_TPM_RESULT, &status,
BSG_TPM_COMMAND_CODE, &command,
BSG_TPM_SIZE32_DATA, &clearData_pack);
TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
key_usage_auth, auth,
hContext) );
TPMTRYRETURN( VerifyAuth( paramText, paramTextSize,
data_usage_auth, dataAuth,
hContext) );
// Unpack/return key structure
TPMTRYRETURN( buffer_init(outData, clearDataSize, clearData) );
goto egress;
abort_egress:
egress:
if (flatSealedData)
TCS_FreeMemory( hContext, clearData);
free(paramText);
return status;
}
// Function Reaches into unsupported TCS command, beware.
TPM_RESULT VTSP_RawTransmit(const TCS_CONTEXT_HANDLE hContext,
const buffer_t *inbuf,
+20 -1
View File
@@ -86,7 +86,8 @@ TPM_RESULT VTSP_LoadKey(const TCS_CONTEXT_HANDLE hContext,
const TPM_AUTHDATA *parentAuth,
TPM_HANDLE *newKeyHandle,
TCS_AUTH *pAuth,
CRYPTO_INFO *cryptoinfo);
CRYPTO_INFO *cryptoinfo,
const BOOL skipTPMLoad);
TPM_RESULT VTSP_Unbind( const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_HANDLE key_handle,
@@ -99,4 +100,22 @@ TPM_RESULT VTSP_Bind( CRYPTO_INFO *cryptoInfo,
const buffer_t *inData,
buffer_t *outData);
TPM_RESULT VTSP_Seal(const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_HANDLE keyHandle,
const TPM_AUTHDATA *sealDataAuth,
const TPM_PCR_COMPOSITE *pcrComp,
const buffer_t *inData,
TPM_STORED_DATA *sealedData,
const TPM_SECRET *osapSharedSecret,
TCS_AUTH *auth);
TPM_RESULT VTSP_Unseal(const TCS_CONTEXT_HANDLE hContext,
const TPM_KEY_HANDLE keyHandle,
const TPM_STORED_DATA *sealedData,
const TPM_AUTHDATA *key_usage_auth,
const TPM_AUTHDATA *data_usage_auth,
buffer_t *outData,
TCS_AUTH *auth,
TCS_AUTH *dataAuth);
#endif //_VTSP_H_
+1 -1
View File
@@ -636,7 +636,7 @@ TPM_RESULT TCSP_Seal( TCS_CONTEXT_HANDLE hContext, // in
TDDL_UINT32 OutLength = TCPA_MAX_BUFFER_LENGTH;
// check input params
if (inData == NULL || pubAuth == NULL || SealedDataSize == NULL || *SealedData == NULL)
if (inData == NULL || pubAuth == NULL || SealedDataSize == NULL || SealedData == NULL)
return TPM_BAD_PARAMETER;
// Convert Byte Input parameter in the input byte stream InBuf
+11 -3
View File
@@ -15,24 +15,32 @@ HDRS = $(wildcard *.h)
OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
BIN = xentrace tbctl setsize
LIBBIN = xenctx
LIBBIN =
SCRIPTS = xentrace_format
MAN1 = $(wildcard *.1)
MAN8 = $(wildcard *.8)
ifeq ($(XEN_TARGET_ARCH),x86_32)
LIBBIN += xenctx
endif
ifeq ($(XEN_TARGET_ARCH),x86_64)
LIBBIN += xenctx
endif
all: build
build: $(BIN) $(LIBBIN)
install: build
[ -d $(DESTDIR)/usr/bin ] || $(INSTALL_DIR) $(DESTDIR)/usr/bin
[ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
[ -z "$(LIBBIN)"] || [ -d $(DESTDIR)/usr/$(LIBDIR)/xen/bin ] || \
$(INSTALL_DIR) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
[ -d $(DESTDIR)/usr/share/man/man1 ] || \
$(INSTALL_DIR) $(DESTDIR)/usr/share/man/man1
[ -d $(DESTDIR)/usr/share/man/man8 ] || \
$(INSTALL_DIR) $(DESTDIR)/usr/share/man/man8
$(INSTALL_PROG) $(BIN) $(SCRIPTS) $(DESTDIR)/usr/bin
$(INSTALL_PROG) $(LIBBIN) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
[ -z "$(LIBBIN)"] || $(INSTALL_PROG) $(LIBBIN) $(DESTDIR)/usr/$(LIBDIR)/xen/bin
$(INSTALL_DATA) $(MAN1) $(DESTDIR)/usr/share/man/man1
$(INSTALL_DATA) $(MAN8) $(DESTDIR)/usr/share/man/man8
+2 -2
View File
@@ -380,10 +380,10 @@ void dump_ctx(int vcpu)
exit(-1);
}
ret = xc_domain_get_vcpu_context(xc_handle, domid, vcpu, &ctx);
ret = xc_vcpu_getcontext(xc_handle, domid, vcpu, &ctx);
if (ret < 0) {
xc_domain_unpause(xc_handle, domid);
perror("xc_domain_get_vcpu_context");
perror("xc_vcpu_getcontext");
exit(-1);
}
@@ -6,7 +6,7 @@ TESTS = 01_network_attach_pos.test \
03_network_attach_detach_multiple_pos.test \
04_network_attach_baddomain_neg.test
XFAIL_TESTS = 03_network_attach_detach_multiple_pos.test
XFAIL_TESTS =
EXTRA_DIST = $(TESTS) $(XFAIL_TESTS) network_utils.py
+26 -4
View File
@@ -23,6 +23,13 @@ OBJS += bitop.o clear_page.o flush.o copy_page_mck.o \
__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
# xen stack unwinder
# unwind_decoder.c is included in unwind.c
OBJS += unwind.o
#unwind.o: CFLAGS += -DUNW_DEBUG=4
OBJS += process-linux-xen.o
# perfmon.o
# unwind.o needed for kernel unwinding (rare)
@@ -31,11 +38,26 @@ OBJS := $(subst $(TARGET_ARCH)/asm-offsets.o,,$(OBJS))
# remove following line if not privifying in memory
# OBJS += privify.o
default: $(OBJS) head.o xen.lds.s
$(LD) -r -o arch.o $(OBJS)
default: $(TARGET)
$(CURDIR)/arch.o: $(OBJS)
$(LD) -r -o $@ $(OBJS)
$(TARGET)-syms: $(ALL_OBJS) head.o xen.lds.s
$(LD) $(LDFLAGS) -T $(BASEDIR)/arch/$(TARGET_ARCH)/xen.lds.s -N \
-Map map.out head.o $(ALL_OBJS) -o $(TARGET)-syms
$(OBJCOPY) -R .note -R .comment -S $(TARGET)-syms $(TARGET)
-Map map.out head.o $(ALL_OBJS) -o $@
$(NM) -n $@ | $(BASEDIR)/tools/symbols > $(BASEDIR)/xen-syms.S
$(MAKE) $(BASEDIR)/xen-syms.o
$(LD) $(LDFLAGS) -T $(BASEDIR)/arch/$(TARGET_ARCH)/xen.lds.s -N \
-Map map.out head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
$(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
$(MAKE) $(BASEDIR)/xen-syms.o
$(LD) $(LDFLAGS) -T $(BASEDIR)/arch/$(TARGET_ARCH)/xen.lds.s -N \
-Map map.out head.o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o
$(TARGET): $(TARGET)-syms
$(OBJCOPY) -R .note -R .comment -S $(TARGET)-syms $@
$(NM) -n $(TARGET)-syms | grep -v '\( [aUw] \)\|\(__crc_\)\|\( \$[adt]\)'\
> $(BASEDIR)/System.map
+1 -1
View File
@@ -1417,7 +1417,6 @@ GLOBAL_ENTRY(ia64_prepare_handle_unaligned)
br.cond.sptk.many rp // goes to ia64_leave_kernel
END(ia64_prepare_handle_unaligned)
#ifndef XEN
//
// unw_init_running(void (*callback)(info, arg), void *arg)
//
@@ -1463,6 +1462,7 @@ GLOBAL_ENTRY(unw_init_running)
br.ret.sptk.many rp
END(unw_init_running)
#ifndef XEN
.rodata
.align 8
.globl sys_call_table
+848
View File
@@ -0,0 +1,848 @@
/*
* Architecture-specific setup.
*
* Copyright (C) 1998-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
* 04/11/17 Ashok Raj <ashok.raj@intel.com> Added CPU Hotplug Support
*/
#ifdef XEN
#include <xen/types.h>
#include <xen/lib.h>
#include <xen/symbols.h>
#include <xen/smp.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/ptrace.h>
#include <asm/unwind.h>
#else
#define __KERNEL_SYSCALLS__ /* see <asm/unistd.h> */
#include <linux/config.h>
#include <linux/cpu.h>
#include <linux/pm.h>
#include <linux/elf.h>
#include <linux/errno.h>
#include <linux/kallsyms.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/module.h>
#include <linux/notifier.h>
#include <linux/personality.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/smp_lock.h>
#include <linux/stddef.h>
#include <linux/thread_info.h>
#include <linux/unistd.h>
#include <linux/efi.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/kprobes.h>
#include <asm/cpu.h>
#include <asm/delay.h>
#include <asm/elf.h>
#include <asm/ia32.h>
#include <asm/irq.h>
#include <asm/pgalloc.h>
#include <asm/processor.h>
#include <asm/sal.h>
#include <asm/tlbflush.h>
#include <asm/uaccess.h>
#include <asm/unwind.h>
#include <asm/user.h>
#include "entry.h"
#ifdef CONFIG_PERFMON
# include <asm/perfmon.h>
#endif
#include "sigframe.h"
void (*ia64_mark_idle)(int);
static DEFINE_PER_CPU(unsigned int, cpu_idle_state);
unsigned long boot_option_idle_override = 0;
EXPORT_SYMBOL(boot_option_idle_override);
#endif
void
ia64_do_show_stack (struct unw_frame_info *info, void *arg)
{
unsigned long ip, sp, bsp;
char buf[128]; /* don't make it so big that it overflows the stack! */
printk("\nCall Trace:\n");
do {
unw_get_ip(info, &ip);
if (ip == 0)
break;
unw_get_sp(info, &sp);
unw_get_bsp(info, &bsp);
snprintf(buf, sizeof(buf),
" [<%016lx>] %%s\n"
" sp=%016lx bsp=%016lx\n",
ip, sp, bsp);
print_symbol(buf, ip);
} while (unw_unwind(info) >= 0);
}
void
show_stack (struct task_struct *task, unsigned long *sp)
{
if (!task)
unw_init_running(ia64_do_show_stack, NULL);
else {
struct unw_frame_info info;
unw_init_from_blocked_task(&info, task);
ia64_do_show_stack(&info, NULL);
}
}
#ifndef XEN
void
dump_stack (void)
{
show_stack(NULL, NULL);
}
EXPORT_SYMBOL(dump_stack);
#endif
#ifdef XEN
void
show_registers(struct pt_regs *regs)
#else
void
show_regs (struct pt_regs *regs)
#endif
{
unsigned long ip = regs->cr_iip + ia64_psr(regs)->ri;
#ifndef XEN
print_modules();
printk("\nPid: %d, CPU %d, comm: %20s\n", current->pid, smp_processor_id(), current->comm);
printk("psr : %016lx ifs : %016lx ip : [<%016lx>] %s\n",
regs->cr_ipsr, regs->cr_ifs, ip, print_tainted());
#else
printk("\nCPU %d\n", smp_processor_id());
printk("psr : %016lx ifs : %016lx ip : [<%016lx>]\n",
regs->cr_ipsr, regs->cr_ifs, ip);
#endif
print_symbol("ip is at %s\n", ip);
printk("unat: %016lx pfs : %016lx rsc : %016lx\n",
regs->ar_unat, regs->ar_pfs, regs->ar_rsc);
printk("rnat: %016lx bsps: %016lx pr : %016lx\n",
regs->ar_rnat, regs->ar_bspstore, regs->pr);
printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n",
regs->loadrs, regs->ar_ccv, regs->ar_fpsr);
printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd);
printk("b0 : %016lx b6 : %016lx b7 : %016lx\n", regs->b0, regs->b6, regs->b7);
printk("f6 : %05lx%016lx f7 : %05lx%016lx\n",
regs->f6.u.bits[1], regs->f6.u.bits[0],
regs->f7.u.bits[1], regs->f7.u.bits[0]);
printk("f8 : %05lx%016lx f9 : %05lx%016lx\n",
regs->f8.u.bits[1], regs->f8.u.bits[0],
regs->f9.u.bits[1], regs->f9.u.bits[0]);
printk("f10 : %05lx%016lx f11 : %05lx%016lx\n",
regs->f10.u.bits[1], regs->f10.u.bits[0],
regs->f11.u.bits[1], regs->f11.u.bits[0]);
printk("r1 : %016lx r2 : %016lx r3 : %016lx\n", regs->r1, regs->r2, regs->r3);
printk("r8 : %016lx r9 : %016lx r10 : %016lx\n", regs->r8, regs->r9, regs->r10);
printk("r11 : %016lx r12 : %016lx r13 : %016lx\n", regs->r11, regs->r12, regs->r13);
printk("r14 : %016lx r15 : %016lx r16 : %016lx\n", regs->r14, regs->r15, regs->r16);
printk("r17 : %016lx r18 : %016lx r19 : %016lx\n", regs->r17, regs->r18, regs->r19);
printk("r20 : %016lx r21 : %016lx r22 : %016lx\n", regs->r20, regs->r21, regs->r22);
printk("r23 : %016lx r24 : %016lx r25 : %016lx\n", regs->r23, regs->r24, regs->r25);
printk("r26 : %016lx r27 : %016lx r28 : %016lx\n", regs->r26, regs->r27, regs->r28);
printk("r29 : %016lx r30 : %016lx r31 : %016lx\n", regs->r29, regs->r30, regs->r31);
if (user_mode(regs)) {
/* print the stacked registers */
unsigned long val, *bsp, ndirty;
int i, sof, is_nat = 0;
sof = regs->cr_ifs & 0x7f; /* size of frame */
ndirty = (regs->loadrs >> 19);
bsp = ia64_rse_skip_regs((unsigned long *) regs->ar_bspstore, ndirty);
for (i = 0; i < sof; ++i) {
get_user(val, (unsigned long __user *) ia64_rse_skip_regs(bsp, i));
printk("r%-3u:%c%016lx%s", 32 + i, is_nat ? '*' : ' ', val,
((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
}
} else
show_stack(NULL, NULL);
}
#ifndef XEN
void
do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
{
if (fsys_mode(current, &scr->pt)) {
/* defer signal-handling etc. until we return to privilege-level 0. */
if (!ia64_psr(&scr->pt)->lp)
ia64_psr(&scr->pt)->lp = 1;
return;
}
#ifdef CONFIG_PERFMON
if (current->thread.pfm_needs_checking)
pfm_handle_work();
#endif
/* deal with pending signal delivery */
if (test_thread_flag(TIF_SIGPENDING))
ia64_do_signal(oldset, scr, in_syscall);
}
static int pal_halt = 1;
static int can_do_pal_halt = 1;
static int __init nohalt_setup(char * str)
{
pal_halt = can_do_pal_halt = 0;
return 1;
}
__setup("nohalt", nohalt_setup);
void
update_pal_halt_status(int status)
{
can_do_pal_halt = pal_halt && status;
}
/*
* We use this if we don't have any better idle routine..
*/
void
default_idle (void)
{
local_irq_enable();
while (!need_resched())
if (can_do_pal_halt)
safe_halt();
else
cpu_relax();
}
#ifdef CONFIG_HOTPLUG_CPU
/* We don't actually take CPU down, just spin without interrupts. */
static inline void play_dead(void)
{
extern void ia64_cpu_local_tick (void);
unsigned int this_cpu = smp_processor_id();
/* Ack it */
__get_cpu_var(cpu_state) = CPU_DEAD;
max_xtp();
local_irq_disable();
idle_domain_exit();
ia64_jump_to_sal(&sal_boot_rendez_state[this_cpu]);
/*
* The above is a point of no-return, the processor is
* expected to be in SAL loop now.
*/
BUG();
}
#else
static inline void play_dead(void)
{
BUG();
}
#endif /* CONFIG_HOTPLUG_CPU */
void cpu_idle_wait(void)
{
unsigned int cpu, this_cpu = get_cpu();
cpumask_t map;
set_cpus_allowed(current, cpumask_of_cpu(this_cpu));
put_cpu();
cpus_clear(map);
for_each_online_cpu(cpu) {
per_cpu(cpu_idle_state, cpu) = 1;
cpu_set(cpu, map);
}
__get_cpu_var(cpu_idle_state) = 0;
wmb();
do {
ssleep(1);
for_each_online_cpu(cpu) {
if (cpu_isset(cpu, map) && !per_cpu(cpu_idle_state, cpu))
cpu_clear(cpu, map);
}
cpus_and(map, map, cpu_online_map);
} while (!cpus_empty(map));
}
EXPORT_SYMBOL_GPL(cpu_idle_wait);
void __attribute__((noreturn))
cpu_idle (void)
{
void (*mark_idle)(int) = ia64_mark_idle;
/* endless idle loop with no priority at all */
while (1) {
#ifdef CONFIG_SMP
if (!need_resched())
min_xtp();
#endif
while (!need_resched()) {
void (*idle)(void);
if (__get_cpu_var(cpu_idle_state))
__get_cpu_var(cpu_idle_state) = 0;
rmb();
if (mark_idle)
(*mark_idle)(1);
idle = pm_idle;
if (!idle)
idle = default_idle;
(*idle)();
}
if (mark_idle)
(*mark_idle)(0);
#ifdef CONFIG_SMP
normal_xtp();
#endif
schedule();
check_pgt_cache();
if (cpu_is_offline(smp_processor_id()))
play_dead();
}
}
void
ia64_save_extra (struct task_struct *task)
{
#ifdef CONFIG_PERFMON
unsigned long info;
#endif
if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
ia64_save_debug_regs(&task->thread.dbr[0]);
#ifdef CONFIG_PERFMON
if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
pfm_save_regs(task);
info = __get_cpu_var(pfm_syst_info);
if (info & PFM_CPUINFO_SYST_WIDE)
pfm_syst_wide_update_task(task, info, 0);
#endif
#ifdef CONFIG_IA32_SUPPORT
if (IS_IA32_PROCESS(ia64_task_regs(task)))
ia32_save_state(task);
#endif
}
void
ia64_load_extra (struct task_struct *task)
{
#ifdef CONFIG_PERFMON
unsigned long info;
#endif
if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0)
ia64_load_debug_regs(&task->thread.dbr[0]);
#ifdef CONFIG_PERFMON
if ((task->thread.flags & IA64_THREAD_PM_VALID) != 0)
pfm_load_regs(task);
info = __get_cpu_var(pfm_syst_info);
if (info & PFM_CPUINFO_SYST_WIDE)
pfm_syst_wide_update_task(task, info, 1);
#endif
#ifdef CONFIG_IA32_SUPPORT
if (IS_IA32_PROCESS(ia64_task_regs(task)))
ia32_load_state(task);
#endif
}
/*
* Copy the state of an ia-64 thread.
*
* We get here through the following call chain:
*
* from user-level: from kernel:
*
* <clone syscall> <some kernel call frames>
* sys_clone :
* do_fork do_fork
* copy_thread copy_thread
*
* This means that the stack layout is as follows:
*
* +---------------------+ (highest addr)
* | struct pt_regs |
* +---------------------+
* | struct switch_stack |
* +---------------------+
* | |
* | memory stack |
* | | <-- sp (lowest addr)
* +---------------------+
*
* Observe that we copy the unat values that are in pt_regs and switch_stack. Spilling an
* integer to address X causes bit N in ar.unat to be set to the NaT bit of the register,
* with N=(X & 0x1ff)/8. Thus, copying the unat value preserves the NaT bits ONLY if the
* pt_regs structure in the parent is congruent to that of the child, modulo 512. Since
* the stack is page aligned and the page size is at least 4KB, this is always the case,
* so there is nothing to worry about.
*/
int
copy_thread (int nr, unsigned long clone_flags,
unsigned long user_stack_base, unsigned long user_stack_size,
struct task_struct *p, struct pt_regs *regs)
{
extern char ia64_ret_from_clone, ia32_ret_from_clone;
struct switch_stack *child_stack, *stack;
unsigned long rbs, child_rbs, rbs_size;
struct pt_regs *child_ptregs;
int retval = 0;
#ifdef CONFIG_SMP
/*
* For SMP idle threads, fork_by_hand() calls do_fork with
* NULL regs.
*/
if (!regs)
return 0;
#endif
stack = ((struct switch_stack *) regs) - 1;
child_ptregs = (struct pt_regs *) ((unsigned long) p + IA64_STK_OFFSET) - 1;
child_stack = (struct switch_stack *) child_ptregs - 1;
/* copy parent's switch_stack & pt_regs to child: */
memcpy(child_stack, stack, sizeof(*child_ptregs) + sizeof(*child_stack));
rbs = (unsigned long) current + IA64_RBS_OFFSET;
child_rbs = (unsigned long) p + IA64_RBS_OFFSET;
rbs_size = stack->ar_bspstore - rbs;
/* copy the parent's register backing store to the child: */
memcpy((void *) child_rbs, (void *) rbs, rbs_size);
if (likely(user_mode(child_ptregs))) {
if ((clone_flags & CLONE_SETTLS) && !IS_IA32_PROCESS(regs))
child_ptregs->r13 = regs->r16; /* see sys_clone2() in entry.S */
if (user_stack_base) {
child_ptregs->r12 = user_stack_base + user_stack_size - 16;
child_ptregs->ar_bspstore = user_stack_base;
child_ptregs->ar_rnat = 0;
child_ptregs->loadrs = 0;
}
} else {
/*
* Note: we simply preserve the relative position of
* the stack pointer here. There is no need to
* allocate a scratch area here, since that will have
* been taken care of by the caller of sys_clone()
* already.
*/
child_ptregs->r12 = (unsigned long) child_ptregs - 16; /* kernel sp */
child_ptregs->r13 = (unsigned long) p; /* set `current' pointer */
}
child_stack->ar_bspstore = child_rbs + rbs_size;
if (IS_IA32_PROCESS(regs))
child_stack->b0 = (unsigned long) &ia32_ret_from_clone;
else
child_stack->b0 = (unsigned long) &ia64_ret_from_clone;
/* copy parts of thread_struct: */
p->thread.ksp = (unsigned long) child_stack - 16;
/* stop some PSR bits from being inherited.
* the psr.up/psr.pp bits must be cleared on fork but inherited on execve()
* therefore we must specify them explicitly here and not include them in
* IA64_PSR_BITS_TO_CLEAR.
*/
child_ptregs->cr_ipsr = ((child_ptregs->cr_ipsr | IA64_PSR_BITS_TO_SET)
& ~(IA64_PSR_BITS_TO_CLEAR | IA64_PSR_PP | IA64_PSR_UP));
/*
* NOTE: The calling convention considers all floating point
* registers in the high partition (fph) to be scratch. Since
* the only way to get to this point is through a system call,
* we know that the values in fph are all dead. Hence, there
* is no need to inherit the fph state from the parent to the
* child and all we have to do is to make sure that
* IA64_THREAD_FPH_VALID is cleared in the child.
*
* XXX We could push this optimization a bit further by
* clearing IA64_THREAD_FPH_VALID on ANY system call.
* However, it's not clear this is worth doing. Also, it
* would be a slight deviation from the normal Linux system
* call behavior where scratch registers are preserved across
* system calls (unless used by the system call itself).
*/
# define THREAD_FLAGS_TO_CLEAR (IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID \
| IA64_THREAD_PM_VALID)
# define THREAD_FLAGS_TO_SET 0
p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
| THREAD_FLAGS_TO_SET);
ia64_drop_fpu(p); /* don't pick up stale state from a CPU's fph */
#ifdef CONFIG_IA32_SUPPORT
/*
* If we're cloning an IA32 task then save the IA32 extra
* state from the current task to the new task
*/
if (IS_IA32_PROCESS(ia64_task_regs(current))) {
ia32_save_state(p);
if (clone_flags & CLONE_SETTLS)
retval = ia32_clone_tls(p, child_ptregs);
/* Copy partially mapped page list */
if (!retval)
retval = ia32_copy_partial_page_list(p, clone_flags);
}
#endif
#ifdef CONFIG_PERFMON
if (current->thread.pfm_context)
pfm_inherit(p, child_ptregs);
#endif
return retval;
}
static void
do_copy_task_regs (struct task_struct *task, struct unw_frame_info *info, void *arg)
{
unsigned long mask, sp, nat_bits = 0, ip, ar_rnat, urbs_end, cfm;
elf_greg_t *dst = arg;
struct pt_regs *pt;
char nat;
int i;
memset(dst, 0, sizeof(elf_gregset_t)); /* don't leak any kernel bits to user-level */
if (unw_unwind_to_user(info) < 0)
return;
unw_get_sp(info, &sp);
pt = (struct pt_regs *) (sp + 16);
urbs_end = ia64_get_user_rbs_end(task, pt, &cfm);
if (ia64_sync_user_rbs(task, info->sw, pt->ar_bspstore, urbs_end) < 0)
return;
ia64_peek(task, info->sw, urbs_end, (long) ia64_rse_rnat_addr((long *) urbs_end),
&ar_rnat);
/*
* coredump format:
* r0-r31
* NaT bits (for r0-r31; bit N == 1 iff rN is a NaT)
* predicate registers (p0-p63)
* b0-b7
* ip cfm user-mask
* ar.rsc ar.bsp ar.bspstore ar.rnat
* ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec
*/
/* r0 is zero */
for (i = 1, mask = (1UL << i); i < 32; ++i) {
unw_get_gr(info, i, &dst[i], &nat);
if (nat)
nat_bits |= mask;
mask <<= 1;
}
dst[32] = nat_bits;
unw_get_pr(info, &dst[33]);
for (i = 0; i < 8; ++i)
unw_get_br(info, i, &dst[34 + i]);
unw_get_rp(info, &ip);
dst[42] = ip + ia64_psr(pt)->ri;
dst[43] = cfm;
dst[44] = pt->cr_ipsr & IA64_PSR_UM;
unw_get_ar(info, UNW_AR_RSC, &dst[45]);
/*
* For bsp and bspstore, unw_get_ar() would return the kernel
* addresses, but we need the user-level addresses instead:
*/
dst[46] = urbs_end; /* note: by convention PT_AR_BSP points to the end of the urbs! */
dst[47] = pt->ar_bspstore;
dst[48] = ar_rnat;
unw_get_ar(info, UNW_AR_CCV, &dst[49]);
unw_get_ar(info, UNW_AR_UNAT, &dst[50]);
unw_get_ar(info, UNW_AR_FPSR, &dst[51]);
dst[52] = pt->ar_pfs; /* UNW_AR_PFS is == to pt->cr_ifs for interrupt frames */
unw_get_ar(info, UNW_AR_LC, &dst[53]);
unw_get_ar(info, UNW_AR_EC, &dst[54]);
unw_get_ar(info, UNW_AR_CSD, &dst[55]);
unw_get_ar(info, UNW_AR_SSD, &dst[56]);
}
void
do_dump_task_fpu (struct task_struct *task, struct unw_frame_info *info, void *arg)
{
elf_fpreg_t *dst = arg;
int i;
memset(dst, 0, sizeof(elf_fpregset_t)); /* don't leak any "random" bits */
if (unw_unwind_to_user(info) < 0)
return;
/* f0 is 0.0, f1 is 1.0 */
for (i = 2; i < 32; ++i)
unw_get_fr(info, i, dst + i);
ia64_flush_fph(task);
if ((task->thread.flags & IA64_THREAD_FPH_VALID) != 0)
memcpy(dst + 32, task->thread.fph, 96*16);
}
void
do_copy_regs (struct unw_frame_info *info, void *arg)
{
do_copy_task_regs(current, info, arg);
}
void
do_dump_fpu (struct unw_frame_info *info, void *arg)
{
do_dump_task_fpu(current, info, arg);
}
int
dump_task_regs(struct task_struct *task, elf_gregset_t *regs)
{
struct unw_frame_info tcore_info;
if (current == task) {
unw_init_running(do_copy_regs, regs);
} else {
memset(&tcore_info, 0, sizeof(tcore_info));
unw_init_from_blocked_task(&tcore_info, task);
do_copy_task_regs(task, &tcore_info, regs);
}
return 1;
}
void
ia64_elf_core_copy_regs (struct pt_regs *pt, elf_gregset_t dst)
{
unw_init_running(do_copy_regs, dst);
}
int
dump_task_fpu (struct task_struct *task, elf_fpregset_t *dst)
{
struct unw_frame_info tcore_info;
if (current == task) {
unw_init_running(do_dump_fpu, dst);
} else {
memset(&tcore_info, 0, sizeof(tcore_info));
unw_init_from_blocked_task(&tcore_info, task);
do_dump_task_fpu(task, &tcore_info, dst);
}
return 1;
}
int
dump_fpu (struct pt_regs *pt, elf_fpregset_t dst)
{
unw_init_running(do_dump_fpu, dst);
return 1; /* f0-f31 are always valid so we always return 1 */
}
long
sys_execve (char __user *filename, char __user * __user *argv, char __user * __user *envp,
struct pt_regs *regs)
{
char *fname;
int error;
fname = getname(filename);
error = PTR_ERR(fname);
if (IS_ERR(fname))
goto out;
error = do_execve(fname, argv, envp, regs);
putname(fname);
out:
return error;
}
pid_t
kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
{
extern void start_kernel_thread (void);
unsigned long *helper_fptr = (unsigned long *) &start_kernel_thread;
struct {
struct switch_stack sw;
struct pt_regs pt;
} regs;
memset(&regs, 0, sizeof(regs));
regs.pt.cr_iip = helper_fptr[0]; /* set entry point (IP) */
regs.pt.r1 = helper_fptr[1]; /* set GP */
regs.pt.r9 = (unsigned long) fn; /* 1st argument */
regs.pt.r11 = (unsigned long) arg; /* 2nd argument */
/* Preserve PSR bits, except for bits 32-34 and 37-45, which we can't read. */
regs.pt.cr_ipsr = ia64_getreg(_IA64_REG_PSR) | IA64_PSR_BN;
regs.pt.cr_ifs = 1UL << 63; /* mark as valid, empty frame */
regs.sw.ar_fpsr = regs.pt.ar_fpsr = ia64_getreg(_IA64_REG_AR_FPSR);
regs.sw.ar_bspstore = (unsigned long) current + IA64_RBS_OFFSET;
regs.sw.pr = (1 << PRED_KERNEL_STACK);
return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, &regs.pt, 0, NULL, NULL);
}
EXPORT_SYMBOL(kernel_thread);
/* This gets called from kernel_thread() via ia64_invoke_thread_helper(). */
int
kernel_thread_helper (int (*fn)(void *), void *arg)
{
#ifdef CONFIG_IA32_SUPPORT
if (IS_IA32_PROCESS(ia64_task_regs(current))) {
/* A kernel thread is always a 64-bit process. */
current->thread.map_base = DEFAULT_MAP_BASE;
current->thread.task_size = DEFAULT_TASK_SIZE;
ia64_set_kr(IA64_KR_IO_BASE, current->thread.old_iob);
ia64_set_kr(IA64_KR_TSSD, current->thread.old_k1);
}
#endif
return (*fn)(arg);
}
/*
* Flush thread state. This is called when a thread does an execve().
*/
void
flush_thread (void)
{
/*
* Remove function-return probe instances associated with this task
* and put them back on the free list. Do not insert an exit probe for
* this function, it will be disabled by kprobe_flush_task if you do.
*/
kprobe_flush_task(current);
/* drop floating-point and debug-register state if it exists: */
current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
ia64_drop_fpu(current);
if (IS_IA32_PROCESS(ia64_task_regs(current)))
ia32_drop_partial_page_list(current);
}
/*
* Clean up state associated with current thread. This is called when
* the thread calls exit().
*/
void
exit_thread (void)
{
/*
* Remove function-return probe instances associated with this task
* and put them back on the free list. Do not insert an exit probe for
* this function, it will be disabled by kprobe_flush_task if you do.
*/
kprobe_flush_task(current);
ia64_drop_fpu(current);
#ifdef CONFIG_PERFMON
/* if needed, stop monitoring and flush state to perfmon context */
if (current->thread.pfm_context)
pfm_exit_thread(current);
/* free debug register resources */
if (current->thread.flags & IA64_THREAD_DBG_VALID)
pfm_release_debug_registers(current);
#endif
if (IS_IA32_PROCESS(ia64_task_regs(current)))
ia32_drop_partial_page_list(current);
}
unsigned long
get_wchan (struct task_struct *p)
{
struct unw_frame_info info;
unsigned long ip;
int count = 0;
/*
* Note: p may not be a blocked task (it could be current or
* another process running on some other CPU. Rather than
* trying to determine if p is really blocked, we just assume
* it's blocked and rely on the unwind routines to fail
* gracefully if the process wasn't really blocked after all.
* --davidm 99/12/15
*/
unw_init_from_blocked_task(&info, p);
do {
if (unw_unwind(&info) < 0)
return 0;
unw_get_ip(&info, &ip);
if (!in_sched_functions(ip))
return ip;
} while (count++ < 16);
return 0;
}
void
cpu_halt (void)
{
pal_power_mgmt_info_u_t power_info[8];
unsigned long min_power;
int i, min_power_state;
if (ia64_pal_halt_info(power_info) != 0)
return;
min_power_state = 0;
min_power = power_info[0].pal_power_mgmt_info_s.power_consumption;
for (i = 1; i < 8; ++i)
if (power_info[i].pal_power_mgmt_info_s.im
&& power_info[i].pal_power_mgmt_info_s.power_consumption < min_power) {
min_power = power_info[i].pal_power_mgmt_info_s.power_consumption;
min_power_state = i;
}
while (1)
ia64_pal_halt(min_power_state);
}
void
machine_restart (char *restart_cmd)
{
(*efi.reset_system)(EFI_RESET_WARM, 0, 0, NULL);
}
void
machine_halt (void)
{
cpu_halt();
}
void
machine_power_off (void)
{
if (pm_power_off)
pm_power_off();
machine_halt();
}
#endif // !XEN
File diff suppressed because it is too large. Load diff
+459
View File
@@ -0,0 +1,459 @@
/*
* Copyright (C) 2000 Hewlett-Packard Co
* Copyright (C) 2000 David Mosberger-Tang <davidm@hpl.hp.com>
*
* Generic IA-64 unwind info decoder.
*
* This file is used both by the Linux kernel and objdump. Please keep
* the two copies of this file in sync.
*
* You need to customize the decoder by defining the following
* macros/constants before including this file:
*
* Types:
* unw_word Unsigned integer type with at least 64 bits
*
* Register names:
* UNW_REG_BSP
* UNW_REG_BSPSTORE
* UNW_REG_FPSR
* UNW_REG_LC
* UNW_REG_PFS
* UNW_REG_PR
* UNW_REG_RNAT
* UNW_REG_PSP
* UNW_REG_RP
* UNW_REG_UNAT
*
* Decoder action macros:
* UNW_DEC_BAD_CODE(code)
* UNW_DEC_ABI(fmt,abi,context,arg)
* UNW_DEC_BR_GR(fmt,brmask,gr,arg)
* UNW_DEC_BR_MEM(fmt,brmask,arg)
* UNW_DEC_COPY_STATE(fmt,label,arg)
* UNW_DEC_EPILOGUE(fmt,t,ecount,arg)
* UNW_DEC_FRGR_MEM(fmt,grmask,frmask,arg)
* UNW_DEC_FR_MEM(fmt,frmask,arg)
* UNW_DEC_GR_GR(fmt,grmask,gr,arg)
* UNW_DEC_GR_MEM(fmt,grmask,arg)
* UNW_DEC_LABEL_STATE(fmt,label,arg)
* UNW_DEC_MEM_STACK_F(fmt,t,size,arg)
* UNW_DEC_MEM_STACK_V(fmt,t,arg)
* UNW_DEC_PRIUNAT_GR(fmt,r,arg)
* UNW_DEC_PRIUNAT_WHEN_GR(fmt,t,arg)
* UNW_DEC_PRIUNAT_WHEN_MEM(fmt,t,arg)
* UNW_DEC_PRIUNAT_WHEN_PSPREL(fmt,pspoff,arg)
* UNW_DEC_PRIUNAT_WHEN_SPREL(fmt,spoff,arg)
* UNW_DEC_PROLOGUE(fmt,body,rlen,arg)
* UNW_DEC_PROLOGUE_GR(fmt,rlen,mask,grsave,arg)
* UNW_DEC_REG_PSPREL(fmt,reg,pspoff,arg)
* UNW_DEC_REG_REG(fmt,src,dst,arg)
* UNW_DEC_REG_SPREL(fmt,reg,spoff,arg)
* UNW_DEC_REG_WHEN(fmt,reg,t,arg)
* UNW_DEC_RESTORE(fmt,t,abreg,arg)
* UNW_DEC_RESTORE_P(fmt,qp,t,abreg,arg)
* UNW_DEC_SPILL_BASE(fmt,pspoff,arg)
* UNW_DEC_SPILL_MASK(fmt,imaskp,arg)
* UNW_DEC_SPILL_PSPREL(fmt,t,abreg,pspoff,arg)
* UNW_DEC_SPILL_PSPREL_P(fmt,qp,t,abreg,pspoff,arg)
* UNW_DEC_SPILL_REG(fmt,t,abreg,x,ytreg,arg)
* UNW_DEC_SPILL_REG_P(fmt,qp,t,abreg,x,ytreg,arg)
* UNW_DEC_SPILL_SPREL(fmt,t,abreg,spoff,arg)
* UNW_DEC_SPILL_SPREL_P(fmt,qp,t,abreg,pspoff,arg)
*/
static unw_word
unw_decode_uleb128 (unsigned char **dpp)
{
unsigned shift = 0;
unw_word byte, result = 0;
unsigned char *bp = *dpp;
while (1)
{
byte = *bp++;
result |= (byte & 0x7f) << shift;
if ((byte & 0x80) == 0)
break;
shift += 7;
}
*dpp = bp;
return result;
}
static unsigned char *
unw_decode_x1 (unsigned char *dp, unsigned char code, void *arg)
{
unsigned char byte1, abreg;
unw_word t, off;
byte1 = *dp++;
t = unw_decode_uleb128 (&dp);
off = unw_decode_uleb128 (&dp);
abreg = (byte1 & 0x7f);
if (byte1 & 0x80)
UNW_DEC_SPILL_SPREL(X1, t, abreg, off, arg);
else
UNW_DEC_SPILL_PSPREL(X1, t, abreg, off, arg);
return dp;
}
static unsigned char *
unw_decode_x2 (unsigned char *dp, unsigned char code, void *arg)
{
unsigned char byte1, byte2, abreg, x, ytreg;
unw_word t;
byte1 = *dp++; byte2 = *dp++;
t = unw_decode_uleb128 (&dp);
abreg = (byte1 & 0x7f);
ytreg = byte2;
x = (byte1 >> 7) & 1;
if ((byte1 & 0x80) == 0 && ytreg == 0)
UNW_DEC_RESTORE(X2, t, abreg, arg);
else
UNW_DEC_SPILL_REG(X2, t, abreg, x, ytreg, arg);
return dp;
}
static unsigned char *
unw_decode_x3 (unsigned char *dp, unsigned char code, void *arg)
{
unsigned char byte1, byte2, abreg, qp;
unw_word t, off;
byte1 = *dp++; byte2 = *dp++;
t = unw_decode_uleb128 (&dp);
off = unw_decode_uleb128 (&dp);
qp = (byte1 & 0x3f);
abreg = (byte2 & 0x7f);
if (byte1 & 0x80)
UNW_DEC_SPILL_SPREL_P(X3, qp, t, abreg, off, arg);
else
UNW_DEC_SPILL_PSPREL_P(X3, qp, t, abreg, off, arg);
return dp;
}
static unsigned char *
unw_decode_x4 (unsigned char *dp, unsigned char code, void *arg)
{
unsigned char byte1, byte2, byte3, qp, abreg, x, ytreg;
unw_word t;
byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
t = unw_decode_uleb128 (&dp);
qp = (byte1 & 0x3f);
abreg = (byte2 & 0x7f);
x = (byte2 >> 7) & 1;
ytreg = byte3;
if ((byte2 & 0x80) == 0 && byte3 == 0)
UNW_DEC_RESTORE_P(X4, qp, t, abreg, arg);
else
UNW_DEC_SPILL_REG_P(X4, qp, t, abreg, x, ytreg, arg);
return dp;
}
static unsigned char *
unw_decode_r1 (unsigned char *dp, unsigned char code, void *arg)
{
int body = (code & 0x20) != 0;
unw_word rlen;
rlen = (code & 0x1f);
UNW_DEC_PROLOGUE(R1, body, rlen, arg);
return dp;
}
static unsigned char *
unw_decode_r2 (unsigned char *dp, unsigned char code, void *arg)
{
unsigned char byte1, mask, grsave;
unw_word rlen;
byte1 = *dp++;
mask = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
grsave = (byte1 & 0x7f);
rlen = unw_decode_uleb128 (&dp);
UNW_DEC_PROLOGUE_GR(R2, rlen, mask, grsave, arg);
return dp;
}
static unsigned char *
unw_decode_r3 (unsigned char *dp, unsigned char code, void *arg)
{
unw_word rlen;
rlen = unw_decode_uleb128 (&dp);
UNW_DEC_PROLOGUE(R3, ((code & 0x3) == 1), rlen, arg);
return dp;
}
static unsigned char *
unw_decode_p1 (unsigned char *dp, unsigned char code, void *arg)
{
unsigned char brmask = (code & 0x1f);
UNW_DEC_BR_MEM(P1, brmask, arg);
return dp;
}
static unsigned char *
unw_decode_p2_p5 (unsigned char *dp, unsigned char code, void *arg)
{
if ((code & 0x10) == 0)
{
unsigned char byte1 = *dp++;
UNW_DEC_BR_GR(P2, ((code & 0xf) << 1) | ((byte1 >> 7) & 1),
(byte1 & 0x7f), arg);
}
else if ((code & 0x08) == 0)
{
unsigned char byte1 = *dp++, r, dst;
r = ((code & 0x7) << 1) | ((byte1 >> 7) & 1);
dst = (byte1 & 0x7f);
switch (r)
{
case 0: UNW_DEC_REG_GR(P3, UNW_REG_PSP, dst, arg); break;
case 1: UNW_DEC_REG_GR(P3, UNW_REG_RP, dst, arg); break;
case 2: UNW_DEC_REG_GR(P3, UNW_REG_PFS, dst, arg); break;
case 3: UNW_DEC_REG_GR(P3, UNW_REG_PR, dst, arg); break;
case 4: UNW_DEC_REG_GR(P3, UNW_REG_UNAT, dst, arg); break;
case 5: UNW_DEC_REG_GR(P3, UNW_REG_LC, dst, arg); break;
case 6: UNW_DEC_RP_BR(P3, dst, arg); break;
case 7: UNW_DEC_REG_GR(P3, UNW_REG_RNAT, dst, arg); break;
case 8: UNW_DEC_REG_GR(P3, UNW_REG_BSP, dst, arg); break;
case 9: UNW_DEC_REG_GR(P3, UNW_REG_BSPSTORE, dst, arg); break;
case 10: UNW_DEC_REG_GR(P3, UNW_REG_FPSR, dst, arg); break;
case 11: UNW_DEC_PRIUNAT_GR(P3, dst, arg); break;
default: UNW_DEC_BAD_CODE(r); break;
}
}
else if ((code & 0x7) == 0)
UNW_DEC_SPILL_MASK(P4, dp, arg);
else if ((code & 0x7) == 1)
{
unw_word grmask, frmask, byte1, byte2, byte3;
byte1 = *dp++; byte2 = *dp++; byte3 = *dp++;
grmask = ((byte1 >> 4) & 0xf);
frmask = ((byte1 & 0xf) << 16) | (byte2 << 8) | byte3;
UNW_DEC_FRGR_MEM(P5, grmask, frmask, arg);
}
else
UNW_DEC_BAD_CODE(code);
return dp;
}
static unsigned char *
unw_decode_p6 (unsigned char *dp, unsigned char code, void *arg)
{
int gregs = (code & 0x10) != 0;
unsigned char mask = (code & 0x0f);
if (gregs)
UNW_DEC_GR_MEM(P6, mask, arg);
else
UNW_DEC_FR_MEM(P6, mask, arg);
return dp;
}
static unsigned char *
unw_decode_p7_p10 (unsigned char *dp, unsigned char code, void *arg)
{
unsigned char r, byte1, byte2;
unw_word t, size;
if ((code & 0x10) == 0)
{
r = (code & 0xf);
t = unw_decode_uleb128 (&dp);
switch (r)
{
case 0:
size = unw_decode_uleb128 (&dp);
UNW_DEC_MEM_STACK_F(P7, t, size, arg);
break;
case 1: UNW_DEC_MEM_STACK_V(P7, t, arg); break;
case 2: UNW_DEC_SPILL_BASE(P7, t, arg); break;
case 3: UNW_DEC_REG_SPREL(P7, UNW_REG_PSP, t, arg); break;
case 4: UNW_DEC_REG_WHEN(P7, UNW_REG_RP, t, arg); break;
case 5: UNW_DEC_REG_PSPREL(P7, UNW_REG_RP, t, arg); break;
case 6: UNW_DEC_REG_WHEN(P7, UNW_REG_PFS, t, arg); break;
case 7: UNW_DEC_REG_PSPREL(P7, UNW_REG_PFS, t, arg); break;
case 8: UNW_DEC_REG_WHEN(P7, UNW_REG_PR, t, arg); break;
case 9: UNW_DEC_REG_PSPREL(P7, UNW_REG_PR, t, arg); break;
case 10: UNW_DEC_REG_WHEN(P7, UNW_REG_LC, t, arg); break;
case 11: UNW_DEC_REG_PSPREL(P7, UNW_REG_LC, t, arg); break;
case 12: UNW_DEC_REG_WHEN(P7, UNW_REG_UNAT, t, arg); break;
case 13: UNW_DEC_REG_PSPREL(P7, UNW_REG_UNAT, t, arg); break;
case 14: UNW_DEC_REG_WHEN(P7, UNW_REG_FPSR, t, arg); break;
case 15: UNW_DEC_REG_PSPREL(P7, UNW_REG_FPSR, t, arg); break;
default: UNW_DEC_BAD_CODE(r); break;
}
}
else
{
switch (code & 0xf)
{
case 0x0: /* p8 */
{
r = *dp++;
t = unw_decode_uleb128 (&dp);
switch (r)
{
case 1: UNW_DEC_REG_SPREL(P8, UNW_REG_RP, t, arg); break;
case 2: UNW_DEC_REG_SPREL(P8, UNW_REG_PFS, t, arg); break;
case 3: UNW_DEC_REG_SPREL(P8, UNW_REG_PR, t, arg); break;
case 4: UNW_DEC_REG_SPREL(P8, UNW_REG_LC, t, arg); break;
case 5: UNW_DEC_REG_SPREL(P8, UNW_REG_UNAT, t, arg); break;
case 6: UNW_DEC_REG_SPREL(P8, UNW_REG_FPSR, t, arg); break;
case 7: UNW_DEC_REG_WHEN(P8, UNW_REG_BSP, t, arg); break;
case 8: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSP, t, arg); break;
case 9: UNW_DEC_REG_SPREL(P8, UNW_REG_BSP, t, arg); break;
case 10: UNW_DEC_REG_WHEN(P8, UNW_REG_BSPSTORE, t, arg); break;
case 11: UNW_DEC_REG_PSPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
case 12: UNW_DEC_REG_SPREL(P8, UNW_REG_BSPSTORE, t, arg); break;
case 13: UNW_DEC_REG_WHEN(P8, UNW_REG_RNAT, t, arg); break;
case 14: UNW_DEC_REG_PSPREL(P8, UNW_REG_RNAT, t, arg); break;
case 15: UNW_DEC_REG_SPREL(P8, UNW_REG_RNAT, t, arg); break;
case 16: UNW_DEC_PRIUNAT_WHEN_GR(P8, t, arg); break;
case 17: UNW_DEC_PRIUNAT_PSPREL(P8, t, arg); break;
case 18: UNW_DEC_PRIUNAT_SPREL(P8, t, arg); break;
case 19: UNW_DEC_PRIUNAT_WHEN_MEM(P8, t, arg); break;
default: UNW_DEC_BAD_CODE(r); break;
}
}
break;
case 0x1:
byte1 = *dp++; byte2 = *dp++;
UNW_DEC_GR_GR(P9, (byte1 & 0xf), (byte2 & 0x7f), arg);
break;
case 0xf: /* p10 */
byte1 = *dp++; byte2 = *dp++;
UNW_DEC_ABI(P10, byte1, byte2, arg);
break;
case 0x9:
return unw_decode_x1 (dp, code, arg);
case 0xa:
return unw_decode_x2 (dp, code, arg);
case 0xb:
return unw_decode_x3 (dp, code, arg);
case 0xc:
return unw_decode_x4 (dp, code, arg);
default:
UNW_DEC_BAD_CODE(code);
break;
}
}
return dp;
}
static unsigned char *
unw_decode_b1 (unsigned char *dp, unsigned char code, void *arg)
{
unw_word label = (code & 0x1f);
if ((code & 0x20) != 0)
UNW_DEC_COPY_STATE(B1, label, arg);
else
UNW_DEC_LABEL_STATE(B1, label, arg);
return dp;
}
static unsigned char *
unw_decode_b2 (unsigned char *dp, unsigned char code, void *arg)
{
unw_word t;
t = unw_decode_uleb128 (&dp);
UNW_DEC_EPILOGUE(B2, t, (code & 0x1f), arg);
return dp;
}
static unsigned char *
unw_decode_b3_x4 (unsigned char *dp, unsigned char code, void *arg)
{
unw_word t, ecount, label;
if ((code & 0x10) == 0)
{
t = unw_decode_uleb128 (&dp);
ecount = unw_decode_uleb128 (&dp);
UNW_DEC_EPILOGUE(B3, t, ecount, arg);
}
else if ((code & 0x07) == 0)
{
label = unw_decode_uleb128 (&dp);
if ((code & 0x08) != 0)
UNW_DEC_COPY_STATE(B4, label, arg);
else
UNW_DEC_LABEL_STATE(B4, label, arg);
}
else
switch (code & 0x7)
{
case 1: return unw_decode_x1 (dp, code, arg);
case 2: return unw_decode_x2 (dp, code, arg);
case 3: return unw_decode_x3 (dp, code, arg);
case 4: return unw_decode_x4 (dp, code, arg);
default: UNW_DEC_BAD_CODE(code); break;
}
return dp;
}
typedef unsigned char *(*unw_decoder) (unsigned char *, unsigned char, void *);
static unw_decoder unw_decode_table[2][8] =
{
/* prologue table: */
{
unw_decode_r1, /* 0 */
unw_decode_r1,
unw_decode_r2,
unw_decode_r3,
unw_decode_p1, /* 4 */
unw_decode_p2_p5,
unw_decode_p6,
unw_decode_p7_p10
},
{
unw_decode_r1, /* 0 */
unw_decode_r1,
unw_decode_r2,
unw_decode_r3,
unw_decode_b1, /* 4 */
unw_decode_b1,
unw_decode_b2,
unw_decode_b3_x4
}
};
/*
* Decode one descriptor and return address of next descriptor.
*/
static inline unsigned char *
unw_decode (unsigned char *dp, int inside_body, void *arg)
{
unw_decoder decoder;
unsigned char code;
code = *dp++;
decoder = unw_decode_table[inside_body][code >> 5];
dp = (*decoder) (dp, code, arg);
return dp;
}
+164
View File
@@ -0,0 +1,164 @@
/*
* Copyright (C) 2000, 2002-2003 Hewlett-Packard Co
* David Mosberger-Tang <davidm@hpl.hp.com>
*
* Kernel unwind support.
*/
#define UNW_VER(x) ((x) >> 48)
#define UNW_FLAG_MASK 0x0000ffff00000000
#define UNW_FLAG_OSMASK 0x0000f00000000000
#define UNW_FLAG_EHANDLER(x) ((x) & 0x0000000100000000L)
#define UNW_FLAG_UHANDLER(x) ((x) & 0x0000000200000000L)
#define UNW_LENGTH(x) ((x) & 0x00000000ffffffffL)
enum unw_register_index {
/* primary unat: */
UNW_REG_PRI_UNAT_GR,
UNW_REG_PRI_UNAT_MEM,
/* register stack */
UNW_REG_BSP, /* register stack pointer */
UNW_REG_BSPSTORE,
UNW_REG_PFS, /* previous function state */
UNW_REG_RNAT,
/* memory stack */
UNW_REG_PSP, /* previous memory stack pointer */
/* return pointer: */
UNW_REG_RP,
/* preserved registers: */
UNW_REG_R4, UNW_REG_R5, UNW_REG_R6, UNW_REG_R7,
UNW_REG_UNAT, UNW_REG_PR, UNW_REG_LC, UNW_REG_FPSR,
UNW_REG_B1, UNW_REG_B2, UNW_REG_B3, UNW_REG_B4, UNW_REG_B5,
UNW_REG_F2, UNW_REG_F3, UNW_REG_F4, UNW_REG_F5,
UNW_REG_F16, UNW_REG_F17, UNW_REG_F18, UNW_REG_F19,
UNW_REG_F20, UNW_REG_F21, UNW_REG_F22, UNW_REG_F23,
UNW_REG_F24, UNW_REG_F25, UNW_REG_F26, UNW_REG_F27,
UNW_REG_F28, UNW_REG_F29, UNW_REG_F30, UNW_REG_F31,
UNW_NUM_REGS
};
struct unw_info_block {
u64 header;
u64 desc[0]; /* unwind descriptors */
/* personality routine and language-specific data follow behind descriptors */
};
struct unw_table {
struct unw_table *next; /* must be first member! */
const char *name;
unsigned long gp; /* global pointer for this load-module */
unsigned long segment_base; /* base for offsets in the unwind table entries */
unsigned long start;
unsigned long end;
const struct unw_table_entry *array;
unsigned long length;
};
enum unw_where {
UNW_WHERE_NONE, /* register isn't saved at all */
UNW_WHERE_GR, /* register is saved in a general register */
UNW_WHERE_FR, /* register is saved in a floating-point register */
UNW_WHERE_BR, /* register is saved in a branch register */
UNW_WHERE_SPREL, /* register is saved on memstack (sp-relative) */
UNW_WHERE_PSPREL, /* register is saved on memstack (psp-relative) */
/*
* At the end of each prologue these locations get resolved to
* UNW_WHERE_PSPREL and UNW_WHERE_GR, respectively:
*/
UNW_WHERE_SPILL_HOME, /* register is saved in its spill home */
UNW_WHERE_GR_SAVE /* register is saved in next general register */
};
#define UNW_WHEN_NEVER 0x7fffffff
struct unw_reg_info {
unsigned long val; /* save location: register number or offset */
enum unw_where where; /* where the register gets saved */
int when; /* when the register gets saved */
};
struct unw_reg_state {
struct unw_reg_state *next; /* next (outer) element on state stack */
struct unw_reg_info reg[UNW_NUM_REGS]; /* register save locations */
};
struct unw_labeled_state {
struct unw_labeled_state *next; /* next labeled state (or NULL) */
unsigned long label; /* label for this state */
struct unw_reg_state saved_state;
};
struct unw_state_record {
unsigned int first_region : 1; /* is this the first region? */
unsigned int done : 1; /* are we done scanning descriptors? */
unsigned int any_spills : 1; /* got any register spills? */
unsigned int in_body : 1; /* are we inside a body (as opposed to a prologue)? */
unsigned long flags; /* see UNW_FLAG_* in unwind.h */
u8 *imask; /* imask of spill_mask record or NULL */
unsigned long pr_val; /* predicate values */
unsigned long pr_mask; /* predicate mask */
long spill_offset; /* psp-relative offset for spill base */
int region_start;
int region_len;
int epilogue_start;
int epilogue_count;
int when_target;
u8 gr_save_loc; /* next general register to use for saving a register */
u8 return_link_reg; /* branch register in which the return link is passed */
struct unw_labeled_state *labeled_states; /* list of all labeled states */
struct unw_reg_state curr; /* current state */
};
enum unw_nat_type {
UNW_NAT_NONE, /* NaT not represented */
UNW_NAT_VAL, /* NaT represented by NaT value (fp reg) */
UNW_NAT_MEMSTK, /* NaT value is in unat word at offset OFF */
UNW_NAT_REGSTK /* NaT is in rnat */
};
enum unw_insn_opcode {
UNW_INSN_ADD, /* s[dst] += val */
UNW_INSN_ADD_PSP, /* s[dst] = (s.psp + val) */
UNW_INSN_ADD_SP, /* s[dst] = (s.sp + val) */
UNW_INSN_MOVE, /* s[dst] = s[val] */
UNW_INSN_MOVE2, /* s[dst] = s[val]; s[dst+1] = s[val+1] */
UNW_INSN_MOVE_STACKED, /* s[dst] = ia64_rse_skip(*s.bsp, val) */
UNW_INSN_SETNAT_MEMSTK, /* s[dst+1].nat.type = MEMSTK;
s[dst+1].nat.off = *s.pri_unat - s[dst] */
UNW_INSN_SETNAT_TYPE, /* s[dst+1].nat.type = val */
UNW_INSN_LOAD, /* s[dst] = *s[val] */
UNW_INSN_MOVE_SCRATCH, /* s[dst] = scratch reg "val" */
UNW_INSN_MOVE_CONST, /* s[dst] = constant reg "val" */
};
struct unw_insn {
unsigned int opc : 4;
unsigned int dst : 9;
signed int val : 19;
};
/*
* Preserved general static registers (r4-r7) give rise to two script
* instructions; everything else yields at most one instruction; at
* the end of the script, the psp gets popped, accounting for one more
* instruction.
*/
#define UNW_MAX_SCRIPT_LEN (UNW_NUM_REGS + 5)
struct unw_script {
unsigned long ip; /* ip this script is for */
unsigned long pr_mask; /* mask of predicates script depends on */
unsigned long pr_val; /* predicate values this script is for */
rwlock_t lock;
unsigned int flags; /* see UNW_FLAG_* in unwind.h */
unsigned short lru_chain; /* used for least-recently-used chain */
unsigned short coll_chain; /* used for hash collisions */
unsigned short hint; /* hint for next script to try (or -1) */
unsigned short count; /* number of instructions in script */
struct unw_insn insn[UNW_MAX_SCRIPT_LEN];
};
+1 -1
View File
@@ -29,7 +29,7 @@
#include <asm/vmx_vcpu.h>
#include <asm/privop.h>
#include <asm/types.h>
#include <public/io/ioreq.h>
#include <public/hvm/ioreq.h>
#include <asm/mm.h>
#include <asm/vmx.h>
+2 -2
View File
@@ -218,7 +218,7 @@ void vtm_interruption_update(VCPU *vcpu, vtime_t* vtm)
*/
void vtm_domain_out(VCPU *vcpu)
{
if(!is_idle_task(vcpu->domain))
if(!is_idle_domain(vcpu->domain))
rem_ac_timer(&vcpu->arch.arch_vmx.vtm.vtm_timer);
}
@@ -230,7 +230,7 @@ void vtm_domain_in(VCPU *vcpu)
{
vtime_t *vtm;
if(!is_idle_task(vcpu->domain)) {
if(!is_idle_domain(vcpu->domain)) {
vtm=&(vcpu->arch.arch_vmx.vtm);
vtm_interruption_update(vcpu, vtm);
}
+1 -1
View File
@@ -42,7 +42,7 @@
#include <xen/lib.h>
#include <asm/vmmu.h>
#include <public/arch-ia64.h>
#include <public/io/ioreq.h>
#include <public/hvm/ioreq.h>
#include <asm/vmx_phy_mode.h>
#include <asm/processor.h>
#include <asm/vmx.h>
+6 -2
View File
@@ -53,6 +53,7 @@
#define INITIAL_PSR_VALUE_AT_INTERRUPTION 0x0000001808028034
extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
extern void rnat_consumption (VCPU *vcpu);
#define DOMN_PAL_REQUEST 0x110000
@@ -185,8 +186,11 @@ vmx_ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long is
}else if(iim == DOMN_PAL_REQUEST){
pal_emul(current);
vmx_vcpu_increment_iip(current);
} else
} else {
if (iim == 0)
die_if_kernel("bug check", regs, iim);
vmx_reflect_interruption(ifa,isr,iim,11,regs);
}
}
@@ -227,7 +231,7 @@ void leave_hypervisor_tail(struct pt_regs *regs)
struct domain *d = current->domain;
struct vcpu *v = current;
// FIXME: Will this work properly if doing an RFI???
if (!is_idle_task(d) ) { // always comes from guest
if (!is_idle_domain(d) ) { // always comes from guest
extern void vmx_dorfirfi(void);
struct pt_regs *user_regs = vcpu_regs(current);
if (local_softirq_pending())
+1 -1
View File
@@ -21,7 +21,7 @@
*/
#include <xen/config.h>
#include <xen/sched.h>
#include <public/io/ioreq.h>
#include <public/hvm/ioreq.h>
#include <asm/vmx.h>
#include <asm/vmx_vcpu.h>
+11 -7
View File
@@ -861,12 +861,16 @@ dom_fw_init (struct domain *d, char *args, int arglen, char *fw_mem, int fw_mem_
bp->console_info.orig_x = 0;
bp->console_info.orig_y = 24;
bp->fpswa = 0;
bp->initrd_start = (dom0_start+dom0_size) -
(PAGE_ALIGN(ia64_boot_param->initrd_size) + 4*1024*1024);
bp->initrd_size = ia64_boot_param->initrd_size;
printf(" initrd start %0xlx", bp->initrd_start);
printf(" initrd size %0xlx", bp->initrd_size);
if (d == dom0) {
bp->initrd_start = (dom0_start+dom0_size) -
(PAGE_ALIGN(ia64_boot_param->initrd_size) + 4*1024*1024);
bp->initrd_size = ia64_boot_param->initrd_size;
}
else {
bp->initrd_start = d->arch.initrd_start;
bp->initrd_size = d->arch.initrd_len;
}
printf(" initrd start %0xlx", bp->initrd_start);
printf(" initrd size %0xlx", bp->initrd_size);
return bp;
}
+16 -55
View File
@@ -19,6 +19,7 @@
#include <xen/delay.h>
#include <xen/softirq.h>
#include <xen/mm.h>
#include <xen/iocap.h>
#include <asm/ptrace.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -45,7 +46,7 @@
#include <asm/vmx_vcpu.h>
#include <asm/vmx_vpd.h>
#include <asm/pal.h>
#include <public/io/ioreq.h>
#include <public/hvm/ioreq.h>
#define CONFIG_DOMAIN0_CONTIGUOUS
unsigned long dom0_start = -1L;
@@ -181,7 +182,7 @@ static void init_switch_stack(struct vcpu *v)
memset(v->arch._thread.fph,0,sizeof(struct ia64_fpreg)*96);
}
void arch_do_createdomain(struct vcpu *v)
int arch_do_createdomain(struct vcpu *v)
{
struct domain *d = v->domain;
struct thread_info *ti = alloc_thread_info(v);
@@ -248,7 +249,9 @@ void arch_do_createdomain(struct vcpu *v)
}
} else
d->arch.mm = NULL;
printf ("arch_do_create_domain: domain=%p\n", d);
printf ("arch_do_create_domain: domain=%p\n", d);
return 0;
}
void arch_getdomaininfo_ctxt(struct vcpu *v, struct vcpu_guest_context *c)
@@ -291,16 +294,7 @@ int arch_set_info_guest(struct vcpu *v, struct vcpu_guest_context *c)
d->arch.cmdline = c->cmdline;
new_thread(v, regs->cr_iip, 0, 0);
#ifdef CONFIG_IA64_SPLIT_CACHE
/* Sync d/i cache conservatively */
if (!running_on_sim) {
ret = ia64_pal_cache_flush(4, 0, &progress, NULL);
if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED))
printk("PAL CACHE FLUSH failed for dom0.\n");
else
printk("Sync i/d cache for guest SUCC\n");
}
#endif
sync_split_caches();
v->vcpu_info->arch.evtchn_vector = c->vcpu.evtchn_vector;
if ( c->vcpu.privregs && copy_from_user(v->arch.privregs,
c->vcpu.privregs, sizeof(mapped_regs_t))) {
@@ -428,7 +422,7 @@ extern unsigned long vhpt_paddr, vhpt_pend;
{
p = alloc_domheap_page(d);
// zero out pages for security reasons
memset(__va(page_to_phys(p)),0,PAGE_SIZE);
if (p) memset(__va(page_to_phys(p)),0,PAGE_SIZE);
}
if (unlikely(!p)) {
printf("map_new_domain_page: Can't alloc!!!! Aaaargh!\n");
@@ -763,7 +757,10 @@ void alloc_dom0(void)
*/
void physdev_init_dom0(struct domain *d)
{
set_bit(_DOMF_physdev_access, &d->domain_flags);
if (iomem_permit_access(d, 0UL, ~0UL))
BUG();
if (irqs_permit_access(d, 0, NR_PIRQS-1))
BUG();
}
unsigned int vmx_dom0 = 0;
@@ -912,9 +909,9 @@ int construct_dom0(struct domain *d,
memset(si, 0, PAGE_SIZE);
d->shared_info->arch.start_info_pfn = __pa(si) >> PAGE_SHIFT;
sprintf(si->magic, "xen-%i.%i-ia64", XEN_VERSION, XEN_SUBVERSION);
si->nr_pages = d->tot_pages;
#if 0
si->nr_pages = d->tot_pages;
si->shared_info = virt_to_phys(d->shared_info);
si->flags = SIF_PRIVILEGED | SIF_INITDOMAIN;
//si->pt_base = vpt_start;
@@ -959,16 +956,7 @@ int construct_dom0(struct domain *d,
new_thread(v, pkern_entry, 0, 0);
physdev_init_dom0(d);
#ifdef CONFIG_IA64_SPLIT_CACHE
/* Sync d/i cache conservatively */
if (!running_on_sim) {
ret = ia64_pal_cache_flush(4, 0, &progress, NULL);
if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED))
printk("PAL CACHE FLUSH failed for dom0.\n");
else
printk("Sync i/d cache for guest SUCC\n");
}
#endif
sync_split_caches();
// FIXME: Hack for keyboard input
#ifdef CLONE_DOMAIN0
@@ -1027,16 +1015,7 @@ int construct_domU(struct domain *d,
#endif
new_thread(v, pkern_entry, 0, 0);
printk("new_thread returns\n");
#ifdef CONFIG_IA64_SPLIT_CACHE
/* Sync d/i cache conservatively */
if (!running_on_sim) {
ret = ia64_pal_cache_flush(4, 0, &progress, NULL);
if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED))
printk("PAL CACHE FLUSH failed for dom0.\n");
else
printk("Sync i/d cache for guest SUCC\n");
}
#endif
sync_split_caches();
__set_bit(0x30, VCPU(v, delivery_mask));
return 0;
@@ -1050,16 +1029,7 @@ void reconstruct_domU(struct vcpu *v)
v->domain->domain_id);
loaddomainelfimage(v->domain,v->domain->arch.image_start);
new_thread(v, v->domain->arch.entry, 0, 0);
#ifdef CONFIG_IA64_SPLIT_CACHE
/* Sync d/i cache conservatively */
if (!running_on_sim) {
ret = ia64_pal_cache_flush(4, 0, &progress, NULL);
if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED))
printk("PAL CACHE FLUSH failed for dom0.\n");
else
printk("Sync i/d cache for guest SUCC\n");
}
#endif
sync_split_caches();
}
#endif
@@ -1100,15 +1070,6 @@ void domain_pend_keyboard_interrupt(int irq)
vcpu_pend_interrupt(dom0->vcpu[0],irq);
}
void vcpu_migrate_cpu(struct vcpu *v, int newcpu)
{
if ( v->processor == newcpu )
return;
set_bit(_VCPUF_cpu_migrated, &v->vcpu_flags);
v->processor = newcpu;
}
void sync_vcpu_execstate(struct vcpu *v)
{
ia64_save_fpu(v->arch._thread.fph);
+7
View File
@@ -543,6 +543,13 @@ GLOBAL_ENTRY(fast_break_reflect)
extr.u r21=r30,IA64_PSR_PP_BIT,1 ;;
cmp.ne p7,p0=r21,r0 ;;
(p7) br.spnt.few dispatch_break_fault ;;
movl r20=IA64_PSR_CPL ;;
and r22=r20,r30 ;;
cmp.ne p7,p0=r22,r0
(p7) br.spnt.many 1f ;;
cmp.eq p7,p0=r17,r0
(p7) br.spnt.few dispatch_break_fault ;;
1:
#if 1 /* special handling in case running on simulator */
movl r20=first_break;;
ld4 r23=[r20];;
-3
View File
@@ -1378,9 +1378,6 @@ int pirq_guest_bind(struct vcpu *d, int irq, int will_share)
unsigned long flags;
int rc = 0;
if ( !IS_CAPABLE_PHYSDEV(d->domain) )
return -EPERM;
spin_lock_irqsave(&desc->lock, flags);
action = (irq_guest_action_t *)desc->action;
+2
View File
@@ -839,6 +839,8 @@ ENTRY(break_fault)
mov r17=cr.iim
mov r31=pr
;;
cmp.eq p7,p0=r17,r0
(p7) br.spnt.few dispatch_break_fault ;;
movl r18=XSI_PSR_IC
;;
ld8 r19=[r18]
+12 -19
View File
@@ -33,6 +33,7 @@
#include <xen/multicall.h>
extern unsigned long vcpu_get_itir_on_fault(struct vcpu *, UINT64);
extern void die_if_kernel(char *str, struct pt_regs *regs, long err);
extern unsigned long dom0_start, dom0_size;
@@ -64,26 +65,16 @@ long do_iopl(domid_t domain, unsigned int new_io_pl)
extern struct schedule_data schedule_data[NR_CPUS];
void schedule_tail(struct vcpu *next)
void schedule_tail(struct vcpu *prev)
{
unsigned long rr7;
//printk("current=%lx,shared_info=%lx\n",current,current->vcpu_info);
//printk("next=%lx,shared_info=%lx\n",next,next->vcpu_info);
context_saved(prev);
// TG: Real HACK FIXME.
// This is currently necessary because when a new domain is started,
// the context_switch function of xen/common/schedule.c(__enter_scheduler)
// never returns. Therefore, the lock must be released.
// schedule_tail is only called when a domain is started.
spin_unlock_irq(&schedule_data[current->processor].schedule_lock);
/* rr7 will be postponed to last point when resuming back to guest */
if(VMX_DOMAIN(current)){
vmx_load_all_rr(current);
}else{
load_region_regs(current);
vcpu_load_kernel_regs(current);
}
if (VMX_DOMAIN(current)) {
vmx_load_all_rr(current);
} else {
load_region_regs(current);
vcpu_load_kernel_regs(current);
}
}
void tdpfoo(void) { }
@@ -251,7 +242,7 @@ void deliver_pending_interrupt(struct pt_regs *regs)
struct domain *d = current->domain;
struct vcpu *v = current;
// FIXME: Will this work properly if doing an RFI???
if (!is_idle_task(d) && user_mode(regs)) {
if (!is_idle_domain(d) && user_mode(regs)) {
//vcpu_poke_timer(v);
if (vcpu_deliverable_interrupts(v))
reflect_extint(regs);
@@ -686,6 +677,8 @@ ia64_handle_break (unsigned long ifa, struct pt_regs *regs, unsigned long isr, u
vcpu_increment_iip(current);
}
else {
if (iim == 0)
die_if_kernel("bug check", regs, iim);
PSCB(v,iim) = iim;
reflect_interruption(isr,regs,IA64_BREAK_VECTOR);
}
+1 -1
View File
@@ -1085,7 +1085,7 @@ void vcpu_set_next_timer(VCPU *vcpu)
/* gloss over the wraparound problem for now... we know it exists
* but it doesn't matter right now */
if (is_idle_task(vcpu->domain)) {
if (is_idle_domain(vcpu->domain)) {
// printf("****** vcpu_set_next_timer called during idle!!\n");
vcpu_safe_set_itm(s);
return;
+29 -12
View File
@@ -25,7 +25,6 @@ unsigned long wait_init_idle;
int phys_proc_id[NR_CPUS];
unsigned long loops_per_jiffy = (1<<12); // from linux/init/main.c
void unw_init(void) { printf("unw_init() skipped (NEED FOR KERNEL UNWIND)\n"); }
void ia64_mca_init(void) { printf("ia64_mca_init() skipped (Machine check abort handling)\n"); }
void ia64_mca_cpu_init(void *x) { }
void ia64_patch_mckinley_e9(unsigned long a, unsigned long b) { }
@@ -180,11 +179,6 @@ void pgtable_quicklist_free(void *pgtable_entry)
// from arch/ia64/traps.c
///////////////////////////////
void show_registers(struct pt_regs *regs)
{
printf("*** ADD REGISTER DUMP HERE FOR DEBUGGING\n");
}
int is_kernel_text(unsigned long addr)
{
extern char _stext[], _etext[];
@@ -236,7 +230,13 @@ void sys_exit(void)
void die_if_kernel(char *str, struct pt_regs *regs, long err) /* __attribute__ ((noreturn)) */
{
printk("die_if_kernel: called, not implemented\n");
if (user_mode(regs))
return;
printk("%s: %s %ld\n", __func__, str, err);
debugtrace_dump();
show_registers(regs);
domain_crash_synchronous();
}
long
@@ -320,18 +320,15 @@ if (!i--) { printk("+",id); i = 1000000; }
ia64_set_iva(&ia64_ivt);
ia64_set_pta(VHPT_ADDR | (1 << 8) | (VHPT_SIZE_LOG2 << 2) |
VHPT_ENABLED);
if (!is_idle_task(current->domain)) {
if (!is_idle_domain(current->domain)) {
load_region_regs(current);
vcpu_load_kernel_regs(current);
if (vcpu_timer_expired(current)) vcpu_pend_timer(current);
}
if (vcpu_timer_expired(current)) vcpu_pend_timer(current);
}
}
void context_switch_finalise(struct vcpu *next)
{
/* nothing to do */
context_saved(prev);
}
void continue_running(struct vcpu *same)
@@ -368,3 +365,23 @@ loop:
goto loop;
}
}
/* FIXME: for the forseeable future, all cpu's that enable VTi have split
* caches and all cpu's that have split caches enable VTi. This may
* eventually be untrue though. */
#define cpu_has_split_cache vmx_enabled
extern unsigned int vmx_enabled;
void sync_split_caches(void)
{
unsigned long ret, progress = 0;
if (cpu_has_split_cache) {
/* Sync d/i cache conservatively */
ret = ia64_pal_cache_flush(4, 0, &progress, NULL);
if ((ret!=PAL_STATUS_SUCCESS)&& (ret!=PAL_STATUS_UNIMPLEMENTED))
printk("PAL CACHE FLUSH failed\n");
else printk("Sync i/d cache for guest SUCC\n");
}
else printk("sync_split_caches ignored for CPU with no split cache\n");
}
+2 -3
View File
@@ -26,7 +26,7 @@ unsigned long xenheap_phys_end;
char saved_command_line[COMMAND_LINE_SIZE];
struct vcpu *idle_task[NR_CPUS] = { &idle0_vcpu };
struct vcpu *idle_domain[NR_CPUS] = { &idle0_vcpu };
cpumask_t cpu_present_map;
@@ -382,8 +382,7 @@ printk("About to call do_createdomain()\n");
panic("Could not set up DOM0 guest OS\n");
/* PIN domain0 on CPU 0. */
dom0->vcpu[0]->cpumap=1;
set_bit(_VCPUF_cpu_pinned, &dom0->vcpu[0]->vcpu_flags);
dom0->vcpu[0]->cpu_affinity = cpumask_of_cpu(0);
#ifdef CLONE_DOMAIN0
{
+1 -1
View File
@@ -127,7 +127,7 @@ xen_timer_interrupt (int irq, void *dev_id, struct pt_regs *regs)
vcpu_wake(dom0->vcpu[0]);
}
}
if (!is_idle_task(current->domain)) {
if (!is_idle_domain(current->domain)) {
if (vcpu_timer_expired(current)) {
vcpu_pend_timer(current);
// ensure another timer interrupt happens even if domain doesn't
+9 -4
View File
@@ -29,6 +29,7 @@ ifeq ($(TARGET_SUBARCH),x86_32)
endif
OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS))
OBJS := $(subst $(TARGET_SUBARCH)/xen.lds.o,,$(OBJS))
ifneq ($(crash_debug),y)
OBJS := $(patsubst cdb%.o,,$(OBJS))
@@ -43,22 +44,25 @@ $(TARGET): $(TARGET)-syms boot/mkelf32
$(CURDIR)/arch.o: $(OBJS)
$(LD) $(LDFLAGS) -r -o $@ $(OBJS)
$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(TARGET_SUBARCH)/xen.lds
$(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
$(TARGET)-syms: boot/$(TARGET_SUBARCH).o $(ALL_OBJS) xen.lds
$(LD) $(LDFLAGS) -T xen.lds -N \
boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $@
$(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
$(MAKE) $(BASEDIR)/xen-syms.o
$(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
$(LD) $(LDFLAGS) -T xen.lds -N \
boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
$(NM) -n $@ | $(BASEDIR)/tools/symbols >$(BASEDIR)/xen-syms.S
$(MAKE) $(BASEDIR)/xen-syms.o
$(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
$(LD) $(LDFLAGS) -T xen.lds -N \
boot/$(TARGET_SUBARCH).o $(ALL_OBJS) $(BASEDIR)/xen-syms.o -o $@
rm -f $(BASEDIR)/xen-syms.S $(BASEDIR)/xen-syms.o
asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c $(HDRS)
$(CC) $(CFLAGS) -S -o $@ $<
xen.lds: $(TARGET_SUBARCH)/xen.lds.S $(HDRS)
$(CC) $(CFLAGS) -P -E -Ui386 -D__ASSEMBLY__ -o $@ $<
boot/mkelf32: boot/mkelf32.c
$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
@@ -73,5 +77,6 @@ clean:
rm -f dm/*.o dm/*~ dm/core
rm -f genapic/*.o genapic/*~ genapic/core
rm -f cpu/*.o cpu/*~ cpu/core
rm -f xen.lds
.PHONY: default clean
+6 -8
View File
@@ -1,5 +1,6 @@
#include <xen/config.h>
#include <public/xen.h>
#include <asm/asm_defns.h>
#include <asm/desc.h>
#include <asm/page.h>
#include <asm/msr.h>
@@ -53,6 +54,7 @@ __start:
mov %ecx,%gs
ljmp $(__HYPERVISOR_CS),$(1f)-__PAGE_OFFSET
1: lss stack_start-__PAGE_OFFSET,%esp
add $(STACK_SIZE-CPUINFO_sizeof-__PAGE_OFFSET),%esp
/* Reset EFLAGS (subsumes CLI and CLD). */
pushl $0
@@ -98,7 +100,7 @@ __start:
1: stosl /* low mappings cover as much physmem as possible */
add $4,%edi
add $(1<<L2_PAGETABLE_SHIFT),%eax
cmp $__HYPERVISOR_VIRT_START+0xe3,%eax
cmp $HYPERVISOR_VIRT_START+0xe3,%eax
jne 1b
#else
/* Initialize low and high mappings of all memory with 4MB pages */
@@ -111,7 +113,7 @@ __start:
jne 1b
1: stosl /* low mappings cover as much physmem as possible */
add $(1<<L2_PAGETABLE_SHIFT),%eax
cmp $__HYPERVISOR_VIRT_START+0xe3,%eax
cmp $HYPERVISOR_VIRT_START+0xe3,%eax
jne 1b
#endif
@@ -189,7 +191,7 @@ ignore_int:
/*** STACK LOCATION ***/
ENTRY(stack_start)
.long cpu0_stack + STACK_SIZE - 200 - __PAGE_OFFSET
.long cpu0_stack
.long __HYPERVISOR_DS
/*** DESCRIPTOR TABLES ***/
@@ -256,10 +258,6 @@ ENTRY(idle_pg_table_l2)
.fill 1*PAGE_SIZE,1,0
#endif
#if (STACK_ORDER == 0)
.section ".bss.page_aligned","w"
#else
.section ".bss.twopage_aligned","w"
#endif
.section ".bss.stack_aligned","w"
ENTRY(cpu0_stack)
.fill STACK_SIZE,1,0
+6 -8
View File
@@ -1,5 +1,6 @@
#include <xen/config.h>
#include <public/xen.h>
#include <asm/asm_defns.h>
#include <asm/desc.h>
#include <asm/page.h>
#include <asm/msr.h>
@@ -121,7 +122,8 @@ skip_boot_checks:
mov %rcx,%cr4
mov stack_start(%rip),%rsp
or $(STACK_SIZE-CPUINFO_sizeof),%rsp
/* Reset EFLAGS (subsumes CLI and CLD). */
pushq $0
popf
@@ -140,7 +142,7 @@ __high_start:
mov %ecx,%ss
lidt idt_descr(%rip)
cmp $(SECONDARY_CPU_FLAG),%ebx
je start_secondary
@@ -219,7 +221,7 @@ idt:
.quad idt_table
ENTRY(stack_start)
.quad cpu0_stack + STACK_SIZE - 200
.quad cpu0_stack
high_start:
.quad __high_start
@@ -265,10 +267,6 @@ ENTRY(idle_pg_table_l2)
.org 0x4000 + PAGE_SIZE
.code64
#if (STACK_ORDER == 0)
.section ".bss.page_aligned","w"
#else
.section ".bss.twopage_aligned","w"
#endif
.section ".bss.stack_aligned","w"
ENTRY(cpu0_stack)
.fill STACK_SIZE,1,0
+1 -1
View File
@@ -29,7 +29,7 @@
#include <xen/lib.h>
#include <xen/errno.h>
#include <xen/sched.h>
#include <public/io/ioreq.h>
#include <public/hvm/ioreq.h>
#include <asm/vmx.h>
#include <asm/vmx_vpic.h>
#include <asm/current.h>
+1 -1
View File
@@ -37,7 +37,7 @@
#include <xen/lib.h>
#include <xen/errno.h>
#include <xen/sched.h>
#include <public/io/ioreq.h>
#include <public/hvm/ioreq.h>
#include <asm/vmx.h>
#include <asm/vmx_vpic.h>
#include <asm/current.h>
+26 -25
View File
@@ -17,6 +17,7 @@
#include <asm/msr.h>
#include <xen/trace.h>
#include <xen/console.h>
#include <xen/iocap.h>
#include <asm/shadow.h>
#include <asm/irq.h>
#include <asm/processor.h>
@@ -35,13 +36,13 @@ static unsigned long msr_hi;
static void write_msr_for(void *unused)
{
if ( ((1 << current->processor) & msr_cpu_mask) )
if ( ((1 << smp_processor_id()) & msr_cpu_mask) )
(void)wrmsr_user(msr_addr, msr_lo, msr_hi);
}
static void read_msr_for(void *unused)
{
if ( ((1 << current->processor) & msr_cpu_mask) )
if ( ((1 << smp_processor_id()) & msr_cpu_mask) )
(void)rdmsr_user(msr_addr, msr_lo, msr_hi);
}
@@ -102,12 +103,27 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
op->u.add_memtype.nr_pfns,
op->u.add_memtype.type,
1);
if (ret > 0)
{
(void)__put_user(0, &u_dom0_op->u.add_memtype.handle);
(void)__put_user(ret, &u_dom0_op->u.add_memtype.reg);
ret = 0;
}
}
break;
case DOM0_DEL_MEMTYPE:
{
ret = mtrr_del_page(op->u.del_memtype.reg, 0, 0);
if (op->u.del_memtype.handle == 0
/* mtrr/main.c otherwise does a lookup */
&& (int)op->u.del_memtype.reg >= 0)
{
ret = mtrr_del_page(op->u.del_memtype.reg, 0, 0);
if (ret > 0)
ret = 0;
}
else
ret = -EINVAL;
}
break;
@@ -141,7 +157,6 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
struct domain *d;
unsigned int fp = op->u.ioport_permission.first_port;
unsigned int np = op->u.ioport_permission.nr_ports;
unsigned int p;
ret = -EINVAL;
if ( (fp + np) > 65536 )
@@ -152,26 +167,12 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
op->u.ioport_permission.domain)) == NULL) )
break;
ret = -ENOMEM;
if ( d->arch.iobmp_mask != NULL )
{
if ( (d->arch.iobmp_mask = xmalloc_array(
u8, IOBMP_BYTES)) == NULL )
{
put_domain(d);
break;
}
memset(d->arch.iobmp_mask, 0xFF, IOBMP_BYTES);
}
ret = 0;
for ( p = fp; p < (fp + np); p++ )
{
if ( op->u.ioport_permission.allow_access )
clear_bit(p, d->arch.iobmp_mask);
else
set_bit(p, d->arch.iobmp_mask);
}
if ( np == 0 )
ret = 0;
else if ( op->u.ioport_permission.allow_access )
ret = ioports_permit_access(d, fp, fp + np - 1);
else
ret = ioports_deny_access(d, fp, fp + np - 1);
put_domain(d);
}
@@ -193,7 +194,7 @@ long arch_do_dom0_op(dom0_op_t *op, dom0_op_t *u_dom0_op)
memcpy(pi->hw_cap, boot_cpu_data.x86_capability, NCAPINTS*4);
ret = 0;
if ( copy_to_user(u_dom0_op, op, sizeof(*op)) )
ret = -EFAULT;
ret = -EFAULT;
}
break;
+65 -77
View File
@@ -20,6 +20,7 @@
#include <xen/delay.h>
#include <xen/softirq.h>
#include <xen/grant_table.h>
#include <xen/iocap.h>
#include <asm/regs.h>
#include <asm/mc146818rtc.h>
#include <asm/system.h>
@@ -35,9 +36,7 @@
#include <xen/console.h>
#include <xen/elf.h>
#include <asm/vmx.h>
#include <asm/vmx_vmcs.h>
#include <asm/msr.h>
#include <asm/physdev.h>
#include <xen/kernel.h>
#include <xen/multicall.h>
@@ -47,17 +46,16 @@ boolean_param("noreboot", opt_noreboot);
struct percpu_ctxt {
struct vcpu *curr_vcpu;
unsigned int context_not_finalised;
unsigned int dirty_segment_mask;
} __cacheline_aligned;
static struct percpu_ctxt percpu_ctxt[NR_CPUS];
static void continue_idle_task(struct vcpu *v)
static void continue_idle_domain(struct vcpu *v)
{
reset_stack_and_jump(idle_loop);
}
static void continue_nonidle_task(struct vcpu *v)
static void continue_nonidle_domain(struct vcpu *v)
{
reset_stack_and_jump(ret_from_intr);
}
@@ -93,12 +91,13 @@ void startup_cpu_idle_loop(void)
{
struct vcpu *v = current;
ASSERT(is_idle_task(v->domain));
ASSERT(is_idle_domain(v->domain));
percpu_ctxt[smp_processor_id()].curr_vcpu = v;
cpu_set(smp_processor_id(), v->domain->cpumask);
v->arch.schedule_tail = continue_idle_task;
cpu_set(smp_processor_id(), v->domain->domain_dirty_cpumask);
cpu_set(smp_processor_id(), v->vcpu_dirty_cpumask);
v->arch.schedule_tail = continue_idle_domain;
idle_loop();
reset_stack_and_jump(idle_loop);
}
static long no_idt[2];
@@ -185,11 +184,17 @@ void dump_pageframe_info(struct domain *d)
{
struct pfn_info *page;
if ( d->tot_pages < 10 )
printk("Memory pages belonging to domain %u:\n", d->domain_id);
if ( d->tot_pages >= 10 )
{
printk(" DomPage list too long to display\n");
}
else
{
list_for_each_entry ( page, &d->page_list, list )
{
printk("Page %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
printk(" DomPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
_p(page_to_phys(page)), _p(page_to_pfn(page)),
page->count_info, page->u.inuse.type_info);
}
@@ -197,15 +202,10 @@ void dump_pageframe_info(struct domain *d)
list_for_each_entry ( page, &d->xenpage_list, list )
{
printk("XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
printk(" XenPage %p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
_p(page_to_phys(page)), _p(page_to_pfn(page)),
page->count_info, page->u.inuse.type_info);
}
page = virt_to_page(d->shared_info);
printk("Shared_info@%p: mfn=%p, caf=%08x, taf=%" PRtype_info "\n",
_p(page_to_phys(page)), _p(page_to_pfn(page)), page->count_info,
page->u.inuse.type_info);
}
struct vcpu *alloc_vcpu_struct(struct domain *d, unsigned int vcpu_id)
@@ -250,24 +250,36 @@ void free_perdomain_pt(struct domain *d)
#endif
}
void arch_do_createdomain(struct vcpu *v)
int arch_do_createdomain(struct vcpu *v)
{
struct domain *d = v->domain;
l1_pgentry_t gdt_l1e;
int vcpuid, pdpt_order;
int vcpuid, pdpt_order, rc;
#ifdef __x86_64__
int i;
#endif
if ( is_idle_task(d) )
return;
if ( is_idle_domain(d) )
return 0;
v->arch.schedule_tail = continue_nonidle_task;
d->arch.ioport_caps =
rangeset_new(d, "I/O Ports", RANGESETF_prettyprint_hex);
if ( d->arch.ioport_caps == NULL )
return -ENOMEM;
if ( (d->shared_info = alloc_xenheap_page()) == NULL )
return -ENOMEM;
if ( (rc = ptwr_init(d)) != 0 )
{
free_xenheap_page(d->shared_info);
return rc;
}
v->arch.schedule_tail = continue_nonidle_domain;
d->shared_info = alloc_xenheap_page();
memset(d->shared_info, 0, PAGE_SIZE);
v->vcpu_info = &d->shared_info->vcpu_info[v->vcpu_id];
v->cpumap = CPUMAP_RUNANYWHERE;
SHARE_PFN_WITH_DOMAIN(virt_to_page(d->shared_info), d);
pdpt_order = get_order_from_bytes(PDPT_L1_ENTRIES * sizeof(l1_pgentry_t));
@@ -308,25 +320,10 @@ void arch_do_createdomain(struct vcpu *v)
__PAGE_HYPERVISOR);
#endif
(void)ptwr_init(d);
shadow_lock_init(d);
INIT_LIST_HEAD(&d->arch.free_shadow_frames);
}
void vcpu_migrate_cpu(struct vcpu *v, int newcpu)
{
if ( v->processor == newcpu )
return;
set_bit(_VCPUF_cpu_migrated, &v->vcpu_flags);
v->processor = newcpu;
if ( VMX_DOMAIN(v) )
{
__vmpclear(virt_to_phys(v->arch.arch_vmx.vmcs));
v->arch.schedule_tail = arch_vmx_do_relaunch;
}
return 0;
}
/* This is called by arch_final_setup_guest and do_boot_vcpu */
@@ -348,6 +345,8 @@ int arch_set_info_guest(
((c->user_regs.ss & 3) == 0) )
return -EINVAL;
}
else if ( !hvm_enabled )
return -EINVAL;
clear_bit(_VCPUF_fpu_initialised, &v->vcpu_flags);
if ( c->flags & VGCF_I387_VALID )
@@ -690,7 +689,7 @@ static void __context_switch(void)
struct vcpu *p = percpu_ctxt[cpu].curr_vcpu;
struct vcpu *n = current;
if ( !is_idle_task(p->domain) )
if ( !is_idle_domain(p->domain) )
{
memcpy(&p->arch.guest_context.user_regs,
stack_regs,
@@ -699,7 +698,7 @@ static void __context_switch(void)
save_segments(p);
}
if ( !is_idle_task(n->domain) )
if ( !is_idle_domain(n->domain) )
{
memcpy(stack_regs,
&n->arch.guest_context.user_regs,
@@ -725,7 +724,8 @@ static void __context_switch(void)
}
if ( p->domain != n->domain )
cpu_set(cpu, n->domain->cpumask);
cpu_set(cpu, n->domain->domain_dirty_cpumask);
cpu_set(cpu, n->vcpu_dirty_cpumask);
write_ptbase(n);
@@ -738,7 +738,8 @@ static void __context_switch(void)
}
if ( p->domain != n->domain )
cpu_clear(cpu, p->domain->cpumask);
cpu_clear(cpu, p->domain->domain_dirty_cpumask);
cpu_clear(cpu, p->vcpu_dirty_cpumask);
percpu_ctxt[cpu].curr_vcpu = n;
}
@@ -748,28 +749,24 @@ void context_switch(struct vcpu *prev, struct vcpu *next)
{
unsigned int cpu = smp_processor_id();
ASSERT(!local_irq_is_enabled());
ASSERT(local_irq_is_enabled());
set_current(next);
if ( (percpu_ctxt[cpu].curr_vcpu != next) && !is_idle_task(next->domain) )
if ( (percpu_ctxt[cpu].curr_vcpu != next) &&
!is_idle_domain(next->domain) )
{
/* This may happen if next has been migrated by the scheduler. */
if ( unlikely(!cpus_empty(next->vcpu_dirty_cpumask)) )
{
ASSERT(!cpu_isset(cpu, next->vcpu_dirty_cpumask));
sync_vcpu_execstate(next);
ASSERT(cpus_empty(next->vcpu_dirty_cpumask));
}
local_irq_disable();
__context_switch();
percpu_ctxt[cpu].context_not_finalised = 1;
}
}
void context_switch_finalise(struct vcpu *next)
{
unsigned int cpu = smp_processor_id();
ASSERT(local_irq_is_enabled());
if ( percpu_ctxt[cpu].context_not_finalised )
{
percpu_ctxt[cpu].context_not_finalised = 0;
BUG_ON(percpu_ctxt[cpu].curr_vcpu != next);
local_irq_enable();
if ( VMX_DOMAIN(next) )
{
@@ -783,6 +780,8 @@ void context_switch_finalise(struct vcpu *next)
}
}
context_saved(prev);
schedule_tail(next);
BUG();
}
@@ -812,20 +811,11 @@ int __sync_lazy_execstate(void)
void sync_vcpu_execstate(struct vcpu *v)
{
unsigned int cpu = v->processor;
if ( !cpu_isset(cpu, v->domain->cpumask) )
return;
if ( cpu == smp_processor_id() )
{
if ( cpu_isset(smp_processor_id(), v->vcpu_dirty_cpumask) )
(void)__sync_lazy_execstate();
}
else
{
/* Other cpus call __sync_lazy_execstate from flush ipi handler. */
flush_tlb_mask(cpumask_of_cpu(cpu));
}
/* Other cpus call __sync_lazy_execstate from flush ipi handler. */
flush_tlb_mask(v->vcpu_dirty_cpumask);
}
unsigned long __hypercall_create_continuation(
@@ -951,9 +941,7 @@ void domain_relinquish_resources(struct domain *d)
struct vcpu *v;
unsigned long pfn;
BUG_ON(!cpus_empty(d->cpumask));
physdev_destroy_state(d);
BUG_ON(!cpus_empty(d->domain_dirty_cpumask));
ptwr_destroy(d);
+19 -14
View File
@@ -16,13 +16,13 @@
#include <xen/kernel.h>
#include <xen/domain.h>
#include <xen/compile.h>
#include <xen/iocap.h>
#include <asm/regs.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/processor.h>
#include <asm/desc.h>
#include <asm/i387.h>
#include <asm/physdev.h>
#include <asm/shadow.h>
static long dom0_nrpages;
@@ -94,9 +94,9 @@ static struct pfn_info *alloc_chunk(struct domain *d, unsigned long max_pages)
return page;
}
static void process_dom0_ioports_disable()
static void process_dom0_ioports_disable(void)
{
unsigned long io_from, io_to, io_nr;
unsigned long io_from, io_to;
char *t, *u, *s = opt_dom0_ioports_disable;
if ( *s == '\0' )
@@ -126,8 +126,8 @@ static void process_dom0_ioports_disable()
printk("Disabling dom0 access to ioport range %04lx-%04lx\n",
io_from, io_to);
io_nr = io_to - io_from + 1;
physdev_modify_ioport_access_range(dom0, 0, io_from, io_nr);
if ( ioports_deny_access(dom0, io_from, io_to) != 0 )
BUG();
}
}
@@ -183,7 +183,6 @@ int construct_dom0(struct domain *d,
/* Machine address of next candidate page-table page. */
unsigned long mpt_alloc;
extern void physdev_init_dom0(struct domain *);
extern void translate_l2pgtable(
struct domain *d, l1_pgentry_t *p2m, unsigned long l2mfn);
@@ -692,9 +691,6 @@ int construct_dom0(struct domain *d,
zap_low_mappings(l2start);
zap_low_mappings(idle_pg_table_l2);
#endif
/* DOM0 gets access to everything. */
physdev_init_dom0(d);
init_domain_time(d);
@@ -746,20 +742,29 @@ int construct_dom0(struct domain *d,
printk("dom0: shadow setup done\n");
}
i = 0;
/* DOM0 is permitted full I/O capabilities. */
i |= ioports_permit_access(dom0, 0, 0xFFFF);
i |= iomem_permit_access(dom0, 0UL, ~0UL);
i |= irqs_permit_access(dom0, 0, NR_PIRQS-1);
/*
* Modify I/O port access permissions.
*/
/* Master Interrupt Controller (PIC). */
physdev_modify_ioport_access_range(dom0, 0, 0x20, 2);
i |= ioports_deny_access(dom0, 0x20, 0x21);
/* Slave Interrupt Controller (PIC). */
physdev_modify_ioport_access_range(dom0, 0, 0xA0, 2);
i |= ioports_deny_access(dom0, 0xA0, 0xA1);
/* Interval Timer (PIT). */
physdev_modify_ioport_access_range(dom0, 0, 0x40, 4);
i |= ioports_deny_access(dom0, 0x40, 0x43);
/* PIT Channel 2 / PC Speaker Control. */
physdev_modify_ioport_access_range(dom0, 0, 0x61, 1);
/* Command-line passed i/o ranges */
i |= ioports_deny_access(dom0, 0x61, 0x61);
/* Command-line I/O ranges. */
process_dom0_ioports_disable();
BUG_ON(i != 0);
return 0;
}
+1
View File
@@ -11,6 +11,7 @@ struct domain idle0_domain = {
struct vcpu idle0_vcpu = {
processor: 0,
cpu_affinity:CPU_MASK_CPU0,
domain: &idle0_domain
};
+44
View File
@@ -1807,3 +1807,47 @@ int ioapic_guest_write(int apicid, int address, u32 val)
return 0;
}
void dump_ioapic_irq_info(void)
{
struct irq_pin_list *entry;
struct IO_APIC_route_entry rte;
unsigned int irq, pin, printed = 0;
unsigned long flags;
for ( irq = 0; irq < NR_IRQS; irq++ )
{
entry = &irq_2_pin[irq];
if ( entry->pin == -1 )
continue;
if ( !printed++ )
printk("IO-APIC interrupt information:\n");
printk(" IRQ%3d Vec%3d:\n", irq, irq_to_vector(irq));
for ( ; ; )
{
pin = entry->pin;
printk(" Apic 0x%02x, Pin %2d: ", entry->apic, pin);
spin_lock_irqsave(&ioapic_lock, flags);
*(((int *)&rte) + 0) = io_apic_read(entry->apic, 0x10 + 2 * pin);
*(((int *)&rte) + 1) = io_apic_read(entry->apic, 0x11 + 2 * pin);
spin_unlock_irqrestore(&ioapic_lock, flags);
printk("vector=%u, delivery_mode=%u, dest_mode=%s, "
"delivery_status=%d, polarity=%d, irr=%d, "
"trigger=%s, mask=%d\n",
rte.vector, rte.delivery_mode,
rte.dest_mode ? "logical" : "physical",
rte.delivery_status, rte.polarity, rte.irr,
rte.trigger ? "level" : "edge", rte.mask);
if ( entry->next == 0 )
break;
entry = &irq_2_pin[entry->next];
}
}
}
+77 -6
View File
@@ -12,6 +12,7 @@
#include <xen/irq.h>
#include <xen/perfc.h>
#include <xen/sched.h>
#include <xen/keyhandler.h>
#include <asm/current.h>
#include <asm/smpboot.h>
@@ -198,19 +199,21 @@ int pirq_guest_unmask(struct domain *d)
int pirq_guest_bind(struct vcpu *v, int irq, int will_share)
{
unsigned int vector = irq_to_vector(irq);
struct domain *d = v->domain;
irq_desc_t *desc = &irq_desc[vector];
unsigned int vector;
irq_desc_t *desc;
irq_guest_action_t *action;
unsigned long flags;
int rc = 0;
cpumask_t cpumask = CPU_MASK_NONE;
if ( !IS_CAPABLE_PHYSDEV(d) )
return -EPERM;
if ( (irq < 0) || (irq >= NR_IRQS) )
return -EINVAL;
vector = irq_to_vector(irq);
if ( vector == 0 )
return -EBUSY;
return -EINVAL;
desc = &irq_desc[vector];
spin_lock_irqsave(&desc->lock, flags);
@@ -309,3 +312,71 @@ int pirq_guest_unbind(struct domain *d, int irq)
spin_unlock_irqrestore(&desc->lock, flags);
return 0;
}
extern void dump_ioapic_irq_info(void);
static void dump_irqs(unsigned char key)
{
int i, irq, vector;
irq_desc_t *desc;
irq_guest_action_t *action;
struct domain *d;
unsigned long flags;
printk("Guest interrupt information:\n");
for ( irq = 0; irq < NR_IRQS; irq++ )
{
vector = irq_to_vector(irq);
if ( vector == 0 )
continue;
desc = &irq_desc[vector];
spin_lock_irqsave(&desc->lock, flags);
if ( desc->status & IRQ_GUEST )
{
action = (irq_guest_action_t *)desc->action;
printk(" IRQ%3d Vec%3d: type=%-15s status=%08x "
"in-flight=%d domain-list=",
irq, vector, desc->handler->typename,
desc->status, action->in_flight);
for ( i = 0; i < action->nr_guests; i++ )
{
d = action->guest[i];
printk("%u(%c%c%c%c)",
d->domain_id,
(test_bit(d->pirq_to_evtchn[irq],
&d->shared_info->evtchn_pending[0]) ?
'P' : '-'),
(test_bit(d->pirq_to_evtchn[irq]/BITS_PER_LONG,
&d->shared_info->vcpu_info[0].
evtchn_pending_sel) ?
'S' : '-'),
(test_bit(d->pirq_to_evtchn[irq],
&d->shared_info->evtchn_mask[0]) ?
'M' : '-'),
(test_bit(irq, &d->pirq_mask) ?
'M' : '-'));
if ( i != action->nr_guests )
printk(",");
}
printk("\n");
}
spin_unlock_irqrestore(&desc->lock, flags);
}
dump_ioapic_irq_info();
}
static int __init setup_dump_irqs(void)
{
register_keyhandler('i', dump_irqs, "dump interrupt bindings");
return 0;
}
__initcall(setup_dump_irqs);
+16 -19
View File
@@ -96,6 +96,7 @@
#include <xen/softirq.h>
#include <xen/domain_page.h>
#include <xen/event.h>
#include <xen/iocap.h>
#include <asm/shadow.h>
#include <asm/page.h>
#include <asm/flushtlb.h>
@@ -437,7 +438,6 @@ get_page_from_l1e(
unsigned long mfn = l1e_get_pfn(l1e);
struct pfn_info *page = pfn_to_page(mfn);
int okay;
extern int domain_iomem_in_pfn(struct domain *d, unsigned long pfn);
if ( !(l1e_get_flags(l1e) & _PAGE_PRESENT) )
return 1;
@@ -455,8 +455,7 @@ get_page_from_l1e(
if ( d == dom_io )
d = current->domain;
if ( (!IS_PRIV(d)) &&
(!IS_CAPABLE_PHYSDEV(d) || !domain_iomem_in_pfn(d, mfn)) )
if ( !iomem_access_permitted(d, mfn, mfn) )
{
MEM_LOG("Non-privileged attempt to map I/O space %08lx", mfn);
return 0;
@@ -1458,7 +1457,8 @@ int get_page_type(struct pfn_info *page, unsigned long type)
* was GDT/LDT) but those circumstances should be
* very rare.
*/
cpumask_t mask = page_get_owner(page)->cpumask;
cpumask_t mask =
page_get_owner(page)->domain_dirty_cpumask;
tlbflush_filter(mask, page->tlbflush_timestamp);
if ( unlikely(!cpus_empty(mask)) )
@@ -1620,7 +1620,7 @@ static void process_deferred_ops(unsigned int cpu)
if ( shadow_mode_enabled(d) )
shadow_sync_all(d);
if ( deferred_ops & DOP_FLUSH_ALL_TLBS )
flush_tlb_mask(d->cpumask);
flush_tlb_mask(d->domain_dirty_cpumask);
else
local_flush_tlb();
}
@@ -1692,7 +1692,7 @@ static inline cpumask_t vcpumask_to_pcpumask(
struct domain *d, unsigned long vmask)
{
unsigned int vcpu_id;
cpumask_t pmask;
cpumask_t pmask = CPU_MASK_NONE;
struct vcpu *v;
while ( vmask != 0 )
@@ -1701,7 +1701,7 @@ static inline cpumask_t vcpumask_to_pcpumask(
vmask &= ~(1UL << vcpu_id);
if ( (vcpu_id < MAX_VIRT_CPUS) &&
((v = d->vcpu[vcpu_id]) != NULL) )
cpu_set(v->processor, pmask);
cpus_or(pmask, pmask, v->vcpu_dirty_cpumask);
}
return pmask;
@@ -1870,7 +1870,6 @@ int do_mmuext_op(
break;
}
pmask = vcpumask_to_pcpumask(d, vmask);
cpus_and(pmask, pmask, d->cpumask);
if ( op.cmd == MMUEXT_TLB_FLUSH_MULTI )
flush_tlb_mask(pmask);
else
@@ -1879,15 +1878,15 @@ int do_mmuext_op(
}
case MMUEXT_TLB_FLUSH_ALL:
flush_tlb_mask(d->cpumask);
flush_tlb_mask(d->domain_dirty_cpumask);
break;
case MMUEXT_INVLPG_ALL:
flush_tlb_one_mask(d->cpumask, op.arg1.linear_addr);
flush_tlb_one_mask(d->domain_dirty_cpumask, op.arg1.linear_addr);
break;
case MMUEXT_FLUSH_CACHE:
if ( unlikely(!IS_CAPABLE_PHYSDEV(d)) )
if ( unlikely(!cache_flush_permitted(d)) )
{
MEM_LOG("Non-physdev domain tried to FLUSH_CACHE.");
okay = 0;
@@ -2498,7 +2497,7 @@ int do_update_va_mapping(unsigned long va, u64 val64,
l1_pgentry_t val = l1e_from_intpte(val64);
struct vcpu *v = current;
struct domain *d = v->domain;
unsigned int cpu = v->processor;
unsigned int cpu = smp_processor_id();
unsigned long vmask, bmap_ptr;
cpumask_t pmask;
int rc = 0;
@@ -2549,13 +2548,12 @@ int do_update_va_mapping(unsigned long va, u64 val64,
local_flush_tlb();
break;
case UVMF_ALL:
flush_tlb_mask(d->cpumask);
flush_tlb_mask(d->domain_dirty_cpumask);
break;
default:
if ( unlikely(get_user(vmask, (unsigned long *)bmap_ptr)) )
rc = -EFAULT;
pmask = vcpumask_to_pcpumask(d, vmask);
cpus_and(pmask, pmask, d->cpumask);
flush_tlb_mask(pmask);
break;
}
@@ -2570,13 +2568,12 @@ int do_update_va_mapping(unsigned long va, u64 val64,
local_flush_tlb_one(va);
break;
case UVMF_ALL:
flush_tlb_one_mask(d->cpumask, va);
flush_tlb_one_mask(d->domain_dirty_cpumask, va);
break;
default:
if ( unlikely(get_user(vmask, (unsigned long *)bmap_ptr)) )
rc = -EFAULT;
pmask = vcpumask_to_pcpumask(d, vmask);
cpus_and(pmask, pmask, d->cpumask);
flush_tlb_one_mask(pmask, va);
break;
}
@@ -3019,7 +3016,7 @@ void ptwr_flush(struct domain *d, const int which)
/* Ensure that there are no stale writable mappings in any TLB. */
/* NB. INVLPG is a serialising instruction: flushes pending updates. */
flush_tlb_one_mask(d->cpumask, l1va);
flush_tlb_one_mask(d->domain_dirty_cpumask, l1va);
PTWR_PRINTK("[%c] disconnected_l1va at %p now %"PRIpte"\n",
PTWR_PRINT_WHICH, ptep, pte.l1);
@@ -3343,7 +3340,7 @@ int ptwr_do_page_fault(struct domain *d, unsigned long addr,
if ( which == PTWR_PT_ACTIVE )
{
l2e_remove_flags(*pl2e, _PAGE_PRESENT);
flush_tlb_mask(d->cpumask);
flush_tlb_mask(d->domain_dirty_cpumask);
}
/* Temporarily map the L1 page, and make a copy of it. */
@@ -3370,7 +3367,7 @@ int ptwr_do_page_fault(struct domain *d, unsigned long addr,
emulate:
if ( x86_emulate_memop(guest_cpu_user_regs(), addr,
&ptwr_mem_emulator, BITS_PER_LONG/8) )
&ptwr_mem_emulator, X86EMUL_MODE_HOST) )
return 0;
perfc_incrc(ptwr_emulations);
return EXCRET_fault_fixed;
-33
View File
@@ -14,27 +14,6 @@
extern int ioapic_guest_read(int apicid, int address, u32 *pval);
extern int ioapic_guest_write(int apicid, int address, u32 pval);
void physdev_modify_ioport_access_range(
struct domain *d, int enable, int port, int num)
{
int i;
for ( i = port; i < (port + num); i++ )
(enable ? clear_bit : set_bit)(i, d->arch.iobmp_mask);
}
void physdev_destroy_state(struct domain *d)
{
xfree(d->arch.iobmp_mask);
d->arch.iobmp_mask = NULL;
}
/* Check if a domain controls a device with IO memory within frame @pfn.
* Returns: 1 if the domain should be allowed to map @pfn, 0 otherwise. */
int domain_iomem_in_pfn(struct domain *p, unsigned long pfn)
{
return 0;
}
/*
* Demuxing hypercall.
*/
@@ -120,18 +99,6 @@ long do_physdev_op(physdev_op_t *uop)
return ret;
}
/* Domain 0 has read access to all devices. */
void physdev_init_dom0(struct domain *d)
{
/* Access to all I/O ports. */
d->arch.iobmp_mask = xmalloc_array(u8, IOBMP_BYTES);
BUG_ON(d->arch.iobmp_mask == NULL);
memset(d->arch.iobmp_mask, 0, IOBMP_BYTES);
set_bit(_DOMF_physdev_access, &d->domain_flags);
}
/*
* Local variables:
* mode: C
+117 -117
View File
@@ -92,7 +92,7 @@ unsigned long mmu_cr4_features = X86_CR4_PSE;
#endif
EXPORT_SYMBOL(mmu_cr4_features);
struct vcpu *idle_task[NR_CPUS] = { &idle0_vcpu };
struct vcpu *idle_domain[NR_CPUS] = { &idle0_vcpu };
int acpi_disabled;
@@ -138,131 +138,19 @@ static void __init do_initcalls(void)
(*call)();
}
static void __init start_of_day(void)
{
int i;
unsigned long vgdt, gdt_pfn;
early_cpu_init();
paging_init();
/* Unmap the first page of CPU0's stack. */
memguard_guard_stack(cpu0_stack);
open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
if ( opt_watchdog )
nmi_watchdog = NMI_LOCAL_APIC;
sort_exception_tables();
arch_do_createdomain(current);
/*
* Map default GDT into its final positions in the idle page table. As
* noted in arch_do_createdomain(), we must map for every possible VCPU#.
*/
vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE;
gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT;
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
{
map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR);
vgdt += 1 << PDPT_VCPU_VA_SHIFT;
}
find_smp_config();
smp_alloc_memory();
dmi_scan_machine();
generic_apic_probe();
acpi_boot_table_init();
acpi_boot_init();
if ( smp_found_config )
get_smp_config();
init_apic_mappings();
init_IRQ();
trap_init();
ac_timer_init();
early_time_init();
arch_init_memory();
scheduler_init();
identify_cpu(&boot_cpu_data);
if ( cpu_has_fxsr )
set_in_cr4(X86_CR4_OSFXSR);
if ( cpu_has_xmm )
set_in_cr4(X86_CR4_OSXMMEXCPT);
if ( opt_nosmp )
{
max_cpus = 0;
smp_num_siblings = 1;
boot_cpu_data.x86_num_cores = 1;
}
smp_prepare_cpus(max_cpus);
/* We aren't hotplug-capable yet. */
BUG_ON(!cpus_empty(cpu_present_map));
for_each_cpu ( i )
cpu_set(i, cpu_present_map);
/*
* Initialise higher-level timer functions. We do this fairly late
* (post-SMP) because the time bases and scale factors need to be updated
* regularly, and SMP initialisation can cause a long delay with
* interrupts not yet enabled.
*/
init_xen_time();
initialize_keytable();
serial_init_postirq();
BUG_ON(!local_irq_is_enabled());
for_each_present_cpu ( i )
{
if ( num_online_cpus() >= max_cpus )
break;
if ( !cpu_online(i) )
__cpu_up(i);
}
printk("Brought up %ld CPUs\n", (long)num_online_cpus());
smp_cpus_done(max_cpus);
do_initcalls();
schedulers_start();
watchdog_enable();
}
#define EARLY_FAIL() for ( ; ; ) __asm__ __volatile__ ( "hlt" )
static struct e820entry e820_raw[E820MAX];
void __init __start_xen(multiboot_info_t *mbi)
{
unsigned long vgdt, gdt_pfn;
char *cmdline;
unsigned long _initrd_start = 0, _initrd_len = 0;
unsigned int initrdidx = 1;
module_t *mod = (module_t *)__va(mbi->mods_addr);
unsigned long nr_pages, modules_length;
unsigned long initial_images_start, initial_images_end;
unsigned long _initrd_start = 0, _initrd_len = 0;
unsigned int initrdidx = 1;
physaddr_t s, e;
int i, e820_warn = 0, e820_raw_nr = 0, bytes = 0;
struct ns16550_defaults ns16550 = {
@@ -455,6 +343,12 @@ void __init __start_xen(multiboot_info_t *mbi)
BUG_ON(sizeof(shared_info_t) > PAGE_SIZE);
BUG_ON(sizeof(vcpu_info_t) != 64);
/* __foo are defined in public headers. Check they match internal defs. */
BUG_ON(__HYPERVISOR_VIRT_START != HYPERVISOR_VIRT_START);
#ifdef HYPERVISOR_VIRT_END
BUG_ON(__HYPERVISOR_VIRT_END != HYPERVISOR_VIRT_END);
#endif
init_frametable();
end_boot_allocator();
@@ -486,7 +380,113 @@ void __init __start_xen(multiboot_info_t *mbi)
early_boot = 0;
start_of_day();
early_cpu_init();
paging_init();
/* Unmap the first page of CPU0's stack. */
memguard_guard_stack(cpu0_stack);
open_softirq(NEW_TLBFLUSH_CLOCK_PERIOD_SOFTIRQ, new_tlbflush_clock_period);
if ( opt_watchdog )
nmi_watchdog = NMI_LOCAL_APIC;
sort_exception_tables();
if ( arch_do_createdomain(current) != 0 )
BUG();
/*
* Map default GDT into its final positions in the idle page table. As
* noted in arch_do_createdomain(), we must map for every possible VCPU#.
*/
vgdt = GDT_VIRT_START(current) + FIRST_RESERVED_GDT_BYTE;
gdt_pfn = virt_to_phys(gdt_table) >> PAGE_SHIFT;
for ( i = 0; i < MAX_VIRT_CPUS; i++ )
{
map_pages_to_xen(vgdt, gdt_pfn, 1, PAGE_HYPERVISOR);
vgdt += 1 << PDPT_VCPU_VA_SHIFT;
}
find_smp_config();
smp_alloc_memory();
dmi_scan_machine();
generic_apic_probe();
acpi_boot_table_init();
acpi_boot_init();
if ( smp_found_config )
get_smp_config();
init_apic_mappings();
init_IRQ();
trap_init();
ac_timer_init();
early_time_init();
arch_init_memory();
scheduler_init();
identify_cpu(&boot_cpu_data);
if ( cpu_has_fxsr )
set_in_cr4(X86_CR4_OSFXSR);
if ( cpu_has_xmm )
set_in_cr4(X86_CR4_OSXMMEXCPT);
if ( opt_nosmp )
{
max_cpus = 0;
smp_num_siblings = 1;
boot_cpu_data.x86_num_cores = 1;
}
smp_prepare_cpus(max_cpus);
/* We aren't hotplug-capable yet. */
BUG_ON(!cpus_empty(cpu_present_map));
for_each_cpu ( i )
cpu_set(i, cpu_present_map);
/*
* Initialise higher-level timer functions. We do this fairly late
* (post-SMP) because the time bases and scale factors need to be updated
* regularly, and SMP initialisation can cause a long delay with
* interrupts not yet enabled.
*/
init_xen_time();
initialize_keytable();
serial_init_postirq();
BUG_ON(!local_irq_is_enabled());
for_each_present_cpu ( i )
{
if ( num_online_cpus() >= max_cpus )
break;
if ( !cpu_online(i) )
__cpu_up(i);
}
printk("Brought up %ld CPUs\n", (long)num_online_cpus());
smp_cpus_done(max_cpus);
do_initcalls();
schedulers_start();
watchdog_enable();
shadow_mode_init();
+1 -1
View File
@@ -1800,7 +1800,7 @@ static void sync_all(struct domain *d)
}
/* Other VCPUs mustn't use the revoked writable mappings. */
other_vcpus_mask = d->cpumask;
other_vcpus_mask = d->domain_dirty_cpumask;
cpu_clear(smp_processor_id(), other_vcpus_mask);
flush_tlb_mask(other_vcpus_mask);
Loaded 100 of 162 files, more files were not shown because too many files have changed in this diff. Show more
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.