Patchwork [V9,03/16] xen: Add a generic layer for xc calls

login
register
mail settings
Submitter Anthony PERARD
Date Jan. 25, 2011, 2:29 p.m.
Message ID <1295965760-31508-4-git-send-email-anthony.perard@citrix.com>
Download mbox | patch
Permalink /patch/80368/
State New
Headers show

Comments

Anthony PERARD - Jan. 25, 2011, 2:29 p.m.
From: Alexander Graf <agraf@suse.de>

This patch adds a generic layer for xc calls, allowing us to choose between the
xenner and xen implementations at runtime.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Anthony PERARD <anthony.perard@citrix.com>
---
 hw/xen_interfaces.c |  100 +++++++++++++++++++++++++++++++++++++++++++++++++
 hw/xen_interfaces.h |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/xen_redirect.h   |   56 +++++++++++++++++++++++++++
 3 files changed, 260 insertions(+), 0 deletions(-)
 create mode 100644 hw/xen_interfaces.c
 create mode 100644 hw/xen_interfaces.h
 create mode 100644 hw/xen_redirect.h
Anthony Liguori - Jan. 26, 2011, 10:49 p.m.
On 01/25/2011 08:29 AM, anthony.perard@citrix.com wrote:
> From: Alexander Graf<agraf@suse.de>
>
> This patch adds a generic layer for xc calls, allowing us to choose between the
> xenner and xen implementations at runtime.
>
> Signed-off-by: Alexander Graf<agraf@suse.de>
> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
> ---
>   hw/xen_interfaces.c |  100 +++++++++++++++++++++++++++++++++++++++++++++++++
>   hw/xen_interfaces.h |  104 +++++++++++++++++++++++++++++++++++++++++++++++++++
>   hw/xen_redirect.h   |   56 +++++++++++++++++++++++++++
>   3 files changed, 260 insertions(+), 0 deletions(-)
>   create mode 100644 hw/xen_interfaces.c
>   create mode 100644 hw/xen_interfaces.h
>   create mode 100644 hw/xen_redirect.h
>
> diff --git a/hw/xen_interfaces.c b/hw/xen_interfaces.c
> new file mode 100644
> index 0000000..09f40e0
> --- /dev/null
> +++ b/hw/xen_interfaces.c
> @@ -0,0 +1,100 @@
>    

Needs a copyright.

> +#include<xenctrl.h>
> +#include<xs.h>
> +
> +#include "hw.h"
> +#include "xen.h"
> +#include "xen_interfaces.h"
> +
> +#ifdef CONFIG_XEN
> +
> +static int xc_evtchn_domid(int handle, int domid)
> +{
> +    return -1;
> +}
> +
> +static struct XenEvtOps xc_evtchn_xen = {
> +    .open               = xc_evtchn_open,
> +    .domid              = xc_evtchn_domid,
> +    .close              = xc_evtchn_close,
> +    .fd                 = xc_evtchn_fd,
> +    .notify             = xc_evtchn_notify,
> +    .bind_unbound_port  = xc_evtchn_bind_unbound_port,
> +    .bind_interdomain   = xc_evtchn_bind_interdomain,
> +    .bind_virq          = xc_evtchn_bind_virq,
> +    .unbind             = xc_evtchn_unbind,
> +    .pending            = xc_evtchn_pending,
> +    .unmask             = xc_evtchn_unmask,
> +};
> +
> +static int xs_domid(struct xs_handle *h, int domid)
> +{
> +    return -1;
> +}
> +
> +static struct XenStoreOps xs_xen = {
> +    .daemon_open           = xs_daemon_open,
> +    .domain_open           = xs_domain_open,
> +    .daemon_open_readonly  = xs_daemon_open_readonly,
> +    .domid                 = xs_domid,
> +    .daemon_close          = xs_daemon_close,
> +    .directory             = xs_directory,
> +    .read                  = xs_read,
> +    .write                 = xs_write,
> +    .mkdir                 = xs_mkdir,
> +    .rm                    = xs_rm,
> +    .get_permissions       = xs_get_permissions,
> +    .set_permissions       = xs_set_permissions,
> +    .watch                 = xs_watch,
> +    .fileno                = xs_fileno,
> +    .read_watch            = xs_read_watch,
> +    .unwatch               = xs_unwatch,
> +    .transaction_start     = xs_transaction_start,
> +    .transaction_end       = xs_transaction_end,
> +    .introduce_domain      = xs_introduce_domain,
> +    .resume_domain         = xs_resume_domain,
> +    .release_domain        = xs_release_domain,
> +    .get_domain_path       = xs_get_domain_path,
> +    .is_domain_introduced  = xs_is_domain_introduced,
> +};
> +
> +static struct XenGnttabOps xc_gnttab_xen = {
> +    .open            = xc_gnttab_open,
> +    .close           = xc_gnttab_close,
> +    .map_grant_ref   = xc_gnttab_map_grant_ref,
> +    .map_grant_refs  = xc_gnttab_map_grant_refs,
> +    .munmap          = xc_gnttab_munmap,
> +};
> +
> +struct XenIfOps xc_xen = {
> +    .interface_open                 = xc_interface_open,
> +    .interface_close                = xc_interface_close,
> +    .map_foreign_range              = xc_map_foreign_range,
> +    .map_foreign_pages              = xc_map_foreign_pages,
> +    .map_foreign_bulk               = xc_map_foreign_bulk,
> +};
> +
> +#endif
> +
> +struct XenEvtOps xc_evtchn;
> +struct XenGnttabOps xc_gnttab;
> +struct XenIfOps xc;
> +struct XenStoreOps xs;
> +
> +void xen_interfaces_init(void)
> +{
> +    switch (xen_mode) {
> +#ifdef CONFIG_XEN
> +    case XEN_ATTACH:
> +    case XEN_CREATE:
> +        xc_evtchn = xc_evtchn_xen;
> +        xc_gnttab = xc_gnttab_xen;
> +        xc        = xc_xen;
> +        xs        = xs_xen;
> +        break;
> +#endif
> +    default:
> +        fprintf(stderr, "ERROR: Compiled without %s support, sorry.\n",
> +                xen_mode == XEN_EMULATE ? "xenner" : "Xen");
> +        exit(1);
> +    }
> +}
> diff --git a/hw/xen_interfaces.h b/hw/xen_interfaces.h
> new file mode 100644
> index 0000000..1086850
> --- /dev/null
> +++ b/hw/xen_interfaces.h
> @@ -0,0 +1,104 @@
> +#ifndef QEMU_HW_XEN_INTERFACES_H
> +#define QEMU_HW_XEN_INTERFACES_H 1
> +
> +#include<xenctrl.h>
> +#include<xs.h>
> +
> +/* ------------------------------------------------------------- */
> +/* xen event channel interface                                   */
> +
> +struct XenEvtOps {
> +    int (*open)(void);
> +    int (*domid)(int xce_handle, int domid);
> +    int (*close)(int xce_handle);
> +    int (*fd)(int xce_handle);
> +    int (*notify)(int xce_handle, evtchn_port_t port);
> +    evtchn_port_or_error_t (*bind_unbound_port)(int xce_handle, int domid);
> +    evtchn_port_or_error_t (*bind_interdomain)(int xce_handle, int domid,
> +                                               evtchn_port_t remote_port);
> +    evtchn_port_or_error_t (*bind_virq)(int xce_handle, unsigned int virq);
> +    int (*unbind)(int xce_handle, evtchn_port_t port);
> +    evtchn_port_or_error_t (*pending)(int xce_handle);
> +    int (*unmask)(int xce_handle, evtchn_port_t port);
> +};
> +extern struct XenEvtOps xc_evtchn;
>    

typedef away the struct please.

> +/* ------------------------------------------------------------- */
> +/* xenstore interface                                            */
> +
> +struct xs_handle;
> +struct XenStoreOps {
> +    struct xs_handle *(*daemon_open)(void);
> +    struct xs_handle *(*domain_open)(void);
> +    struct xs_handle *(*daemon_open_readonly)(void);
> +    int (*domid)(struct xs_handle *h, int domid);
> +    void (*daemon_close)(struct xs_handle *);
> +    char **(*directory)(struct xs_handle *h, xs_transaction_t t,
> +                        const char *path, unsigned int *num);
> +    void *(*read)(struct xs_handle *h, xs_transaction_t t,
> +                  const char *path, unsigned int *len);
> +    bool (*write)(struct xs_handle *h, xs_transaction_t t,
> +                  const char *path, const void *data, unsigned int len);
> +    bool (*mkdir)(struct xs_handle *h, xs_transaction_t t,
> +                  const char *path);
> +    bool (*rm)(struct xs_handle *h, xs_transaction_t t,
> +               const char *path);
> +    struct xs_permissions *(*get_permissions)(struct xs_handle *h,
> +                                              xs_transaction_t t,
> +                                              const char *path, unsigned int *num);
> +    bool (*set_permissions)(struct xs_handle *h, xs_transaction_t t,
> +                            const char *path, struct xs_permissions *perms,
> +                            unsigned int num_perms);
> +    bool (*watch)(struct xs_handle *h, const char *path, const char *token);
> +    int (*fileno)(struct xs_handle *h);
> +    char **(*read_watch)(struct xs_handle *h, unsigned int *num);
> +    bool (*unwatch)(struct xs_handle *h, const char *path, const char *token);
> +    xs_transaction_t (*transaction_start)(struct xs_handle *h);
> +    bool (*transaction_end)(struct xs_handle *h, xs_transaction_t t,
> +                            bool abort);
> +    bool (*introduce_domain)(struct xs_handle *h,
> +                             unsigned int domid,
> +                             unsigned long mfn,
> +                             unsigned int eventchn);
> +    bool (*resume_domain)(struct xs_handle *h, unsigned int domid);
> +    bool (*release_domain)(struct xs_handle *h, unsigned int domid);
> +    char *(*get_domain_path)(struct xs_handle *h, unsigned int domid);
> +    bool (*is_domain_introduced)(struct xs_handle *h, unsigned int domid);
> +};
> +extern struct XenStoreOps xs;
> +
> +/* ------------------------------------------------------------- */
> +/* xen grant table interface                                     */
> +
> +struct XenGnttabOps {
> +    int (*open)(void);
> +    int (*close)(int xcg_handle);
> +    void *(*map_grant_ref)(int xcg_handle, uint32_t domid,
> +                          uint32_t ref, int prot);
> +    void *(*map_grant_refs)(int xcg_handle, uint32_t count,
> +                            uint32_t *domids, uint32_t *refs, int prot);
> +    int (*munmap)(int xcg_handle, void *start_address, uint32_t count);
> +};
> +extern struct XenGnttabOps xc_gnttab;
> +
> +/* ------------------------------------------------------------- */
> +/* xen hypercall interface                                       */
> +
> +struct XenIfOps {
> +    int (*interface_open)(void);
> +    int (*interface_close)(int xc_handle);
> +    void *(*map_foreign_range)(int xc_handle, uint32_t dom,
> +                               int size, int prot,
> +                               unsigned long mfn);
> +    void *(*map_foreign_pages)(int xc_handle, uint32_t dom, int prot,
> +                               const xen_pfn_t *arr, int num);
> +    void *(*map_foreign_bulk)(int xc_handle, uint32_t dom, int prot,
> +                              xen_pfn_t *arr, int num);
> +};
> +extern struct XenIfOps xc;
> +
> +/* ------------------------------------------------------------- */
> +
> +void xen_interfaces_init(void);
> +
> +#endif /* QEMU_HW_XEN_INTERFACES_H */
> diff --git a/hw/xen_redirect.h b/hw/xen_redirect.h
> new file mode 100644
> index 0000000..6ddecf3
> --- /dev/null
> +++ b/hw/xen_redirect.h
> @@ -0,0 +1,56 @@
> +#ifndef QEMU_HW_XEN_REDIRECT_H
> +#define QEMU_HW_XEN_REDIRECT_H 1
> +
> +#include "xen_interfaces.h"
> +
> +/* xen event channel interface */
> +#define xc_evtchn_open              xc_evtchn.open
> +#define xc_evtchn_close             xc_evtchn.close
> +#define xc_evtchn_fd                xc_evtchn.fd
> +#define xc_evtchn_notify            xc_evtchn.notify
> +#define xc_evtchn_bind_unbound_port xc_evtchn.bind_unbound_port
> +#define xc_evtchn_bind_interdomain  xc_evtchn.bind_interdomain
> +#define xc_evtchn_bind_virq         xc_evtchn.bind_virq
> +#define xc_evtchn_unbind            xc_evtchn.unbind
> +#define xc_evtchn_pending           xc_evtchn.pending
> +#define xc_evtchn_unmask            xc_evtchn.unmask
> +
> +/* grant table interface */
> +#define xc_gnttab_open              xc_gnttab.open
> +#define xc_gnttab_close             xc_gnttab.close
> +#define xc_gnttab_map_grant_ref     xc_gnttab.map_grant_ref
> +#define xc_gnttab_map_grant_refs    xc_gnttab.map_grant_refs
> +#define xc_gnttab_munmap            xc_gnttab.munmap
> +
> +/* xen hypercall interface */
> +#define xc_interface_open           xc.interface_open
> +#define xc_interface_close          xc.interface_close
> +#define xc_map_foreign_range        xc.map_foreign_range
> +#define xc_map_foreign_pages        xc.map_foreign_pages
> +#define xc_map_foreign_bulk         xc.map_foreign_bulk
> +
> +/* xenstore interface */
> +#define xs_daemon_open              xs.daemon_open
> +#define xs_domain_open              xs.domain_open
> +#define xs_daemon_open_readonly     xs.daemon_open_readonly
> +#define xs_daemon_close             xs.daemon_close
> +#define xs_directory                xs.directory
> +#define xs_read                     xs.read
> +#define xs_write                    xs.write
> +#define xs_mkdir                    xs.mkdir
> +#define xs_rm                       xs.rm
> +#define xs_get_permissions          xs.get_permissions
> +#define xs_set_permissions          xs.set_permissions
> +#define xs_watch                    xs.watch
> +#define xs_fileno                   xs.fileno
> +#define xs_read_watch               xs.read_watch
> +#define xs_unwatch                  xs.unwatch
> +#define xs_transaction_start        xs.transaction_start
> +#define xs_transaction_end          xs.transaction_end
> +#define xs_introduce_domain         xs.introduce_domain
> +#define xs_resume_domain            xs.resume_domain
> +#define xs_release_domain           xs.release_domain
> +#define xs_get_domain_path          xs.get_domain_path
> +#define xs_is_domain_introduced     xs.is_domain_introduced
>    

static inline please.

Regards,

Anthony Liguori

> +#endif /* QEMU_HW_XEN_REDIRECT_H */
>
Anthony PERARD - Jan. 28, 2011, 3:09 p.m.
On Wed, Jan 26, 2011 at 22:49, Anthony Liguori <anthony@codemonkey.ws> wrote:
> On 01/25/2011 08:29 AM, anthony.perard@citrix.com wrote:
>>
>> From: Alexander Graf<agraf@suse.de>
>>
>> This patch adds a generic layer for xc calls, allowing us to choose
>> between the
>> xenner and xen implementations at runtime.
>>
>> Signed-off-by: Alexander Graf<agraf@suse.de>
>> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
>> ---
>>  hw/xen_interfaces.c |  100
>> +++++++++++++++++++++++++++++++++++++++++++++++++
>>  hw/xen_interfaces.h |  104
>> +++++++++++++++++++++++++++++++++++++++++++++++++++
>>  hw/xen_redirect.h   |   56 +++++++++++++++++++++++++++
>>  3 files changed, 260 insertions(+), 0 deletions(-)
>>  create mode 100644 hw/xen_interfaces.c
>>  create mode 100644 hw/xen_interfaces.h
>>  create mode 100644 hw/xen_redirect.h
>>
>> diff --git a/hw/xen_interfaces.c b/hw/xen_interfaces.c
>> new file mode 100644
>> index 0000000..09f40e0
>> --- /dev/null
>> +++ b/hw/xen_interfaces.c
>> @@ -0,0 +1,100 @@
>>
>
> Needs a copyright.

Will put one.


>> diff --git a/hw/xen_interfaces.h b/hw/xen_interfaces.h
>> new file mode 100644
>> index 0000000..1086850
>> --- /dev/null
>> +++ b/hw/xen_interfaces.h
>> @@ -0,0 +1,104 @@
>> +#ifndef QEMU_HW_XEN_INTERFACES_H
>> +#define QEMU_HW_XEN_INTERFACES_H 1
>> +
>> +#include<xenctrl.h>
>> +#include<xs.h>
>> +
>> +/* ------------------------------------------------------------- */
>> +/* xen event channel interface                                   */
>> +
>> +struct XenEvtOps {
>> +    int (*open)(void);
>> +    int (*domid)(int xce_handle, int domid);
>> +    int (*close)(int xce_handle);
>> +    int (*fd)(int xce_handle);
>> +    int (*notify)(int xce_handle, evtchn_port_t port);
>> +    evtchn_port_or_error_t (*bind_unbound_port)(int xce_handle, int
>> domid);
>> +    evtchn_port_or_error_t (*bind_interdomain)(int xce_handle, int domid,
>> +                                               evtchn_port_t
>> remote_port);
>> +    evtchn_port_or_error_t (*bind_virq)(int xce_handle, unsigned int
>> virq);
>> +    int (*unbind)(int xce_handle, evtchn_port_t port);
>> +    evtchn_port_or_error_t (*pending)(int xce_handle);
>> +    int (*unmask)(int xce_handle, evtchn_port_t port);
>> +};
>> +extern struct XenEvtOps xc_evtchn;
>>
>
> typedef away the struct please.

Ok, I will do that.


>> diff --git a/hw/xen_redirect.h b/hw/xen_redirect.h
>> new file mode 100644
>> index 0000000..6ddecf3
>> --- /dev/null
>> +++ b/hw/xen_redirect.h
>> @@ -0,0 +1,56 @@
>> +#ifndef QEMU_HW_XEN_REDIRECT_H
>> +#define QEMU_HW_XEN_REDIRECT_H 1
>> +
>> +#include "xen_interfaces.h"
[...]
>> +
>> +/* xenstore interface */
>> +#define xs_daemon_open              xs.daemon_open
>> +#define xs_domain_open              xs.domain_open
>> +#define xs_daemon_open_readonly     xs.daemon_open_readonly
>> +#define xs_daemon_close             xs.daemon_close
>
> static inline please.

Because the define have the same name as the Xen function, I will have
to rename all these functions, or I can just replace all calls in
xen*.c files.

> Regards,

Thanks,
Alexander Graf - Jan. 28, 2011, 3:12 p.m.
On 28.01.2011, at 16:09, Anthony PERARD <anthony.perard@citrix.com> wrote:

> On Wed, Jan 26, 2011 at 22:49, Anthony Liguori <anthony@codemonkey.ws> wrote:
>> On 01/25/2011 08:29 AM, anthony.perard@citrix.com wrote:
>>> 
>>> From: Alexander Graf<agraf@suse.de>
>>> 
>>> This patch adds a generic layer for xc calls, allowing us to choose
>>> between the
>>> xenner and xen implementations at runtime.
>>> 
>>> Signed-off-by: Alexander Graf<agraf@suse.de>
>>> Signed-off-by: Anthony PERARD<anthony.perard@citrix.com>
>>> ---
>>>  hw/xen_interfaces.c |  100
>>> +++++++++++++++++++++++++++++++++++++++++++++++++
>>>  hw/xen_interfaces.h |  104
>>> +++++++++++++++++++++++++++++++++++++++++++++++++++
>>>  hw/xen_redirect.h   |   56 +++++++++++++++++++++++++++
>>>  3 files changed, 260 insertions(+), 0 deletions(-)
>>>  create mode 100644 hw/xen_interfaces.c
>>>  create mode 100644 hw/xen_interfaces.h
>>>  create mode 100644 hw/xen_redirect.h
>>> 
>>> diff --git a/hw/xen_interfaces.c b/hw/xen_interfaces.c
>>> new file mode 100644
>>> index 0000000..09f40e0
>>> --- /dev/null
>>> +++ b/hw/xen_interfaces.c
>>> @@ -0,0 +1,100 @@
>>> 
>> 
>> Needs a copyright.
> 
> Will put one.
> 
> 
>>> diff --git a/hw/xen_interfaces.h b/hw/xen_interfaces.h
>>> new file mode 100644
>>> index 0000000..1086850
>>> --- /dev/null
>>> +++ b/hw/xen_interfaces.h
>>> @@ -0,0 +1,104 @@
>>> +#ifndef QEMU_HW_XEN_INTERFACES_H
>>> +#define QEMU_HW_XEN_INTERFACES_H 1
>>> +
>>> +#include<xenctrl.h>
>>> +#include<xs.h>
>>> +
>>> +/* ------------------------------------------------------------- */
>>> +/* xen event channel interface                                   */
>>> +
>>> +struct XenEvtOps {
>>> +    int (*open)(void);
>>> +    int (*domid)(int xce_handle, int domid);
>>> +    int (*close)(int xce_handle);
>>> +    int (*fd)(int xce_handle);
>>> +    int (*notify)(int xce_handle, evtchn_port_t port);
>>> +    evtchn_port_or_error_t (*bind_unbound_port)(int xce_handle, int
>>> domid);
>>> +    evtchn_port_or_error_t (*bind_interdomain)(int xce_handle, int domid,
>>> +                                               evtchn_port_t
>>> remote_port);
>>> +    evtchn_port_or_error_t (*bind_virq)(int xce_handle, unsigned int
>>> virq);
>>> +    int (*unbind)(int xce_handle, evtchn_port_t port);
>>> +    evtchn_port_or_error_t (*pending)(int xce_handle);
>>> +    int (*unmask)(int xce_handle, evtchn_port_t port);
>>> +};
>>> +extern struct XenEvtOps xc_evtchn;
>>> 
>> 
>> typedef away the struct please.
> 
> Ok, I will do that.
> 
> 
>>> diff --git a/hw/xen_redirect.h b/hw/xen_redirect.h
>>> new file mode 100644
>>> index 0000000..6ddecf3
>>> --- /dev/null
>>> +++ b/hw/xen_redirect.h
>>> @@ -0,0 +1,56 @@
>>> +#ifndef QEMU_HW_XEN_REDIRECT_H
>>> +#define QEMU_HW_XEN_REDIRECT_H 1
>>> +
>>> +#include "xen_interfaces.h"
> [...]
>>> +
>>> +/* xenstore interface */
>>> +#define xs_daemon_open              xs.daemon_open
>>> +#define xs_domain_open              xs.domain_open
>>> +#define xs_daemon_open_readonly     xs.daemon_open_readonly
>>> +#define xs_daemon_close             xs.daemon_close
>> 
>> static inline please.
> 
> Because the define have the same name as the Xen function, I will have
> to rename all these functions, or I can just replace all calls in
> xen*.c files.

Just replace the calls directly :)


Alex

> 
>> Regards,
> 
> Thanks,
> 
> -- 
> Anthony PERARD

Patch

diff --git a/hw/xen_interfaces.c b/hw/xen_interfaces.c
new file mode 100644
index 0000000..09f40e0
--- /dev/null
+++ b/hw/xen_interfaces.c
@@ -0,0 +1,100 @@ 
+#include <xenctrl.h>
+#include <xs.h>
+
+#include "hw.h"
+#include "xen.h"
+#include "xen_interfaces.h"
+
+#ifdef CONFIG_XEN
+
+static int xc_evtchn_domid(int handle, int domid)
+{
+    return -1;
+}
+
+static struct XenEvtOps xc_evtchn_xen = {
+    .open               = xc_evtchn_open,
+    .domid              = xc_evtchn_domid,
+    .close              = xc_evtchn_close,
+    .fd                 = xc_evtchn_fd,
+    .notify             = xc_evtchn_notify,
+    .bind_unbound_port  = xc_evtchn_bind_unbound_port,
+    .bind_interdomain   = xc_evtchn_bind_interdomain,
+    .bind_virq          = xc_evtchn_bind_virq,
+    .unbind             = xc_evtchn_unbind,
+    .pending            = xc_evtchn_pending,
+    .unmask             = xc_evtchn_unmask,
+};
+
+static int xs_domid(struct xs_handle *h, int domid)
+{
+    return -1;
+}
+
+static struct XenStoreOps xs_xen = {
+    .daemon_open           = xs_daemon_open,
+    .domain_open           = xs_domain_open,
+    .daemon_open_readonly  = xs_daemon_open_readonly,
+    .domid                 = xs_domid,
+    .daemon_close          = xs_daemon_close,
+    .directory             = xs_directory,
+    .read                  = xs_read,
+    .write                 = xs_write,
+    .mkdir                 = xs_mkdir,
+    .rm                    = xs_rm,
+    .get_permissions       = xs_get_permissions,
+    .set_permissions       = xs_set_permissions,
+    .watch                 = xs_watch,
+    .fileno                = xs_fileno,
+    .read_watch            = xs_read_watch,
+    .unwatch               = xs_unwatch,
+    .transaction_start     = xs_transaction_start,
+    .transaction_end       = xs_transaction_end,
+    .introduce_domain      = xs_introduce_domain,
+    .resume_domain         = xs_resume_domain,
+    .release_domain        = xs_release_domain,
+    .get_domain_path       = xs_get_domain_path,
+    .is_domain_introduced  = xs_is_domain_introduced,
+};
+
+static struct XenGnttabOps xc_gnttab_xen = {
+    .open            = xc_gnttab_open,
+    .close           = xc_gnttab_close,
+    .map_grant_ref   = xc_gnttab_map_grant_ref,
+    .map_grant_refs  = xc_gnttab_map_grant_refs,
+    .munmap          = xc_gnttab_munmap,
+};
+
+struct XenIfOps xc_xen = {
+    .interface_open                 = xc_interface_open,
+    .interface_close                = xc_interface_close,
+    .map_foreign_range              = xc_map_foreign_range,
+    .map_foreign_pages              = xc_map_foreign_pages,
+    .map_foreign_bulk               = xc_map_foreign_bulk,
+};
+
+#endif
+
+struct XenEvtOps xc_evtchn;
+struct XenGnttabOps xc_gnttab;
+struct XenIfOps xc;
+struct XenStoreOps xs;
+
+void xen_interfaces_init(void)
+{
+    switch (xen_mode) {
+#ifdef CONFIG_XEN
+    case XEN_ATTACH:
+    case XEN_CREATE:
+        xc_evtchn = xc_evtchn_xen;
+        xc_gnttab = xc_gnttab_xen;
+        xc        = xc_xen;
+        xs        = xs_xen;
+        break;
+#endif
+    default:
+        fprintf(stderr, "ERROR: Compiled without %s support, sorry.\n",
+                xen_mode == XEN_EMULATE ? "xenner" : "Xen");
+        exit(1);
+    }
+}
diff --git a/hw/xen_interfaces.h b/hw/xen_interfaces.h
new file mode 100644
index 0000000..1086850
--- /dev/null
+++ b/hw/xen_interfaces.h
@@ -0,0 +1,104 @@ 
+#ifndef QEMU_HW_XEN_INTERFACES_H
+#define QEMU_HW_XEN_INTERFACES_H 1
+
+#include <xenctrl.h>
+#include <xs.h>
+
+/* ------------------------------------------------------------- */
+/* xen event channel interface                                   */
+
+struct XenEvtOps {
+    int (*open)(void);
+    int (*domid)(int xce_handle, int domid);
+    int (*close)(int xce_handle);
+    int (*fd)(int xce_handle);
+    int (*notify)(int xce_handle, evtchn_port_t port);
+    evtchn_port_or_error_t (*bind_unbound_port)(int xce_handle, int domid);
+    evtchn_port_or_error_t (*bind_interdomain)(int xce_handle, int domid,
+                                               evtchn_port_t remote_port);
+    evtchn_port_or_error_t (*bind_virq)(int xce_handle, unsigned int virq);
+    int (*unbind)(int xce_handle, evtchn_port_t port);
+    evtchn_port_or_error_t (*pending)(int xce_handle);
+    int (*unmask)(int xce_handle, evtchn_port_t port);
+};
+extern struct XenEvtOps xc_evtchn;
+
+/* ------------------------------------------------------------- */
+/* xenstore interface                                            */
+
+struct xs_handle;
+struct XenStoreOps {
+    struct xs_handle *(*daemon_open)(void);
+    struct xs_handle *(*domain_open)(void);
+    struct xs_handle *(*daemon_open_readonly)(void);
+    int (*domid)(struct xs_handle *h, int domid);
+    void (*daemon_close)(struct xs_handle *);
+    char **(*directory)(struct xs_handle *h, xs_transaction_t t,
+                        const char *path, unsigned int *num);
+    void *(*read)(struct xs_handle *h, xs_transaction_t t,
+                  const char *path, unsigned int *len);
+    bool (*write)(struct xs_handle *h, xs_transaction_t t,
+                  const char *path, const void *data, unsigned int len);
+    bool (*mkdir)(struct xs_handle *h, xs_transaction_t t,
+                  const char *path);
+    bool (*rm)(struct xs_handle *h, xs_transaction_t t,
+               const char *path);
+    struct xs_permissions *(*get_permissions)(struct xs_handle *h,
+                                              xs_transaction_t t,
+                                              const char *path, unsigned int *num);
+    bool (*set_permissions)(struct xs_handle *h, xs_transaction_t t,
+                            const char *path, struct xs_permissions *perms,
+                            unsigned int num_perms);
+    bool (*watch)(struct xs_handle *h, const char *path, const char *token);
+    int (*fileno)(struct xs_handle *h);
+    char **(*read_watch)(struct xs_handle *h, unsigned int *num);
+    bool (*unwatch)(struct xs_handle *h, const char *path, const char *token);
+    xs_transaction_t (*transaction_start)(struct xs_handle *h);
+    bool (*transaction_end)(struct xs_handle *h, xs_transaction_t t,
+                            bool abort);
+    bool (*introduce_domain)(struct xs_handle *h,
+                             unsigned int domid,
+                             unsigned long mfn,
+                             unsigned int eventchn);
+    bool (*resume_domain)(struct xs_handle *h, unsigned int domid);
+    bool (*release_domain)(struct xs_handle *h, unsigned int domid);
+    char *(*get_domain_path)(struct xs_handle *h, unsigned int domid);
+    bool (*is_domain_introduced)(struct xs_handle *h, unsigned int domid);
+};
+extern struct XenStoreOps xs;
+
+/* ------------------------------------------------------------- */
+/* xen grant table interface                                     */
+
+struct XenGnttabOps {
+    int (*open)(void);
+    int (*close)(int xcg_handle);
+    void *(*map_grant_ref)(int xcg_handle, uint32_t domid,
+                          uint32_t ref, int prot);
+    void *(*map_grant_refs)(int xcg_handle, uint32_t count,
+                            uint32_t *domids, uint32_t *refs, int prot);
+    int (*munmap)(int xcg_handle, void *start_address, uint32_t count);
+};
+extern struct XenGnttabOps xc_gnttab;
+
+/* ------------------------------------------------------------- */
+/* xen hypercall interface                                       */
+
+struct XenIfOps {
+    int (*interface_open)(void);
+    int (*interface_close)(int xc_handle);
+    void *(*map_foreign_range)(int xc_handle, uint32_t dom,
+                               int size, int prot,
+                               unsigned long mfn);
+    void *(*map_foreign_pages)(int xc_handle, uint32_t dom, int prot,
+                               const xen_pfn_t *arr, int num);
+    void *(*map_foreign_bulk)(int xc_handle, uint32_t dom, int prot,
+                              xen_pfn_t *arr, int num);
+};
+extern struct XenIfOps xc;
+
+/* ------------------------------------------------------------- */
+
+void xen_interfaces_init(void);
+
+#endif /* QEMU_HW_XEN_INTERFACES_H */
diff --git a/hw/xen_redirect.h b/hw/xen_redirect.h
new file mode 100644
index 0000000..6ddecf3
--- /dev/null
+++ b/hw/xen_redirect.h
@@ -0,0 +1,56 @@ 
+#ifndef QEMU_HW_XEN_REDIRECT_H
+#define QEMU_HW_XEN_REDIRECT_H 1
+
+#include "xen_interfaces.h"
+
+/* xen event channel interface */
+#define xc_evtchn_open              xc_evtchn.open
+#define xc_evtchn_close             xc_evtchn.close
+#define xc_evtchn_fd                xc_evtchn.fd
+#define xc_evtchn_notify            xc_evtchn.notify
+#define xc_evtchn_bind_unbound_port xc_evtchn.bind_unbound_port
+#define xc_evtchn_bind_interdomain  xc_evtchn.bind_interdomain
+#define xc_evtchn_bind_virq         xc_evtchn.bind_virq
+#define xc_evtchn_unbind            xc_evtchn.unbind
+#define xc_evtchn_pending           xc_evtchn.pending
+#define xc_evtchn_unmask            xc_evtchn.unmask
+
+/* grant table interface */
+#define xc_gnttab_open              xc_gnttab.open
+#define xc_gnttab_close             xc_gnttab.close
+#define xc_gnttab_map_grant_ref     xc_gnttab.map_grant_ref
+#define xc_gnttab_map_grant_refs    xc_gnttab.map_grant_refs
+#define xc_gnttab_munmap            xc_gnttab.munmap
+
+/* xen hypercall interface */
+#define xc_interface_open           xc.interface_open
+#define xc_interface_close          xc.interface_close
+#define xc_map_foreign_range        xc.map_foreign_range
+#define xc_map_foreign_pages        xc.map_foreign_pages
+#define xc_map_foreign_bulk         xc.map_foreign_bulk
+
+/* xenstore interface */
+#define xs_daemon_open              xs.daemon_open
+#define xs_domain_open              xs.domain_open
+#define xs_daemon_open_readonly     xs.daemon_open_readonly
+#define xs_daemon_close             xs.daemon_close
+#define xs_directory                xs.directory
+#define xs_read                     xs.read
+#define xs_write                    xs.write
+#define xs_mkdir                    xs.mkdir
+#define xs_rm                       xs.rm
+#define xs_get_permissions          xs.get_permissions
+#define xs_set_permissions          xs.set_permissions
+#define xs_watch                    xs.watch
+#define xs_fileno                   xs.fileno
+#define xs_read_watch               xs.read_watch
+#define xs_unwatch                  xs.unwatch
+#define xs_transaction_start        xs.transaction_start
+#define xs_transaction_end          xs.transaction_end
+#define xs_introduce_domain         xs.introduce_domain
+#define xs_resume_domain            xs.resume_domain
+#define xs_release_domain           xs.release_domain
+#define xs_get_domain_path          xs.get_domain_path
+#define xs_is_domain_introduced     xs.is_domain_introduced
+
+#endif /* QEMU_HW_XEN_REDIRECT_H */