[PATCH v2] xen: introduce privcmd device

  • From: Wei Liu <wei.liu2@xxxxxxxxxx>
  • To: <rumpkernel-users@xxxxxxxxxxxxx>
  • Date: Tue, 23 Jun 2015 11:59:37 +0100

This patch implements /kern/xen/privcmd interface for rump kernel. That
interface is needed for application to issue hypercalls into Xen
hypervisor. It's essential for any application that wishes to make use
of Xen interfaces.

This patch does several things:
1. Implement minios_hypercall, a wrapper to issue arbitrary hypercall.
2. Export minios_map_frames.
3. Implement /kern/xen/privcmd, using NetBSD's implementation as
template.

The semantics of /kern/xen/privcmd is the same as NetBSD's privcmd.

List of changes (all squashed into one patch):

minios: implement minios_hypercall
minios: introduce minios_get_l1prot
minios: export do_map_frames as minios_map_frames
minios: make wrmsr match the prototype in netbsd
xen: introduce privcmd device

---
platform/xen/rumpxendev/Makefile | 1 +
platform/xen/rumpxendev/privcmd.c | 317 ++++++++++++++++++++++++++
platform/xen/rumpxendev/rumpxen_xendev.h | 1 +
platform/xen/rumpxendev/xendev_component.c | 16 ++
platform/xen/rumpxendev/xenio.h | 125 ++++++++++
platform/xen/xen/arch/x86/mm.c | 12 +-
platform/xen/xen/arch/x86/sched.c | 2 +-
platform/xen/xen/events.c | 4 +-
platform/xen/xen/hypervisor.c | 19 ++
platform/xen/xen/include/mini-os/hypervisor.h | 3 +
platform/xen/xen/include/mini-os/mm.h | 6 +-
platform/xen/xen/include/mini-os/x86/mm.h | 2 +-
platform/xen/xen/include/mini-os/x86/os.h | 7 +-
platform/xen/xen/mm.c | 5 +
14 files changed, 506 insertions(+), 14 deletions(-)
create mode 100644 platform/xen/rumpxendev/privcmd.c
create mode 100644 platform/xen/rumpxendev/xenio.h

diff --git a/platform/xen/rumpxendev/Makefile b/platform/xen/rumpxendev/Makefile
index d68fe3b..3fac085 100644
--- a/platform/xen/rumpxendev/Makefile
+++ b/platform/xen/rumpxendev/Makefile
@@ -3,6 +3,7 @@ LIB= rumpxen_xendev
SRCS= xendev_component.c
SRCS+= busdev.c
SRCS+= evtdev.c
+SRCS+= privcmd.c

RUMPTOP= ${TOPRUMP}

diff --git a/platform/xen/rumpxendev/privcmd.c
b/platform/xen/rumpxendev/privcmd.c
new file mode 100644
index 0000000..c26bf17
--- /dev/null
+++ b/platform/xen/rumpxendev/privcmd.c
@@ -0,0 +1,317 @@
+/* $NetBSD: privcmd.c,v 1.49 2014/10/17 16:37:02 christos Exp $ */
+
+/*-
+ * Copyright (c) 2004 Christian Limpach.
+ * Copyright (c) 2015 Wei Liu.
+ * 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.
+ *
+ * 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>
+__KERNEL_RCSID(0, "$NetBSD: privcmd.c,v 1.49 2014/10/17 16:37:02 christos Exp
$");
+
+#include "rumpxen_xendev.h"
+
+#include <mini-os/mm.h>
+
+#include <sys/errno.h>
+#include <sys/mount.h>
+#include <sys/dirent.h>
+#include <uvm/uvm_prot.h>
+#include <sys/vnode_if.h>
+#include <sys/vnode.h>
+#include <miscfs/kernfs/kernfs.h>
+#include "xenio.h"
+
+static int
+xenprivcmd_xen2bsd_errno(int error)
+{
+ /*
+ * Xen uses System V error codes.
+ * In order to keep bloat as minimal as possible,
+ * only convert what really impact us.
+ */
+
+ switch(-error) {
+ case 0:
+ return 0;
+ case 1:
+ return EPERM;
+ case 2:
+ return ENOENT;
+ case 3:
+ return ESRCH;
+ case 4:
+ return EINTR;
+ case 5:
+ return EIO;
+ case 6:
+ return ENXIO;
+ case 7:
+ return E2BIG;
+ case 8:
+ return ENOEXEC;
+ case 9:
+ return EBADF;
+ case 10:
+ return ECHILD;
+ case 11:
+ return EAGAIN;
+ case 12:
+ return ENOMEM;
+ case 13:
+ return EACCES;
+ case 14:
+ return EFAULT;
+ case 15:
+ return ENOTBLK;
+ case 16:
+ return EBUSY;
+ case 17:
+ return EEXIST;
+ case 18:
+ return EXDEV;
+ case 19:
+ return ENODEV;
+ case 20:
+ return ENOTDIR;
+ case 21:
+ return EISDIR;
+ case 22:
+ return EINVAL;
+ case 23:
+ return ENFILE;
+ case 24:
+ return EMFILE;
+ case 25:
+ return ENOTTY;
+ case 26:
+ return ETXTBSY;
+ case 27:
+ return EFBIG;
+ case 28:
+ return ENOSPC;
+ case 29:
+ return ESPIPE;
+ case 30:
+ return EROFS;
+ case 31:
+ return EMLINK;
+ case 32:
+ return EPIPE;
+ case 33:
+ return EDOM;
+ case 34:
+ return ERANGE;
+ case 35:
+ return EDEADLK;
+ case 36:
+ return ENAMETOOLONG;
+ case 37:
+ return ENOLCK;
+ case 38:
+ return ENOSYS;
+ case 39:
+ return ENOTEMPTY;
+ case 40:
+ return ELOOP;
+ case 42:
+ return ENOMSG;
+ case 43:
+ return EIDRM;
+ case 60:
+ return ENOSTR;
+ case 61:
+ return ENODATA;
+ case 62:
+ return ETIME;
+ case 63:
+ return ENOSR;
+ case 66:
+ return EREMOTE;
+ case 74:
+ return EBADMSG;
+ case 75:
+ return EOVERFLOW;
+ case 84:
+ return EILSEQ;
+ case 87:
+ return EUSERS;
+ case 88:
+ return ENOTSOCK;
+ case 89:
+ return EDESTADDRREQ;
+ case 90:
+ return EMSGSIZE;
+ case 91:
+ return EPROTOTYPE;
+ case 92:
+ return ENOPROTOOPT;
+ case 93:
+ return EPROTONOSUPPORT;
+ case 94:
+ return ESOCKTNOSUPPORT;
+ case 95:
+ return EOPNOTSUPP;
+ case 96:
+ return EPFNOSUPPORT;
+ case 97:
+ return EAFNOSUPPORT;
+ case 98:
+ return EADDRINUSE;
+ case 99:
+ return EADDRNOTAVAIL;
+ case 100:
+ return ENETDOWN;
+ case 101:
+ return ENETUNREACH;
+ case 102:
+ return ENETRESET;
+ case 103:
+ return ECONNABORTED;
+ case 104:
+ return ECONNRESET;
+ case 105:
+ return ENOBUFS;
+ case 106:
+ return EISCONN;
+ case 107:
+ return ENOTCONN;
+ case 108:
+ return ESHUTDOWN;
+ case 109:
+ return ETOOMANYREFS;
+ case 110:
+ return ETIMEDOUT;
+ case 111:
+ return ECONNREFUSED;
+ case 112:
+ return EHOSTDOWN;
+ case 113:
+ return EHOSTUNREACH;
+ case 114:
+ return EALREADY;
+ case 115:
+ return EINPROGRESS;
+ case 116:
+ return ESTALE;
+ case 122:
+ return EDQUOT;
+ default:
+ printf("unknown xen error code %d\n", -error);
+ return -error;
+ }
+}
+
+static int
+xenprivcmd_ioctl(void *v)
+{
+ int err;
+ struct vop_ioctl_args *ap = v;
+
+ switch (ap->a_command) {
+ case IOCTL_PRIVCMD_HYPERCALL:
+ {
+ privcmd_hypercall_t *hc = (privcmd_hypercall_t *)ap->a_data;
+
+ err = minios_hypercall(hc->op, hc->arg[0], hc->arg[1],
+ hc->arg[2], hc->arg[3], hc->arg[4]);
+ if (err >= 0) {
+ hc->retval = err;
+ err = 0;
+ } else {
+ err = xenprivcmd_xen2bsd_errno(err);
+ hc->retval = 0;
+ }
+
+ break;
+ }
+ case IOCTL_PRIVCMD_MMAP:
+ {
+ int i;
+ privcmd_mmap_t *mcmd = ap->a_data;
+ privcmd_mmap_entry_t mentry;
+
+ for (i = 0; i < mcmd->num; i++) {
+ err = copyin(&mcmd->entry[i], &mentry, sizeof(mentry));
+ if (err)
+ return err;
+
+ if (mentry.npages == 0 || mentry.va & PAGE_MASK)
+ return EINVAL;
+
+ /* Call with err argument == NULL will just crash
+ * the domain.
+ */
+ minios_map_frames(mentry.va, &mentry.mfn, mentry.npages,
+ 0, 0, mcmd->dom, NULL,
+ minios_get_l1prot());
+ }
+
+ err = 0;
+ break;
+ }
+ case IOCTL_PRIVCMD_MMAPBATCH:
+ {
+ privcmd_mmapbatch_t *pmb = ap->a_data;
+
+ if (pmb->num == 0 || pmb->addr & PAGE_MASK)
+ return EINVAL;
+
+ /* Call with err argument == NULL will just crash the
+ * domain.
+ */
+ minios_map_frames(pmb->addr, pmb->arr, pmb->num, 1, 0,
+ pmb->dom, NULL, minios_get_l1prot());
+ err = 0;
+ break;
+ }
+ default:
+ err = EINVAL;
+ }
+
+ return err;
+}
+
+static const struct kernfs_fileop xenprivcmd_fileops[] = {
+ { .kf_fileop = KERNFS_FILEOP_IOCTL, .kf_vop = xenprivcmd_ioctl },
+};
+
+#define XENPRIVCMD_MODE (S_IRUSR)
+extern kernfs_parentdir_t *kernxen_pkt;
+void xenprivcmd_init(void)
+{
+ kernfs_entry_t *dkt;
+ kfstype kfst;
+
+ kfst = KERNFS_ALLOCTYPE(xenprivcmd_fileops);
+
+ KERNFS_ALLOCENTRY(dkt, M_TEMP, M_WAITOK);
+ /* XXX: Take VREG value from sys/vnode.h. Including vnode.h
+ * opens a can of worms. Remember to update that value if
+ * vnode.h changes.
+ */
+ KERNFS_INITENTRY(dkt, DT_REG, "privcmd", NULL, kfst, VREG,
+ XENPRIVCMD_MODE);
+ kernfs_addentry(kernxen_pkt, dkt);
+}
diff --git a/platform/xen/rumpxendev/rumpxen_xendev.h
b/platform/xen/rumpxendev/rumpxen_xendev.h
index ce6092f..16ebd5c 100644
--- a/platform/xen/rumpxendev/rumpxen_xendev.h
+++ b/platform/xen/rumpxendev/rumpxen_xendev.h
@@ -60,6 +60,7 @@ extern const struct fileops xenbus_dev_fileops;
extern void xenevt_dev_init(void);
extern int xenevt_dev_open(struct file *fp, void **fdata);
extern const struct fileops xenevt_dev_fileops;
+extern void xenprivcmd_init(void);

static inline void*
xbd_malloc(size_t sz)
diff --git a/platform/xen/rumpxendev/xendev_component.c
b/platform/xen/rumpxendev/xendev_component.c
index f0aca3d..91e4c28 100644
--- a/platform/xen/rumpxendev/xendev_component.c
+++ b/platform/xen/rumpxendev/xendev_component.c
@@ -33,6 +33,8 @@ __KERNEL_RCSID(0, "$NetBSD: $");
#include "rump_vfs_private.h"

#include <sys/vfs_syscalls.h>
+#include <sys/dirent.h>
+#include <miscfs/kernfs/kernfs.h>

char *xbd_strdup(const char *s)
{
@@ -112,6 +114,17 @@ static const struct cdevsw xen_dev_cdevsw = {
.d_flag = D_OTHER
};

+#define DIR_MODE (S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH)
+kernfs_parentdir_t *kernxen_pkt;
+static void xenkernfs_init(void)
+{
+ kernfs_entry_t *dkt;
+ KERNFS_ALLOCENTRY(dkt, M_TEMP, M_WAITOK);
+ KERNFS_INITENTRY(dkt, DT_DIR, "xen", NULL, KFSsubdir, VDIR, DIR_MODE);
+ kernfs_addentry(NULL, dkt);
+ kernxen_pkt = KERNFS_ENTOPARENTDIR(dkt);
+}
+
RUMP_COMPONENT(RUMP_COMPONENT_DEV)
{
devmajor_t bmaj, cmaj;
@@ -141,6 +154,9 @@ RUMP_COMPONENT(RUMP_COMPONENT_DEV)
DPRINTF(("%s: created, %lu.%lu\n",
xdinfo->path, (unsigned long)cmaj, (unsigned long)cmin));
}
+
+ xenkernfs_init();
+ xenprivcmd_init();
}

/*
diff --git a/platform/xen/rumpxendev/xenio.h b/platform/xen/rumpxendev/xenio.h
new file mode 100644
index 0000000..6b25733
--- /dev/null
+++ b/platform/xen/rumpxendev/xenio.h
@@ -0,0 +1,125 @@
+/* $NetBSD: xenio.h,v 1.9 2011/01/10 11:13:03 cegger Exp $ */
+
+/******************************************************************************
+ * privcmd.h
+ *
+ * Copyright (c) 2003-2004, K A Fraser
+ *
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __XEN_XENIO_H__
+#define __XEN_XENIO_H__
+
+/* Interface to /proc/xen/privcmd */
+
+typedef struct privcmd_hypercall
+{
+ unsigned long op;
+ unsigned long arg[5];
+ long retval;
+} privcmd_hypercall_t;
+
+typedef struct privcmd_mmap_entry {
+ unsigned long va;
+ unsigned long mfn;
+ unsigned long npages;
+} privcmd_mmap_entry_t;
+
+typedef struct privcmd_mmap {
+ int num;
+ domid_t dom; /* target domain */
+ privcmd_mmap_entry_t *entry;
+} privcmd_mmap_t;
+
+typedef struct privcmd_mmapbatch {
+ int num; /* number of pages to populate */
+ domid_t dom; /* target domain */
+ unsigned long addr; /* virtual address */
+ unsigned long *arr; /* array of mfns - top nibble set on err */
+} privcmd_mmapbatch_t;
+
+typedef struct privcmd_mmapbatch_v2 {
+ int num; /* number of pages to populate */
+ domid_t dom; /* target domain */
+ uint64_t addr; /* virtual address */
+ const xen_pfn_t *arr; /* array of mfns */
+ int *err; /* array of error codes */
+} privcmd_mmapbatch_v2_t;
+
+typedef struct privcmd_blkmsg
+{
+ unsigned long op;
+ void *buf;
+ int buf_size;
+} privcmd_blkmsg_t;
+
+/*
+ * @cmd: IOCTL_PRIVCMD_HYPERCALL
+ * @arg: &privcmd_hypercall_t
+ * Return: Value returned from execution of the specified hypercall.
+ */
+#define IOCTL_PRIVCMD_HYPERCALL \
+ _IOWR('P', 0, privcmd_hypercall_t)
+
+#if defined(_KERNEL)
+/* compat */
+#define IOCTL_PRIVCMD_INITDOMAIN_EVTCHN_OLD \
+ _IO('P', 1)
+
+typedef struct oprivcmd_hypercall
+{
+ unsigned long op;
+ unsigned long arg[5];
+} oprivcmd_hypercall_t;
+
+#define IOCTL_PRIVCMD_HYPERCALL_OLD \
+ _IOWR('P', 0, oprivcmd_hypercall_t)
+#endif /* defined(_KERNEL) */
+
+#define IOCTL_PRIVCMD_MMAP \
+ _IOW('P', 2, privcmd_mmap_t)
+#define IOCTL_PRIVCMD_MMAPBATCH \
+ _IOW('P', 3, privcmd_mmapbatch_t)
+#define IOCTL_PRIVCMD_GET_MACH2PHYS_START_MFN \
+ _IOR('P', 4, unsigned long)
+
+/*
+ * @cmd: IOCTL_PRIVCMD_INITDOMAIN_EVTCHN
+ * @arg: n/a
+ * Return: Port associated with domain-controller end of control event channel
+ * for the initial domain.
+ */
+#define IOCTL_PRIVCMD_INITDOMAIN_EVTCHN \
+ _IOR('P', 5, int)
+#define IOCTL_PRIVCMD_MMAPBATCH_V2 \
+ _IOW('P', 6, privcmd_mmapbatch_v2_t)
+
+/* Interface to /dev/xenevt */
+/* EVTCHN_RESET: Clear and reinit the event buffer. Clear error condition. */
+#define EVTCHN_RESET _IO('E', 1)
+/* EVTCHN_BIND: Bind to the specified event-channel port. */
+#define EVTCHN_BIND _IOW('E', 2, unsigned long)
+/* EVTCHN_UNBIND: Unbind from the specified event-channel port. */
+#define EVTCHN_UNBIND _IOW('E', 3, unsigned long)
+
+#endif /* __XEN_XENIO_H__ */
diff --git a/platform/xen/xen/arch/x86/mm.c b/platform/xen/xen/arch/x86/mm.c
index e9ac1ea..b2fb64b 100644
--- a/platform/xen/xen/arch/x86/mm.c
+++ b/platform/xen/xen/arch/x86/mm.c
@@ -553,10 +553,10 @@ unsigned long allocate_ondemand(unsigned long n, unsigned
long alignment)
* va. map f[i*stride]+i*increment for i in 0..n-1.
*/
#define MAP_BATCH ((STACK_SIZE / 2) / sizeof(mmu_update_t))
-void do_map_frames(unsigned long va,
- const unsigned long *mfns, unsigned long n,
- unsigned long stride, unsigned long incr,
- domid_t id, int *err, unsigned long prot)
+void minios_map_frames(unsigned long va,
+ const unsigned long *mfns, unsigned long n,
+ unsigned long stride, unsigned long incr,
+ domid_t id, int *err, unsigned long prot)
{
pgentry_t *pgt = NULL;
unsigned long done = 0;
@@ -565,7 +565,7 @@ void do_map_frames(unsigned long va,

if ( !mfns )
{
- minios_printk("do_map_frames: no mfns supplied\n");
+ minios_printk("minios_map_frames: no mfns supplied\n");
return;
}
DEBUG("va=%p n=0x%lx, mfns[0]=0x%lx stride=0x%lx incr=0x%lx prot=0x%lx\n",
@@ -629,7 +629,7 @@ void *minios_map_frames_ex(const unsigned long *mfns,
unsigned long n,
if ( !va )
return NULL;

- do_map_frames(va, mfns, n, stride, incr, id, err, prot);
+ minios_map_frames(va, mfns, n, stride, incr, id, err, prot);

return (void *)va;
}
diff --git a/platform/xen/xen/arch/x86/sched.c
b/platform/xen/xen/arch/x86/sched.c
index a6419ba..2c9c4e8 100644
--- a/platform/xen/xen/arch/x86/sched.c
+++ b/platform/xen/xen/arch/x86/sched.c
@@ -80,6 +80,6 @@ bmk_platform_cpu_sched_settls(struct bmk_tcb *next)
#if defined(__i386__)
tlsswitch32(next->btcb_tp);
#else /* x86_64 */
- wrmsrl(0xc0000100, next->btcb_tp);
+ wrmsr(0xc0000100, next->btcb_tp);
#endif
}
diff --git a/platform/xen/xen/events.c b/platform/xen/xen/events.c
index a179cc4..a7251ae 100644
--- a/platform/xen/xen/events.c
+++ b/platform/xen/xen/events.c
@@ -232,7 +232,7 @@ void init_events(void)
int i;
#if defined(__x86_64__)
asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
- wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
+ wrmsr(0xc0000101, (uint64_t)&cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
cpu0_pda.irqcount = -1;
cpu0_pda.irqstackptr = (void*) (((unsigned long)irqstack + 2 * STACK_SIZE)
& ~(STACK_SIZE - 1));
@@ -251,7 +251,7 @@ void fini_events(void)
/* Dealloc all events */
unbind_all_ports();
#if defined(__x86_64__)
- wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
+ wrmsr(0xc0000101, 0); /* 0xc0000101 is MSR_GS_BASE */
#endif
}

diff --git a/platform/xen/xen/hypervisor.c b/platform/xen/xen/hypervisor.c
index e4d8bbd..7fb053c 100644
--- a/platform/xen/xen/hypervisor.c
+++ b/platform/xen/xen/hypervisor.c
@@ -120,3 +120,22 @@ inline void minios_clear_evtchn(uint32_t port)
shared_info_t *s = HYPERVISOR_shared_info;
synch_clear_bit(port, &s->evtchn_pending[0]);
}
+
+int minios_hypercall(unsigned op, unsigned long a0,
+ unsigned long a1, unsigned long a2,
+ unsigned long a3, unsigned long a4)
+{
+ multicall_entry_t call;
+ int ret;
+
+ call.op = op;
+ call.args[0] = a0;
+ call.args[1] = a1;
+ call.args[2] = a2;
+ call.args[3] = a3;
+ call.args[4] = a4;
+
+ ret = HYPERVISOR_multicall(&call, 1);
+
+ return ret;
+}
diff --git a/platform/xen/xen/include/mini-os/hypervisor.h
b/platform/xen/xen/include/mini-os/hypervisor.h
index 6c70db8..318c2d9 100644
--- a/platform/xen/xen/include/mini-os/hypervisor.h
+++ b/platform/xen/xen/include/mini-os/hypervisor.h
@@ -41,6 +41,9 @@ void minios_do_hypervisor_callback(struct pt_regs *regs);
void minios_mask_evtchn(uint32_t port);
void minios_unmask_evtchn(uint32_t port);
void minios_clear_evtchn(uint32_t port);
+int minios_hypercall(unsigned op, unsigned long a0,
+ unsigned long a1, unsigned long a2,
+ unsigned long a3, unsigned long a4);

extern int _minios_in_hypervisor_callback;

diff --git a/platform/xen/xen/include/mini-os/mm.h
b/platform/xen/xen/include/mini-os/mm.h
index 7a94a81..016a332 100644
--- a/platform/xen/xen/include/mini-os/mm.h
+++ b/platform/xen/xen/include/mini-os/mm.h
@@ -63,8 +63,8 @@ void *minios_map_frames_ex(const unsigned long *f, unsigned
long n,
unsigned long stride,
unsigned long increment, unsigned long alignment, domid_t id,
int *err, unsigned long prot);
-void do_map_frames(unsigned long addr,
- const unsigned long *f, unsigned long n, unsigned long stride,
+void minios_map_frames(unsigned long addr,
+ const unsigned long *f, unsigned long n, unsigned long stride,
unsigned long increment, domid_t id, int *err, unsigned long prot);
int unmap_frames(unsigned long va, unsigned long num_frames);
unsigned long minios_alloc_contig_pages(int order, unsigned int addr_bits);
@@ -72,4 +72,6 @@ unsigned long minios_alloc_contig_pages(int order, unsigned
int addr_bits);
int free_physical_pages(xen_pfn_t *mfns, int n);
void fini_mm(void);

+unsigned long long minios_get_l1prot(void);
+
#endif /* _MINIOS_MM_H_ */
diff --git a/platform/xen/xen/include/mini-os/x86/mm.h
b/platform/xen/xen/include/mini-os/x86/mm.h
index 53c2875..b40f81a 100644
--- a/platform/xen/xen/include/mini-os/x86/mm.h
+++ b/platform/xen/xen/include/mini-os/x86/mm.h
@@ -228,7 +228,7 @@ static __inline__ paddr_t machine_to_phys(maddr_t machine)

#define map_frames(f, n) minios_map_frames_ex(f, n, 1, 0, 1, DOMID_SELF, NULL,
L1_PROT)
#define map_zero(n, a) minios_map_frames_ex(&mfn_zero, n, 0, 0, a, DOMID_SELF,
NULL, L1_PROT_RO)
-#define do_map_zero(start, n) do_map_frames(start, &mfn_zero, n, 0, 0,
DOMID_SELF, NULL, L1_PROT_RO)
+#define do_map_zero(start, n) minios_map_frames(start, &mfn_zero, n, 0, 0,
DOMID_SELF, NULL, L1_PROT_RO)

pgentry_t *need_pgt(unsigned long addr);
int mfn_is_ram(unsigned long mfn);
diff --git a/platform/xen/xen/include/mini-os/x86/os.h
b/platform/xen/xen/include/mini-os/x86/os.h
index 9aa4275..22750d8 100644
--- a/platform/xen/xen/include/mini-os/x86/os.h
+++ b/platform/xen/xen/include/mini-os/x86/os.h
@@ -434,12 +434,15 @@ static __inline__ unsigned long __ffs(unsigned long word)
(val) = ((unsigned long)__a) | (((unsigned long)__d)<<32); \
} while(0)

-#define wrmsr(msr,val1,val2) \
+#define _wrmsr(msr,val1,val2) \
__asm__ __volatile__("wrmsr" \
: /* no outputs */ \
: "c" (msr), "a" (val1), "d" (val2))

-#define wrmsrl(msr,val)
wrmsr(msr,(uint32_t)((uint64_t)(val)),((uint64_t)(val))>>32)
+static inline void wrmsr(uint32_t msr, uint64_t val)
+{
+ _wrmsr(msr,(uint32_t)((uint64_t)(val)),((uint64_t)(val))>>32);
+}


#else /* ifdef __x86_64__ */
diff --git a/platform/xen/xen/mm.c b/platform/xen/xen/mm.c
index 691cf36..f996ca2 100644
--- a/platform/xen/xen/mm.c
+++ b/platform/xen/xen/mm.c
@@ -92,3 +92,8 @@ void init_mm(void)
void fini_mm(void)
{
}
+
+unsigned long long minios_get_l1prot(void)
+{
+ return L1_PROT;
+}
--
1.9.1


Other related posts: