svn commit: r188684 - user/dfr/xenhvm/7/sys/xen
Doug Rabson
dfr at FreeBSD.org
Mon Feb 16 09:16:27 PST 2009
Author: dfr
Date: Mon Feb 16 17:16:26 2009
New Revision: 188684
URL: http://svn.freebsd.org/changeset/base/188684
Log:
Diff reduction with user/dfr/xenhvm/6.
Added:
user/dfr/xenhvm/7/sys/xen/features.h
user/dfr/xenhvm/7/sys/xen/reboot.c
Modified:
user/dfr/xenhvm/7/sys/xen/evtchn.h
user/dfr/xenhvm/7/sys/xen/features.c
user/dfr/xenhvm/7/sys/xen/gnttab.c
user/dfr/xenhvm/7/sys/xen/gnttab.h
user/dfr/xenhvm/7/sys/xen/hypervisor.h
user/dfr/xenhvm/7/sys/xen/xen_intr.h
Modified: user/dfr/xenhvm/7/sys/xen/evtchn.h
==============================================================================
--- user/dfr/xenhvm/7/sys/xen/evtchn.h Mon Feb 16 17:13:00 2009 (r188683)
+++ user/dfr/xenhvm/7/sys/xen/evtchn.h Mon Feb 16 17:16:26 2009 (r188684)
@@ -28,7 +28,7 @@ void notify_remote_via_irq(int irq);
/* Entry point for notifications into Linux subsystems. */
-void evtchn_do_upcall(struct trapframe *frame);
+void evtchn_do_upcall(struct intrframe *frame);
/* Entry point for notifications into the userland character device. */
void evtchn_device_upcall(int port);
Modified: user/dfr/xenhvm/7/sys/xen/features.c
==============================================================================
--- user/dfr/xenhvm/7/sys/xen/features.c Mon Feb 16 17:13:00 2009 (r188683)
+++ user/dfr/xenhvm/7/sys/xen/features.c Mon Feb 16 17:16:26 2009 (r188684)
@@ -1,10 +1,12 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+
#include <machine/xen/xen-os.h>
#include <xen/hypervisor.h>
-#include <machine/xen/features.h>
+#include <xen/features.h>
uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32] /* __read_mostly */;
Added: user/dfr/xenhvm/7/sys/xen/features.h
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/dfr/xenhvm/7/sys/xen/features.h Mon Feb 16 17:16:26 2009 (r188684)
@@ -0,0 +1,20 @@
+/******************************************************************************
+ * features.h
+ *
+ * Query the features reported by Xen.
+ *
+ * Copyright (c) 2006, Ian Campbell
+ */
+
+#ifndef __ASM_XEN_FEATURES_H__
+#define __ASM_XEN_FEATURES_H__
+
+#include <xen/interface/version.h>
+
+extern void setup_xen_features(void);
+
+extern uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32];
+
+#define xen_feature(flag) (xen_features[flag])
+
+#endif /* __ASM_XEN_FEATURES_H__ */
Modified: user/dfr/xenhvm/7/sys/xen/gnttab.c
==============================================================================
--- user/dfr/xenhvm/7/sys/xen/gnttab.c Mon Feb 16 17:13:00 2009 (r188683)
+++ user/dfr/xenhvm/7/sys/xen/gnttab.c Mon Feb 16 17:16:26 2009 (r188684)
@@ -25,28 +25,20 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/malloc.h>
#include <sys/mman.h>
-#include <vm/vm.h>
-#include <vm/vm_extern.h>
-
-#include <vm/vm_page.h>
-#include <vm/vm_kern.h>
+#include <machine/xen/xen-os.h>
#include <xen/hypervisor.h>
#include <machine/xen/synch_bitops.h>
-#include <xen/gnttab.h>
-#define cmpxchg(a, b, c) atomic_cmpset_int((volatile u_int *)(a),(b),(c))
+#include <xen/hypervisor.h>
+#include <xen/gnttab.h>
-#if 1
-#define ASSERT(_p) \
- if ( !(_p) ) { printk("Assertion '%s': line %d, file %s\n", \
- #_p , __LINE__, __FILE__); *(int*)0=0; }
-#else
-#define ASSERT(_p) ((void)0)
-#endif
+#include <vm/vm.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_extern.h>
+#include <vm/pmap.h>
-#define WPRINTK(fmt, args...) \
- printk("xen_grant: " fmt, ##args)
+#define cmpxchg(a, b, c) atomic_cmpset_int((volatile u_int *)(a),(b),(c))
/* External tools reserve first few grant table entries. */
#define NR_RESERVED_ENTRIES 8
@@ -72,14 +64,14 @@ static int gnttab_expand(unsigned int re
static int
get_free_entries(int count, int *entries)
{
- int ref, rc;
+ int ref, error;
grant_ref_t head;
mtx_lock(&gnttab_list_lock);
if ((gnttab_free_count < count) &&
- ((rc = gnttab_expand(count - gnttab_free_count)) != 0)) {
+ ((error = gnttab_expand(count - gnttab_free_count)) != 0)) {
mtx_unlock(&gnttab_list_lock);
- return (rc);
+ return (error);
}
ref = head = gnttab_free_head;
gnttab_free_count -= count;
@@ -163,6 +155,7 @@ void
gnttab_grant_foreign_access_ref(grant_ref_t ref, domid_t domid,
unsigned long frame, int readonly)
{
+
shared[ref].frame = frame;
shared[ref].domid = domid;
wmb();
@@ -213,7 +206,8 @@ gnttab_end_foreign_access(grant_ref_t re
}
int
-gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn)
+gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn,
+ grant_ref_t *result)
{
int error, ref;
@@ -223,7 +217,8 @@ gnttab_grant_foreign_transfer(domid_t do
gnttab_grant_foreign_transfer_ref(ref, domid, pfn);
- return (ref);
+ *result = ref;
+ return (0);
}
void
@@ -261,7 +256,7 @@ gnttab_end_foreign_transfer_ref(grant_re
/* Read the frame number /after/ reading completion status. */
rmb();
frame = shared[ref].frame;
- PANIC_IF(frame == 0);
+ KASSERT(frame != 0, ("grant table inconsistent"));
return (frame);
}
@@ -320,6 +315,7 @@ gnttab_alloc_grant_references(uint16_t c
int
gnttab_empty_grant_references(const grant_ref_t *private_head)
{
+
return (*private_head == GNTTAB_LIST_END);
}
@@ -331,20 +327,20 @@ gnttab_claim_grant_reference(grant_ref_t
if (unlikely(g == GNTTAB_LIST_END))
return (ENOSPC);
*private_head = gnttab_entry(g);
-
return (g);
}
void
gnttab_release_grant_reference(grant_ref_t *private_head, grant_ref_t release)
{
+
gnttab_entry(release) = *private_head;
*private_head = release;
}
void
gnttab_request_free_callback(struct gnttab_free_callback *callback,
- void (*fn)(void *), void *arg, uint16_t count)
+ void (*fn)(void *), void *arg, uint16_t count)
{
mtx_lock(&gnttab_list_lock);
@@ -387,7 +383,8 @@ grow_gnttab_list(unsigned int more_frame
for (i = nr_grant_frames; i < new_nr_grant_frames; i++)
{
- gnttab_list[i] = (grant_ref_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
+ gnttab_list[i] = (grant_ref_t *)
+ malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
if (!gnttab_list[i])
goto grow_nomem;
@@ -405,12 +402,12 @@ grow_gnttab_list(unsigned int more_frame
check_free_callbacks();
- return 0;
+ return (0);
grow_nomem:
for ( ; i >= nr_grant_frames; i--)
free(gnttab_list[i], M_DEVBUF);
- return (-ENOMEM);
+ return (ENOMEM);
}
static unsigned int
@@ -464,6 +461,8 @@ unmap_pte_fn(pte_t *pte, struct page *pm
}
#endif
+#ifndef XENHVM
+
static int
gnttab_map(unsigned int start_idx, unsigned int end_idx)
{
@@ -486,50 +485,117 @@ gnttab_map(unsigned int start_idx, unsig
free(frames, M_DEVBUF);
return (ENOSYS);
}
- PANIC_IF(rc || setup.status);
+ KASSERT(!(rc || setup.status),
+ ("unexpected result from grant_table_op"));
if (shared == NULL) {
vm_offset_t area;
area = kmem_alloc_nofault(kernel_map,
PAGE_SIZE * max_nr_grant_frames());
- PANIC_IF(area == 0);
+ KASSERT(area, ("can't allocate VM space for grant table"));
shared = (grant_entry_t *)area;
}
+
for (i = 0; i < nr_gframes; i++)
PT_SET_MA(((caddr_t)shared) + i*PAGE_SIZE,
((vm_paddr_t)frames[i]) << PAGE_SHIFT | PG_RW | PG_V);
free(frames, M_DEVBUF);
- return 0;
+ return (0);
}
int
gnttab_resume(void)
{
+
if (max_nr_grant_frames() < nr_grant_frames)
- return -ENOSYS;
- return gnttab_map(0, nr_grant_frames - 1);
+ return (ENOSYS);
+ return (gnttab_map(0, nr_grant_frames - 1));
}
int
gnttab_suspend(void)
{
- int i, pages;
+ int i;
+
+ for (i = 0; i < nr_grant_frames; i++)
+ pmap_kremove((vm_offset_t) shared + i * PAGE_SIZE);
+
+ return (0);
+}
+
+#else /* XENHVM */
- pages = (PAGE_SIZE*nr_grant_frames) >> PAGE_SHIFT;
+#include <dev/xen/xenpci/xenpcivar.h>
- for (i = 0; i < pages; i++)
- PT_SET_MA(shared + (i*PAGE_SIZE), (vm_paddr_t)0);
+static vm_paddr_t resume_frames;
+
+static int gnttab_map(unsigned int start_idx, unsigned int end_idx)
+{
+ struct xen_add_to_physmap xatp;
+ unsigned int i = end_idx;
+
+ /*
+ * Loop backwards, so that the first hypercall has the largest index,
+ * ensuring that the table will grow only once.
+ */
+ do {
+ xatp.domid = DOMID_SELF;
+ xatp.idx = i;
+ xatp.space = XENMAPSPACE_grant_table;
+ xatp.gpfn = (resume_frames >> PAGE_SHIFT) + i;
+ if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp))
+ panic("HYPERVISOR_memory_op failed to map gnttab");
+ } while (i-- > start_idx);
+
+ if (shared == NULL) {
+ vm_offset_t area;
+
+ area = kmem_alloc_nofault(kernel_map,
+ PAGE_SIZE * max_nr_grant_frames());
+ KASSERT(area, ("can't allocate VM space for grant table"));
+ shared = (grant_entry_t *)area;
+ }
+
+ for (i = start_idx; i <= end_idx; i++) {
+ pmap_kenter((vm_offset_t) shared + i * PAGE_SIZE,
+ resume_frames + i * PAGE_SIZE);
+ }
return (0);
}
+int
+gnttab_resume(void)
+{
+ int error;
+ unsigned int max_nr_gframes, nr_gframes;
+
+ nr_gframes = nr_grant_frames;
+ max_nr_gframes = max_nr_grant_frames();
+ if (max_nr_gframes < nr_gframes)
+ return (ENOSYS);
+
+ if (!resume_frames) {
+ error = xenpci_alloc_space(PAGE_SIZE * max_nr_gframes,
+ &resume_frames);
+ if (error) {
+ printf("error mapping gnttab share frames\n");
+ return (error);
+ }
+ }
+
+ return (gnttab_map(0, nr_gframes - 1));
+}
+
+#endif
+
static int
gnttab_expand(unsigned int req_entries)
{
- int rc;
+ int error;
unsigned int cur, extra;
cur = nr_grant_frames;
@@ -538,10 +604,11 @@ gnttab_expand(unsigned int req_entries)
if (cur + extra > max_nr_grant_frames())
return (ENOSPC);
- if ((rc = gnttab_map(cur, cur + extra - 1)) == 0)
- rc = grow_gnttab_list(extra);
+ error = gnttab_map(cur, cur + extra - 1);
+ if (!error)
+ error = grow_gnttab_list(extra);
- return rc;
+ return (error);
}
int
@@ -552,7 +619,7 @@ gnttab_init()
unsigned int nr_init_grefs;
if (!is_running_on_xen())
- return -ENODEV;
+ return (ENODEV);
nr_grant_frames = 1;
boot_max_nr_grant_frames = __max_nr_grant_frames();
@@ -571,7 +638,8 @@ gnttab_init()
return (ENOMEM);
for (i = 0; i < nr_grant_frames; i++) {
- gnttab_list[i] = (grant_ref_t *)malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
+ gnttab_list[i] = (grant_ref_t *)
+ malloc(PAGE_SIZE, M_DEVBUF, M_NOWAIT);
if (gnttab_list[i] == NULL)
goto ini_nomem;
}
@@ -588,8 +656,10 @@ gnttab_init()
gnttab_free_count = nr_init_grefs - NR_RESERVED_ENTRIES;
gnttab_free_head = NR_RESERVED_ENTRIES;
- printk("Grant table initialized\n");
- return 0;
+ if (bootverbose)
+ printf("Grant table initialized\n");
+
+ return (0);
ini_nomem:
for (i--; i >= 0; i--)
Modified: user/dfr/xenhvm/7/sys/xen/gnttab.h
==============================================================================
--- user/dfr/xenhvm/7/sys/xen/gnttab.h Mon Feb 16 17:13:00 2009 (r188683)
+++ user/dfr/xenhvm/7/sys/xen/gnttab.h Mon Feb 16 17:16:26 2009 (r188684)
@@ -36,10 +36,12 @@
#ifndef __ASM_GNTTAB_H__
+#include <xen/interface/grant_table.h>
+
#include <xen/hypervisor.h>
#include <xen/interface/grant_table.h>
#include <machine/xen/xen-os.h>
-#include <machine/xen/features.h>
+#include <xen/features.h>
struct gnttab_free_callback {
struct gnttab_free_callback *next;
@@ -50,6 +52,10 @@ struct gnttab_free_callback {
int gnttab_init(void);
+/*
+ * Allocate a grant table reference and return it in *result. Returns
+ * zero on success or errno on error.
+ */
int gnttab_grant_foreign_access(domid_t domid, unsigned long frame,
int flags, grant_ref_t *result);
@@ -68,7 +74,7 @@ int gnttab_end_foreign_access_ref(grant_
*/
void gnttab_end_foreign_access(grant_ref_t ref, void *page);
-int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn);
+int gnttab_grant_foreign_transfer(domid_t domid, unsigned long pfn, grant_ref_t *result);
unsigned long gnttab_end_foreign_transfer_ref(grant_ref_t ref);
unsigned long gnttab_end_foreign_transfer(grant_ref_t ref);
@@ -104,6 +110,10 @@ void gnttab_grant_foreign_transfer_ref(g
int gnttab_suspend(void);
int gnttab_resume(void);
+#if 0
+
+#include <xen/features.h>
+
static inline void
gnttab_set_map_op(struct gnttab_map_grant_ref *map, vm_paddr_t addr,
uint32_t flags, grant_ref_t ref, domid_t domid)
@@ -149,5 +159,6 @@ gnttab_set_replace_op(struct gnttab_unma
unmap->handle = handle;
}
+#endif
#endif /* __ASM_GNTTAB_H__ */
Modified: user/dfr/xenhvm/7/sys/xen/hypervisor.h
==============================================================================
--- user/dfr/xenhvm/7/sys/xen/hypervisor.h Mon Feb 16 17:13:00 2009 (r188683)
+++ user/dfr/xenhvm/7/sys/xen/hypervisor.h Mon Feb 16 17:16:26 2009 (r188684)
@@ -6,11 +6,19 @@
* Copyright (c) 2002, K A Fraser
*/
-#ifndef __HYPERVISOR_H__
-#define __HYPERVISOR_H__
+#ifndef __XEN_HYPERVISOR_H__
+#define __XEN_HYPERVISOR_H__
+
+#ifdef XENHVM
+
+#define is_running_on_xen() (HYPERVISOR_shared_info != NULL)
+
+#else
#define is_running_on_xen() 1
+#endif
+
#ifdef PAE
#ifndef CONFIG_X86_PAE
#define CONFIG_X86_PAE
@@ -25,6 +33,7 @@
#include <xen/interface/physdev.h>
#include <xen/interface/sched.h>
#include <xen/interface/callback.h>
+#include <xen/interface/memory.h>
#include <machine/xen/hypercall.h>
#if defined(__amd64__)
@@ -129,7 +138,7 @@ MULTI_update_va_mapping(
mcl->op = __HYPERVISOR_update_va_mapping;
mcl->args[0] = va;
#if defined(__amd64__)
- mcl->args[1] = new_val.pte;
+ mcl->args[1] = new_val;
#elif defined(PAE)
mcl->args[1] = (uint32_t)(new_val & 0xffffffff) ;
mcl->args[2] = (uint32_t)(new_val >> 32);
@@ -140,4 +149,4 @@ MULTI_update_va_mapping(
mcl->args[MULTI_UVMFLAGS_INDEX] = flags;
}
-#endif /* __HYPERVISOR_H__ */
+#endif /* __XEN_HYPERVISOR_H__ */
Added: user/dfr/xenhvm/7/sys/xen/reboot.c
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ user/dfr/xenhvm/7/sys/xen/reboot.c Mon Feb 16 17:16:26 2009 (r188684)
@@ -0,0 +1,262 @@
+/*
+ *
+ * Copyright (c) 2004 Christian Limpach.
+ * Copyright (c) 2004-2006,2008 Kip Macy
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Christian Limpach.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/malloc.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+#include <sys/reboot.h>
+#include <sys/sched.h>
+#include <sys/smp.h>
+#include <sys/systm.h>
+
+#include <machine/xen/xen-os.h>
+#include <xen/hypervisor.h>
+#include <xen/gnttab.h>
+#include <xen/xen_intr.h>
+#include <xen/xenbus/xenbusvar.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+
+#ifdef XENHVM
+
+#include <dev/xen/xenpci/xenpcivar.h>
+
+#else
+
+static void xen_suspend(void);
+
+#endif
+
+static void
+shutdown_handler(struct xenbus_watch *watch,
+ const char **vec, unsigned int len)
+{
+ char *str;
+ struct xenbus_transaction xbt;
+ int error, howto;
+
+ howto = 0;
+
+ again:
+ error = xenbus_transaction_start(&xbt);
+ if (error)
+ return;
+
+ error = xenbus_read(xbt, "control", "shutdown", NULL, (void **) &str);
+
+ /* Ignore read errors and empty reads. */
+ if (error || strlen(str) == 0) {
+ xenbus_transaction_end(xbt, 1);
+ return;
+ }
+
+ xenbus_write(xbt, "control", "shutdown", "");
+
+ error = xenbus_transaction_end(xbt, 0);
+ if (error == EAGAIN) {
+ free(str, M_DEVBUF);
+ goto again;
+ }
+
+ if (strcmp(str, "reboot") == 0)
+ howto = 0;
+ else if (strcmp(str, "poweroff") == 0)
+ howto |= (RB_POWEROFF | RB_HALT);
+ else if (strcmp(str, "halt") == 0)
+#ifdef XENHVM
+ /*
+ * We rely on acpi powerdown to halt the VM.
+ */
+ howto |= (RB_POWEROFF | RB_HALT);
+#else
+ howto |= RB_HALT;
+#endif
+ else if (strcmp(str, "suspend") == 0)
+ howto = -1;
+ else {
+ printf("Ignoring shutdown request: %s\n", str);
+ goto done;
+ }
+
+ if (howto == -1) {
+ xen_suspend();
+ goto done;
+ }
+
+ shutdown_nice(howto);
+ done:
+ free(str, M_DEVBUF);
+}
+
+#ifndef XENHVM
+
+/*
+ * In HV mode, we let acpi take care of halts and reboots.
+ */
+
+static void
+xen_shutdown_final(void *arg, int howto)
+{
+
+ if (howto & (RB_HALT | RB_POWEROFF))
+ HYPERVISOR_shutdown(SHUTDOWN_poweroff);
+ else
+ HYPERVISOR_shutdown(SHUTDOWN_reboot);
+}
+
+#endif
+
+static struct xenbus_watch shutdown_watch = {
+ .node = "control/shutdown",
+ .callback = shutdown_handler
+};
+
+static void
+setup_shutdown_watcher(void *unused)
+{
+
+ if (register_xenbus_watch(&shutdown_watch))
+ printf("Failed to set shutdown watcher\n");
+#ifndef XENHVM
+ EVENTHANDLER_REGISTER(shutdown_final, xen_shutdown_final, NULL,
+ SHUTDOWN_PRI_LAST);
+#endif
+}
+
+SYSINIT(shutdown, SI_SUB_PSEUDO, SI_ORDER_ANY, setup_shutdown_watcher, NULL);
+
+#ifndef XENHVM
+
+extern void xencons_suspend(void);
+extern void xencons_resume(void);
+
+static void
+xen_suspend()
+{
+ int i, j, k, fpp;
+ unsigned long max_pfn, start_info_mfn;
+
+#ifdef SMP
+ cpumask_t map;
+ /*
+ * Bind us to CPU 0 and stop any other VCPUs.
+ */
+ mtx_lock_spin(&sched_lock);
+ sched_bind(curthread, 0);
+ mtx_unlock_spin(&sched_lock);
+ KASSERT(PCPU_GET(cpuid) == 0, ("xen_suspend: not running on cpu 0"));
+
+ map = PCPU_GET(other_cpus) & ~stopped_cpus;
+ if (map)
+ stop_cpus(map);
+#endif
+
+ if (DEVICE_SUSPEND(root_bus) != 0) {
+ printf("xen_suspend: device_suspend failed\n");
+ if (map)
+ restart_cpus(map);
+ return;
+ }
+
+ local_irq_disable();
+
+ xencons_suspend();
+ gnttab_suspend();
+
+ max_pfn = HYPERVISOR_shared_info->arch.max_pfn;
+
+ void *shared_info = HYPERVISOR_shared_info;
+ HYPERVISOR_shared_info = NULL;
+ pmap_kremove((vm_offset_t) shared_info);
+ PT_UPDATES_FLUSH();
+
+ xen_start_info->store_mfn = MFNTOPFN(xen_start_info->store_mfn);
+ xen_start_info->console.domU.mfn = MFNTOPFN(xen_start_info->console.domU.mfn);
+
+ /*
+ * We'll stop somewhere inside this hypercall. When it returns,
+ * we'll start resuming after the restore.
+ */
+ start_info_mfn = VTOMFN(xen_start_info);
+ pmap_suspend();
+ HYPERVISOR_suspend(start_info_mfn);
+ pmap_resume();
+
+ pmap_kenter_ma((vm_offset_t) shared_info, xen_start_info->shared_info);
+ HYPERVISOR_shared_info = shared_info;
+
+ HYPERVISOR_shared_info->arch.pfn_to_mfn_frame_list_list =
+ VTOMFN(xen_pfn_to_mfn_frame_list_list);
+
+ fpp = PAGE_SIZE/sizeof(unsigned long);
+ for (i = 0, j = 0, k = -1; i < max_pfn; i += fpp, j++) {
+ if ((j % fpp) == 0) {
+ k++;
+ xen_pfn_to_mfn_frame_list_list[k] =
+ VTOMFN(xen_pfn_to_mfn_frame_list[k]);
+ j = 0;
+ }
+ xen_pfn_to_mfn_frame_list[k][j] =
+ VTOMFN(&xen_phys_machine[i]);
+ }
+ HYPERVISOR_shared_info->arch.max_pfn = max_pfn;
+
+ gnttab_resume();
+ irq_resume();
+ local_irq_enable();
+ xencons_resume();
+
+#ifdef CONFIG_SMP
+ for_each_cpu(i)
+ vcpu_prepare(i);
+
+#endif
+ /*
+ * Only resume xenbus /after/ we've prepared our VCPUs; otherwise
+ * the VCPU hotplug callback can race with our vcpu_prepare
+ */
+ DEVICE_RESUME(root_bus);
+
+#ifdef SMP
+ sched_unbind(curthread);
+ if (map)
+ restart_cpus(map);
+#endif
+}
+
+#endif
Modified: user/dfr/xenhvm/7/sys/xen/xen_intr.h
==============================================================================
--- user/dfr/xenhvm/7/sys/xen/xen_intr.h Mon Feb 16 17:13:00 2009 (r188683)
+++ user/dfr/xenhvm/7/sys/xen/xen_intr.h Mon Feb 16 17:16:26 2009 (r188684)
@@ -29,37 +29,62 @@
#define dynirq_to_irq(_x) ((_x) + DYNIRQ_BASE)
#define irq_to_dynirq(_x) ((_x) - DYNIRQ_BASE)
-/* Dynamic binding of event channels and VIRQ sources to Linux IRQ space. */
-extern void unbind_from_irq(int irq);
-
+/*
+ * Dynamic binding of event channels and VIRQ sources to guest IRQ space.
+ */
+
+/*
+ * Bind a caller port event channel to an interrupt handler. If
+ * successful, the guest IRQ number is returned in *irqp. Return zero
+ * on success or errno otherwise.
+ */
extern int bind_caller_port_to_irqhandler(unsigned int caller_port,
const char *devname, driver_intr_t handler, void *arg,
unsigned long irqflags, unsigned int *irqp);
+
+/*
+ * Bind a listening port to an interrupt handler. If successful, the
+ * guest IRQ number is returned in *irqp. Return zero on success or
+ * errno otherwise.
+ */
extern int bind_listening_port_to_irqhandler(unsigned int remote_domain,
- const char *devname, driver_intr_t handler, void *arg, unsigned long irqflags,
- unsigned int *irqp);
+ const char *devname, driver_intr_t handler, void *arg,
+ unsigned long irqflags, unsigned int *irqp);
+
+/*
+ * Bind a VIRQ to an interrupt handler. If successful, the guest IRQ
+ * number is returned in *irqp. Return zero on success or errno
+ * otherwise.
+ */
extern int bind_virq_to_irqhandler(unsigned int virq, unsigned int cpu,
- const char *devname, driver_filter_t filter, driver_intr_t handler,
+ const char *devname, driver_intr_t handler,
unsigned long irqflags, unsigned int *irqp);
-extern int bind_ipi_to_irqhandler(unsigned int ipi,
- unsigned int cpu,
- const char *devname,
- driver_filter_t handler,
- unsigned long irqflags,
- unsigned int *irqp);
-extern int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
- unsigned int remote_port,
- const char *devname,
- driver_filter_t filter,
- driver_intr_t handler,
- unsigned long irqflags,
- unsigned int *irqp);
+/*
+ * Bind an IPI to an interrupt handler. If successful, the guest
+ * IRQ number is returned in *irqp. Return zero on success or errno
+ * otherwise.
+ */
+extern int bind_ipi_to_irqhandler(unsigned int ipi, unsigned int cpu,
+ const char *devname, driver_intr_t handler,
+ unsigned long irqflags, unsigned int *irqp);
+/*
+ * Bind an interdomain event channel to an interrupt handler. If
+ * successful, the guest IRQ number is returned in *irqp. Return zero
+ * on success or errno otherwise.
+ */
+extern int bind_interdomain_evtchn_to_irqhandler(unsigned int remote_domain,
+ unsigned int remote_port, const char *devname, driver_intr_t handler,
+ unsigned long irqflags, unsigned int *irqp);
+/*
+ * Unbind an interrupt handler using the guest IRQ number returned
+ * when it was bound.
+ */
+extern void unbind_from_irqhandler(unsigned int irq);
-extern void unbind_from_irqhandler(unsigned int evtchn);
-static __inline__ int irq_cannonicalize(int irq)
+static __inline__ int irq_cannonicalize(unsigned int irq)
{
return (irq == 2) ? 9 : irq;
}
More information about the svn-src-user
mailing list