ia64/xen-unstable

changeset 3047:f5a6b3a8c9b9

bitkeeper revision 1.1159.1.437 (419ce215yttRnYIZuqaNEyi1KIplMA)

sync w/ head.
author cl349@arcadians.cl.cam.ac.uk
date Thu Nov 18 17:55:33 2004 +0000 (2004-11-18)
parents f32a9a67a8c0 81e74f5bf690
children 32610e557901
files .rootkeys BitKeeper/etc/ignore tools/python/xen/xend/server/netif.py tools/x2d2/Makefile tools/x2d2/cntrl_con.c tools/x2d2/domain_controller.h tools/x2d2/main.c tools/x2d2/minixend.c tools/x2d2/minixend.h xen/Makefile xen/arch/x86/Makefile xen/arch/x86/dom0_ops.c xen/arch/x86/domain.c xen/arch/x86/nmi.c xen/arch/x86/pdb-stub.c xen/arch/x86/traps.c xen/arch/x86/x86_32/asm-offsets.c xen/arch/x86/x86_32/entry.S xen/arch/x86/x86_32/seg_fixup.c xen/common/keyhandler.c xen/include/asm-x86/processor.h xen/include/asm-x86/shadow.h xen/include/asm-x86/x86_32/asm_defns.h xen/include/xen/sched.h
line diff
     1.1 --- a/.rootkeys	Thu Nov 18 17:43:29 2004 +0000
     1.2 +++ b/.rootkeys	Thu Nov 18 17:55:33 2004 +0000
     1.3 @@ -536,8 +536,7 @@ 41013a83z27rKvWIxAfUBMVZ1eDCDg tools/sv/
     1.4  40fcefb3zGC9XNBkSwTEobCoq8YClA tools/sv/inc/style.css
     1.5  4194e861IgTabTt8HOuh143QIJFD1Q tools/x2d2/Makefile
     1.6  4194e861M2gcBz4i94cQYpqzi8n6UA tools/x2d2/cntrl_con.c
     1.7 -4194e861xToz-o2KH6VT_CPJqVGMCg tools/x2d2/domain_controller.h
     1.8 -4194e8612TrrMvC8ZlA4h2ZYCPWz4g tools/x2d2/main.c
     1.9 +4194e8612TrrMvC8ZlA4h2ZYCPWz4g tools/x2d2/minixend.c
    1.10  4194e861x2eqNCD61RYPCUEBVdMYuw tools/x2d2/minixend.h
    1.11  4194e861A4V9VbD_FYmgXpYEj5YwVg tools/x2d2/util.c
    1.12  403a3edbrr8RE34gkbR40zep98SXbg tools/xentrace/Makefile
    1.13 @@ -612,6 +611,7 @@ 3ddb79bcfUN3-UBCPzX26IU8bq-3aw xen/arch/
    1.14  3ddb79bc-Udq7ol-NX4q9XsYnN7A2Q xen/arch/x86/time.c
    1.15  3ddb79bccYVzXZJyVaxuv5T42Z1Fsw xen/arch/x86/trampoline.S
    1.16  3ddb79bcOftONV9h4QCxXOfiT0h91w xen/arch/x86/traps.c
    1.17 +419cbedeQDg8IrO3izo3o5rQNlo0kQ xen/arch/x86/x86_32/asm-offsets.c
    1.18  3e32af9aRnYGl4GMOaDKp7JdfhOGhg xen/arch/x86/x86_32/domain_page.c
    1.19  3ddb79bcecupHj56ZbTa3B0FxDowMg xen/arch/x86/x86_32/entry.S
    1.20  3ddb79bcHwuCQDjBICDTSis52hWguw xen/arch/x86/x86_32/mm.c
     2.1 --- a/BitKeeper/etc/ignore	Thu Nov 18 17:43:29 2004 +0000
     2.2 +++ b/BitKeeper/etc/ignore	Thu Nov 18 17:55:33 2004 +0000
     2.3 @@ -12,6 +12,7 @@ PENDING/*
     2.4  TAGS
     2.5  Twisted-1.3.0.tar.gz
     2.6  Twisted-1.3.0/*
     2.7 +dist/*
     2.8  docs/*.aux
     2.9  docs/*.dvi
    2.10  docs/*.log
    2.11 @@ -42,16 +43,18 @@ docs/user/labels.pl
    2.12  docs/user/user.css
    2.13  docs/user/user.html
    2.14  extras/mini-os/h/hypervisor-ifs
    2.15 -dist/*
    2.16 +install/*
    2.17  linux-*-xen0/*
    2.18  linux-*-xenU/*
    2.19 +linux-*.patch
    2.20  linux-xen-sparse
    2.21 -linux-*.patch
    2.22  mkddbxen
    2.23  netbsd-*-tools/*
    2.24  netbsd-*-xen0/*
    2.25  netbsd-*-xenU/*
    2.26  netbsd-*.patch
    2.27 +patches/ebtables-brnf-5_vs_2.4.25.diff
    2.28 +patches/ebtables.diff
    2.29  patches/tmp/*
    2.30  pristine-*
    2.31  tools/*/build/lib*/*.py
    2.32 @@ -61,8 +64,10 @@ tools/libxc/xen/*
    2.33  tools/misc/miniterm/miniterm
    2.34  tools/misc/xen_cpuperf
    2.35  tools/web-shutdown.tap
    2.36 +tools/x2d2/minixend
    2.37  tools/xentrace/xentrace
    2.38  tools/xfrd/xfrd
    2.39 +xen/arch/x86/asm-offsets.s
    2.40  xen/arch/x86/boot/mkelf32
    2.41  xen/ddb/*
    2.42  xen/drivers/pci/classlist.h
    2.43 @@ -70,6 +75,7 @@ xen/drivers/pci/devlist.h
    2.44  xen/drivers/pci/gen-devlist
    2.45  xen/figlet/figlet
    2.46  xen/include/asm
    2.47 +xen/include/asm-*/asm-offsets.h
    2.48  xen/include/hypervisor-ifs/arch
    2.49  xen/include/xen/compile.h
    2.50  xen/tools/elf-reloc
    2.51 @@ -77,7 +83,3 @@ xen/tools/figlet/figlet
    2.52  xen/xen
    2.53  xen/xen-syms
    2.54  xen/xen.*
    2.55 -install/*
    2.56 -patches/ebtables-brnf-5_vs_2.4.25.diff
    2.57 -patches/ebtables.diff
    2.58 -tools/x2d2/minixend
     4.1 --- a/tools/x2d2/Makefile	Thu Nov 18 17:43:29 2004 +0000
     4.2 +++ b/tools/x2d2/Makefile	Thu Nov 18 17:55:33 2004 +0000
     4.3 @@ -1,10 +1,22 @@
     4.4 -CFLAGS+=-Wall -g -Werror
     4.5 +XEN_ROOT=../..
     4.6 +include $(XEN_ROOT)/tools/Make.defs
     4.7  
     4.8 -SRCS=main.c cntrl_con.c util.c
     4.9 +CC       = gcc
    4.10 +CFLAGS   = -Wall -Werror -g
    4.11 +
    4.12 +CFLAGS  += -I $(XEN_XC)
    4.13 +CFLAGS  += -I $(XEN_LIBXC)
    4.14 +CFLAGS  += -I $(XEN_LIBXUTIL)
    4.15  
    4.16 -all: minixend
    4.17 +HDRS     = $(wildcard *.h)
    4.18 +OBJS     = $(patsubst %.c,%.o,$(wildcard *.c))
    4.19 +
    4.20 +BIN      = minixend
    4.21  
    4.22 -#$(SRCS): minixend.h
    4.23 +all: $(BIN)
    4.24  
    4.25 -minixend: $(subst .c,.o,$(SRCS))
    4.26 -	gcc $^ -o $@ $(LDFLAGS) -lxc -lpthread
    4.27 +clean:
    4.28 +	$(RM) *.a *.so *.o *.rpm $(BIN)
    4.29 +
    4.30 +$(BIN): $(OBJS)
    4.31 +	$(CC) $(CFLAGS) $^ -o $@ -L$(XEN_LIBXC) -L$(XEN_LIBXUTIL) -lxc -lxutil -lpthread
     5.1 --- a/tools/x2d2/cntrl_con.c	Thu Nov 18 17:43:29 2004 +0000
     5.2 +++ b/tools/x2d2/cntrl_con.c	Thu Nov 18 17:55:33 2004 +0000
     5.3 @@ -40,7 +40,6 @@ domain_created(const char *name, int mem
     5.4  
     5.5  	pthread_mutex_init(&d->mux, NULL);
     5.6  	pthread_cond_init(&d->cond, NULL);
     5.7 -
     5.8  	pthread_create(&d->thread, NULL, domain_thread_func, d);
     5.9  
    5.10  	list_insert_after(&d->domain_list, &head_domain);
    5.11 @@ -164,7 +163,7 @@ create_command_handler(struct open_conne
    5.12  		send_message(oc, "E01 failed to parse %s\n", args);
    5.13  		return;
    5.14  	}
    5.15 -	r = xc_domain_create(xc_handle, mem_kb, name, -1, 0, &domid);
    5.16 +	r = xc_domain_create(xc_handle, mem_kb, -1, 0, &domid);
    5.17  	if (r < 0) {
    5.18  		send_message(oc, "E02 creating domain (%s)\n",
    5.19  			     strerror(errno));
    5.20 @@ -377,8 +376,8 @@ destroy_command_handler(struct open_conn
    5.21  
    5.22  	r = xc_domain_destroy(xc_handle, domid);
    5.23  	if (r < 0) {
    5.24 -		send_message(oc, "E19 error destroying domain %d: %s\n",
    5.25 -			     domid, sys_errlist[errno]);
    5.26 +		send_message( oc, "E19 error destroying domain %d: %s\n",
    5.27 +			      domid, strerror(errno) );
    5.28  		return;
    5.29  	}
    5.30  	d->state = DOM_STATE_DEAD;
     6.1 --- a/tools/x2d2/domain_controller.h	Thu Nov 18 17:43:29 2004 +0000
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,562 +0,0 @@
     6.4 -/******************************************************************************
     6.5 - * domain_controller.h
     6.6 - * 
     6.7 - * Interface to server controller (e.g., 'xend'). This header file defines the 
     6.8 - * interface that is shared with guest OSes.
     6.9 - * 
    6.10 - * Copyright (c) 2004, K A Fraser
    6.11 - */
    6.12 -
    6.13 -/* I've copied this from the xen source pool as getting Xen and
    6.14 -   userspace headers to play nicely together is beyond me -- sos22 */
    6.15 -#define PACKED __attribute__ ((packed))
    6.16 -typedef unsigned long memory_t;   /* Full-sized pointer/address/memory-size. */
    6.17 -#define __MEMORY_PADDING(_X) u32 __pad_ ## _X
    6.18 -#define _MEMORY_PADDING(_X)  __MEMORY_PADDING(_X)
    6.19 -#define MEMORY_PADDING       _MEMORY_PADDING(__LINE__)
    6.20 -typedef u16 domid_t;
    6.21 -
    6.22 -/*
    6.23 - * Reason codes for SCHEDOP_shutdown. These are opaque to Xen but may be
    6.24 - * interpreted by control software to determine the appropriate action. These 
    6.25 - * are only really advisories: the controller can actually do as it likes.
    6.26 - */
    6.27 -#define SHUTDOWN_poweroff   0  /* Domain exited normally. Clean up and kill. */
    6.28 -#define SHUTDOWN_reboot     1  /* Clean up, kill, and then restart.          */
    6.29 -#define SHUTDOWN_suspend    2  /* Clean up, save suspend info, kill.         */
    6.30 -
    6.31 -
    6.32 -/*
    6.33 - * CONTROLLER MESSAGING INTERFACE.
    6.34 - */
    6.35 -
    6.36 -typedef struct {
    6.37 -    u8 type;     /*  0: echoed in response */
    6.38 -    u8 subtype;  /*  1: echoed in response */
    6.39 -    u8 id;       /*  2: echoed in response */
    6.40 -    u8 length;   /*  3: number of bytes in 'msg' */
    6.41 -    u8 msg[60];  /*  4: type-specific message data */
    6.42 -} PACKED control_msg_t; /* 64 bytes */
    6.43 -
    6.44 -#define CONTROL_RING_SIZE 8
    6.45 -typedef u32 CONTROL_RING_IDX;
    6.46 -#define MASK_CONTROL_IDX(_i) ((_i)&(CONTROL_RING_SIZE-1))
    6.47 -
    6.48 -typedef struct {
    6.49 -    control_msg_t tx_ring[CONTROL_RING_SIZE];   /*    0: guest -> controller */
    6.50 -    control_msg_t rx_ring[CONTROL_RING_SIZE];   /*  512: controller -> guest */
    6.51 -    CONTROL_RING_IDX tx_req_prod, tx_resp_prod; /* 1024, 1028 */
    6.52 -    CONTROL_RING_IDX rx_req_prod, rx_resp_prod; /* 1032, 1036 */
    6.53 -} PACKED control_if_t; /* 1040 bytes */
    6.54 -
    6.55 -/*
    6.56 - * Top-level command types.
    6.57 - */
    6.58 -#define CMSG_CONSOLE        0  /* Console                 */
    6.59 -#define CMSG_BLKIF_BE       1  /* Block-device backend    */
    6.60 -#define CMSG_BLKIF_FE       2  /* Block-device frontend   */
    6.61 -#define CMSG_NETIF_BE       3  /* Network-device backend  */
    6.62 -#define CMSG_NETIF_FE       4  /* Network-device frontend */
    6.63 -#define CMSG_SHUTDOWN       6  /* Shutdown messages       */
    6.64 -#define CMSG_PDB_BE         7  /* PDB backend.            */
    6.65 -#define CMSG_PDB_FE         8  /* PDB frontend.           */
    6.66 -
    6.67 -/******************************************************************************
    6.68 - * CONSOLE DEFINITIONS
    6.69 - */
    6.70 -
    6.71 -/*
    6.72 - * Subtypes for console messages.
    6.73 - */
    6.74 -#define CMSG_CONSOLE_DATA       0
    6.75 -
    6.76 -
    6.77 -/******************************************************************************
    6.78 - * BLOCK-INTERFACE FRONTEND DEFINITIONS
    6.79 - */
    6.80 -
    6.81 -/* Messages from domain controller to guest. */
    6.82 -#define CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED   0
    6.83 -
    6.84 -/* Messages from guest to domain controller. */
    6.85 -#define CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED     32
    6.86 -#define CMSG_BLKIF_FE_INTERFACE_CONNECT         33
    6.87 -#define CMSG_BLKIF_FE_INTERFACE_DISCONNECT      34
    6.88 -
    6.89 -/* These are used by both front-end and back-end drivers. */
    6.90 -#define blkif_vdev_t   u16
    6.91 -#define blkif_pdev_t   u16
    6.92 -#define blkif_sector_t u64
    6.93 -
    6.94 -/*
    6.95 - * CMSG_BLKIF_FE_INTERFACE_STATUS_CHANGED:
    6.96 - *  Notify a guest about a status change on one of its block interfaces.
    6.97 - *  If the interface is DESTROYED or DOWN then the interface is disconnected:
    6.98 - *   1. The shared-memory frame is available for reuse.
    6.99 - *   2. Any unacknowledged messgaes pending on the interface were dropped.
   6.100 - */
   6.101 -#define BLKIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
   6.102 -#define BLKIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
   6.103 -#define BLKIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
   6.104 -typedef struct {
   6.105 -    u32 handle; /*  0 */
   6.106 -    u32 status; /*  4 */
   6.107 -    u16 evtchn; /*  8: (only if status == BLKIF_INTERFACE_STATUS_CONNECTED). */
   6.108 -} PACKED blkif_fe_interface_status_changed_t; /* 10 bytes */
   6.109 -
   6.110 -/*
   6.111 - * CMSG_BLKIF_FE_DRIVER_STATUS_CHANGED:
   6.112 - *  Notify the domain controller that the front-end driver is DOWN or UP.
   6.113 - *  When the driver goes DOWN then the controller will send no more
   6.114 - *  status-change notifications. When the driver comes UP then the controller
   6.115 - *  will send a notification for each interface that currently exists.
   6.116 - *  If the driver goes DOWN while interfaces are still UP, the domain
   6.117 - *  will automatically take the interfaces DOWN.
   6.118 - */
   6.119 -#define BLKIF_DRIVER_STATUS_DOWN   0
   6.120 -#define BLKIF_DRIVER_STATUS_UP     1
   6.121 -typedef struct {
   6.122 -    /* IN */
   6.123 -    u32 status;        /*  0: BLKIF_DRIVER_STATUS_??? */
   6.124 -    /* OUT */
   6.125 -    /*
   6.126 -     * Tells driver how many interfaces it should expect to immediately
   6.127 -     * receive notifications about.
   6.128 -     */
   6.129 -    u32 nr_interfaces; /*  4 */
   6.130 -} PACKED blkif_fe_driver_status_changed_t; /* 8 bytes */
   6.131 -
   6.132 -/*
   6.133 - * CMSG_BLKIF_FE_INTERFACE_CONNECT:
   6.134 - *  If successful, the domain controller will acknowledge with a
   6.135 - *  STATUS_CONNECTED message.
   6.136 - */
   6.137 -typedef struct {
   6.138 -    u32      handle;      /*  0 */
   6.139 -    u32      __pad;
   6.140 -    memory_t shmem_frame; /*  8 */
   6.141 -    MEMORY_PADDING;
   6.142 -} PACKED blkif_fe_interface_connect_t; /* 16 bytes */
   6.143 -
   6.144 -/*
   6.145 - * CMSG_BLKIF_FE_INTERFACE_DISCONNECT:
   6.146 - *  If successful, the domain controller will acknowledge with a
   6.147 - *  STATUS_DISCONNECTED message.
   6.148 - */
   6.149 -typedef struct {
   6.150 -    u32 handle; /*  0 */
   6.151 -} PACKED blkif_fe_interface_disconnect_t; /* 4 bytes */
   6.152 -
   6.153 -
   6.154 -/******************************************************************************
   6.155 - * BLOCK-INTERFACE BACKEND DEFINITIONS
   6.156 - */
   6.157 -
   6.158 -/* Messages from domain controller. */
   6.159 -#define CMSG_BLKIF_BE_CREATE      0  /* Create a new block-device interface. */
   6.160 -#define CMSG_BLKIF_BE_DESTROY     1  /* Destroy a block-device interface.    */
   6.161 -#define CMSG_BLKIF_BE_CONNECT     2  /* Connect i/f to remote driver.        */
   6.162 -#define CMSG_BLKIF_BE_DISCONNECT  3  /* Disconnect i/f from remote driver.   */
   6.163 -#define CMSG_BLKIF_BE_VBD_CREATE  4  /* Create a new VBD for an interface.   */
   6.164 -#define CMSG_BLKIF_BE_VBD_DESTROY 5  /* Delete a VBD from an interface.      */
   6.165 -#define CMSG_BLKIF_BE_VBD_GROW    6  /* Append an extent to a given VBD.     */
   6.166 -#define CMSG_BLKIF_BE_VBD_SHRINK  7  /* Remove last extent from a given VBD. */
   6.167 -
   6.168 -/* Messages to domain controller. */
   6.169 -#define CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED 32
   6.170 -
   6.171 -/*
   6.172 - * Message request/response definitions for block-device messages.
   6.173 - */
   6.174 -
   6.175 -typedef struct {
   6.176 -    blkif_sector_t sector_start;   /*  0 */
   6.177 -    blkif_sector_t sector_length;  /*  8 */
   6.178 -    blkif_pdev_t   device;         /* 16 */
   6.179 -    u16            __pad;          /* 18 */
   6.180 -} PACKED blkif_extent_t; /* 20 bytes */
   6.181 -
   6.182 -/* Non-specific 'okay' return. */
   6.183 -#define BLKIF_BE_STATUS_OKAY                0
   6.184 -/* Non-specific 'error' return. */
   6.185 -#define BLKIF_BE_STATUS_ERROR               1
   6.186 -/* The following are specific error returns. */
   6.187 -#define BLKIF_BE_STATUS_INTERFACE_EXISTS    2
   6.188 -#define BLKIF_BE_STATUS_INTERFACE_NOT_FOUND 3
   6.189 -#define BLKIF_BE_STATUS_INTERFACE_CONNECTED 4
   6.190 -#define BLKIF_BE_STATUS_VBD_EXISTS          5
   6.191 -#define BLKIF_BE_STATUS_VBD_NOT_FOUND       6
   6.192 -#define BLKIF_BE_STATUS_OUT_OF_MEMORY       7
   6.193 -#define BLKIF_BE_STATUS_EXTENT_NOT_FOUND    8
   6.194 -#define BLKIF_BE_STATUS_MAPPING_ERROR       9
   6.195 -
   6.196 -/* This macro can be used to create an array of descriptive error strings. */
   6.197 -#define BLKIF_BE_STATUS_ERRORS {    \
   6.198 -    "Okay",                         \
   6.199 -    "Non-specific error",           \
   6.200 -    "Interface already exists",     \
   6.201 -    "Interface not found",          \
   6.202 -    "Interface is still connected", \
   6.203 -    "VBD already exists",           \
   6.204 -    "VBD not found",                \
   6.205 -    "Out of memory",                \
   6.206 -    "Extent not found for VBD",     \
   6.207 -    "Could not map domain memory" }
   6.208 -
   6.209 -/*
   6.210 - * CMSG_BLKIF_BE_CREATE:
   6.211 - *  When the driver sends a successful response then the interface is fully
   6.212 - *  created. The controller will send a DOWN notification to the front-end
   6.213 - *  driver.
   6.214 - */
   6.215 -typedef struct { 
   6.216 -    /* IN */
   6.217 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   6.218 -    u16        __pad;
   6.219 -    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
   6.220 -    /* OUT */
   6.221 -    u32        status;        /*  8 */
   6.222 -} PACKED blkif_be_create_t; /* 12 bytes */
   6.223 -
   6.224 -/*
   6.225 - * CMSG_BLKIF_BE_DESTROY:
   6.226 - *  When the driver sends a successful response then the interface is fully
   6.227 - *  torn down. The controller will send a DESTROYED notification to the
   6.228 - *  front-end driver.
   6.229 - */
   6.230 -typedef struct { 
   6.231 -    /* IN */
   6.232 -    domid_t    domid;         /*  0: Identify interface to be destroyed. */
   6.233 -    u16        __pad;
   6.234 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   6.235 -    /* OUT */
   6.236 -    u32        status;        /*  8 */
   6.237 -} PACKED blkif_be_destroy_t; /* 12 bytes */
   6.238 -
   6.239 -/*
   6.240 - * CMSG_BLKIF_BE_CONNECT:
   6.241 - *  When the driver sends a successful response then the interface is fully
   6.242 - *  connected. The controller will send a CONNECTED notification to the
   6.243 - *  front-end driver.
   6.244 - */
   6.245 -typedef struct { 
   6.246 -    /* IN */
   6.247 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   6.248 -    u16        __pad;
   6.249 -    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
   6.250 -    memory_t   shmem_frame;   /*  8: Page cont. shared comms window.     */
   6.251 -    MEMORY_PADDING;
   6.252 -    u32        evtchn;        /* 16: Event channel for notifications.    */
   6.253 -    /* OUT */
   6.254 -    u32        status;        /* 20 */
   6.255 -} PACKED blkif_be_connect_t;  /* 24 bytes */
   6.256 -
   6.257 -/*
   6.258 - * CMSG_BLKIF_BE_DISCONNECT:
   6.259 - *  When the driver sends a successful response then the interface is fully
   6.260 - *  disconnected. The controller will send a DOWN notification to the front-end
   6.261 - *  driver.
   6.262 - */
   6.263 -typedef struct { 
   6.264 -    /* IN */
   6.265 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   6.266 -    u16        __pad;
   6.267 -    u32        blkif_handle;  /*  4: Domain-specific interface handle.   */
   6.268 -    /* OUT */
   6.269 -    u32        status;        /*  8 */
   6.270 -} PACKED blkif_be_disconnect_t; /* 12 bytes */
   6.271 -
   6.272 -/* CMSG_BLKIF_BE_VBD_CREATE */
   6.273 -typedef struct { 
   6.274 -    /* IN */
   6.275 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   6.276 -    u16        __pad;
   6.277 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   6.278 -    blkif_vdev_t vdevice;     /*  8: Interface-specific id for this VBD. */
   6.279 -    u16        readonly;      /* 10: Non-zero -> VBD isn't writable.     */
   6.280 -    /* OUT */
   6.281 -    u32        status;        /* 12 */
   6.282 -} PACKED blkif_be_vbd_create_t; /* 16 bytes */
   6.283 -
   6.284 -/* CMSG_BLKIF_BE_VBD_DESTROY */
   6.285 -typedef struct {
   6.286 -    /* IN */
   6.287 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   6.288 -    u16        __pad0;        /*  2 */
   6.289 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   6.290 -    blkif_vdev_t vdevice;     /*  8: Interface-specific id of the VBD.   */
   6.291 -    u16        __pad1;        /* 10 */
   6.292 -    /* OUT */
   6.293 -    u32        status;        /* 12 */
   6.294 -} PACKED blkif_be_vbd_destroy_t; /* 16 bytes */
   6.295 -
   6.296 -/* CMSG_BLKIF_BE_VBD_GROW */
   6.297 -typedef struct { 
   6.298 -    /* IN */
   6.299 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   6.300 -    u16        __pad0;        /*  2 */
   6.301 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   6.302 -    blkif_extent_t extent;    /*  8: Physical extent to append to VBD.   */
   6.303 -    blkif_vdev_t vdevice;     /* 28: Interface-specific id of the VBD.   */
   6.304 -    u16        __pad1;        /* 30 */
   6.305 -    /* OUT */
   6.306 -    u32        status;        /* 32 */
   6.307 -} PACKED blkif_be_vbd_grow_t; /* 36 bytes */
   6.308 -
   6.309 -/* CMSG_BLKIF_BE_VBD_SHRINK */
   6.310 -typedef struct { 
   6.311 -    /* IN */
   6.312 -    domid_t    domid;         /*  0: Identify blkdev interface.          */
   6.313 -    u16        __pad0;        /*  2 */
   6.314 -    u32        blkif_handle;  /*  4: ...ditto...                         */
   6.315 -    blkif_vdev_t vdevice;     /*  8: Interface-specific id of the VBD.   */
   6.316 -    u16        __pad1;        /* 10 */
   6.317 -    /* OUT */
   6.318 -    u32        status;        /* 12 */
   6.319 -} PACKED blkif_be_vbd_shrink_t; /* 16 bytes */
   6.320 -
   6.321 -/*
   6.322 - * CMSG_BLKIF_BE_DRIVER_STATUS_CHANGED:
   6.323 - *  Notify the domain controller that the back-end driver is DOWN or UP.
   6.324 - *  If the driver goes DOWN while interfaces are still UP, the controller
   6.325 - *  will automatically send DOWN notifications.
   6.326 - */
   6.327 -typedef struct {
   6.328 -    u32        status;        /*  0: BLKIF_DRIVER_STATUS_??? */
   6.329 -} PACKED blkif_be_driver_status_changed_t; /* 4 bytes */
   6.330 -
   6.331 -
   6.332 -/******************************************************************************
   6.333 - * NETWORK-INTERFACE FRONTEND DEFINITIONS
   6.334 - */
   6.335 -
   6.336 -/* Messages from domain controller to guest. */
   6.337 -#define CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED   0
   6.338 -
   6.339 -/* Messages from guest to domain controller. */
   6.340 -#define CMSG_NETIF_FE_DRIVER_STATUS_CHANGED     32
   6.341 -#define CMSG_NETIF_FE_INTERFACE_CONNECT         33
   6.342 -#define CMSG_NETIF_FE_INTERFACE_DISCONNECT      34
   6.343 -
   6.344 -/*
   6.345 - * CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED:
   6.346 - *  Notify a guest about a status change on one of its network interfaces.
   6.347 - *  If the interface is DESTROYED or DOWN then the interface is disconnected:
   6.348 - *   1. The shared-memory frame is available for reuse.
   6.349 - *   2. Any unacknowledged messgaes pending on the interface were dropped.
   6.350 - */
   6.351 -#define NETIF_INTERFACE_STATUS_DESTROYED    0 /* Interface doesn't exist.    */
   6.352 -#define NETIF_INTERFACE_STATUS_DISCONNECTED 1 /* Exists but is disconnected. */
   6.353 -#define NETIF_INTERFACE_STATUS_CONNECTED    2 /* Exists and is connected.    */
   6.354 -typedef struct {
   6.355 -    u32        handle; /*  0 */
   6.356 -    u32        status; /*  4 */
   6.357 -    u16        evtchn; /*  8: status == NETIF_INTERFACE_STATUS_CONNECTED */
   6.358 -    u8         mac[6]; /* 10: status == NETIF_INTERFACE_STATUS_CONNECTED */
   6.359 -} PACKED netif_fe_interface_status_changed_t; /* 16 bytes */
   6.360 -
   6.361 -/*
   6.362 - * CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
   6.363 - *  Notify the domain controller that the front-end driver is DOWN or UP.
   6.364 - *  When the driver goes DOWN then the controller will send no more
   6.365 - *  status-change notifications. When the driver comes UP then the controller
   6.366 - *  will send a notification for each interface that currently exists.
   6.367 - *  If the driver goes DOWN while interfaces are still UP, the domain
   6.368 - *  will automatically take the interfaces DOWN.
   6.369 - */
   6.370 -#define NETIF_DRIVER_STATUS_DOWN   0
   6.371 -#define NETIF_DRIVER_STATUS_UP     1
   6.372 -typedef struct {
   6.373 -    /* IN */
   6.374 -    u32        status;        /*  0: NETIF_DRIVER_STATUS_??? */
   6.375 -    /* OUT */
   6.376 -    /*
   6.377 -     * Tells driver how many interfaces it should expect to immediately
   6.378 -     * receive notifications about.
   6.379 -     */
   6.380 -    u32        nr_interfaces; /*  4 */
   6.381 -} PACKED netif_fe_driver_status_changed_t; /* 8 bytes */
   6.382 -
   6.383 -/*
   6.384 - * CMSG_NETIF_FE_INTERFACE_CONNECT:
   6.385 - *  If successful, the domain controller will acknowledge with a
   6.386 - *  STATUS_CONNECTED message.
   6.387 - */
   6.388 -typedef struct {
   6.389 -    u32        handle;         /*  0 */
   6.390 -    u32        __pad;          /*  4 */
   6.391 -    memory_t   tx_shmem_frame; /*  8 */
   6.392 -    MEMORY_PADDING;
   6.393 -    memory_t   rx_shmem_frame; /* 16 */
   6.394 -    MEMORY_PADDING;
   6.395 -} PACKED netif_fe_interface_connect_t; /* 24 bytes */
   6.396 -
   6.397 -/*
   6.398 - * CMSG_NETIF_FE_INTERFACE_DISCONNECT:
   6.399 - *  If successful, the domain controller will acknowledge with a
   6.400 - *  STATUS_DISCONNECTED message.
   6.401 - */
   6.402 -typedef struct {
   6.403 -    u32        handle;        /*  0 */
   6.404 -} PACKED netif_fe_interface_disconnect_t; /* 4 bytes */
   6.405 -
   6.406 -
   6.407 -/******************************************************************************
   6.408 - * NETWORK-INTERFACE BACKEND DEFINITIONS
   6.409 - */
   6.410 -
   6.411 -/* Messages from domain controller. */
   6.412 -#define CMSG_NETIF_BE_CREATE      0  /* Create a new net-device interface. */
   6.413 -#define CMSG_NETIF_BE_DESTROY     1  /* Destroy a net-device interface.    */
   6.414 -#define CMSG_NETIF_BE_CONNECT     2  /* Connect i/f to remote driver.        */
   6.415 -#define CMSG_NETIF_BE_DISCONNECT  3  /* Disconnect i/f from remote driver.   */
   6.416 -
   6.417 -/* Messages to domain controller. */
   6.418 -#define CMSG_NETIF_BE_DRIVER_STATUS_CHANGED 32
   6.419 -
   6.420 -/*
   6.421 - * Message request/response definitions for net-device messages.
   6.422 - */
   6.423 -
   6.424 -/* Non-specific 'okay' return. */
   6.425 -#define NETIF_BE_STATUS_OKAY                0
   6.426 -/* Non-specific 'error' return. */
   6.427 -#define NETIF_BE_STATUS_ERROR               1
   6.428 -/* The following are specific error returns. */
   6.429 -#define NETIF_BE_STATUS_INTERFACE_EXISTS    2
   6.430 -#define NETIF_BE_STATUS_INTERFACE_NOT_FOUND 3
   6.431 -#define NETIF_BE_STATUS_INTERFACE_CONNECTED 4
   6.432 -#define NETIF_BE_STATUS_OUT_OF_MEMORY       5
   6.433 -#define NETIF_BE_STATUS_MAPPING_ERROR       6
   6.434 -
   6.435 -/* This macro can be used to create an array of descriptive error strings. */
   6.436 -#define NETIF_BE_STATUS_ERRORS {    \
   6.437 -    "Okay",                         \
   6.438 -    "Non-specific error",           \
   6.439 -    "Interface already exists",     \
   6.440 -    "Interface not found",          \
   6.441 -    "Interface is still connected", \
   6.442 -    "Out of memory",                \
   6.443 -    "Could not map domain memory" }
   6.444 -
   6.445 -/*
   6.446 - * CMSG_NETIF_BE_CREATE:
   6.447 - *  When the driver sends a successful response then the interface is fully
   6.448 - *  created. The controller will send a DOWN notification to the front-end
   6.449 - *  driver.
   6.450 - */
   6.451 -typedef struct { 
   6.452 -    /* IN */
   6.453 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   6.454 -    u16        __pad0;        /*  2 */
   6.455 -    u32        netif_handle;  /*  4: Domain-specific interface handle.   */
   6.456 -    u8         mac[6];        /*  8 */
   6.457 -    u16        __pad1;        /* 14 */
   6.458 -    /* OUT */
   6.459 -    u32        status;        /* 16 */
   6.460 -} PACKED netif_be_create_t; /* 20 bytes */
   6.461 -
   6.462 -/*
   6.463 - * CMSG_NETIF_BE_DESTROY:
   6.464 - *  When the driver sends a successful response then the interface is fully
   6.465 - *  torn down. The controller will send a DESTROYED notification to the
   6.466 - *  front-end driver.
   6.467 - */
   6.468 -typedef struct { 
   6.469 -    /* IN */
   6.470 -    domid_t    domid;         /*  0: Identify interface to be destroyed. */
   6.471 -    u16        __pad;
   6.472 -    u32        netif_handle;  /*  4: ...ditto...                         */
   6.473 -    /* OUT */
   6.474 -    u32   status;             /*  8 */
   6.475 -} PACKED netif_be_destroy_t; /* 12 bytes */
   6.476 -
   6.477 -/*
   6.478 - * CMSG_NETIF_BE_CONNECT:
   6.479 - *  When the driver sends a successful response then the interface is fully
   6.480 - *  connected. The controller will send a CONNECTED notification to the
   6.481 - *  front-end driver.
   6.482 - */
   6.483 -typedef struct { 
   6.484 -    /* IN */
   6.485 -    domid_t    domid;          /*  0: Domain attached to new interface.   */
   6.486 -    u16        __pad0;         /*  2 */
   6.487 -    u32        netif_handle;   /*  4: Domain-specific interface handle.   */
   6.488 -    memory_t   tx_shmem_frame; /*  8: Page cont. tx shared comms window.  */
   6.489 -    MEMORY_PADDING;
   6.490 -    memory_t   rx_shmem_frame; /* 16: Page cont. rx shared comms window.  */
   6.491 -    MEMORY_PADDING;
   6.492 -    u16        evtchn;         /* 24: Event channel for notifications.    */
   6.493 -    u16        __pad1;         /* 26 */
   6.494 -    /* OUT */
   6.495 -    u32        status;         /* 28 */
   6.496 -} PACKED netif_be_connect_t; /* 32 bytes */
   6.497 -
   6.498 -/*
   6.499 - * CMSG_NETIF_BE_DISCONNECT:
   6.500 - *  When the driver sends a successful response then the interface is fully
   6.501 - *  disconnected. The controller will send a DOWN notification to the front-end
   6.502 - *  driver.
   6.503 - */
   6.504 -typedef struct { 
   6.505 -    /* IN */
   6.506 -    domid_t    domid;         /*  0: Domain attached to new interface.   */
   6.507 -    u16        __pad;
   6.508 -    u32        netif_handle;  /*  4: Domain-specific interface handle.   */
   6.509 -    /* OUT */
   6.510 -    u32        status;        /*  8 */
   6.511 -} PACKED netif_be_disconnect_t; /* 12 bytes */
   6.512 -
   6.513 -/*
   6.514 - * CMSG_NETIF_BE_DRIVER_STATUS_CHANGED:
   6.515 - *  Notify the domain controller that the back-end driver is DOWN or UP.
   6.516 - *  If the driver goes DOWN while interfaces are still UP, the domain
   6.517 - *  will automatically send DOWN notifications.
   6.518 - */
   6.519 -typedef struct {
   6.520 -    u32        status;        /*  0: NETIF_DRIVER_STATUS_??? */
   6.521 -} PACKED netif_be_driver_status_changed_t; /* 4 bytes */
   6.522 -
   6.523 -
   6.524 -/******************************************************************************
   6.525 - * SHUTDOWN DEFINITIONS
   6.526 - */
   6.527 -
   6.528 -/*
   6.529 - * Subtypes for shutdown messages.
   6.530 - */
   6.531 -#define CMSG_SHUTDOWN_POWEROFF  0   /* Clean shutdown (SHUTDOWN_poweroff).   */
   6.532 -#define CMSG_SHUTDOWN_REBOOT    1   /* Clean shutdown (SHUTDOWN_reboot).     */
   6.533 -#define CMSG_SHUTDOWN_SUSPEND   2   /* Create suspend info, then             */
   6.534 -                                    /* SHUTDOWN_suspend.                     */
   6.535 -
   6.536 -/******************************************************************************
   6.537 - * PDB DEFINITIONS
   6.538 - */
   6.539 -
   6.540 -/* Notify the backend that a new frontend has connected. */
   6.541 -#define CMSG_PDB_BE_INTERFACE_CONNECTED 0
   6.542 -typedef struct {
   6.543 -    int assist_port;
   6.544 -    int event_port;
   6.545 -} pdb_be_connected_t;
   6.546 -
   6.547 -/* Notify the domain controller that the status of the backend has
   6.548 -   changed. */
   6.549 -#define CMSG_PDB_BE_DRIVER_STATUS_CHANGED 1
   6.550 -typedef struct {
   6.551 -    unsigned status;
   6.552 -#define PDB_DRIVER_STATUS_UP 1
   6.553 -    unsigned long event_page;
   6.554 -    unsigned long assist_page;
   6.555 -} pdb_be_driver_status_changed_t;
   6.556 -
   6.557 -/* Notify a front end that a back end just popped up. */
   6.558 -#define CMSG_PDB_FE_NEW_BE 0
   6.559 -typedef struct {
   6.560 -    int domain;
   6.561 -    int assist_evtchn;
   6.562 -    int event_evtchn;
   6.563 -    unsigned long assist_frame;
   6.564 -    unsigned long event_frame;
   6.565 -} pdb_fe_new_be_t;
     7.1 --- a/tools/x2d2/main.c	Thu Nov 18 17:43:29 2004 +0000
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,1015 +0,0 @@
     7.4 -#define _GNU_SOURCE
     7.5 -
     7.6 -#include <sys/types.h>
     7.7 -#include <sys/fcntl.h>
     7.8 -#include <sys/ioctl.h>
     7.9 -#include <sys/mman.h>
    7.10 -#include <sys/select.h>
    7.11 -#include <sys/socket.h>
    7.12 -#include <sys/wait.h>
    7.13 -#include <asm/page.h>
    7.14 -#include <assert.h>
    7.15 -#include <ctype.h>
    7.16 -#include <err.h>
    7.17 -#include <errno.h>
    7.18 -#include <netinet/in.h>
    7.19 -#include <printf.h>
    7.20 -#include <pthread.h>
    7.21 -#include <stdarg.h>
    7.22 -#include <stddef.h>
    7.23 -#include <stdio.h>
    7.24 -#include <stdlib.h>
    7.25 -#include <string.h>
    7.26 -#include <unistd.h>
    7.27 -
    7.28 -#include "minixend.h"
    7.29 -
    7.30 -#define NETWORK_SCRIPT "/etc/xen/scripts/network"
    7.31 -#define VIFBRIDGE_SCRIPT "/etc/xen/scripts/vif-bridge"
    7.32 -
    7.33 -#define MINIXEND_PORT 5123
    7.34 -
    7.35 -#define mb() asm volatile ("" ::: "memory")
    7.36 -
    7.37 -static void send_control_message(int type, int subtype, int id,
    7.38 -				 int size, void *payload,
    7.39 -				 struct domain *target);
    7.40 -
    7.41 -struct list_head
    7.42 -head_domain = LIST_HEAD(&head_domain);
    7.43 -
    7.44 -static struct list_head
    7.45 -head_connection = LIST_HEAD(&head_connection);
    7.46 -
    7.47 -struct list_head
    7.48 -head_console = LIST_HEAD(&head_console);
    7.49 -
    7.50 -#define foreach_open_connection(d)                                          \
    7.51 -foreach_item(d, &head_connection, struct open_connection, connection_list)
    7.52 -
    7.53 -/* Not modified after initial start up */
    7.54 -static struct domain *
    7.55 -dom0;
    7.56 -unsigned
    7.57 -xc_handle;
    7.58 -static int
    7.59 -listen_fd;
    7.60 -int
    7.61 -evtchn_fd;
    7.62 -
    7.63 -static struct list_head
    7.64 -head_event_receiver = LIST_HEAD(&head_event_receiver);
    7.65 -
    7.66 -struct event_receiver {
    7.67 -	struct list_head list;
    7.68 -	int id;
    7.69 -	pthread_cond_t cond;
    7.70 -};
    7.71 -
    7.72 -/* We're protected by the dom0 mutex in here */
    7.73 -static struct event_receiver *
    7.74 -allocate_event_receiver(struct domain *d)
    7.75 -{
    7.76 -	static int next_message_id;
    7.77 -	struct event_receiver *work;
    7.78 -
    7.79 -	assert(d == dom0);
    7.80 -	work = xmalloc(sizeof(*work));
    7.81 -	work->id = next_message_id++;
    7.82 -	pthread_cond_init(&work->cond, NULL);
    7.83 -
    7.84 -	list_insert_after(&work->list, &head_event_receiver);
    7.85 -
    7.86 -	return work;
    7.87 -}
    7.88 -
    7.89 -static struct event_receiver *
    7.90 -find_event_receiver(int id)
    7.91 -{
    7.92 -	struct event_receiver *work;
    7.93 -	foreach_item(work, &head_event_receiver, struct event_receiver, list)
    7.94 -		if (work->id == id)
    7.95 -			return work;
    7.96 -	return NULL;
    7.97 -}
    7.98 -
    7.99 -static void
   7.100 -release_event_receiver(struct event_receiver *w)
   7.101 -{
   7.102 -	list_remove(&w->list);
   7.103 -	pthread_cond_destroy(&w->cond);
   7.104 -	free(w);
   7.105 -}
   7.106 -
   7.107 -/* Send a message to dom0, and then block awaiting a reply. */
   7.108 -/* Make sure we don't hold any domain mutexs */
   7.109 -static void
   7.110 -send_dom0_message_block(control_msg_t *msg)
   7.111 -{
   7.112 -	CONTROL_RING_IDX c;
   7.113 -	struct event_receiver *er;
   7.114 -	control_msg_t buf;
   7.115 -
   7.116 -	PRINTF(0, "sending message to dom0 and blocking for reply.\n");
   7.117 -	pthread_mutex_lock(&dom0->mux);
   7.118 -	PRINTF(0, "got dom0 lock.\n");
   7.119 -	er = allocate_event_receiver(dom0);
   7.120 -	PRINTF(0, "allocated evetn receiver.\n");
   7.121 -	msg->id = er->id;
   7.122 -	PRINTF(1, "sending message with id %d\n", msg->id);
   7.123 -	send_control_message(msg->type, msg->subtype,
   7.124 -			     msg->id, msg->length, msg->msg, dom0);
   7.125 -	xc_evtchn_send(xc_handle, dom0->control_evtchn);
   7.126 -
   7.127 -	PRINTF(0, "waiting for reply\n");
   7.128 -	pthread_cond_wait(&er->cond, &dom0->mux);
   7.129 -	PRINTF(0, "got reply\n");
   7.130 -
   7.131 -	c = dom0->rx_resp_cons % CONTROL_RING_SIZE;
   7.132 -	memcpy(&buf, &dom0->ctrl_if->rx_ring[c], sizeof(buf));
   7.133 -	assert(msg->id == buf.id);
   7.134 -	assert(msg->type == buf.type);
   7.135 -	assert(msg->subtype == buf.subtype);
   7.136 -	memcpy(msg, &buf, sizeof(*msg));
   7.137 -	dom0->rx_resp_cons++;
   7.138 -
   7.139 -	release_event_receiver(er);
   7.140 -
   7.141 -	pthread_mutex_unlock(&dom0->mux);
   7.142 -
   7.143 -	PRINTF(1, "got reply to message with id %d\n", msg->id);
   7.144 -}
   7.145 -
   7.146 -/* Allocate an interdomain event channel.  event_ports[0] is the
   7.147 -   local event port number, event_ports[1] the remote */
   7.148 -int
   7.149 -allocate_event_channel(struct domain *d, int event_ports[2])
   7.150 -{
   7.151 -	return xc_evtchn_bind_interdomain(xc_handle, DOMID_SELF,
   7.152 -					  d->domid, event_ports,
   7.153 -					  event_ports+1);
   7.154 -}
   7.155 -
   7.156 -static void
   7.157 -accept_new_connection(void)
   7.158 -{
   7.159 -	int fd;
   7.160 -	struct open_connection *oc;
   7.161 -
   7.162 -	fd = accept(listen_fd, NULL, NULL);
   7.163 -	if (fd < 0)
   7.164 -		return;
   7.165 -	oc = xmalloc(sizeof(*oc));
   7.166 -	oc->fd = fd;
   7.167 -	oc->state = OC_STATE_CONNECTED;
   7.168 -	oc->buf_used = 0;
   7.169 -	oc->buf_allocated = 16;
   7.170 -	oc->buf = xmalloc(oc->buf_allocated);
   7.171 -	list_insert_after(&oc->connection_list, &head_connection);
   7.172 -}
   7.173 -
   7.174 -static void
   7.175 -closedown_connection(struct open_connection *oc)
   7.176 -{
   7.177 -	close(oc->fd);
   7.178 -	assert(oc->buf);
   7.179 -	free(oc->buf);
   7.180 -	free(oc);
   7.181 -}
   7.182 -
   7.183 -#if 0
   7.184 -/* Hackl for the benefit of domain replay */
   7.185 -static unsigned
   7.186 -report_work(u32 *ptr, u32 val, unsigned dom, int do_direct)
   7.187 -{
   7.188 -	if (!do_direct) {
   7.189 -		int rc;
   7.190 -		asm("int $0x80" : "=a" (rc)
   7.191 -		    : "0" (264), "b" (ptr), "c" (val), "d" (dom));
   7.192 -		if (rc < 0) {
   7.193 -			errno = -rc;
   7.194 -			rc = -1;
   7.195 -		}
   7.196 -		return rc;
   7.197 -	} else {
   7.198 -		*ptr = val;
   7.199 -		return 0;
   7.200 -	}
   7.201 -}
   7.202 -#else
   7.203 -static unsigned
   7.204 -report_work(u32 *ptr, u32 val, unsigned dom, int do_direct)
   7.205 -{
   7.206 -	*ptr = val;
   7.207 -	return 0;
   7.208 -}
   7.209 -#endif
   7.210 -
   7.211 -static void
   7.212 -send_control_reply(const control_msg_t *msg, struct domain *d)
   7.213 -{
   7.214 -	CONTROL_RING_IDX c;
   7.215 -
   7.216 -	PRINTF(3,"Control reply, type %d:%d, length %d.\n",
   7.217 -	       msg->type, msg->subtype, msg->length);
   7.218 -	c = d->ctrl_if->tx_resp_prod % CONTROL_RING_SIZE;
   7.219 -	memcpy(&d->ctrl_if->tx_ring[c], msg, sizeof(*msg));
   7.220 -	report_work(&d->ctrl_if->tx_resp_prod,
   7.221 -		    d->ctrl_if->tx_resp_prod + 1,
   7.222 -		    d->domid,
   7.223 -		    0);
   7.224 -	PRINTF(4,"tx_resp_prod %ld.\n", d->ctrl_if->tx_resp_prod);
   7.225 -	assert(!d->plugged);
   7.226 -}
   7.227 -
   7.228 -static void
   7.229 -send_trivial_control_reply(const control_msg_t *msg, struct domain *d)
   7.230 -{
   7.231 -	control_msg_t rep;
   7.232 -
   7.233 -	memset(&rep, 0, sizeof(rep));
   7.234 -	rep.type = msg->type;
   7.235 -	rep.subtype = msg->subtype;
   7.236 -	rep.id = msg->id;
   7.237 -	send_control_reply(&rep, d);
   7.238 -}
   7.239 -
   7.240 -static void
   7.241 -process_console_control_message(control_msg_t *m, struct domain *d)
   7.242 -{
   7.243 -	int off;
   7.244 -	int r;
   7.245 -
   7.246 -	if (m->subtype != CMSG_CONSOLE_DATA) {
   7.247 -		warnx("unknown console message subtype %d",
   7.248 -		      m->subtype);
   7.249 -		return;
   7.250 -	}
   7.251 -
   7.252 -	if (m->length > 60) {
   7.253 -		warnx("truncating message from domain %d (was length %d)",
   7.254 -		      d->domid, m->length);
   7.255 -		m->length = 60;
   7.256 -	}
   7.257 -	PRINTF(1, "DOM%d: %.*s\n", d->domid, m->length, m->msg);
   7.258 -	send_trivial_control_reply(m, d);
   7.259 -
   7.260 -	if (d->cc) {
   7.261 -		PRINTF(5, "Have a console connection.\n");
   7.262 -		if (d->cc->state == CC_STATE_CONNECTED) {
   7.263 -			PRINTF(5, "Console is connected, sending directly.\n");
   7.264 -			for (off = 0; off < m->length; off += r) {
   7.265 -				r = write(d->cc->fd, m->msg + off,
   7.266 -					  m->length - off);
   7.267 -				if (r <= 0) {
   7.268 -					d->cc->state = CC_STATE_ERROR;
   7.269 -					break;
   7.270 -				}
   7.271 -			}
   7.272 -		} else {
   7.273 -			PRINTF(5, "Console not connected, buffering.\n");
   7.274 -			if (d->cc->buf_allocated == 0) {
   7.275 -				d->cc->buf_allocated = 60;
   7.276 -				d->cc->buf = xmalloc(d->cc->buf_allocated);
   7.277 -				d->cc->buf_used = 0;
   7.278 -			} else if (d->cc->buf_allocated <
   7.279 -				   d->cc->buf_used + m->length) {
   7.280 -				d->cc->buf_allocated += 60;
   7.281 -				d->cc->buf = xrealloc(d->cc->buf,
   7.282 -						      d->cc->buf_allocated);
   7.283 -			}
   7.284 -			assert(d->cc->buf_allocated >=
   7.285 -			       d->cc->buf_used + m->length);
   7.286 -			memcpy(d->cc->buf + d->cc->buf_used,
   7.287 -			       m->msg,
   7.288 -			       m->length);
   7.289 -			d->cc->buf_used += m->length;
   7.290 -		}
   7.291 -	}
   7.292 -}
   7.293 -
   7.294 -static void
   7.295 -process_blkif_fe_message(control_msg_t *m, struct domain *d)
   7.296 -{
   7.297 -	switch (m->subtype) {
   7.298 -	default:
   7.299 -		warnx("unknown blkif front end message subtype %d",
   7.300 -		      m->subtype);
   7.301 -	}
   7.302 -}
   7.303 -
   7.304 -static void
   7.305 -send_control_message(int type, int subtype, int id,
   7.306 -		     int size, void *payload, struct domain *target)
   7.307 -{
   7.308 -	control_msg_t msg;
   7.309 -	CONTROL_RING_IDX c;
   7.310 -
   7.311 -	msg.type = type;
   7.312 -	msg.subtype = subtype;
   7.313 -	msg.id = id;
   7.314 -	msg.length = size;
   7.315 -	memcpy(msg.msg, payload, size);
   7.316 -
   7.317 -	c = target->ctrl_if->rx_req_prod % CONTROL_RING_SIZE;
   7.318 -	memcpy(&target->ctrl_if->rx_ring[c], &msg, sizeof(msg));
   7.319 -	report_work(&target->ctrl_if->rx_req_prod,
   7.320 -		    target->ctrl_if->rx_req_prod + 1,
   7.321 -		    target->domid,
   7.322 -		    0);
   7.323 -	assert(!target->plugged);
   7.324 -}
   7.325 -
   7.326 -/* Procedure for bringing a new netif front end up:
   7.327 -
   7.328 -   -- Front end sends us NETIF_FE_DRIVER_STATUS_CHANGED
   7.329 -   -- We send back end NETIF_BE_CREATE, wait for a reply
   7.330 -   -- Back end creates a new netif for us, replies
   7.331 -   -- We send front end a NETIF_FE_DRIVER_STATUS_CHANGED message saying
   7.332 -      how many interfaces we've created for it
   7.333 -   -- We send front end a NETIF_FE_INTERFACE_STATUS_CHANGED for each
   7.334 -      netif created
   7.335 -   -- Front end sends us a NETIF_FE_INTERFACE_CONNECT for each netif
   7.336 -*/
   7.337 -static void
   7.338 -handle_netif_fe_driver_status_changed(control_msg_t *m,
   7.339 -				      netif_fe_driver_status_changed_t *sh,
   7.340 -				      struct domain *d)
   7.341 -{
   7.342 -	netif_fe_interface_status_changed_t if_s;
   7.343 -	control_msg_t be_msg;
   7.344 -	netif_be_create_t *be = (void *)be_msg.msg;
   7.345 -	int r;
   7.346 -
   7.347 -	switch (sh->status) {
   7.348 -	case NETIF_DRIVER_STATUS_UP:
   7.349 -		/* Tell the back end about the new interface coming
   7.350 -		 * up. */
   7.351 -		if (d->created_netif_backend) {
   7.352 -			PRINTF(10, "Front end came up twice in dom %d -> reporting no interfaces this time around.\n", d->domid);
   7.353 -			sh->nr_interfaces = 0;
   7.354 -			send_control_reply(m, d);
   7.355 -			send_control_message(CMSG_NETIF_FE,
   7.356 -					     CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
   7.357 -					     1,
   7.358 -					     sizeof(*sh),
   7.359 -					     sh,
   7.360 -					     d);
   7.361 -			return;
   7.362 -		}
   7.363 -		be_msg.type = CMSG_NETIF_BE;
   7.364 -		be_msg.subtype = CMSG_NETIF_BE_CREATE;
   7.365 -		be_msg.id = d->domid;
   7.366 -		be_msg.length = sizeof(*be);
   7.367 -		be->domid = d->domid;
   7.368 -		be->netif_handle = 0;
   7.369 -		memcpy(be->mac, d->netif_mac, 6);
   7.370 -
   7.371 -		PRINTF(2,"Telling back end about new front end.\n");
   7.372 -		pthread_mutex_unlock(&d->mux);
   7.373 -		send_dom0_message_block(&be_msg);
   7.374 -		pthread_mutex_lock(&d->mux);
   7.375 -		PRINTF(3,"Done.\n");
   7.376 -
   7.377 -		if (be->status != NETIF_BE_STATUS_OKAY) {
   7.378 -			/* Uh oh... can't bring back end
   7.379 -			 * up. */
   7.380 -			sh->nr_interfaces = 0;
   7.381 -			send_control_reply(m, d);
   7.382 -			send_control_message(CMSG_NETIF_FE,
   7.383 -					     CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
   7.384 -					     1,
   7.385 -					     sizeof(*sh),
   7.386 -					     sh,
   7.387 -					     d);
   7.388 -			return;
   7.389 -		}
   7.390 -		d->created_netif_backend = 1;
   7.391 -
   7.392 -		r = our_system(VIFBRIDGE_SCRIPT " up domain=%s mac=%.02x:%.02x:%.02x:%.02x:%.02x:%.02x vif=vif%d.0 bridge=xen-br0",
   7.393 -			       d->name,
   7.394 -			       d->netif_mac[0],
   7.395 -			       d->netif_mac[1],
   7.396 -			       d->netif_mac[2],
   7.397 -			       d->netif_mac[3],
   7.398 -			       d->netif_mac[4],
   7.399 -			       d->netif_mac[5],
   7.400 -			       d->domid);
   7.401 -		if (r != 0)
   7.402 -			warn("error %d running " VIFBRIDGE_SCRIPT, r);
   7.403 -
   7.404 -		/* Tell domain how many interfaces it has to deal
   7.405 -		 * with. */
   7.406 -		sh->nr_interfaces = 1;
   7.407 -		send_control_reply(m, d);
   7.408 -		send_control_message(CMSG_NETIF_FE,
   7.409 -				     CMSG_NETIF_FE_DRIVER_STATUS_CHANGED,
   7.410 -				     1,
   7.411 -				     sizeof(*sh),
   7.412 -				     sh,
   7.413 -				     d);
   7.414 -
   7.415 -		PRINTF(2,"Telling front end about its interfaces.\n");
   7.416 -		if_s.handle = 0;
   7.417 -		if_s.status = NETIF_INTERFACE_STATUS_DISCONNECTED;
   7.418 -		send_control_message(CMSG_NETIF_FE,
   7.419 -				     CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED,
   7.420 -				     1,
   7.421 -				     sizeof(if_s),
   7.422 -				     &if_s,
   7.423 -				     d);
   7.424 -		PRINTF(3,"Done.\n");
   7.425 -
   7.426 -		break;
   7.427 -	default:
   7.428 -		warnx("unknown netif status %ld", sh->status);
   7.429 -		break;
   7.430 -	}
   7.431 -}
   7.432 -
   7.433 -static void
   7.434 -handle_netif_fe_interface_connect(control_msg_t *m,
   7.435 -				  netif_fe_interface_connect_t *ic,
   7.436 -				  struct domain *d)
   7.437 -{
   7.438 -	control_msg_t be_msg;
   7.439 -	netif_be_connect_t *bmsg = (void *)be_msg.msg;
   7.440 -	netif_fe_interface_status_changed_t fmsg = {0};
   7.441 -	int evtchn_ports[2];
   7.442 -	int r;
   7.443 -
   7.444 -	PRINTF(4, "front end sent us an interface connect message.\n");
   7.445 -	send_trivial_control_reply(m, d);
   7.446 -
   7.447 -	r = xc_evtchn_bind_interdomain(xc_handle,
   7.448 -				       dom0->domid,
   7.449 -				       d->domid,
   7.450 -				       &evtchn_ports[0],
   7.451 -				       &evtchn_ports[1]);
   7.452 -	if (r < 0)
   7.453 -		err(1, "allocating network event channel");
   7.454 -
   7.455 -	be_msg.type = CMSG_NETIF_BE;
   7.456 -	be_msg.subtype = CMSG_NETIF_BE_CONNECT;
   7.457 -	be_msg.id = 0;
   7.458 -	be_msg.length = sizeof(*bmsg);
   7.459 -	bmsg->domid = d->domid;
   7.460 -	bmsg->netif_handle = ic->handle;
   7.461 -	bmsg->tx_shmem_frame = ic->tx_shmem_frame;
   7.462 -	bmsg->rx_shmem_frame = ic->rx_shmem_frame;
   7.463 -	bmsg->evtchn = evtchn_ports[0];
   7.464 -
   7.465 -	pthread_mutex_unlock(&d->mux);
   7.466 -	send_dom0_message_block(&be_msg);
   7.467 -	pthread_mutex_lock(&d->mux);
   7.468 -
   7.469 -	if (bmsg->status != NETIF_BE_STATUS_OKAY) {
   7.470 -		PRINTF(2, "error connected backend netif: %ld\n",
   7.471 -		       bmsg->status);
   7.472 -		abort(); /* Need to handle this */
   7.473 -	} else {
   7.474 -		PRINTF(3, "connect backend netif\n");
   7.475 -
   7.476 -		/* Tell the domain that we've connected it up. */
   7.477 -		fmsg.handle = ic->handle;
   7.478 -		fmsg.status = NETIF_INTERFACE_STATUS_CONNECTED;
   7.479 -		fmsg.evtchn = evtchn_ports[1];
   7.480 -		memcpy(fmsg.mac, d->netif_mac, 6);
   7.481 -
   7.482 -		send_control_message(CMSG_NETIF_FE,
   7.483 -				     CMSG_NETIF_FE_INTERFACE_STATUS_CHANGED,
   7.484 -				     0,
   7.485 -				     sizeof(fmsg),
   7.486 -				     &fmsg,
   7.487 -				     d);
   7.488 -	}
   7.489 -}
   7.490 -
   7.491 -static void
   7.492 -process_netif_fe_message(control_msg_t *m, struct domain *d)
   7.493 -{
   7.494 -	switch (m->subtype) {
   7.495 -	case CMSG_NETIF_FE_DRIVER_STATUS_CHANGED:
   7.496 -	{
   7.497 -		netif_fe_driver_status_changed_t *sh =
   7.498 -			(netif_fe_driver_status_changed_t *)m->msg;
   7.499 -		handle_netif_fe_driver_status_changed(m, sh, d);
   7.500 -		break;
   7.501 -	}
   7.502 -	case CMSG_NETIF_FE_INTERFACE_CONNECT:
   7.503 -	{
   7.504 -		netif_fe_interface_connect_t *ic =
   7.505 -			(netif_fe_interface_connect_t *)m->msg;
   7.506 -		handle_netif_fe_interface_connect(m, ic, d);
   7.507 -		break;
   7.508 -	}
   7.509 -	default:
   7.510 -		warnx("unknown netif front end message subtype %d",
   7.511 -		      m->subtype);
   7.512 -	}
   7.513 -}
   7.514 -
   7.515 -static void
   7.516 -process_pdb_be_driver_status_changed_message(control_msg_t *msg,
   7.517 -					     pdb_be_driver_status_changed_t*pe,
   7.518 -					     struct domain *d)
   7.519 -{
   7.520 -	pdb_be_connected_t conn;
   7.521 -	pdb_fe_new_be_t new_be;
   7.522 -	int assist_channel[2];
   7.523 -	int event_channel[2];
   7.524 -	int r;
   7.525 -
   7.526 -	switch (pe->status) {
   7.527 -	case PDB_DRIVER_STATUS_UP:
   7.528 -		PRINTF(4, "creating event channel for PDB device\n");
   7.529 -		r = allocate_event_channel(d, assist_channel);
   7.530 -		r |= allocate_event_channel(d, event_channel);
   7.531 -		if (r < 0)
   7.532 -			abort(); /* XXX need to handle this */
   7.533 -
   7.534 -		send_trivial_control_reply(msg, d);
   7.535 -
   7.536 -		PRINTF(4, "informing front end of event channel\n");
   7.537 -		conn.assist_port = assist_channel[1];
   7.538 -		conn.event_port = event_channel[1];
   7.539 -		send_control_message(CMSG_PDB_BE,
   7.540 -				     CMSG_PDB_BE_INTERFACE_CONNECTED,
   7.541 -				     0,
   7.542 -				     sizeof(conn),
   7.543 -				     &conn,
   7.544 -				     d);
   7.545 -
   7.546 -		PRINTF(4, "informing back end of front end\n");
   7.547 -		new_be.domain = d->domid;
   7.548 -		new_be.assist_evtchn = assist_channel[0];
   7.549 -		new_be.event_evtchn = event_channel[0];
   7.550 -		new_be.assist_frame = pe->assist_page;
   7.551 -		new_be.event_frame = pe->event_page;
   7.552 -		send_control_message(CMSG_PDB_FE,
   7.553 -				     CMSG_PDB_FE_NEW_BE,
   7.554 -				     0,
   7.555 -				     sizeof(new_be),
   7.556 -				     &new_be,
   7.557 -				     dom0);
   7.558 -		break;
   7.559 -	default:
   7.560 -		warnx("unknown pdb status %d", pe->status);
   7.561 -	}
   7.562 -}
   7.563 -
   7.564 -static void
   7.565 -process_pdb_be_message(control_msg_t *msg, struct domain *d)
   7.566 -{
   7.567 -	switch (msg->subtype) {
   7.568 -	case CMSG_PDB_BE_DRIVER_STATUS_CHANGED:
   7.569 -	{
   7.570 -		pdb_be_driver_status_changed_t *pe =
   7.571 -			(pdb_be_driver_status_changed_t *)msg->msg;
   7.572 -		process_pdb_be_driver_status_changed_message(msg, pe, d);
   7.573 -		break;
   7.574 -	}
   7.575 -	default:
   7.576 -		warnx("unknown pdb back end message subtype %d",
   7.577 -		      msg->subtype);
   7.578 -	}
   7.579 -}
   7.580 -
   7.581 -static void
   7.582 -process_control_message(control_msg_t *msg, struct domain *d)
   7.583 -{
   7.584 -	control_msg_t m;
   7.585 -
   7.586 -	/* Don't want a malicous domain messing us about, so copy the
   7.587 -	   control mesasge into a local buffer. */
   7.588 -	memcpy(&m, msg, sizeof(m));
   7.589 -	switch (m.type) {
   7.590 -	case CMSG_CONSOLE:
   7.591 -		process_console_control_message(&m, d);
   7.592 -		break;
   7.593 -	case CMSG_BLKIF_FE:
   7.594 -		process_blkif_fe_message(&m, d);
   7.595 -		break;
   7.596 -	case CMSG_NETIF_FE:
   7.597 -		process_netif_fe_message(&m, d);
   7.598 -		break;
   7.599 -	case CMSG_PDB_BE:
   7.600 -		process_pdb_be_message(&m, d);
   7.601 -		break;
   7.602 -	default:
   7.603 -		warnx("unknown control message type %d", m.type);
   7.604 -	}
   7.605 -}
   7.606 -
   7.607 -static void
   7.608 -domain_did_control_event(struct domain *d)
   7.609 -{
   7.610 -	CONTROL_RING_IDX c;
   7.611 -
   7.612 -	/* Pick up and process control ring messages. */
   7.613 -	while (d->tx_req_cons != d->ctrl_if->tx_req_prod) {
   7.614 -		c = d->tx_req_cons % CONTROL_RING_SIZE;
   7.615 -		process_control_message(&d->ctrl_if->tx_ring[c], d);
   7.616 -		d->tx_req_cons++;
   7.617 -		assert(d->tx_req_cons <= d->ctrl_if->tx_req_prod);
   7.618 -		PRINTF(5, "req_cons %ld, req_prod %ld.\n",
   7.619 -		       d->tx_req_cons, d->ctrl_if->tx_req_prod);
   7.620 -	}
   7.621 -
   7.622 -	/* Take any replies off, and discard them. */
   7.623 -	if (d->rx_resp_cons != d->ctrl_if->rx_resp_prod)
   7.624 -		PRINTF(1, "discard %ld events\n",
   7.625 -		       d->ctrl_if->rx_resp_prod -
   7.626 -		       d->rx_resp_cons);
   7.627 -	d->rx_resp_cons = d->ctrl_if->rx_resp_prod;
   7.628 -}
   7.629 -
   7.630 -/* This is the main function for domain control threads */
   7.631 -void *
   7.632 -domain_thread_func(void *D)
   7.633 -{
   7.634 -	struct domain *d = D;
   7.635 -	int r;
   7.636 -	CONTROL_RING_IDX old_resp_prod, old_req_prod;
   7.637 -
   7.638 -	pthread_mutex_lock(&d->mux);
   7.639 -	for (;;) {
   7.640 -		pthread_cond_wait(&d->cond, &d->mux);
   7.641 -
   7.642 -		old_resp_prod = d->ctrl_if->tx_resp_prod;
   7.643 -		old_req_prod = d->ctrl_if->rx_req_prod;
   7.644 -
   7.645 -		domain_did_control_event(d);
   7.646 -		if (d->cc && d->cc->in_buf_used != 0 && d->plugged == 0) {
   7.647 -			r = d->cc->in_buf_used;
   7.648 -			if (r > 60)
   7.649 -				r = 60;
   7.650 -			PRINTF(1, "Sending to domain: %.*s\n",
   7.651 -			       r, d->cc->in_buf);
   7.652 -			send_control_message(CMSG_CONSOLE,
   7.653 -					     CMSG_CONSOLE_DATA,
   7.654 -					     0,
   7.655 -					     r,
   7.656 -					     d->cc->in_buf,
   7.657 -					     d);
   7.658 -			memmove(d->cc->in_buf, d->cc->in_buf + r,
   7.659 -				d->cc->in_buf_used - r);
   7.660 -			d->cc->in_buf_used -= r;
   7.661 -		}
   7.662 -
   7.663 -		if (d->ctrl_if->tx_resp_prod != old_resp_prod ||
   7.664 -		    d->ctrl_if->rx_req_prod != old_req_prod)
   7.665 -			xc_evtchn_send(xc_handle, d->control_evtchn);
   7.666 -	}
   7.667 -}
   7.668 -
   7.669 -/* This is the only thing you can do with a domain structure if you're
   7.670 -   not in the thread which controls that domain.  Domain 0 is
   7.671 -   special. */
   7.672 -void
   7.673 -signal_domain(struct domain *d)
   7.674 -{
   7.675 -	CONTROL_RING_IDX c;
   7.676 -	int id;
   7.677 -	struct event_receiver *evt;
   7.678 -
   7.679 -	pthread_mutex_lock(&d->mux);
   7.680 -	if (d == dom0) {
   7.681 -		/* Take events off of dom0's control ring, and send
   7.682 -		   them to the event receivers. */
   7.683 -		while (d->tx_req_cons != d->ctrl_if->tx_req_prod) {
   7.684 -			c = d->tx_req_cons % CONTROL_RING_SIZE;
   7.685 -			id = d->ctrl_if->tx_ring[c].id;
   7.686 -			evt = find_event_receiver(id);
   7.687 -			if (evt != NULL) {
   7.688 -				PRINTF(1, "delivering event id %d\n", evt->id);
   7.689 -				pthread_cond_broadcast(&evt->cond);
   7.690 -				pthread_mutex_unlock(&d->mux);
   7.691 -				pthread_yield();
   7.692 -				pthread_mutex_lock(&d->mux);
   7.693 -			} else {
   7.694 -				warnx("unexpected message id %d discarded",
   7.695 -				      id);
   7.696 -				d->tx_req_cons++;
   7.697 -			}
   7.698 -		}
   7.699 -		while (d->rx_resp_cons != d->ctrl_if->rx_resp_prod) {
   7.700 -			c = d->rx_resp_cons % CONTROL_RING_SIZE;
   7.701 -			id = d->ctrl_if->rx_ring[c].id;
   7.702 -			evt = find_event_receiver(id);
   7.703 -			if (evt != NULL) {
   7.704 -				PRINTF(1, "delivering event rep id %d\n", evt->id);
   7.705 -				pthread_cond_broadcast(&evt->cond);
   7.706 -				pthread_mutex_unlock(&d->mux);
   7.707 -				pthread_yield();
   7.708 -				pthread_mutex_lock(&d->mux);
   7.709 -			} else {
   7.710 -				warnx("unexpected message reply id %d discarded",
   7.711 -				      id);
   7.712 -				d->rx_resp_cons++;
   7.713 -			}
   7.714 -		}
   7.715 -	} else {
   7.716 -		if (d->plugged) {
   7.717 -			d->event_pending = 1;
   7.718 -		} else {
   7.719 -			pthread_cond_broadcast(&d->cond);
   7.720 -		}
   7.721 -	}
   7.722 -	pthread_mutex_unlock(&d->mux);
   7.723 -}
   7.724 -
   7.725 -static void
   7.726 -handle_evtchn_event(void)
   7.727 -{
   7.728 -	short port;
   7.729 -	struct domain *d;
   7.730 -
   7.731 -	read(evtchn_fd, &port, sizeof(short));
   7.732 -	write(evtchn_fd, &port, sizeof(short));
   7.733 -	foreach_domain (d) {
   7.734 -		if (d->control_evtchn == port) {
   7.735 -			signal_domain(d);
   7.736 -			return;
   7.737 -		}
   7.738 -	}
   7.739 -	warnx("got an event on an unknown port %d", port);
   7.740 -}
   7.741 -
   7.742 -void *
   7.743 -map_domain_mem(struct domain *d, unsigned long mfn)
   7.744 -{
   7.745 -	return xc_map_foreign_range(xc_handle, d->domid,
   7.746 -				    PAGE_SIZE, PROT_READ | PROT_WRITE,
   7.747 -				    mfn);
   7.748 -}
   7.749 -
   7.750 -static void
   7.751 -handle_console_event(struct console_connection *cc)
   7.752 -{
   7.753 -	int r;
   7.754 -	int fd;
   7.755 -
   7.756 -	switch (cc->state) {
   7.757 -	case CC_STATE_ERROR:
   7.758 -		/* Errors shouldn't get here. */
   7.759 -		abort();
   7.760 -	case CC_STATE_PENDING:
   7.761 -		fd = accept(cc->fd, NULL, NULL);
   7.762 -		if (fd >= 0) {
   7.763 -			PRINTF(3, "Accepted console connection for domain %d",
   7.764 -			       cc->dom->domid);
   7.765 -			close(cc->fd);
   7.766 -			cc->fd = fd;
   7.767 -			cc->state = CC_STATE_CONNECTED;
   7.768 -			while (cc->buf_used != 0) {
   7.769 -				r = write(cc->fd,
   7.770 -					  cc->buf,
   7.771 -					  cc->buf_used);
   7.772 -				if (r <= 0) {
   7.773 -					cc->state = CC_STATE_ERROR;
   7.774 -					break;
   7.775 -				}
   7.776 -				memmove(cc->buf,
   7.777 -					cc->buf + r,
   7.778 -					cc->buf_used - r);
   7.779 -				cc->buf_used -= r;
   7.780 -			}
   7.781 -			free(cc->buf);
   7.782 -			cc->buf = NULL;
   7.783 -			cc->buf_allocated = 0;
   7.784 -		} else {
   7.785 -			PRINTF(1, "error %s accepting console", strerror(errno));
   7.786 -		}
   7.787 -		pthread_mutex_unlock(&cc->dom->mux);
   7.788 -		break;
   7.789 -	case CC_STATE_CONNECTED:
   7.790 -		if (cc->in_buf_allocated == 0) {
   7.791 -			assert(cc->in_buf_used == 0);
   7.792 -			cc->in_buf_allocated = 128;
   7.793 -			cc->in_buf = xmalloc(cc->in_buf_allocated);
   7.794 -		}
   7.795 -		if (cc->in_buf_used == cc->in_buf_allocated) {
   7.796 -			cc->in_buf_allocated *= 2;
   7.797 -			cc->in_buf = xrealloc(cc->in_buf, cc->in_buf_allocated);
   7.798 -		}
   7.799 -		r = read(cc->fd, cc->in_buf + cc->in_buf_used,
   7.800 -			 cc->in_buf_allocated - cc->in_buf_used);
   7.801 -		if (r <= 0) {
   7.802 -			cc->state = CC_STATE_ERROR;
   7.803 -		} else {
   7.804 -			cc->in_buf_used += r;
   7.805 -		}
   7.806 -		pthread_mutex_unlock(&cc->dom->mux);
   7.807 -		signal_domain(cc->dom);
   7.808 -		break;
   7.809 -	}
   7.810 -}
   7.811 -
   7.812 -static void
   7.813 -handle_connection_event(struct open_connection *oc)
   7.814 -{
   7.815 -	int r;
   7.816 -
   7.817 -	/* We know that some amount of data is ready and waiting for
   7.818 -	   us.  Slurp it in. */
   7.819 -	if (oc->buf_used == oc->buf_allocated) {
   7.820 -		oc->buf_allocated *= 2;
   7.821 -		oc->buf = xrealloc(oc->buf, oc->buf_allocated);
   7.822 -	}
   7.823 -	r = read(oc->fd, oc->buf + oc->buf_used,
   7.824 -		 oc->buf_allocated - oc->buf_used);
   7.825 -	if (r < 0) {
   7.826 -		warn("reading command from remote");
   7.827 -		oc->state = OC_STATE_ERROR;
   7.828 -	} else if (r == 0) {
   7.829 -		warnx("reading command from remote");
   7.830 -		oc->state = OC_STATE_ERROR;
   7.831 -	} else {
   7.832 -		oc->buf_used += r;
   7.833 -		if (strchr(oc->buf, '\n'))
   7.834 -			oc->state = OC_STATE_COMMAND_PENDING;
   7.835 -	}
   7.836 -}
   7.837 -
   7.838 -static void
   7.839 -get_and_process_event(void)
   7.840 -{
   7.841 -	fd_set read_fds, except_fds;
   7.842 -	struct open_connection *oc;
   7.843 -	struct console_connection *cc;
   7.844 -	int max_fd = listen_fd;
   7.845 -	int r;
   7.846 -	struct list_head *li, *temp_li;
   7.847 -
   7.848 -	FD_ZERO(&read_fds);
   7.849 -	FD_ZERO(&except_fds);
   7.850 -	FD_SET(listen_fd, &read_fds);
   7.851 -	FD_SET(evtchn_fd, &read_fds);
   7.852 -	if (evtchn_fd > max_fd)
   7.853 -		max_fd = evtchn_fd;
   7.854 -	foreach_open_connection(oc) {
   7.855 -		FD_SET(oc->fd, &read_fds);
   7.856 -		FD_SET(oc->fd, &except_fds);
   7.857 -		if (oc->fd > max_fd)
   7.858 -			max_fd = oc->fd;
   7.859 -	}
   7.860 -	foreach_console_connection(cc) {
   7.861 -		FD_SET(cc->fd, &read_fds);
   7.862 -		FD_SET(cc->fd, &except_fds);
   7.863 -		if (cc->fd > max_fd)
   7.864 -			max_fd = cc->fd;
   7.865 -	}
   7.866 -
   7.867 -	r = select(max_fd + 1, &read_fds, NULL, &except_fds, NULL);
   7.868 -	if (r < 0)
   7.869 -		err(1, "select");
   7.870 -	if (FD_ISSET(listen_fd, &read_fds)) {
   7.871 -		accept_new_connection();
   7.872 -	} else if (FD_ISSET(evtchn_fd, &read_fds))
   7.873 -		handle_evtchn_event();
   7.874 -
   7.875 -
   7.876 -	foreach_open_connection(oc) {
   7.877 -		if (FD_ISSET(oc->fd, &read_fds))
   7.878 -			handle_connection_event(oc);
   7.879 -		if (FD_ISSET(oc->fd, &except_fds))
   7.880 -			oc->state = OC_STATE_ERROR;
   7.881 -	}
   7.882 -	list_foreach_safe(&head_console, li, temp_li) {
   7.883 -		cc = list_item(li, struct console_connection, list);
   7.884 -		if (FD_ISSET(cc->fd, &read_fds))
   7.885 -			handle_console_event(cc);
   7.886 -		if (FD_ISSET(cc->fd, &except_fds) ||
   7.887 -		    cc->state == CC_STATE_ERROR) {
   7.888 -			PRINTF(1, "Cleaning up console connection");
   7.889 -			cc->dom->cc = NULL;
   7.890 -			list_remove(&cc->list);
   7.891 -			close(cc->fd);
   7.892 -			if (cc->buf_allocated != 0)
   7.893 -				free(cc->buf);
   7.894 -			if (cc->in_buf_allocated != 0)
   7.895 -				free(cc->in_buf);
   7.896 -			free(cc);
   7.897 -		}
   7.898 -	}
   7.899 -
   7.900 -	/* Run pending stuff on the open connections. */
   7.901 -	list_foreach_safe(&head_connection, li, temp_li) {
   7.902 -		oc = list_item(li, struct open_connection, connection_list);
   7.903 -		switch (oc->state) {
   7.904 -		case OC_STATE_ERROR:
   7.905 -			list_remove(&oc->connection_list);
   7.906 -			closedown_connection(oc);
   7.907 -			break;
   7.908 -		case OC_STATE_COMMAND_PENDING:
   7.909 -			process_command(oc);
   7.910 -			break;
   7.911 -		case OC_STATE_CONNECTED:
   7.912 -			/* Don't need to do anything */
   7.913 -			break;
   7.914 -		}
   7.915 -	}
   7.916 -}
   7.917 -
   7.918 -static int
   7.919 -start_listening(void)
   7.920 -{
   7.921 -	int sock;
   7.922 -	struct sockaddr_in inaddr;
   7.923 -
   7.924 -	sock = socket(PF_INET, SOCK_STREAM, 0);
   7.925 -	if (sock < 0)
   7.926 -		err(1, "creating socket");
   7.927 -	memset(&inaddr, 0, sizeof(inaddr));
   7.928 -	inaddr.sin_family = AF_INET;
   7.929 -	inaddr.sin_port = htons(MINIXEND_PORT);
   7.930 -
   7.931 -	if (bind(sock, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
   7.932 -		err(1, "binding to port %d", MINIXEND_PORT);
   7.933 -	if (listen(sock, 5) < 0)
   7.934 -		err(1, "listening for connections");
   7.935 -
   7.936 -	return sock;
   7.937 -}
   7.938 -
   7.939 -static struct domain *
   7.940 -find_dom0(void)
   7.941 -{
   7.942 -	int r;
   7.943 -	xc_dominfo_t info;
   7.944 -	struct domain *work;
   7.945 -
   7.946 -	r = xc_domain_getinfo(xc_handle, 0, 1, &info);
   7.947 -	if (r < 0)
   7.948 -		err(1, "getting domain 0 information");
   7.949 -	work = xmalloc(sizeof(*work));
   7.950 -	work->control_evtchn = 2;
   7.951 -	if (ioctl(evtchn_fd, EVTCHN_BIND, 2) < 0)
   7.952 -		err(1, "binding to domain 0 control event channel");
   7.953 -
   7.954 -	work->domid = 0;
   7.955 -	work->name = xstrdup("dom0");
   7.956 -	work->mem_kb = info.max_memkb;
   7.957 -	work->state = DOM_STATE_RUNNING;
   7.958 -	work->shared_info_mfn = info.shared_info_frame;
   7.959 -
   7.960 -	work->shared_info = map_domain_mem(work, info.shared_info_frame);
   7.961 -	work->ctrl_if = (control_if_t *)((unsigned)work->shared_info + 2048);
   7.962 -	work->tx_req_cons = work->ctrl_if->tx_req_prod;
   7.963 -	work->rx_resp_cons = work->ctrl_if->rx_resp_prod;
   7.964 -
   7.965 -	pthread_mutex_init(&work->mux, NULL);
   7.966 -	pthread_cond_init(&work->cond, NULL);
   7.967 -
   7.968 -	list_insert_after(&work->domain_list, &head_domain);
   7.969 -
   7.970 -	return work;
   7.971 -}
   7.972 -
   7.973 -int
   7.974 -main(int argc, char *argv[])
   7.975 -{
   7.976 -	int r;
   7.977 -
   7.978 -	r = our_system(NETWORK_SCRIPT " start antispoof=no");
   7.979 -	if (r < 0)
   7.980 -		err(1, "running " NETWORK_SCRIPT);
   7.981 -	if (!WIFEXITED(r)) {
   7.982 -		if (WIFSIGNALED(r)) {
   7.983 -			errx(1, NETWORK_SCRIPT " killed by signal %d",
   7.984 -			     WTERMSIG(r));
   7.985 -		}
   7.986 -		errx(1, NETWORK_SCRIPT " terminated abnormally");
   7.987 -	}
   7.988 -	if (WEXITSTATUS(r) != 0)
   7.989 -		errx(1, NETWORK_SCRIPT " returned error status %d",
   7.990 -		     WEXITSTATUS(r));
   7.991 -
   7.992 -	xc_handle = xc_interface_open();
   7.993 -
   7.994 -	listen_fd = start_listening();
   7.995 -
   7.996 -	evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
   7.997 -	if (evtchn_fd < 0)
   7.998 -		err(1, "openning /dev/xen/evtchn");
   7.999 -
  7.1000 -	dom0 = find_dom0();
  7.1001 -
  7.1002 -	while (1) {
  7.1003 -		get_and_process_event();
  7.1004 -
  7.1005 -		PRINTF(5, "Dom0 ring state:\n");
  7.1006 -		PRINTF(5, "RX: req_prod %ld, resp_prod %ld, resp_cons %ld\n",
  7.1007 -		       dom0->ctrl_if->rx_req_prod,
  7.1008 -		       dom0->ctrl_if->rx_resp_prod,
  7.1009 -		       dom0->rx_resp_cons);
  7.1010 -		PRINTF(5, "TX: req_prod %ld, resp_prod %ld, req_cons %ld\n",
  7.1011 -		       dom0->ctrl_if->tx_req_prod,
  7.1012 -		       dom0->ctrl_if->tx_resp_prod,
  7.1013 -		       dom0->tx_req_cons);
  7.1014 -	}
  7.1015 -
  7.1016 -	return 0;
  7.1017 -}
  7.1018 -
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/tools/x2d2/minixend.c	Thu Nov 18 17:55:33 2004 +0000
     8.3 @@ -0,0 +1,939 @@
     8.4 +#define _GNU_SOURCE
     8.5 +
     8.6 +#include <sys/types.h>
     8.7 +#include <sys/fcntl.h>
     8.8 +#include <sys/ioctl.h>
     8.9 +#include <sys/mman.h>
    8.10 +#include <sys/select.h>
    8.11 +#include <sys/socket.h>
    8.12 +#include <sys/wait.h>
    8.13 +#include <asm/page.h>
    8.14 +#include <assert.h>
    8.15 +#include <ctype.h>
    8.16 +#include <err.h>
    8.17 +#include <errno.h>
    8.18 +#include <netinet/in.h>
    8.19 +#include <printf.h>
    8.20 +#include <pthread.h>
    8.21 +#include <sched.h>
    8.22 +#include <stdarg.h>
    8.23 +#include <stddef.h>
    8.24 +#include <stdio.h>
    8.25 +#include <stdlib.h>
    8.26 +#include <string.h>
    8.27 +#include <unistd.h>
    8.28 +
    8.29 +#include "minixend.h"
    8.30 +
    8.31 +#define NETWORK_SCRIPT "/etc/xen/scripts/network"
    8.32 +#define VIFBRIDGE_SCRIPT "/etc/xen/scripts/vif-bridge"
    8.33 +
    8.34 +#define MINIXEND_PORT 5123
    8.35 +
    8.36 +#define mb() asm volatile ("" ::: "memory")
    8.37 +
    8.38 +static void send_control_message(int type, int subtype, int id,
    8.39 +				 int size, void *payload,
    8.40 +				 struct domain *target);
    8.41 +
    8.42 +struct list_head
    8.43 +head_domain = LIST_HEAD(&head_domain);
    8.44 +
    8.45 +static struct list_head
    8.46 +head_connection = LIST_HEAD(&head_connection);
    8.47 +
    8.48 +struct list_head
    8.49 +head_console = LIST_HEAD(&head_console);
    8.50 +
    8.51 +#define foreach_open_connection(d)                                          \
    8.52 +foreach_item(d, &head_connection, struct open_connection, connection_list)
    8.53 +
    8.54 +/* Not modified after initial start up */
    8.55 +static struct domain *dom0;
    8.56 +unsigned xc_handle;
    8.57 +static int listen_fd;
    8.58 +int evtchn_fd;
    8.59 +
    8.60 +static struct list_head
    8.61 +head_event_receiver = LIST_HEAD(&head_event_receiver);
    8.62 +
    8.63 +struct event_receiver {
    8.64 +	struct list_head list;
    8.65 +	int id;
    8.66 +	pthread_cond_t cond;
    8.67 +};
    8.68 +
    8.69 +/* We're protected by the dom0 mutex in here */
    8.70 +static struct event_receiver *
    8.71 +allocate_event_receiver(struct domain *d)
    8.72 +{
    8.73 +	static int next_message_id;
    8.74 +	struct event_receiver *work;
    8.75 +
    8.76 +	assert(d == dom0);
    8.77 +	work = xmalloc(sizeof(*work));
    8.78 +	work->id = next_message_id++;
    8.79 +	pthread_cond_init(&work->cond, NULL);
    8.80 +
    8.81 +	list_insert_after(&work->list, &head_event_receiver);
    8.82 +
    8.83 +	return work;
    8.84 +}
    8.85 +
    8.86 +static struct event_receiver *
    8.87 +find_event_receiver(int id)
    8.88 +{
    8.89 +	struct event_receiver *work;
    8.90 +	foreach_item(work, &head_event_receiver, struct event_receiver, list)
    8.91 +		if (work->id == id)
    8.92 +			return work;
    8.93 +	return NULL;
    8.94 +}
    8.95 +
    8.96 +static void
    8.97 +release_event_receiver(struct event_receiver *w)
    8.98 +{
    8.99 +	list_remove(&w->list);
   8.100 +	pthread_cond_destroy(&w->cond);
   8.101 +	free(w);
   8.102 +}
   8.103 +
   8.104 +/* Send a message to dom0, and then block awaiting a reply. */
   8.105 +/* Make sure we don't hold any domain mutexs */
   8.106 +static void
   8.107 +send_dom0_message_block(control_msg_t *msg)
   8.108 +{
   8.109 +	CONTROL_RING_IDX c;
   8.110 +	struct event_receiver *er;
   8.111 +	control_msg_t buf;
   8.112 +
   8.113 +	PRINTF(0, "sending message to dom0 and blocking for reply.\n");
   8.114 +	pthread_mutex_lock(&dom0->mux);
   8.115 +	PRINTF(0, "got dom0 lock.\n");
   8.116 +	er = allocate_event_receiver(dom0);
   8.117 +	PRINTF(0, "allocated evetn receiver.\n");
   8.118 +	msg->id = er->id;
   8.119 +	PRINTF(1, "sending message with id %d\n", msg->id);
   8.120 +	send_control_message(msg->type, msg->subtype,
   8.121 +			     msg->id, msg->length, msg->msg, dom0);
   8.122 +	xc_evtchn_send(xc_handle, dom0->control_evtchn);
   8.123 +
   8.124 +	PRINTF(0, "waiting for reply\n");
   8.125 +	pthread_cond_wait(&er->cond, &dom0->mux);
   8.126 +	PRINTF(0, "got reply\n");
   8.127 +
   8.128 +	c = dom0->rx_resp_cons % CONTROL_RING_SIZE;
   8.129 +	memcpy(&buf, &dom0->ctrl_if->rx_ring[c], sizeof(buf));
   8.130 +	assert(msg->id == buf.id);
   8.131 +	assert(msg->type == buf.type);
   8.132 +	assert(msg->subtype == buf.subtype);
   8.133 +	memcpy(msg, &buf, sizeof(*msg));
   8.134 +	dom0->rx_resp_cons++;
   8.135 +
   8.136 +	release_event_receiver(er);
   8.137 +
   8.138 +	pthread_mutex_unlock(&dom0->mux);
   8.139 +
   8.140 +	PRINTF(1, "got reply to message with id %d\n", msg->id);
   8.141 +}
   8.142 +
   8.143 +/* Allocate an interdomain event channel.  event_ports[0] is the
   8.144 +   local event port number, event_ports[1] the remote */
   8.145 +int
   8.146 +allocate_event_channel(struct domain *d, int event_ports[2])
   8.147 +{
   8.148 +	return xc_evtchn_bind_interdomain(xc_handle, DOMID_SELF,
   8.149 +					  d->domid, event_ports,
   8.150 +					  event_ports+1);
   8.151 +}
   8.152 +
   8.153 +static void
   8.154 +accept_new_connection(void)
   8.155 +{
   8.156 +	int fd;
   8.157 +	struct open_connection *oc;
   8.158 +
   8.159 +	fd = accept(listen_fd, NULL, NULL);
   8.160 +	if (fd < 0)
   8.161 +		return;
   8.162 +	oc = xmalloc(sizeof(*oc));
   8.163 +	oc->fd = fd;
   8.164 +	oc->state = OC_STATE_CONNECTED;
   8.165 +	oc->buf_used = 0;
   8.166 +	oc->buf_allocated = 16;
   8.167 +	oc->buf = xmalloc(oc->buf_allocated);
   8.168 +	list_insert_after(&oc->connection_list, &head_connection);
   8.169 +}
   8.170 +
   8.171 +static void
   8.172 +closedown_connection(struct open_connection *oc)
   8.173 +{
   8.174 +	close(oc->fd);
   8.175 +	assert(oc->buf);
   8.176 +	free(oc->buf);
   8.177 +	free(oc);
   8.178 +}
   8.179 +
   8.180 +#if 0
   8.181 +/* Hackl for the benefit of domain replay */
   8.182 +static unsigned
   8.183 +report_work(u32 *ptr, u32 val, unsigned dom, int do_direct)
   8.184 +{
   8.185 +	if (!do_direct) {
   8.186 +		int rc;
   8.187 +		asm("int $0x80" : "=a" (rc)
   8.188 +		    : "0" (264), "b" (ptr), "c" (val), "d" (dom));
   8.189 +		if (rc < 0) {
   8.190 +			errno = -rc;
   8.191 +			rc = -1;
   8.192 +		}
   8.193 +		return rc;
   8.194 +	} else {
   8.195 +		*ptr = val;
   8.196 +		return 0;
   8.197 +	}
   8.198 +}
   8.199 +#else
   8.200 +static unsigned
   8.201 +report_work(u32 *ptr, u32 val, unsigned dom, int do_direct)
   8.202 +{
   8.203 +	*ptr = val;
   8.204 +	return 0;
   8.205 +}
   8.206 +#endif
   8.207 +
   8.208 +static void
   8.209 +send_control_reply(const control_msg_t *msg, struct domain *d)
   8.210 +{
   8.211 +	CONTROL_RING_IDX c;
   8.212 +
   8.213 +	PRINTF(3,"Control reply, type %d:%d, length %d.\n",
   8.214 +	       msg->type, msg->subtype, msg->length);
   8.215 +	c = d->ctrl_if->tx_resp_prod % CONTROL_RING_SIZE;
   8.216 +	memcpy(&d->ctrl_if->tx_ring[c], msg, sizeof(*msg));
   8.217 +	report_work(&d->ctrl_if->tx_resp_prod,
   8.218 +		    d->ctrl_if->tx_resp_prod + 1,
   8.219 +		    d->domid,
   8.220 +		    0);
   8.221 +	PRINTF(4,"tx_resp_prod %ld.\n", d->ctrl_if->tx_resp_prod);
   8.222 +	assert(!d->plugged);
   8.223 +}
   8.224 +
   8.225 +static void
   8.226 +send_trivial_control_reply(const control_msg_t *msg, struct domain *d)
   8.227 +{
   8.228 +	control_msg_t rep;
   8.229 +
   8.230 +	memset(&rep, 0, sizeof(rep));
   8.231 +	rep.type = msg->type;
   8.232 +	rep.subtype = msg->subtype;
   8.233 +	rep.id = msg->id;
   8.234 +	send_control_reply(&rep, d);
   8.235 +}
   8.236 +
   8.237 +static void
   8.238 +process_console_control_message(control_msg_t *m, struct domain *d)
   8.239 +{
   8.240 +	int off;
   8.241 +	int r;
   8.242 +
   8.243 +	if (m->subtype != CMSG_CONSOLE_DATA) {
   8.244 +		warnx("unknown console message subtype %d",
   8.245 +		      m->subtype);
   8.246 +		return;
   8.247 +	}
   8.248 +
   8.249 +	if (m->length > 60) {
   8.250 +		warnx("truncating message from domain %d (was length %d)",
   8.251 +		      d->domid, m->length);
   8.252 +		m->length = 60;
   8.253 +	}
   8.254 +	PRINTF(1, "DOM%d: %.*s\n", d->domid, m->length, m->msg);
   8.255 +	send_trivial_control_reply(m, d);
   8.256 +
   8.257 +	if (d->cc) {
   8.258 +		PRINTF(5, "Have a console connection.\n");
   8.259 +		if (d->cc->state == CC_STATE_CONNECTED) {
   8.260 +			PRINTF(5, "Console is connected, sending directly.\n");
   8.261 +			for (off = 0; off < m->length; off += r) {
   8.262 +				r = write(d->cc->fd, m->msg + off,
   8.263 +					  m->length - off);
   8.264 +				if (r <= 0) {
   8.265 +					d->cc->state = CC_STATE_ERROR;
   8.266 +					break;
   8.267 +				}
   8.268 +			}
   8.269 +		} else {
   8.270 +			PRINTF(5, "Console not connected, buffering.\n");
   8.271 +			if (d->cc->buf_allocated == 0) {
   8.272 +				d->cc->buf_allocated = 60;
   8.273 +				d->cc->buf = xmalloc(d->cc->buf_allocated);
   8.274 +				d->cc->buf_used = 0;
   8.275 +			} else if (d->cc->buf_allocated <
   8.276 +				   d->cc->buf_used + m->length) {
   8.277 +				d->cc->buf_allocated += 60;
   8.278 +				d->cc->buf = xrealloc(d->cc->buf,
   8.279 +						      d->cc->buf_allocated);
   8.280 +			}
   8.281 +			assert(d->cc->buf_allocated >=
   8.282 +			       d->cc->buf_used + m->length);
   8.283 +			memcpy(d->cc->buf + d->cc->buf_used,
   8.284 +			       m->msg,
   8.285 +			       m->length);
   8.286 +			d->cc->buf_used += m->length;
   8.287 +		}
   8.288 +	}
   8.289 +}
   8.290 +
   8.291 +static void
   8.292 +process_blkif_fe_message(control_msg_t *m, struct domain *d)
   8.293 +{
   8.294 +	switch (m->subtype) {
   8.295 +	default:
   8.296 +		warnx("unknown blkif front end message subtype %d",
   8.297 +		      m->subtype);
   8.298 +	}
   8.299 +}
   8.300 +
   8.301 +static void
   8.302 +send_control_message(int type, int subtype, int id,
   8.303 +		     int size, void *payload, struct domain *target)
   8.304 +{
   8.305 +	control_msg_t msg;
   8.306 +	CONTROL_RING_IDX c;
   8.307 +
   8.308 +	msg.type = type;
   8.309 +	msg.subtype = subtype;
   8.310 +	msg.id = id;
   8.311 +	msg.length = size;
   8.312 +	memcpy(msg.msg, payload, size);
   8.313 +
   8.314 +	c = target->ctrl_if->rx_req_prod % CONTROL_RING_SIZE;
   8.315 +	memcpy(&target->ctrl_if->rx_ring[c], &msg, sizeof(msg));
   8.316 +	report_work(&target->ctrl_if->rx_req_prod,
   8.317 +		    target->ctrl_if->rx_req_prod + 1,
   8.318 +		    target->domid,
   8.319 +		    0);
   8.320 +	assert(!target->plugged);
   8.321 +}
   8.322 +
   8.323 +/* Procedure for bringing a new netif front end up:
   8.324 +
   8.325 +   -- Front end sends us NETIF_FE_DRIVER_STATUS_CHANGED
   8.326 +   -- We send back end NETIF_BE_CREATE, wait for a reply
   8.327 +   -- Back end creates a new netif for us, replies
   8.328 +   -- We send front end a NETIF_FE_DRIVER_STATUS_CHANGED message saying
   8.329 +      how many interfaces we've created for it
   8.330 +   -- We send front end a NETIF_FE_INTERFACE_STATUS_CHANGED for each
   8.331 +      netif created
   8.332 +   -- Front end sends us a NETIF_FE_INTERFACE_CONNECT for each netif
   8.333 +*/
   8.334 +static void
   8.335 +handle_netif_fe_driver_status(control_msg_t *m,
   8.336 +			      netif_fe_driver_status_t *sh,
   8.337 +			      struct domain *d)
   8.338 +{
   8.339 +	netif_fe_interface_status_t if_s;
   8.340 +	control_msg_t be_msg;
   8.341 +	netif_be_create_t *be = (void *)be_msg.msg;
   8.342 +	int r;
   8.343 +
   8.344 +	switch (sh->status) {
   8.345 +	case NETIF_DRIVER_STATUS_UP:
   8.346 +		/* Tell the back end about the new interface coming
   8.347 +		 * up. */
   8.348 +		if (d->created_netif_backend) {
   8.349 +			send_control_reply(m, d);
   8.350 +			send_control_message(CMSG_NETIF_FE,
   8.351 +					     CMSG_NETIF_FE_DRIVER_STATUS,
   8.352 +					     1,
   8.353 +					     sizeof(*sh),
   8.354 +					     sh,
   8.355 +					     d);
   8.356 +			return;
   8.357 +		}
   8.358 +		be_msg.type = CMSG_NETIF_BE;
   8.359 +		be_msg.subtype = CMSG_NETIF_BE_CREATE;
   8.360 +		be_msg.id = d->domid;
   8.361 +		be_msg.length = sizeof(*be);
   8.362 +		be->domid = d->domid;
   8.363 +		be->netif_handle = 0;
   8.364 +		memcpy(be->mac, d->netif_mac, 6);
   8.365 +
   8.366 +		PRINTF(2,"Telling back end about new front end.\n");
   8.367 +		pthread_mutex_unlock(&d->mux);
   8.368 +		send_dom0_message_block(&be_msg);
   8.369 +		pthread_mutex_lock(&d->mux);
   8.370 +		PRINTF(3,"Done.\n");
   8.371 +
   8.372 +		if (be->status != NETIF_BE_STATUS_OKAY) {
   8.373 +			/* Uh oh... can't bring back end
   8.374 +			 * up. */
   8.375 +			send_control_reply(m, d);
   8.376 +			send_control_message(CMSG_NETIF_FE,
   8.377 +					     CMSG_NETIF_FE_DRIVER_STATUS,
   8.378 +					     1,
   8.379 +					     sizeof(*sh),
   8.380 +					     sh,
   8.381 +					     d);
   8.382 +			return;
   8.383 +		}
   8.384 +		d->created_netif_backend = 1;
   8.385 +
   8.386 +		r = our_system(VIFBRIDGE_SCRIPT " up domain=%s mac=%.02x:%.02x:%.02x:%.02x:%.02x:%.02x vif=vif%d.0 bridge=xen-br0",
   8.387 +			       d->name,
   8.388 +			       d->netif_mac[0],
   8.389 +			       d->netif_mac[1],
   8.390 +			       d->netif_mac[2],
   8.391 +			       d->netif_mac[3],
   8.392 +			       d->netif_mac[4],
   8.393 +			       d->netif_mac[5],
   8.394 +			       d->domid);
   8.395 +		if (r != 0)
   8.396 +			warn("error %d running " VIFBRIDGE_SCRIPT, r);
   8.397 +
   8.398 +		/* Tell domain how many interfaces it has to deal
   8.399 +		 * with. */
   8.400 +		send_control_reply(m, d);
   8.401 +		send_control_message(CMSG_NETIF_FE,
   8.402 +				     CMSG_NETIF_FE_DRIVER_STATUS,
   8.403 +				     1,
   8.404 +				     sizeof(*sh),
   8.405 +				     sh,
   8.406 +				     d);
   8.407 +
   8.408 +		PRINTF(2,"Telling front end about its interfaces.\n");
   8.409 +		if_s.handle = 0;
   8.410 +		if_s.status = NETIF_INTERFACE_STATUS_DISCONNECTED;
   8.411 +		send_control_message(CMSG_NETIF_FE,
   8.412 +				     CMSG_NETIF_FE_INTERFACE_STATUS,
   8.413 +				     1,
   8.414 +				     sizeof(if_s),
   8.415 +				     &if_s,
   8.416 +				     d);
   8.417 +		PRINTF(3,"Done.\n");
   8.418 +
   8.419 +		break;
   8.420 +	default:
   8.421 +		warnx("unknown netif status %ld", sh->status);
   8.422 +		break;
   8.423 +	}
   8.424 +}
   8.425 +
   8.426 +static void
   8.427 +handle_netif_fe_interface_connect(control_msg_t *m,
   8.428 +				  netif_fe_interface_connect_t *ic,
   8.429 +				  struct domain *d)
   8.430 +{
   8.431 +	control_msg_t be_msg;
   8.432 +	netif_be_connect_t *bmsg = (void *)be_msg.msg;
   8.433 +	netif_fe_interface_status_t fmsg = {0};
   8.434 +	int evtchn_ports[2];
   8.435 +	int r;
   8.436 +
   8.437 +	PRINTF(4, "front end sent us an interface connect message.\n");
   8.438 +	send_trivial_control_reply(m, d);
   8.439 +
   8.440 +	r = xc_evtchn_bind_interdomain(xc_handle,
   8.441 +				       dom0->domid,
   8.442 +				       d->domid,
   8.443 +				       &evtchn_ports[0],
   8.444 +				       &evtchn_ports[1]);
   8.445 +	if (r < 0)
   8.446 +		err(1, "allocating network event channel");
   8.447 +
   8.448 +	be_msg.type = CMSG_NETIF_BE;
   8.449 +	be_msg.subtype = CMSG_NETIF_BE_CONNECT;
   8.450 +	be_msg.id = 0;
   8.451 +	be_msg.length = sizeof(*bmsg);
   8.452 +	bmsg->domid = d->domid;
   8.453 +	bmsg->netif_handle = ic->handle;
   8.454 +	bmsg->tx_shmem_frame = ic->tx_shmem_frame;
   8.455 +	bmsg->rx_shmem_frame = ic->rx_shmem_frame;
   8.456 +	bmsg->evtchn = evtchn_ports[0];
   8.457 +
   8.458 +	pthread_mutex_unlock(&d->mux);
   8.459 +	send_dom0_message_block(&be_msg);
   8.460 +	pthread_mutex_lock(&d->mux);
   8.461 +
   8.462 +	if (bmsg->status != NETIF_BE_STATUS_OKAY) {
   8.463 +		PRINTF(2, "error connected backend netif: %ld\n",
   8.464 +		       bmsg->status);
   8.465 +		abort(); /* Need to handle this */
   8.466 +	} else {
   8.467 +		PRINTF(3, "connect backend netif\n");
   8.468 +
   8.469 +		/* Tell the domain that we've connected it up. */
   8.470 +		fmsg.handle = ic->handle;
   8.471 +		fmsg.status = NETIF_INTERFACE_STATUS_CONNECTED;
   8.472 +		fmsg.evtchn = evtchn_ports[1];
   8.473 +		memcpy(fmsg.mac, d->netif_mac, 6);
   8.474 +
   8.475 +		send_control_message(CMSG_NETIF_FE,
   8.476 +				     CMSG_NETIF_FE_INTERFACE_STATUS,
   8.477 +				     0,
   8.478 +				     sizeof(fmsg),
   8.479 +				     &fmsg,
   8.480 +				     d);
   8.481 +	}
   8.482 +}
   8.483 +
   8.484 +static void
   8.485 +process_netif_fe_message(control_msg_t *m, struct domain *d)
   8.486 +{
   8.487 +	switch (m->subtype) {
   8.488 +	case CMSG_NETIF_FE_DRIVER_STATUS:
   8.489 +	{
   8.490 +		netif_fe_driver_status_t *sh =
   8.491 +			(netif_fe_driver_status_t *)m->msg;
   8.492 +		handle_netif_fe_driver_status(m, sh, d);
   8.493 +		break;
   8.494 +	}
   8.495 +	case CMSG_NETIF_FE_INTERFACE_CONNECT:
   8.496 +	{
   8.497 +		netif_fe_interface_connect_t *ic =
   8.498 +			(netif_fe_interface_connect_t *)m->msg;
   8.499 +		handle_netif_fe_interface_connect(m, ic, d);
   8.500 +		break;
   8.501 +	}
   8.502 +	default:
   8.503 +		warnx("unknown netif front end message subtype %d",
   8.504 +		      m->subtype);
   8.505 +	}
   8.506 +}
   8.507 +
   8.508 +static void
   8.509 +process_control_message(control_msg_t *msg, struct domain *d)
   8.510 +{
   8.511 +	control_msg_t m;
   8.512 +
   8.513 +	/* Don't want a malicous domain messing us about, so copy the
   8.514 +	   control mesasge into a local buffer. */
   8.515 +	memcpy(&m, msg, sizeof(m));
   8.516 +	switch (m.type) {
   8.517 +	case CMSG_CONSOLE:
   8.518 +		process_console_control_message(&m, d);
   8.519 +		break;
   8.520 +	case CMSG_BLKIF_FE:
   8.521 +		process_blkif_fe_message(&m, d);
   8.522 +		break;
   8.523 +	case CMSG_NETIF_FE:
   8.524 +		process_netif_fe_message(&m, d);
   8.525 +		break;
   8.526 +	default:
   8.527 +		warnx("unknown control message type %d", m.type);
   8.528 +	}
   8.529 +}
   8.530 +
   8.531 +static void
   8.532 +domain_did_control_event(struct domain *d)
   8.533 +{
   8.534 +	CONTROL_RING_IDX c;
   8.535 +
   8.536 +	/* Pick up and process control ring messages. */
   8.537 +	while (d->tx_req_cons != d->ctrl_if->tx_req_prod) {
   8.538 +		c = d->tx_req_cons % CONTROL_RING_SIZE;
   8.539 +		process_control_message(&d->ctrl_if->tx_ring[c], d);
   8.540 +		d->tx_req_cons++;
   8.541 +		assert(d->tx_req_cons <= d->ctrl_if->tx_req_prod);
   8.542 +		PRINTF(5, "req_cons %ld, req_prod %ld.\n",
   8.543 +		       d->tx_req_cons, d->ctrl_if->tx_req_prod);
   8.544 +	}
   8.545 +
   8.546 +	/* Take any replies off, and discard them. */
   8.547 +	if (d->rx_resp_cons != d->ctrl_if->rx_resp_prod)
   8.548 +		PRINTF(1, "discard %ld events\n",
   8.549 +		       d->ctrl_if->rx_resp_prod -
   8.550 +		       d->rx_resp_cons);
   8.551 +	d->rx_resp_cons = d->ctrl_if->rx_resp_prod;
   8.552 +}
   8.553 +
   8.554 +/* This is the main function for domain control threads */
   8.555 +void *
   8.556 +domain_thread_func(void *D)
   8.557 +{
   8.558 +	struct domain *d = D;
   8.559 +	int r;
   8.560 +	CONTROL_RING_IDX old_resp_prod, old_req_prod;
   8.561 +
   8.562 +	pthread_mutex_lock(&d->mux);
   8.563 +	for (;;) {
   8.564 +		pthread_cond_wait(&d->cond, &d->mux);
   8.565 +
   8.566 +		old_resp_prod = d->ctrl_if->tx_resp_prod;
   8.567 +		old_req_prod = d->ctrl_if->rx_req_prod;
   8.568 +
   8.569 +		domain_did_control_event(d);
   8.570 +		if (d->cc && d->cc->in_buf_used != 0 && d->plugged == 0) {
   8.571 +			r = d->cc->in_buf_used;
   8.572 +			if (r > 60)
   8.573 +				r = 60;
   8.574 +			PRINTF(1, "Sending to domain: %.*s\n",
   8.575 +			       r, d->cc->in_buf);
   8.576 +			send_control_message(CMSG_CONSOLE,
   8.577 +					     CMSG_CONSOLE_DATA,
   8.578 +					     0,
   8.579 +					     r,
   8.580 +					     d->cc->in_buf,
   8.581 +					     d);
   8.582 +			memmove(d->cc->in_buf, d->cc->in_buf + r,
   8.583 +				d->cc->in_buf_used - r);
   8.584 +			d->cc->in_buf_used -= r;
   8.585 +		}
   8.586 +
   8.587 +		if (d->ctrl_if->tx_resp_prod != old_resp_prod ||
   8.588 +		    d->ctrl_if->rx_req_prod != old_req_prod)
   8.589 +			xc_evtchn_send(xc_handle, d->control_evtchn);
   8.590 +	}
   8.591 +}
   8.592 +
   8.593 +/* This is the only thing you can do with a domain structure if you're
   8.594 +   not in the thread which controls that domain.  Domain 0 is
   8.595 +   special. */
   8.596 +void
   8.597 +signal_domain(struct domain *d)
   8.598 +{
   8.599 +	CONTROL_RING_IDX c;
   8.600 +	int id;
   8.601 +	struct event_receiver *evt;
   8.602 +
   8.603 +	pthread_mutex_lock(&d->mux);
   8.604 +	if (d == dom0) {
   8.605 +		/* Take events off of dom0's control ring, and send
   8.606 +		   them to the event receivers. */
   8.607 +		while (d->tx_req_cons != d->ctrl_if->tx_req_prod) {
   8.608 +			c = d->tx_req_cons % CONTROL_RING_SIZE;
   8.609 +			id = d->ctrl_if->tx_ring[c].id;
   8.610 +			evt = find_event_receiver(id);
   8.611 +			if (evt != NULL) {
   8.612 +				PRINTF(1, "delivering event id %d\n", evt->id);
   8.613 +				pthread_cond_broadcast(&evt->cond);
   8.614 +				pthread_mutex_unlock(&d->mux);
   8.615 +				sched_yield();
   8.616 +				pthread_mutex_lock(&d->mux);
   8.617 +			} else {
   8.618 +				warnx("unexpected message id %d discarded",
   8.619 +				      id);
   8.620 +				d->tx_req_cons++;
   8.621 +			}
   8.622 +		}
   8.623 +		while (d->rx_resp_cons != d->ctrl_if->rx_resp_prod) {
   8.624 +			c = d->rx_resp_cons % CONTROL_RING_SIZE;
   8.625 +			id = d->ctrl_if->rx_ring[c].id;
   8.626 +			evt = find_event_receiver(id);
   8.627 +			if (evt != NULL) {
   8.628 +				PRINTF(1, "delivering event rep id %d\n", evt->id);
   8.629 +				pthread_cond_broadcast(&evt->cond);
   8.630 +				pthread_mutex_unlock(&d->mux);
   8.631 +				sched_yield();
   8.632 +				pthread_mutex_lock(&d->mux);
   8.633 +			} else {
   8.634 +				warnx("unexpected message reply id %d discarded",
   8.635 +				      id);
   8.636 +				d->rx_resp_cons++;
   8.637 +			}
   8.638 +		}
   8.639 +	} else {
   8.640 +		if (d->plugged) {
   8.641 +			d->event_pending = 1;
   8.642 +		} else {
   8.643 +			pthread_cond_broadcast(&d->cond);
   8.644 +		}
   8.645 +	}
   8.646 +	pthread_mutex_unlock(&d->mux);
   8.647 +}
   8.648 +
   8.649 +static void
   8.650 +handle_evtchn_event(void)
   8.651 +{
   8.652 +	short port;
   8.653 +	struct domain *d;
   8.654 +
   8.655 +	read(evtchn_fd, &port, sizeof(short));
   8.656 +	write(evtchn_fd, &port, sizeof(short));
   8.657 +	foreach_domain (d) {
   8.658 +		if (d->control_evtchn == port) {
   8.659 +			signal_domain(d);
   8.660 +			return;
   8.661 +		}
   8.662 +	}
   8.663 +	warnx("got an event on an unknown port %d", port);
   8.664 +}
   8.665 +
   8.666 +void *
   8.667 +map_domain_mem(struct domain *d, unsigned long mfn)
   8.668 +{
   8.669 +	return xc_map_foreign_range(xc_handle, d->domid,
   8.670 +				    PAGE_SIZE, PROT_READ | PROT_WRITE,
   8.671 +				    mfn);
   8.672 +}
   8.673 +
   8.674 +static void
   8.675 +handle_console_event(struct console_connection *cc)
   8.676 +{
   8.677 +	int r;
   8.678 +	int fd;
   8.679 +
   8.680 +	switch (cc->state) {
   8.681 +	case CC_STATE_ERROR:
   8.682 +		/* Errors shouldn't get here. */
   8.683 +		abort();
   8.684 +	case CC_STATE_PENDING:
   8.685 +		fd = accept(cc->fd, NULL, NULL);
   8.686 +		if (fd >= 0) {
   8.687 +			PRINTF(3, "Accepted console connection for domain %d",
   8.688 +			       cc->dom->domid);
   8.689 +			close(cc->fd);
   8.690 +			cc->fd = fd;
   8.691 +			cc->state = CC_STATE_CONNECTED;
   8.692 +			while (cc->buf_used != 0) {
   8.693 +				r = write(cc->fd,
   8.694 +					  cc->buf,
   8.695 +					  cc->buf_used);
   8.696 +				if (r <= 0) {
   8.697 +					cc->state = CC_STATE_ERROR;
   8.698 +					break;
   8.699 +				}
   8.700 +				memmove(cc->buf,
   8.701 +					cc->buf + r,
   8.702 +					cc->buf_used - r);
   8.703 +				cc->buf_used -= r;
   8.704 +			}
   8.705 +			free(cc->buf);
   8.706 +			cc->buf = NULL;
   8.707 +			cc->buf_allocated = 0;
   8.708 +		} else {
   8.709 +			PRINTF(1, "error %s accepting console", strerror(errno));
   8.710 +		}
   8.711 +		pthread_mutex_unlock(&cc->dom->mux);
   8.712 +		break;
   8.713 +	case CC_STATE_CONNECTED:
   8.714 +		if (cc->in_buf_allocated == 0) {
   8.715 +			assert(cc->in_buf_used == 0);
   8.716 +			cc->in_buf_allocated = 128;
   8.717 +			cc->in_buf = xmalloc(cc->in_buf_allocated);
   8.718 +		}
   8.719 +		if (cc->in_buf_used == cc->in_buf_allocated) {
   8.720 +			cc->in_buf_allocated *= 2;
   8.721 +			cc->in_buf = xrealloc(cc->in_buf, cc->in_buf_allocated);
   8.722 +		}
   8.723 +		r = read(cc->fd, cc->in_buf + cc->in_buf_used,
   8.724 +			 cc->in_buf_allocated - cc->in_buf_used);
   8.725 +		if (r <= 0) {
   8.726 +			cc->state = CC_STATE_ERROR;
   8.727 +		} else {
   8.728 +			cc->in_buf_used += r;
   8.729 +		}
   8.730 +		pthread_mutex_unlock(&cc->dom->mux);
   8.731 +		signal_domain(cc->dom);
   8.732 +		break;
   8.733 +	}
   8.734 +}
   8.735 +
   8.736 +static void
   8.737 +handle_connection_event(struct open_connection *oc)
   8.738 +{
   8.739 +	int r;
   8.740 +
   8.741 +	/* We know that some amount of data is ready and waiting for
   8.742 +	   us.  Slurp it in. */
   8.743 +	if (oc->buf_used == oc->buf_allocated) {
   8.744 +		oc->buf_allocated *= 2;
   8.745 +		oc->buf = xrealloc(oc->buf, oc->buf_allocated);
   8.746 +	}
   8.747 +	r = read(oc->fd, oc->buf + oc->buf_used,
   8.748 +		 oc->buf_allocated - oc->buf_used);
   8.749 +	if (r < 0) {
   8.750 +		warn("reading command from remote");
   8.751 +		oc->state = OC_STATE_ERROR;
   8.752 +	} else if (r == 0) {
   8.753 +		warnx("reading command from remote");
   8.754 +		oc->state = OC_STATE_ERROR;
   8.755 +	} else {
   8.756 +		oc->buf_used += r;
   8.757 +		if (strchr(oc->buf, '\n'))
   8.758 +			oc->state = OC_STATE_COMMAND_PENDING;
   8.759 +	}
   8.760 +}
   8.761 +
   8.762 +static void
   8.763 +get_and_process_event(void)
   8.764 +{
   8.765 +	fd_set read_fds, except_fds;
   8.766 +	struct open_connection *oc;
   8.767 +	struct console_connection *cc;
   8.768 +	int max_fd = listen_fd;
   8.769 +	int r;
   8.770 +	struct list_head *li, *temp_li;
   8.771 +
   8.772 +	FD_ZERO(&read_fds);
   8.773 +	FD_ZERO(&except_fds);
   8.774 +	FD_SET(listen_fd, &read_fds);
   8.775 +	FD_SET(evtchn_fd, &read_fds);
   8.776 +	if (evtchn_fd > max_fd)
   8.777 +		max_fd = evtchn_fd;
   8.778 +	foreach_open_connection(oc) {
   8.779 +		FD_SET(oc->fd, &read_fds);
   8.780 +		FD_SET(oc->fd, &except_fds);
   8.781 +		if (oc->fd > max_fd)
   8.782 +			max_fd = oc->fd;
   8.783 +	}
   8.784 +	foreach_console_connection(cc) {
   8.785 +		FD_SET(cc->fd, &read_fds);
   8.786 +		FD_SET(cc->fd, &except_fds);
   8.787 +		if (cc->fd > max_fd)
   8.788 +			max_fd = cc->fd;
   8.789 +	}
   8.790 +
   8.791 +	r = select(max_fd + 1, &read_fds, NULL, &except_fds, NULL);
   8.792 +	if (r < 0)
   8.793 +		err(1, "select");
   8.794 +	if (FD_ISSET(listen_fd, &read_fds)) {
   8.795 +		accept_new_connection();
   8.796 +	} else if (FD_ISSET(evtchn_fd, &read_fds))
   8.797 +		handle_evtchn_event();
   8.798 +
   8.799 +
   8.800 +	foreach_open_connection(oc) {
   8.801 +		if (FD_ISSET(oc->fd, &read_fds))
   8.802 +			handle_connection_event(oc);
   8.803 +		if (FD_ISSET(oc->fd, &except_fds))
   8.804 +			oc->state = OC_STATE_ERROR;
   8.805 +	}
   8.806 +	list_foreach_safe(&head_console, li, temp_li) {
   8.807 +		cc = list_item(li, struct console_connection, list);
   8.808 +		if (FD_ISSET(cc->fd, &read_fds))
   8.809 +			handle_console_event(cc);
   8.810 +		if (FD_ISSET(cc->fd, &except_fds) ||
   8.811 +		    cc->state == CC_STATE_ERROR) {
   8.812 +			PRINTF(1, "Cleaning up console connection");
   8.813 +			cc->dom->cc = NULL;
   8.814 +			list_remove(&cc->list);
   8.815 +			close(cc->fd);
   8.816 +			if (cc->buf_allocated != 0)
   8.817 +				free(cc->buf);
   8.818 +			if (cc->in_buf_allocated != 0)
   8.819 +				free(cc->in_buf);
   8.820 +			free(cc);
   8.821 +		}
   8.822 +	}
   8.823 +
   8.824 +	/* Run pending stuff on the open connections. */
   8.825 +	list_foreach_safe(&head_connection, li, temp_li) {
   8.826 +		oc = list_item(li, struct open_connection, connection_list);
   8.827 +		switch (oc->state) {
   8.828 +		case OC_STATE_ERROR:
   8.829 +			list_remove(&oc->connection_list);
   8.830 +			closedown_connection(oc);
   8.831 +			break;
   8.832 +		case OC_STATE_COMMAND_PENDING:
   8.833 +			process_command(oc);
   8.834 +			break;
   8.835 +		case OC_STATE_CONNECTED:
   8.836 +			/* Don't need to do anything */
   8.837 +			break;
   8.838 +		}
   8.839 +	}
   8.840 +}
   8.841 +
   8.842 +static int
   8.843 +start_listening(void)
   8.844 +{
   8.845 +	int sock;
   8.846 +	struct sockaddr_in inaddr;
   8.847 +
   8.848 +	sock = socket(PF_INET, SOCK_STREAM, 0);
   8.849 +	if (sock < 0)
   8.850 +		err(1, "creating socket");
   8.851 +	memset(&inaddr, 0, sizeof(inaddr));
   8.852 +	inaddr.sin_family = AF_INET;
   8.853 +	inaddr.sin_port = htons(MINIXEND_PORT);
   8.854 +
   8.855 +	if (bind(sock, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
   8.856 +		err(1, "binding to port %d", MINIXEND_PORT);
   8.857 +	if (listen(sock, 5) < 0)
   8.858 +		err(1, "listening for connections");
   8.859 +
   8.860 +	return sock;
   8.861 +}
   8.862 +
   8.863 +static struct domain *
   8.864 +find_dom0(void)
   8.865 +{
   8.866 +	int r;
   8.867 +	xc_dominfo_t info;
   8.868 +	struct domain *work;
   8.869 +
   8.870 +	r = xc_domain_getinfo(xc_handle, 0, 1, &info);
   8.871 +	if (r < 0)
   8.872 +		err(1, "getting domain 0 information");
   8.873 +	work = xmalloc(sizeof(*work));
   8.874 +	work->control_evtchn = 2;
   8.875 +	if (ioctl(evtchn_fd, EVTCHN_BIND, 2) < 0)
   8.876 +		err(1, "binding to domain 0 control event channel");
   8.877 +
   8.878 +	work->domid = 0;
   8.879 +	work->name = strdup("dom0");
   8.880 +	work->mem_kb = info.max_memkb;
   8.881 +	work->state = DOM_STATE_RUNNING;
   8.882 +	work->shared_info_mfn = info.shared_info_frame;
   8.883 +
   8.884 +	work->shared_info = map_domain_mem(work, info.shared_info_frame);
   8.885 +	work->ctrl_if = (control_if_t *)((unsigned)work->shared_info + 2048);
   8.886 +	work->tx_req_cons = work->ctrl_if->tx_req_prod;
   8.887 +	work->rx_resp_cons = work->ctrl_if->rx_resp_prod;
   8.888 +
   8.889 +	pthread_mutex_init(&work->mux, NULL);
   8.890 +	pthread_cond_init(&work->cond, NULL);
   8.891 +
   8.892 +	list_insert_after(&work->domain_list, &head_domain);
   8.893 +
   8.894 +	return work;
   8.895 +}
   8.896 +
   8.897 +int
   8.898 +main(int argc, char *argv[])
   8.899 +{
   8.900 +	int r;
   8.901 +
   8.902 +	r = our_system(NETWORK_SCRIPT " start antispoof=no");
   8.903 +	if (r < 0)
   8.904 +		err(1, "running " NETWORK_SCRIPT);
   8.905 +	if (!WIFEXITED(r)) {
   8.906 +		if (WIFSIGNALED(r)) {
   8.907 +			errx(1, NETWORK_SCRIPT " killed by signal %d",
   8.908 +			     WTERMSIG(r));
   8.909 +		}
   8.910 +		errx(1, NETWORK_SCRIPT " terminated abnormally");
   8.911 +	}
   8.912 +	if (WEXITSTATUS(r) != 0)
   8.913 +		errx(1, NETWORK_SCRIPT " returned error status %d",
   8.914 +		     WEXITSTATUS(r));
   8.915 +
   8.916 +	xc_handle = xc_interface_open();
   8.917 +
   8.918 +	listen_fd = start_listening();
   8.919 +
   8.920 +	evtchn_fd = open("/dev/xen/evtchn", O_RDWR);
   8.921 +	if (evtchn_fd < 0)
   8.922 +		err(1, "openning /dev/xen/evtchn");
   8.923 +
   8.924 +	dom0 = find_dom0();
   8.925 +
   8.926 +	while (1) {
   8.927 +		get_and_process_event();
   8.928 +
   8.929 +		PRINTF(5, "Dom0 ring state:\n");
   8.930 +		PRINTF(5, "RX: req_prod %ld, resp_prod %ld, resp_cons %ld\n",
   8.931 +		       dom0->ctrl_if->rx_req_prod,
   8.932 +		       dom0->ctrl_if->rx_resp_prod,
   8.933 +		       dom0->rx_resp_cons);
   8.934 +		PRINTF(5, "TX: req_prod %ld, resp_prod %ld, req_cons %ld\n",
   8.935 +		       dom0->ctrl_if->tx_req_prod,
   8.936 +		       dom0->ctrl_if->tx_resp_prod,
   8.937 +		       dom0->tx_req_cons);
   8.938 +	}
   8.939 +
   8.940 +	return 0;
   8.941 +}
   8.942 +
     9.1 --- a/tools/x2d2/minixend.h	Thu Nov 18 17:43:29 2004 +0000
     9.2 +++ b/tools/x2d2/minixend.h	Thu Nov 18 17:55:33 2004 +0000
     9.3 @@ -3,70 +3,6 @@
     9.4  
     9.5  #include <sys/types.h>
     9.6  #include <xc.h>
     9.7 -#include "domain_controller.h"
     9.8 -
     9.9 -/* Yet again, persuading Xen headers to include successfully in a
    9.10 -   userspace process proves to be beyond me.  Sigh. */
    9.11 -#define MAX_VIRT_CPUS 1
    9.12 -
    9.13 -typedef struct {
    9.14 -    u32  tsc_bits;      /* 0: 32 bits read from the CPU's TSC. */
    9.15 -    u32  tsc_bitshift;  /* 4: 'tsc_bits' uses N:N+31 of TSC.   */
    9.16 -} PACKED tsc_timestamp_t; /* 8 bytes */
    9.17 -
    9.18 -typedef struct {
    9.19 -    u64 mfn_to_pfn_start;      /* MFN of start of m2p table */
    9.20 -    u64 pfn_to_mfn_frame_list; /* MFN of a table of MFNs that 
    9.21 -				  make up p2m table */
    9.22 -} PACKED arch_shared_info_t;
    9.23 -
    9.24 -typedef struct
    9.25 -{
    9.26 -    unsigned long ebx;
    9.27 -    unsigned long ecx;
    9.28 -    unsigned long edx;
    9.29 -    unsigned long esi;
    9.30 -    unsigned long edi;
    9.31 -    unsigned long ebp;
    9.32 -    unsigned long eax;
    9.33 -    unsigned long ds;
    9.34 -    unsigned long es;
    9.35 -    unsigned long fs;
    9.36 -    unsigned long gs;
    9.37 -    unsigned long _unused;
    9.38 -    unsigned long eip;
    9.39 -    unsigned long cs;
    9.40 -    unsigned long eflags;
    9.41 -    unsigned long esp;
    9.42 -    unsigned long ss;
    9.43 -} PACKED execution_context_t;
    9.44 -
    9.45 -typedef struct shared_info_st
    9.46 -{
    9.47 -    struct {
    9.48 -        u8 evtchn_upcall_pending;
    9.49 -        u8 evtchn_upcall_mask;
    9.50 -        u8 pad0, pad1;
    9.51 -    } PACKED vcpu_data[MAX_VIRT_CPUS];  /*   0 */
    9.52 -    u32 evtchn_pending[32];             /*   4 */
    9.53 -    u32 evtchn_pending_sel;             /* 132 */
    9.54 -    u32 evtchn_mask[32];                /* 136 */
    9.55 -    u64                cpu_freq;        /* 264: CPU frequency (Hz).          */
    9.56 -    u32                time_version1;   /* 272 */
    9.57 -    u32                time_version2;   /* 276 */
    9.58 -    tsc_timestamp_t    tsc_timestamp;   /* TSC at last update of time vals.  */
    9.59 -    u64                system_time;     /* Time, in nanosecs, since boot.    */
    9.60 -    u32                wc_sec;          /* Secs  00:00:00 UTC, Jan 1, 1970.  */
    9.61 -    u32                wc_usec;         /* Usecs 00:00:00 UTC, Jan 1, 1970.  */
    9.62 -    u64                domain_time;     /* Domain virtual time, in nanosecs. */
    9.63 -    u64                wall_timeout;    /* 312 */
    9.64 -    u64                domain_timeout;  /* 320 */
    9.65 -    execution_context_t execution_context; /* 328 */
    9.66 -    arch_shared_info_t arch;
    9.67 -} PACKED shared_info_t;
    9.68 -
    9.69 -/* End of stuff which belongs in a Xen header */
    9.70 -
    9.71  
    9.72  struct list_head {
    9.73  	struct list_head *next, **pprev;
    10.1 --- a/xen/Makefile	Thu Nov 18 17:43:29 2004 +0000
    10.2 +++ b/xen/Makefile	Thu Nov 18 17:55:33 2004 +0000
    10.3 @@ -2,8 +2,8 @@
    10.4  # This is the correct place to edit the build version.
    10.5  # All other places this is stored (eg. compile.h) should be autogenerated.
    10.6  export XEN_VERSION       = 2
    10.7 -export XEN_SUBVERSION    = 1
    10.8 -export XEN_EXTRAVERSION  = "-devel"
    10.9 +export XEN_SUBVERSION    = 0
   10.10 +export XEN_EXTRAVERSION  = ""
   10.11  
   10.12  export BASEDIR          := $(shell pwd)
   10.13  
   10.14 @@ -34,10 +34,13 @@ clean:
   10.15  	$(MAKE) -C drivers clean
   10.16  	$(MAKE) -C arch/$(TARGET_ARCH) clean
   10.17  	rm -f include/asm *.o $(TARGET)* *~ core include/xen/compile.h
   10.18 +	rm -f include/asm-*/asm-offsets.h
   10.19  
   10.20  $(TARGET): delete-unfresh-files
   10.21  	[ -e include/asm ] || ln -sf asm-$(TARGET_ARCH) include/asm
   10.22  	$(MAKE) include/xen/compile.h
   10.23 +	$(MAKE) -C arch/$(TARGET_ARCH) asm-offsets.s
   10.24 +	$(MAKE) include/asm-$(TARGET_ARCH)/asm-offsets.h
   10.25  	$(MAKE) -C common
   10.26  	$(MAKE) -C drivers
   10.27  	$(MAKE) -C arch/$(TARGET_ARCH)
   10.28 @@ -67,6 +70,22 @@ include/xen/compile.h:
   10.29  	cd ./figlet && make && ./figlet Xen $(XEN_VERSION).$(XEN_SUBVERSION)$(XEN_EXTRAVERSION) 1>>../$@ && cd ..
   10.30  	@LANG=C echo >> $@
   10.31  
   10.32 +include/asm-$(TARGET_ARCH)/asm-offsets.h: arch/$(TARGET_ARCH)/asm-offsets.s
   10.33 +	@(set -e; \
   10.34 +	  echo "/*"; \
   10.35 +	  echo " * DO NOT MODIFY."; \
   10.36 +	  echo " *"; \
   10.37 +	  echo " * This file was auto-generated from $<"; \
   10.38 +	  echo " *"; \
   10.39 +	  echo " */"; \
   10.40 +	  echo ""; \
   10.41 +	  echo "#ifndef __ASM_OFFSETS_H__"; \
   10.42 +	  echo "#define __ASM_OFFSETS_H__"; \
   10.43 +	  echo ""; \
   10.44 +	  sed -ne "/^->/{s:^->\([^ ]*\) [\$$#]*\([^ ]*\) \(.*\):#define \1 \2 /* \3 */:; s:->::; p;}"; \
   10.45 +	  echo ""; \
   10.46 +	  echo "#endif") <$< >$@
   10.47 +
   10.48  .PHONY: default debug install dist clean delete-unfresh-files TAGS
   10.49  
   10.50  SUBDIRS = arch common drivers 
   10.51 @@ -77,4 +96,3 @@ TAGS:
   10.52  	  find $(SUBDIRS) -name '*.[ch]' ) | grep -v /SCCS/ | etags -
   10.53  MAP:
   10.54  	nm $(TARGET) | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map
   10.55 -
    11.1 --- a/xen/arch/x86/Makefile	Thu Nov 18 17:43:29 2004 +0000
    11.2 +++ b/xen/arch/x86/Makefile	Thu Nov 18 17:55:33 2004 +0000
    11.3 @@ -9,16 +9,23 @@ endif
    11.4  OBJS += $(patsubst %.S,%.o,$(wildcard $(TARGET_SUBARCH)/*.S))
    11.5  OBJS += $(patsubst %.c,%.o,$(wildcard $(TARGET_SUBARCH)/*.c))
    11.6  
    11.7 +OBJS := $(subst $(TARGET_SUBARCH)/asm-offsets.o,,$(OBJS))
    11.8 +
    11.9  default: boot/$(TARGET_SUBARCH).o $(OBJS) boot/mkelf32
   11.10  	$(LD) $(LDFLAGS) -r -o arch.o $(OBJS)
   11.11  	$(LD) $(LDFLAGS) -T $(TARGET_SUBARCH)/xen.lds -N \
   11.12  	    boot/$(TARGET_SUBARCH).o $(ALL_OBJS) -o $(TARGET)-syms
   11.13  	./boot/mkelf32 $(TARGET)-syms $(TARGET) 0x100000
   11.14  
   11.15 +asm-offsets.s: $(TARGET_SUBARCH)/asm-offsets.c
   11.16 +	$(CC) $(CFLAGS) -S -o $@ $<
   11.17 +
   11.18  boot/mkelf32: boot/mkelf32.c
   11.19  	$(HOSTCC) $(HOSTCFLAGS) -o $@ $<
   11.20  
   11.21  clean:
   11.22 -	rm -f *.o *~ core boot/*.o boot/*~ boot/core boot/mkelf32
   11.23 +	rm -f *.o *.s *~ core boot/*.o boot/*~ boot/core boot/mkelf32
   11.24  	rm -f x86_32/*.o x86_32/*~ x86_32/core
   11.25  	rm -f x86_64/*.o x86_64/*~ x86_64/core
   11.26 +
   11.27 +.PHONY: default clean
    12.1 --- a/xen/arch/x86/dom0_ops.c	Thu Nov 18 17:43:29 2004 +0000
    12.2 +++ b/xen/arch/x86/dom0_ops.c	Thu Nov 18 17:55:33 2004 +0000
    12.3 @@ -142,12 +142,8 @@ void arch_getdomaininfo_ctxt(struct exec
    12.4      memcpy(c->debugreg, 
    12.5             d->thread.debugreg, 
    12.6             sizeof(d->thread.debugreg));
    12.7 -    c->event_callback_cs  =
    12.8 -        d->event_selector;
    12.9 -    c->event_callback_eip =
   12.10 -        d->event_address;
   12.11 -    c->failsafe_callback_cs  = 
   12.12 -        d->failsafe_selector;
   12.13 -    c->failsafe_callback_eip = 
   12.14 -        d->failsafe_address;
   12.15 +    c->event_callback_cs     = d->thread.event_selector;
   12.16 +    c->event_callback_eip    = d->thread.event_address;
   12.17 +    c->failsafe_callback_cs  = d->thread.failsafe_selector;
   12.18 +    c->failsafe_callback_eip = d->thread.failsafe_address;
   12.19  }
    13.1 --- a/xen/arch/x86/domain.c	Thu Nov 18 17:43:29 2004 +0000
    13.2 +++ b/xen/arch/x86/domain.c	Thu Nov 18 17:55:33 2004 +0000
    13.3 @@ -279,10 +279,10 @@ int arch_final_setup_guestos(struct exec
    13.4      for ( i = 0; i < 8; i++ )
    13.5          (void)set_debugreg(d, i, c->debugreg[i]);
    13.6  
    13.7 -    d->event_selector    = c->event_callback_cs;
    13.8 -    d->event_address     = c->event_callback_eip;
    13.9 -    d->failsafe_selector = c->failsafe_callback_cs;
   13.10 -    d->failsafe_address  = c->failsafe_callback_eip;
   13.11 +    d->thread.event_selector    = c->event_callback_cs;
   13.12 +    d->thread.event_address     = c->event_callback_eip;
   13.13 +    d->thread.failsafe_selector = c->failsafe_callback_cs;
   13.14 +    d->thread.failsafe_address  = c->failsafe_callback_eip;
   13.15      
   13.16      phys_basetab = c->pt_base;
   13.17      d->mm.pagetable = mk_pagetable(phys_basetab);
   13.18 @@ -750,8 +750,8 @@ int construct_dom0(struct domain *p,
   13.19       * We're basically forcing default RPLs to 1, so that our "what privilege
   13.20       * level are we returning to?" logic works.
   13.21       */
   13.22 -    ed->failsafe_selector = FLAT_GUESTOS_CS;
   13.23 -    ed->event_selector    = FLAT_GUESTOS_CS;
   13.24 +    ed->thread.failsafe_selector = FLAT_GUESTOS_CS;
   13.25 +    ed->thread.event_selector    = FLAT_GUESTOS_CS;
   13.26      ed->thread.guestos_ss = FLAT_GUESTOS_DS;
   13.27      for ( i = 0; i < 256; i++ ) 
   13.28          ed->thread.traps[i].cs = FLAT_GUESTOS_CS;
    14.1 --- a/xen/arch/x86/nmi.c	Thu Nov 18 17:43:29 2004 +0000
    14.2 +++ b/xen/arch/x86/nmi.c	Thu Nov 18 17:55:33 2004 +0000
    14.3 @@ -25,12 +25,12 @@
    14.4  #include <asm/smp.h>
    14.5  #include <asm/msr.h>
    14.6  #include <asm/mpspec.h>
    14.7 +#include <asm/debugger.h>
    14.8  
    14.9  unsigned int nmi_watchdog = NMI_NONE;
   14.10  unsigned int watchdog_on = 0;
   14.11  static unsigned int nmi_hz = HZ;
   14.12  unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
   14.13 -extern void show_registers(struct xen_regs *regs);
   14.14  
   14.15  extern int logical_proc_id[];
   14.16  
   14.17 @@ -272,8 +272,6 @@ void touch_nmi_watchdog (void)
   14.18  
   14.19  void nmi_watchdog_tick (struct xen_regs * regs)
   14.20  {
   14.21 -    extern void die(const char * str, struct xen_regs * regs, long err);
   14.22 -
   14.23      int sum, cpu = smp_processor_id();
   14.24  
   14.25      sum = apic_timer_irqs[cpu];
   14.26 @@ -288,7 +286,7 @@ void nmi_watchdog_tick (struct xen_regs 
   14.27          if ( alert_counter[cpu] == 5*nmi_hz )
   14.28          {
   14.29              console_force_unlock();
   14.30 -            die("NMI Watchdog detected LOCKUP on CPU", regs, cpu);
   14.31 +            fatal_trap(TRAP_nmi, regs, 0);
   14.32          }
   14.33      } 
   14.34      else 
    15.1 --- a/xen/arch/x86/pdb-stub.c	Thu Nov 18 17:43:29 2004 +0000
    15.2 +++ b/xen/arch/x86/pdb-stub.c	Thu Nov 18 17:55:33 2004 +0000
    15.3 @@ -1217,8 +1217,8 @@ void pdb_key_pressed(unsigned char key)
    15.4  void pdb_handle_debug_trap(struct xen_regs *regs, long error_code)
    15.5  {
    15.6      unsigned int condition;
    15.7 -    struct domain *tsk = current;
    15.8 -    struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
    15.9 +    struct domain *d = current;
   15.10 +    struct trap_bounce *tb = &d->thread.trap_bounce;
   15.11  
   15.12      __asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
   15.13      if ( (condition & (1 << 14)) != (1 << 14) )
   15.14 @@ -1227,11 +1227,11 @@ void pdb_handle_debug_trap(struct xen_re
   15.15  
   15.16      if ( pdb_handle_exception(1, regs) != 0 )
   15.17      {
   15.18 -        tsk->thread.debugreg[6] = condition;
   15.19 +        d->thread.debugreg[6] = condition;
   15.20  
   15.21 -        gtb->flags = GTBF_TRAP_NOCODE;
   15.22 -        gtb->cs    = tsk->thread.traps[1].cs;
   15.23 -        gtb->eip   = tsk->thread.traps[1].address;
   15.24 +        tb->flags = TBF_TRAP_NOCODE;
   15.25 +        tb->cs    = d->thread.traps[1].cs;
   15.26 +        tb->eip   = d->thread.traps[1].address;
   15.27      }
   15.28  }
   15.29  
    16.1 --- a/xen/arch/x86/traps.c	Thu Nov 18 17:43:29 2004 +0000
    16.2 +++ b/xen/arch/x86/traps.c	Thu Nov 18 17:55:33 2004 +0000
    16.3 @@ -52,10 +52,6 @@
    16.4  #include <asm/i387.h>
    16.5  #include <asm/debugger.h>
    16.6  
    16.7 -extern char opt_nmi[];
    16.8 -
    16.9 -struct guest_trap_bounce guest_trap_bounce[NR_CPUS] = { { 0 } };
   16.10 -
   16.11  #if defined(__i386__)
   16.12  
   16.13  #define DOUBLEFAULT_STACK_SIZE 1024
   16.14 @@ -199,26 +195,45 @@ void show_registers(struct xen_regs *reg
   16.15      show_stack(&regs->esp);
   16.16  } 
   16.17  
   16.18 -
   16.19 -spinlock_t die_lock = SPIN_LOCK_UNLOCKED;
   16.20 -
   16.21 -void die(const char *str, struct xen_regs * regs, long err)
   16.22 +/*
   16.23 + * This is called for faults at very unexpected times (e.g., when interrupts
   16.24 + * are disabled). In such situations we can't do much that is safe. We try to
   16.25 + * print out some tracing and then we just spin.
   16.26 + */
   16.27 +asmlinkage void fatal_trap(int trapnr, struct xen_regs *regs, long error_code)
   16.28  {
   16.29 -    unsigned long flags;
   16.30 -    spin_lock_irqsave(&die_lock, flags);
   16.31 -    printk("%s: %04lx,%04lx\n", str, err >> 16, err & 0xffff);
   16.32 +    int cpu = smp_processor_id();
   16.33 +    static char *trapstr[] = { 
   16.34 +        "divide error", "debug", "nmi", "bkpt", "overflow", "bounds", 
   16.35 +        "invalid operation", "device not available", "double fault", 
   16.36 +        "coprocessor segment", "invalid tss", "segment not found", 
   16.37 +        "stack error", "general protection fault", "page fault", 
   16.38 +        "spurious interrupt", "coprocessor error", "alignment check", 
   16.39 +        "machine check", "simd error"
   16.40 +    };
   16.41 +
   16.42      show_registers(regs);
   16.43 -    spin_unlock_irqrestore(&die_lock, flags);
   16.44 -    panic("Fatal crash within Xen.\n");
   16.45 +    printk("************************************\n");
   16.46 +    printk("CPU%d FATAL TRAP %d (%s), ERROR_CODE %lx%s.\n",
   16.47 +           cpu, trapnr, trapstr[trapnr], error_code,
   16.48 +           (regs->eflags & X86_EFLAGS_IF) ? "" : ", IN INTERRUPT CONTEXT");
   16.49 +    printk("System shutting down -- need manual reset.\n");
   16.50 +    printk("************************************\n");
   16.51 +
   16.52 +    /* Lock up the console to prevent spurious output from other CPUs. */
   16.53 +    console_force_lock();
   16.54 +
   16.55 +    /* Wait for manual reset. */
   16.56 +    for ( ; ; )
   16.57 +        __asm__ __volatile__ ( "hlt" );
   16.58  }
   16.59  
   16.60 -
   16.61  static inline void do_trap(int trapnr, char *str,
   16.62                             struct xen_regs *regs, 
   16.63                             long error_code, int use_error_code)
   16.64  {
   16.65      struct exec_domain *ed = current;
   16.66 -    struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
   16.67 +    struct trap_bounce *tb = &ed->thread.trap_bounce;
   16.68      trap_info_t *ti;
   16.69      unsigned long fixup;
   16.70  
   16.71 @@ -228,10 +243,10 @@ static inline void do_trap(int trapnr, c
   16.72          goto xen_fault;
   16.73  
   16.74      ti = current->thread.traps + trapnr;
   16.75 -    gtb->flags = use_error_code ? GTBF_TRAP : GTBF_TRAP_NOCODE;
   16.76 -    gtb->error_code = error_code;
   16.77 -    gtb->cs         = ti->cs;
   16.78 -    gtb->eip        = ti->address;
   16.79 +    tb->flags = use_error_code ? TBF_TRAP : TBF_TRAP_NOCODE;
   16.80 +    tb->error_code = error_code;
   16.81 +    tb->cs         = ti->cs;
   16.82 +    tb->eip        = ti->address;
   16.83      if ( TI_GET_IF(ti) )
   16.84          ed->vcpu_info->evtchn_upcall_mask = 1;
   16.85      return; 
   16.86 @@ -275,13 +290,12 @@ DO_ERROR(11, "segment not present", segm
   16.87  DO_ERROR(12, "stack segment", stack_segment)
   16.88  DO_ERROR_NOCODE(16, "fpu error", coprocessor_error)
   16.89  DO_ERROR(17, "alignment check", alignment_check)
   16.90 -DO_ERROR_NOCODE(18, "machine check", machine_check)
   16.91  DO_ERROR_NOCODE(19, "simd error", simd_coprocessor_error)
   16.92  
   16.93  asmlinkage void do_int3(struct xen_regs *regs, long error_code)
   16.94  {
   16.95      struct exec_domain *ed = current;
   16.96 -    struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
   16.97 +    struct trap_bounce *tb = &ed->thread.trap_bounce;
   16.98      trap_info_t *ti;
   16.99  
  16.100      DEBUGGER_trap_entry(TRAP_int3, regs, error_code);
  16.101 @@ -296,10 +310,10 @@ asmlinkage void do_int3(struct xen_regs 
  16.102      }
  16.103  
  16.104      ti = current->thread.traps + 3;
  16.105 -    gtb->flags      = GTBF_TRAP_NOCODE;
  16.106 -    gtb->error_code = error_code;
  16.107 -    gtb->cs         = ti->cs;
  16.108 -    gtb->eip        = ti->address;
  16.109 +    tb->flags      = TBF_TRAP_NOCODE;
  16.110 +    tb->error_code = error_code;
  16.111 +    tb->cs         = ti->cs;
  16.112 +    tb->eip        = ti->address;
  16.113      if ( TI_GET_IF(ti) )
  16.114          ed->vcpu_info->evtchn_upcall_mask = 1;
  16.115  }
  16.116 @@ -328,23 +342,27 @@ asmlinkage void do_double_fault(void)
  16.117      printk("System needs manual reset.\n");
  16.118      printk("************************************\n");
  16.119  
  16.120 -    DEBUGGER_trap_fatal(TRAP_double_fault, NULL, 0);
  16.121 -
  16.122      /* Lock up the console to prevent spurious output from other CPUs. */
  16.123      console_force_lock();
  16.124  
  16.125      /* Wait for manual reset. */
  16.126 -    for ( ; ; ) ;
  16.127 +    for ( ; ; )
  16.128 +        __asm__ __volatile__ ( "hlt" );
  16.129 +}
  16.130 +
  16.131 +asmlinkage void do_machine_check(struct xen_regs *regs, long error_code)
  16.132 +{
  16.133 +    fatal_trap(TRAP_machine_check, regs, error_code);
  16.134  }
  16.135  
  16.136  asmlinkage void do_page_fault(struct xen_regs *regs, long error_code)
  16.137  {
  16.138 -    struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
  16.139      trap_info_t *ti;
  16.140      unsigned long off, addr, fixup;
  16.141      struct exec_domain *ed = current;
  16.142      struct domain *d = ed->domain;
  16.143      extern int map_ldt_shadow_page(unsigned int);
  16.144 +    struct trap_bounce *tb = &ed->thread.trap_bounce;
  16.145      int cpu = ed->processor;
  16.146      int ret;
  16.147  
  16.148 @@ -396,11 +414,11 @@ asmlinkage void do_page_fault(struct xen
  16.149          goto xen_fault;
  16.150  
  16.151      ti = ed->thread.traps + 14;
  16.152 -    gtb->flags = GTBF_TRAP_CR2; /* page fault pushes %cr2 */
  16.153 -    gtb->cr2        = addr;
  16.154 -    gtb->error_code = error_code;
  16.155 -    gtb->cs         = ti->cs;
  16.156 -    gtb->eip        = ti->address;
  16.157 +    tb->flags = TBF_TRAP_CR2; /* page fault pushes %cr2 */
  16.158 +    tb->cr2        = addr;
  16.159 +    tb->error_code = error_code;
  16.160 +    tb->cs         = ti->cs;
  16.161 +    tb->eip        = ti->address;
  16.162      if ( TI_GET_IF(ti) )
  16.163          ed->vcpu_info->evtchn_upcall_mask = 1;
  16.164      return; 
  16.165 @@ -446,7 +464,7 @@ asmlinkage void do_general_protection(st
  16.166  {
  16.167      struct exec_domain *ed = current;
  16.168      struct domain *d = ed->domain;
  16.169 -    struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
  16.170 +    struct trap_bounce *tb = &d->thread.trap_bounce;
  16.171      trap_info_t *ti;
  16.172      unsigned long fixup;
  16.173  
  16.174 @@ -482,7 +500,7 @@ asmlinkage void do_general_protection(st
  16.175          ti = current->thread.traps + (error_code>>3);
  16.176          if ( TI_GET_DPL(ti) >= (regs->cs & 3) )
  16.177          {
  16.178 -            gtb->flags = GTBF_TRAP_NOCODE;
  16.179 +            tb->flags = TBF_TRAP_NOCODE;
  16.180              regs->eip += 2;
  16.181              goto finish_propagation;
  16.182          }
  16.183 @@ -497,11 +515,11 @@ asmlinkage void do_general_protection(st
  16.184  
  16.185      /* Pass on GPF as is. */
  16.186      ti = current->thread.traps + 13;
  16.187 -    gtb->flags      = GTBF_TRAP;
  16.188 -    gtb->error_code = error_code;
  16.189 +    tb->flags      = TBF_TRAP;
  16.190 +    tb->error_code = error_code;
  16.191   finish_propagation:
  16.192 -    gtb->cs         = ti->cs;
  16.193 -    gtb->eip        = ti->address;
  16.194 +    tb->cs         = ti->cs;
  16.195 +    tb->eip        = ti->address;
  16.196      if ( TI_GET_IF(ti) )
  16.197          ed->vcpu_info->evtchn_upcall_mask = 1;
  16.198      return;
  16.199 @@ -517,47 +535,24 @@ asmlinkage void do_general_protection(st
  16.200  
  16.201      DEBUGGER_trap_fatal(TRAP_gp_fault, regs, error_code);
  16.202  
  16.203 -    die("general protection fault", regs, error_code);
  16.204 +    show_registers(regs);
  16.205 +    panic("CPU%d GENERAL PROTECTION FAULT\n"
  16.206 +          "[error_code=%08x]\n", smp_processor_id(), error_code);
  16.207  }
  16.208  
  16.209  asmlinkage void mem_parity_error(struct xen_regs *regs)
  16.210  {
  16.211      console_force_unlock();
  16.212 -
  16.213 -    printk("\n\n");
  16.214 -
  16.215 -    show_registers(regs);
  16.216 -
  16.217 -    printk("************************************\n");
  16.218 -    printk("CPU%d MEMORY ERROR -- system shutdown\n", smp_processor_id());
  16.219 -    printk("System needs manual reset.\n");
  16.220 -    printk("************************************\n");
  16.221 -
  16.222 -    /* Lock up the console to prevent spurious output from other CPUs. */
  16.223 -    console_force_lock();
  16.224 -
  16.225 -    /* Wait for manual reset. */
  16.226 -    for ( ; ; ) ;
  16.227 +    printk("\n\nNMI - MEMORY ERROR\n");
  16.228 +    fatal_trap(TRAP_nmi, regs, 0);
  16.229  }
  16.230  
  16.231  asmlinkage void io_check_error(struct xen_regs *regs)
  16.232  {
  16.233      console_force_unlock();
  16.234  
  16.235 -    printk("\n\n");
  16.236 -
  16.237 -    show_registers(regs);
  16.238 -
  16.239 -    printk("************************************\n");
  16.240 -    printk("CPU%d I/O ERROR -- system shutdown\n", smp_processor_id());
  16.241 -    printk("System needs manual reset.\n");
  16.242 -    printk("************************************\n");
  16.243 -
  16.244 -    /* Lock up the console to prevent spurious output from other CPUs. */
  16.245 -    console_force_lock();
  16.246 -
  16.247 -    /* Wait for manual reset. */
  16.248 -    for ( ; ; ) ;
  16.249 +    printk("\n\nNMI - I/O ERROR\n");
  16.250 +    fatal_trap(TRAP_nmi, regs, 0);
  16.251  }
  16.252  
  16.253  static void unknown_nmi_error(unsigned char reason, struct xen_regs * regs)
  16.254 @@ -610,18 +605,18 @@ asmlinkage void math_state_restore(struc
  16.255  
  16.256      if ( test_and_clear_bit(EDF_GUEST_STTS, &current->ed_flags) )
  16.257      {
  16.258 -        struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
  16.259 -        gtb->flags      = GTBF_TRAP_NOCODE;
  16.260 -        gtb->cs         = current->thread.traps[7].cs;
  16.261 -        gtb->eip        = current->thread.traps[7].address;
  16.262 +        struct trap_bounce *tb = &current->thread.trap_bounce;
  16.263 +        tb->flags      = TBF_TRAP_NOCODE;
  16.264 +        tb->cs         = current->thread.traps[7].cs;
  16.265 +        tb->eip        = current->thread.traps[7].address;
  16.266      }
  16.267  }
  16.268  
  16.269  asmlinkage void do_debug(struct xen_regs *regs, long error_code)
  16.270  {
  16.271      unsigned int condition;
  16.272 -    struct exec_domain *tsk = current;
  16.273 -    struct guest_trap_bounce *gtb = guest_trap_bounce+smp_processor_id();
  16.274 +    struct exec_domain *d = current;
  16.275 +    struct trap_bounce *tb = &ed->thread.trap_bounce;
  16.276  
  16.277      DEBUGGER_trap_entry(TRAP_debug, regs, error_code);
  16.278  
  16.279 @@ -629,7 +624,7 @@ asmlinkage void do_debug(struct xen_regs
  16.280  
  16.281      /* Mask out spurious debug traps due to lazy DR7 setting */
  16.282      if ( (condition & (DR_TRAP0|DR_TRAP1|DR_TRAP2|DR_TRAP3)) &&
  16.283 -         (tsk->thread.debugreg[7] == 0) )
  16.284 +         (d->thread.debugreg[7] == 0) )
  16.285      {
  16.286          __asm__("movl %0,%%db7" : : "r" (0));
  16.287          return;
  16.288 @@ -649,11 +644,11 @@ asmlinkage void do_debug(struct xen_regs
  16.289      }
  16.290  
  16.291      /* Save debug status register where guest OS can peek at it */
  16.292 -    tsk->thread.debugreg[6] = condition;
  16.293 +    d->thread.debugreg[6] = condition;
  16.294  
  16.295 -    gtb->flags = GTBF_TRAP_NOCODE;
  16.296 -    gtb->cs    = tsk->thread.traps[1].cs;
  16.297 -    gtb->eip   = tsk->thread.traps[1].address;
  16.298 +    tb->flags = TBF_TRAP_NOCODE;
  16.299 +    tb->cs    = d->thread.traps[1].cs;
  16.300 +    tb->eip   = d->thread.traps[1].address;
  16.301  }
  16.302  
  16.303  
  16.304 @@ -746,26 +741,26 @@ void __init trap_init(void)
  16.305       * saved. The page-fault handler also needs interrupts disabled until %cr2 
  16.306       * has been read and saved on the stack.
  16.307       */
  16.308 -    set_intr_gate(0,&divide_error);
  16.309 -    set_intr_gate(1,&debug);
  16.310 -    set_intr_gate(2,&nmi);
  16.311 -    set_system_gate(3,&int3);     /* usable from all privilege levels */
  16.312 -    set_system_gate(4,&overflow); /* usable from all privilege levels */
  16.313 -    set_intr_gate(5,&bounds);
  16.314 -    set_intr_gate(6,&invalid_op);
  16.315 -    set_intr_gate(7,&device_not_available);
  16.316 -    set_task_gate(8,__DOUBLEFAULT_TSS_ENTRY<<3);
  16.317 -    set_intr_gate(9,&coprocessor_segment_overrun);
  16.318 -    set_intr_gate(10,&invalid_TSS);
  16.319 -    set_intr_gate(11,&segment_not_present);
  16.320 -    set_intr_gate(12,&stack_segment);
  16.321 -    set_intr_gate(13,&general_protection);
  16.322 -    set_intr_gate(14,&page_fault);
  16.323 -    set_intr_gate(15,&spurious_interrupt_bug);
  16.324 -    set_intr_gate(16,&coprocessor_error);
  16.325 -    set_intr_gate(17,&alignment_check);
  16.326 -    set_intr_gate(18,&machine_check);
  16.327 -    set_intr_gate(19,&simd_coprocessor_error);
  16.328 +    set_intr_gate(TRAP_divide_error,&divide_error);
  16.329 +    set_intr_gate(TRAP_debug,&debug);
  16.330 +    set_intr_gate(TRAP_nmi,&nmi);
  16.331 +    set_system_gate(TRAP_int3,&int3);         /* usable from all privileges */
  16.332 +    set_system_gate(TRAP_overflow,&overflow); /* usable from all privileges */
  16.333 +    set_intr_gate(TRAP_bounds,&bounds);
  16.334 +    set_intr_gate(TRAP_invalid_op,&invalid_op);
  16.335 +    set_intr_gate(TRAP_no_device,&device_not_available);
  16.336 +    set_task_gate(TRAP_double_fault,__DOUBLEFAULT_TSS_ENTRY<<3);
  16.337 +    set_intr_gate(TRAP_copro_seg,&coprocessor_segment_overrun);
  16.338 +    set_intr_gate(TRAP_invalid_tss,&invalid_TSS);
  16.339 +    set_intr_gate(TRAP_no_segment,&segment_not_present);
  16.340 +    set_intr_gate(TRAP_stack_error,&stack_segment);
  16.341 +    set_intr_gate(TRAP_gp_fault,&general_protection);
  16.342 +    set_intr_gate(TRAP_page_fault,&page_fault);
  16.343 +    set_intr_gate(TRAP_spurious_int,&spurious_interrupt_bug);
  16.344 +    set_intr_gate(TRAP_copro_error,&coprocessor_error);
  16.345 +    set_intr_gate(TRAP_alignment_check,&alignment_check);
  16.346 +    set_intr_gate(TRAP_machine_check,&machine_check);
  16.347 +    set_intr_gate(TRAP_simd_error,&simd_coprocessor_error);
  16.348  
  16.349      /* Only ring 1 can access Xen services. */
  16.350      _set_gate(idt_table+HYPERCALL_VECTOR,14,1,&hypercall);
  16.351 @@ -815,15 +810,15 @@ long do_set_callbacks(unsigned long even
  16.352                        unsigned long failsafe_selector,
  16.353                        unsigned long failsafe_address)
  16.354  {
  16.355 -    struct exec_domain *p = current;
  16.356 +    struct exec_domain *d = current;
  16.357  
  16.358      if ( !VALID_CODESEL(event_selector) || !VALID_CODESEL(failsafe_selector) )
  16.359          return -EPERM;
  16.360  
  16.361 -    p->event_selector    = event_selector;
  16.362 -    p->event_address     = event_address;
  16.363 -    p->failsafe_selector = failsafe_selector;
  16.364 -    p->failsafe_address  = failsafe_address;
  16.365 +    d->thread.event_selector    = event_selector;
  16.366 +    d->thread.event_address     = event_address;
  16.367 +    d->thread.failsafe_selector = failsafe_selector;
  16.368 +    d->thread.failsafe_address  = failsafe_address;
  16.369  
  16.370      return 0;
  16.371  }
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/xen/arch/x86/x86_32/asm-offsets.c	Thu Nov 18 17:55:33 2004 +0000
    17.3 @@ -0,0 +1,58 @@
    17.4 +/*
    17.5 + * Generate definitions needed by assembly language modules.
    17.6 + * This code generates raw asm output which is post-processed
    17.7 + * to extract and format the required data.
    17.8 + */
    17.9 +
   17.10 +#include <xen/sched.h>
   17.11 +
   17.12 +#define DEFINE(_sym, _val) \
   17.13 +    __asm__ __volatile__ ( "\n->" #_sym " %0 " #_val : : "i" _val )
   17.14 +#define BLANK() \
   17.15 +    __asm__ __volatile__ ( "\n->" : : )
   17.16 +#define OFFSET(_sym, _str, _mem) \
   17.17 +    DEFINE(_sym, offsetof(_str, _mem));
   17.18 +
   17.19 +void __dummy__(void)
   17.20 +{
   17.21 +    OFFSET(XREGS_eax, struct xen_regs, eax);
   17.22 +    OFFSET(XREGS_ebx, struct xen_regs, ebx);
   17.23 +    OFFSET(XREGS_ecx, struct xen_regs, ecx);
   17.24 +    OFFSET(XREGS_edx, struct xen_regs, edx);
   17.25 +    OFFSET(XREGS_esi, struct xen_regs, esi);
   17.26 +    OFFSET(XREGS_edi, struct xen_regs, edi);
   17.27 +    OFFSET(XREGS_esp, struct xen_regs, esp);
   17.28 +    OFFSET(XREGS_ebp, struct xen_regs, ebp);
   17.29 +    OFFSET(XREGS_eip, struct xen_regs, eip);
   17.30 +    OFFSET(XREGS_cs, struct xen_regs, cs);
   17.31 +    OFFSET(XREGS_ds, struct xen_regs, ds);
   17.32 +    OFFSET(XREGS_es, struct xen_regs, es);
   17.33 +    OFFSET(XREGS_fs, struct xen_regs, fs);
   17.34 +    OFFSET(XREGS_gs, struct xen_regs, gs);
   17.35 +    OFFSET(XREGS_ss, struct xen_regs, ss);
   17.36 +    OFFSET(XREGS_eflags, struct xen_regs, eflags);
   17.37 +    OFFSET(XREGS_orig_eax, struct xen_regs, orig_eax);
   17.38 +    BLANK();
   17.39 +
   17.40 +    OFFSET(DOMAIN_processor, struct domain, processor);
   17.41 +    OFFSET(DOMAIN_shared_info, struct domain, shared_info);
   17.42 +    OFFSET(DOMAIN_event_sel, struct domain, thread.event_selector);
   17.43 +    OFFSET(DOMAIN_event_addr, struct domain, thread.event_address);
   17.44 +    OFFSET(DOMAIN_failsafe_sel, struct domain, thread.failsafe_selector);
   17.45 +    OFFSET(DOMAIN_failsafe_addr, struct domain, thread.failsafe_address);
   17.46 +    OFFSET(DOMAIN_trap_bounce, struct domain, thread.trap_bounce);
   17.47 +    BLANK();
   17.48 +
   17.49 +    OFFSET(SHINFO_upcall_pending, shared_info_t, 
   17.50 +           vcpu_data[0].evtchn_upcall_pending);
   17.51 +    OFFSET(SHINFO_upcall_mask, shared_info_t, 
   17.52 +           vcpu_data[0].evtchn_upcall_mask);
   17.53 +    BLANK();
   17.54 +
   17.55 +    OFFSET(TRAPBOUNCE_error_code, struct trap_bounce, error_code);
   17.56 +    OFFSET(TRAPBOUNCE_cr2, struct trap_bounce, cr2);
   17.57 +    OFFSET(TRAPBOUNCE_flags, struct trap_bounce, flags);
   17.58 +    OFFSET(TRAPBOUNCE_cs, struct trap_bounce, cs);
   17.59 +    OFFSET(TRAPBOUNCE_eip, struct trap_bounce, eip);
   17.60 +    BLANK();
   17.61 +}
    18.1 --- a/xen/arch/x86/x86_32/entry.S	Thu Nov 18 17:43:29 2004 +0000
    18.2 +++ b/xen/arch/x86/x86_32/entry.S	Thu Nov 18 17:55:33 2004 +0000
    18.3 @@ -196,13 +196,11 @@ 7:      SET_XEN_SEGMENTS(a)
    18.4  /* No special register assumptions */
    18.5  failsafe_callback:
    18.6          GET_CURRENT(%ebx)
    18.7 -        movl EDOMAIN_processor(%ebx),%eax
    18.8 -        shl  $4,%eax
    18.9 -        lea  guest_trap_bounce(%eax),%edx
   18.10 +        leal EDOMAIN_trap_bounce(%ebx),%edx
   18.11          movl EDOMAIN_failsafe_addr(%ebx),%eax
   18.12 -        movl %eax,GTB_eip(%edx)
   18.13 +        movl %eax,TRAPBOUNCE_eip(%edx)
   18.14          movl EDOMAIN_failsafe_sel(%ebx),%eax
   18.15 -        movw %ax,GTB_cs(%edx)
   18.16 +        movw %ax,TRAPBOUNCE_cs(%edx)
   18.17          call create_bounce_frame
   18.18          subl $16,%esi                # add DS/ES/FS/GS to failsafe stack frame
   18.19          movl XREGS_ds(%esp),%eax
   18.20 @@ -265,13 +263,11 @@ test_all_events:
   18.21          jz   restore_all_guest
   18.22          movb $1,VCPUINFO_upcall_mask(%eax) # Upcalls are masked during delivery
   18.23  /*process_guest_events:*/
   18.24 -        movl EDOMAIN_processor(%ebx),%edx
   18.25 -        shl  $4,%edx                     # sizeof(guest_trap_bounce) == 16
   18.26 -        lea  guest_trap_bounce(%edx),%edx
   18.27 +        leal EDOMAIN_trap_bounce(%ebx),%edx
   18.28          movl EDOMAIN_event_addr(%ebx),%eax
   18.29 -        movl %eax,GTB_eip(%edx)
   18.30 +        movl %eax,TRAPBOUNCE_eip(%edx)
   18.31          movl EDOMAIN_event_sel(%ebx),%eax
   18.32 -        movw %ax,GTB_cs(%edx)
   18.33 +        movw %ax,TRAPBOUNCE_cs(%edx)
   18.34          call create_bounce_frame
   18.35          jmp  restore_all_guest
   18.36  
   18.37 @@ -283,7 +279,7 @@ process_softirqs:
   18.38                  
   18.39  /* CREATE A BASIC EXCEPTION FRAME ON GUEST OS (RING-1) STACK:            */
   18.40  /*   {EIP, CS, EFLAGS, [ESP, SS]}                                        */
   18.41 -/* %edx == guest_trap_bounce, %ebx == task_struct                        */
   18.42 +/* %edx == trap_bounce, %ebx == task_struct                              */
   18.43  /* %eax,%ecx are clobbered. %gs:%esi contain new XREGS_ss/XREGS_esp. */
   18.44  create_bounce_frame:        
   18.45          mov  XREGS_cs+4(%esp),%cl
   18.46 @@ -323,9 +319,9 @@ FAULT12:movl %eax,%gs:8(%esi)
   18.47          movl %eax,XREGS_eflags+4(%esp)
   18.48          movl %gs,XREGS_ss+4(%esp)
   18.49          movl %esi,XREGS_esp+4(%esp)
   18.50 -        movzwl GTB_cs(%edx),%eax
   18.51 +        movzwl TRAPBOUNCE_cs(%edx),%eax
   18.52          movl %eax,XREGS_cs+4(%esp)
   18.53 -        movl GTB_eip(%edx),%eax
   18.54 +        movl TRAPBOUNCE_eip(%edx),%eax
   18.55          movl %eax,XREGS_eip+4(%esp)
   18.56          ret
   18.57  
   18.58 @@ -362,25 +358,23 @@ crash_domain_fixup3:
   18.59  
   18.60          ALIGN
   18.61  process_guest_exception_and_events:        
   18.62 -        movl EDOMAIN_processor(%ebx),%eax
   18.63 -        shl  $4,%eax
   18.64 -        lea  guest_trap_bounce(%eax),%edx
   18.65 -        testb $~0,GTB_flags(%edx)
   18.66 +        leal EDOMAIN_trap_bounce(%ebx),%edx
   18.67 +        testb $~0,TRAPBOUNCE_flags(%edx)
   18.68          jz   test_all_events
   18.69          call create_bounce_frame        # just the basic frame
   18.70 -        mov  GTB_flags(%edx),%cl
   18.71 -        test $GTBF_TRAP_NOCODE,%cl
   18.72 +        mov  TRAPBOUNCE_flags(%edx),%cl
   18.73 +        test $TBF_TRAP_NOCODE,%cl
   18.74          jnz  2f
   18.75          subl $4,%esi                    # push error_code onto guest frame
   18.76 -        movl GTB_error_code(%edx),%eax
   18.77 +        movl TRAPBOUNCE_error_code(%edx),%eax
   18.78  FAULT13:movl %eax,%gs:(%esi)
   18.79 -        test $GTBF_TRAP_CR2,%cl
   18.80 +        test $TBF_TRAP_CR2,%cl
   18.81          jz   1f
   18.82          subl $4,%esi                    # push %cr2 onto guest frame
   18.83 -        movl GTB_cr2(%edx),%eax
   18.84 +        movl TRAPBOUNCE_cr2(%edx),%eax
   18.85  FAULT14:movl %eax,%gs:(%esi)
   18.86  1:      movl %esi,XREGS_esp(%esp)        
   18.87 -2:      movb $0,GTB_flags(%edx)
   18.88 +2:      movb $0,TRAPBOUNCE_flags(%edx)
   18.89          jmp  test_all_events
   18.90  
   18.91          ALIGN
    19.1 --- a/xen/arch/x86/x86_32/seg_fixup.c	Thu Nov 18 17:43:29 2004 +0000
    19.2 +++ b/xen/arch/x86/x86_32/seg_fixup.c	Thu Nov 18 17:55:33 2004 +0000
    19.3 @@ -286,7 +286,7 @@ int gpf_emulate_4gb(struct xen_regs *reg
    19.4  {
    19.5      struct exec_domain *d = current;
    19.6      trap_info_t   *ti;
    19.7 -    struct guest_trap_bounce *gtb;
    19.8 +    struct trap_bounce *tb;
    19.9      u8            modrm, mod, reg, rm, decode;
   19.10      void         *memreg, *regreg;
   19.11      unsigned long offset;
   19.12 @@ -466,11 +466,11 @@ int gpf_emulate_4gb(struct xen_regs *reg
   19.13      if ( VM_ASSIST(d->domain, VMASST_TYPE_4gb_segments_notify) )
   19.14      {
   19.15          ti  = &d->thread.traps[15];
   19.16 -        gtb = &guest_trap_bounce[d->processor];
   19.17 -        gtb->flags      = GTBF_TRAP;
   19.18 -        gtb->error_code = pb - eip;
   19.19 -        gtb->cs         = ti->cs;
   19.20 -        gtb->eip        = ti->address;
   19.21 +        tb = &d->thread.trap_bounce;
   19.22 +        tb->flags      = TBF_TRAP;
   19.23 +        tb->error_code = pb - eip;
   19.24 +        tb->cs         = ti->cs;
   19.25 +        tb->eip        = ti->address;
   19.26          if ( TI_GET_IF(ti) )
   19.27              d->vcpu_info->evtchn_upcall_mask = 1;
   19.28      }
    20.1 --- a/xen/common/keyhandler.c	Thu Nov 18 17:43:29 2004 +0000
    20.2 +++ b/xen/common/keyhandler.c	Thu Nov 18 17:55:33 2004 +0000
    20.3 @@ -81,10 +81,8 @@ static void show_handlers(unsigned char 
    20.4                     key_table[i].desc);
    20.5  }
    20.6  
    20.7 -
    20.8  static void dump_registers(unsigned char key, struct xen_regs *regs)
    20.9  {
   20.10 -    extern void show_registers(struct xen_regs *regs); 
   20.11      printk("'%c' pressed -> dumping registers\n", key); 
   20.12      show_registers(regs); 
   20.13  }
    21.1 --- a/xen/include/asm-x86/processor.h	Thu Nov 18 17:43:29 2004 +0000
    21.2 +++ b/xen/include/asm-x86/processor.h	Thu Nov 18 17:55:33 2004 +0000
    21.3 @@ -7,6 +7,7 @@
    21.4  #ifndef __ASM_X86_PROCESSOR_H
    21.5  #define __ASM_X86_PROCESSOR_H
    21.6  
    21.7 +#ifndef __ASSEMBLY__
    21.8  #include <asm/page.h>
    21.9  #include <asm/types.h>
   21.10  #include <asm/cpufeature.h>
   21.11 @@ -16,6 +17,81 @@
   21.12  #include <xen/config.h>
   21.13  #include <xen/spinlock.h>
   21.14  #include <public/xen.h>
   21.15 +#endif
   21.16 +
   21.17 +/*
   21.18 + * CPU vendor IDs
   21.19 + */
   21.20 +#define X86_VENDOR_INTEL 0
   21.21 +#define X86_VENDOR_CYRIX 1
   21.22 +#define X86_VENDOR_AMD 2
   21.23 +#define X86_VENDOR_UMC 3
   21.24 +#define X86_VENDOR_NEXGEN 4
   21.25 +#define X86_VENDOR_CENTAUR 5
   21.26 +#define X86_VENDOR_RISE 6
   21.27 +#define X86_VENDOR_TRANSMETA 7
   21.28 +#define X86_VENDOR_NSC 8
   21.29 +#define X86_VENDOR_SIS 9
   21.30 +#define X86_VENDOR_UNKNOWN 0xff
   21.31 +
   21.32 +/*
   21.33 + * EFLAGS bits
   21.34 + */
   21.35 +#define X86_EFLAGS_CF	0x00000001 /* Carry Flag */
   21.36 +#define X86_EFLAGS_PF	0x00000004 /* Parity Flag */
   21.37 +#define X86_EFLAGS_AF	0x00000010 /* Auxillary carry Flag */
   21.38 +#define X86_EFLAGS_ZF	0x00000040 /* Zero Flag */
   21.39 +#define X86_EFLAGS_SF	0x00000080 /* Sign Flag */
   21.40 +#define X86_EFLAGS_TF	0x00000100 /* Trap Flag */
   21.41 +#define X86_EFLAGS_IF	0x00000200 /* Interrupt Flag */
   21.42 +#define X86_EFLAGS_DF	0x00000400 /* Direction Flag */
   21.43 +#define X86_EFLAGS_OF	0x00000800 /* Overflow Flag */
   21.44 +#define X86_EFLAGS_IOPL	0x00003000 /* IOPL mask */
   21.45 +#define X86_EFLAGS_NT	0x00004000 /* Nested Task */
   21.46 +#define X86_EFLAGS_RF	0x00010000 /* Resume Flag */
   21.47 +#define X86_EFLAGS_VM	0x00020000 /* Virtual Mode */
   21.48 +#define X86_EFLAGS_AC	0x00040000 /* Alignment Check */
   21.49 +#define X86_EFLAGS_VIF	0x00080000 /* Virtual Interrupt Flag */
   21.50 +#define X86_EFLAGS_VIP	0x00100000 /* Virtual Interrupt Pending */
   21.51 +#define X86_EFLAGS_ID	0x00200000 /* CPUID detection flag */
   21.52 +
   21.53 +/*
   21.54 + * Intel CPU flags in CR0
   21.55 + */
   21.56 +#define X86_CR0_PE              0x00000001 /* Enable Protected Mode    (RW) */
   21.57 +#define X86_CR0_MP              0x00000002 /* Monitor Coprocessor      (RW) */
   21.58 +#define X86_CR0_EM              0x00000004 /* Require FPU Emulation    (RO) */
   21.59 +#define X86_CR0_TS              0x00000008 /* Task Switched            (RW) */
   21.60 +#define X86_CR0_NE              0x00000020 /* Numeric Error Reporting  (RW) */
   21.61 +#define X86_CR0_WP              0x00010000 /* Supervisor Write Protect (RW) */
   21.62 +#define X86_CR0_AM              0x00040000 /* Alignment Checking       (RW) */
   21.63 +#define X86_CR0_NW              0x20000000 /* Not Write-Through        (RW) */
   21.64 +#define X86_CR0_CD              0x40000000 /* Cache Disable            (RW) */
   21.65 +#define X86_CR0_PG              0x80000000 /* Paging                   (RW) */
   21.66 +
   21.67 +/*
   21.68 + * Intel CPU features in CR4
   21.69 + */
   21.70 +#define X86_CR4_VME		0x0001	/* enable vm86 extensions */
   21.71 +#define X86_CR4_PVI		0x0002	/* virtual interrupts flag enable */
   21.72 +#define X86_CR4_TSD		0x0004	/* disable time stamp at ipl 3 */
   21.73 +#define X86_CR4_DE		0x0008	/* enable debugging extensions */
   21.74 +#define X86_CR4_PSE		0x0010	/* enable page size extensions */
   21.75 +#define X86_CR4_PAE		0x0020	/* enable physical address extensions */
   21.76 +#define X86_CR4_MCE		0x0040	/* Machine check enable */
   21.77 +#define X86_CR4_PGE		0x0080	/* enable global pages */
   21.78 +#define X86_CR4_PCE		0x0100	/* enable performance counters at ipl 3 */
   21.79 +#define X86_CR4_OSFXSR		0x0200	/* enable fast FPU save and restore */
   21.80 +#define X86_CR4_OSXMMEXCPT	0x0400	/* enable unmasked SSE exceptions */
   21.81 +
   21.82 +/*
   21.83 + * 'trap_bounce' flags values.
   21.84 + */
   21.85 +#define TBF_TRAP        1
   21.86 +#define TBF_TRAP_NOCODE 2
   21.87 +#define TBF_TRAP_CR2    4
   21.88 +
   21.89 +#ifndef __ASSEMBLY__
   21.90  
   21.91  struct domain;
   21.92  struct exec_domain;
   21.93 @@ -50,18 +126,6 @@ struct cpuinfo_x86 {
   21.94      int	    x86_tlbsize;     /* number of 4K pages in DTLB/ITLB combined */
   21.95  } __attribute__((__aligned__(SMP_CACHE_BYTES)));
   21.96  
   21.97 -#define X86_VENDOR_INTEL 0
   21.98 -#define X86_VENDOR_CYRIX 1
   21.99 -#define X86_VENDOR_AMD 2
  21.100 -#define X86_VENDOR_UMC 3
  21.101 -#define X86_VENDOR_NEXGEN 4
  21.102 -#define X86_VENDOR_CENTAUR 5
  21.103 -#define X86_VENDOR_RISE 6
  21.104 -#define X86_VENDOR_TRANSMETA 7
  21.105 -#define X86_VENDOR_NSC 8
  21.106 -#define X86_VENDOR_SIS 9
  21.107 -#define X86_VENDOR_UNKNOWN 0xff
  21.108 -
  21.109  /*
  21.110   * capabilities of CPUs
  21.111   */
  21.112 @@ -84,27 +148,6 @@ extern void print_cpu_info(struct cpuinf
  21.113  extern void dodgy_tsc(void);
  21.114  
  21.115  /*
  21.116 - * EFLAGS bits
  21.117 - */
  21.118 -#define X86_EFLAGS_CF	0x00000001 /* Carry Flag */
  21.119 -#define X86_EFLAGS_PF	0x00000004 /* Parity Flag */
  21.120 -#define X86_EFLAGS_AF	0x00000010 /* Auxillary carry Flag */
  21.121 -#define X86_EFLAGS_ZF	0x00000040 /* Zero Flag */
  21.122 -#define X86_EFLAGS_SF	0x00000080 /* Sign Flag */
  21.123 -#define X86_EFLAGS_TF	0x00000100 /* Trap Flag */
  21.124 -#define X86_EFLAGS_IF	0x00000200 /* Interrupt Flag */
  21.125 -#define X86_EFLAGS_DF	0x00000400 /* Direction Flag */
  21.126 -#define X86_EFLAGS_OF	0x00000800 /* Overflow Flag */
  21.127 -#define X86_EFLAGS_IOPL	0x00003000 /* IOPL mask */
  21.128 -#define X86_EFLAGS_NT	0x00004000 /* Nested Task */
  21.129 -#define X86_EFLAGS_RF	0x00010000 /* Resume Flag */
  21.130 -#define X86_EFLAGS_VM	0x00020000 /* Virtual Mode */
  21.131 -#define X86_EFLAGS_AC	0x00040000 /* Alignment Check */
  21.132 -#define X86_EFLAGS_VIF	0x00080000 /* Virtual Interrupt Flag */
  21.133 -#define X86_EFLAGS_VIP	0x00100000 /* Virtual Interrupt Pending */
  21.134 -#define X86_EFLAGS_ID	0x00200000 /* CPUID detection flag */
  21.135 -
  21.136 -/*
  21.137   * Generic CPUID function
  21.138   */
  21.139  static inline void cpuid(int op, int *eax, int *ebx, int *ecx, int *edx)
  21.140 @@ -162,20 +205,6 @@ static inline unsigned int cpuid_edx(uns
  21.141  }
  21.142  
  21.143  
  21.144 -/*
  21.145 - * Intel CPU flags in CR0
  21.146 - */
  21.147 -#define X86_CR0_PE              0x00000001 /* Enable Protected Mode    (RW) */
  21.148 -#define X86_CR0_MP              0x00000002 /* Monitor Coprocessor      (RW) */
  21.149 -#define X86_CR0_EM              0x00000004 /* Require FPU Emulation    (RO) */
  21.150 -#define X86_CR0_TS              0x00000008 /* Task Switched            (RW) */
  21.151 -#define X86_CR0_NE              0x00000020 /* Numeric Error Reporting  (RW) */
  21.152 -#define X86_CR0_WP              0x00010000 /* Supervisor Write Protect (RW) */
  21.153 -#define X86_CR0_AM              0x00040000 /* Alignment Checking       (RW) */
  21.154 -#define X86_CR0_NW              0x20000000 /* Not Write-Through        (RW) */
  21.155 -#define X86_CR0_CD              0x40000000 /* Cache Disable            (RW) */
  21.156 -#define X86_CR0_PG              0x80000000 /* Paging                   (RW) */
  21.157 -
  21.158  #define read_cr0() ({ \
  21.159  	unsigned long __dummy; \
  21.160  	__asm__( \
  21.161 @@ -189,21 +218,6 @@ static inline unsigned int cpuid_edx(uns
  21.162  
  21.163  
  21.164  /*
  21.165 - * Intel CPU features in CR4
  21.166 - */
  21.167 -#define X86_CR4_VME		0x0001	/* enable vm86 extensions */
  21.168 -#define X86_CR4_PVI		0x0002	/* virtual interrupts flag enable */
  21.169 -#define X86_CR4_TSD		0x0004	/* disable time stamp at ipl 3 */
  21.170 -#define X86_CR4_DE		0x0008	/* enable debugging extensions */
  21.171 -#define X86_CR4_PSE		0x0010	/* enable page size extensions */
  21.172 -#define X86_CR4_PAE		0x0020	/* enable physical address extensions */
  21.173 -#define X86_CR4_MCE		0x0040	/* Machine check enable */
  21.174 -#define X86_CR4_PGE		0x0080	/* enable global pages */
  21.175 -#define X86_CR4_PCE		0x0100	/* enable performance counters at ipl 3 */
  21.176 -#define X86_CR4_OSFXSR		0x0200	/* enable fast FPU save and restore */
  21.177 -#define X86_CR4_OSXMMEXCPT	0x0400	/* enable unmasked SSE exceptions */
  21.178 -
  21.179 -/*
  21.180   * Save the cr4 feature set we're using (ie
  21.181   * Pentium 4MB enable and PPro Global page
  21.182   * enable), so that any CPU's that boot up
  21.183 @@ -285,16 +299,44 @@ struct tss_struct {
  21.184      u32 __cacheline_filler[5];
  21.185  };
  21.186  
  21.187 +struct trap_bounce {
  21.188 +    unsigned long  error_code;
  21.189 +    unsigned long  cr2;
  21.190 +    unsigned short flags; /* TBF_ */
  21.191 +    unsigned short cs;
  21.192 +    unsigned long  eip;
  21.193 +};
  21.194 +
  21.195  struct thread_struct {
  21.196      unsigned long      guestos_sp;
  21.197      unsigned long      guestos_ss;
  21.198 -/* Hardware debugging registers */
  21.199 +
  21.200 +    /* Hardware debugging registers */
  21.201      unsigned long      debugreg[8];  /* %%db0-7 debug registers */
  21.202 -/* floating point info */
  21.203 +
  21.204 +    /* floating point info */
  21.205      struct i387_state  i387;
  21.206 -/* general user-visible register state */
  21.207 +
  21.208 +    /* general user-visible register state */
  21.209      execution_context_t user_ctxt;
  21.210 -/* Trap info. */
  21.211 +
  21.212 +    /*
  21.213 +     * Return vectors pushed to us by guest OS.
  21.214 +     * The stack frame for events is exactly that of an x86 hardware interrupt.
  21.215 +     * The stack frame for a failsafe callback is augmented with saved values
  21.216 +     * for segment registers %ds, %es, %fs and %gs:
  21.217 +     * 	%ds, %es, %fs, %gs, %eip, %cs, %eflags [, %oldesp, %oldss]
  21.218 +     */
  21.219 +    unsigned long event_selector;    /* 08: entry CS  */
  21.220 +    unsigned long event_address;     /* 12: entry EIP */
  21.221 +
  21.222 +    unsigned long failsafe_selector; /* 16: entry CS  */
  21.223 +    unsigned long failsafe_address;  /* 20: entry EIP */
  21.224 +
  21.225 +    /* Bounce information for propagating an exception to guest OS. */
  21.226 +    struct trap_bounce trap_bounce;
  21.227 +
  21.228 +    /* Trap info. */
  21.229  #ifdef __i386__
  21.230      int                fast_trap_idx;
  21.231      struct desc_struct fast_trap_desc;
  21.232 @@ -330,14 +372,7 @@ extern struct desc_struct *idt_tables[];
  21.233  
  21.234  long set_fast_trap(struct exec_domain *p, int idx);
  21.235  
  21.236 -#define INIT_THREAD  {						\
  21.237 -	0, 0,		      		       			\
  21.238 -	{ [0 ... 7] = 0 },	/* debugging registers */	\
  21.239 -	{ { 0, }, },		/* 387 state */			\
  21.240 -	{ 0 },							\
  21.241 -	0x20, { 0, 0 },		/* DEFAULT_FAST_TRAP */		\
  21.242 -	{ {0} }			/* io permissions */		\
  21.243 -}
  21.244 +#define INIT_THREAD  { fast_trap_idx: 0x20 }
  21.245  
  21.246  #elif defined(__x86_64__)
  21.247  
  21.248 @@ -345,18 +380,6 @@ long set_fast_trap(struct exec_domain *p
  21.249  
  21.250  #endif /* __x86_64__ */
  21.251  
  21.252 -#define GTBF_TRAP        1
  21.253 -#define GTBF_TRAP_NOCODE 2
  21.254 -#define GTBF_TRAP_CR2    4
  21.255 -struct guest_trap_bounce {
  21.256 -    unsigned long  error_code;        /*   0 */
  21.257 -    unsigned long  cr2;               /*   4 */
  21.258 -    unsigned short flags;             /*   8 */
  21.259 -    unsigned short cs;                /*  10 */
  21.260 -    unsigned long  eip;               /*  12 */
  21.261 -};
  21.262 -extern struct guest_trap_bounce guest_trap_bounce[];
  21.263 -
  21.264  extern int gpf_emulate_4gb(struct xen_regs *regs);
  21.265  
  21.266  struct mm_struct {
  21.267 @@ -478,4 +501,12 @@ extern inline void prefetchw(const void 
  21.268  
  21.269  #endif
  21.270  
  21.271 +void show_guest_stack();
  21.272 +void show_trace(unsigned long *esp);
  21.273 +void show_stack(unsigned long *esp);
  21.274 +void show_registers(struct xen_regs *regs);
  21.275 +asmlinkage void fatal_trap(int trapnr, struct xen_regs *regs, long error_code);
  21.276 +
  21.277 +#endif /* !__ASSEMBLY__ */
  21.278 +
  21.279  #endif /* __ASM_X86_PROCESSOR_H */
    22.1 --- a/xen/include/asm-x86/shadow.h	Thu Nov 18 17:43:29 2004 +0000
    22.2 +++ b/xen/include/asm-x86/shadow.h	Thu Nov 18 17:55:33 2004 +0000
    22.3 @@ -116,18 +116,15 @@ static inline int __mark_dirty( struct m
    22.4  #ifndef NDEBUG
    22.5      else if ( mfn < max_page )
    22.6      {
    22.7 +        unsigned long *esp;
    22.8          SH_LOG("mark_dirty OOR! mfn=%x pfn=%lx max=%x (mm %p)",
    22.9                 mfn, pfn, m->shadow_dirty_bitmap_size, m );
   22.10          SH_LOG("dom=%p caf=%08x taf=%08x\n", 
   22.11                 frame_table[mfn].u.inuse.domain,
   22.12                 frame_table[mfn].count_info, 
   22.13                 frame_table[mfn].u.inuse.type_info );
   22.14 -        {
   22.15 -            extern void show_trace(unsigned long *esp);
   22.16 -            unsigned long *esp;
   22.17 -            __asm__ __volatile__ ("movl %%esp,%0" : "=r" (esp) : );
   22.18 -            show_trace(esp);
   22.19 -        }
   22.20 +        __asm__ __volatile__ ("movl %%esp,%0" : "=r" (esp) : );
   22.21 +        show_trace(esp);
   22.22      }
   22.23  #endif
   22.24  
    23.1 --- a/xen/include/asm-x86/x86_32/asm_defns.h	Thu Nov 18 17:43:29 2004 +0000
    23.2 +++ b/xen/include/asm-x86/x86_32/asm_defns.h	Thu Nov 18 17:55:33 2004 +0000
    23.3 @@ -1,56 +1,14 @@
    23.4  #ifndef __ASM_DEFNS_H__
    23.5  #define __ASM_DEFNS_H__
    23.6  
    23.7 -/* Offsets in 'struct xen_regs' --- AUTO-GENERATE ME! */
    23.8 -#define XREGS_ebx      0x00
    23.9 -#define XREGS_ecx      0x04
   23.10 -#define XREGS_edx      0x08
   23.11 -#define XREGS_esi      0x0C
   23.12 -#define XREGS_edi      0x10
   23.13 -#define XREGS_ebp      0x14
   23.14 -#define XREGS_eax      0x18
   23.15 -#define XREGS_orig_eax 0x1C
   23.16 -#define XREGS_eip      0x20
   23.17 -#define XREGS_cs       0x24
   23.18 -#define XREGS_eflags   0x28
   23.19 -#define XREGS_esp      0x2C
   23.20 -#define XREGS_ss       0x30
   23.21 -#define XREGS_es       0x34
   23.22 -#define XREGS_ds       0x38
   23.23 -#define XREGS_fs       0x3C
   23.24 -#define XREGS_gs       0x40
   23.25 -
   23.26 -/* Offsets in 'struct exec_domain' --- AUTO-GENERATE ME! */
   23.27 -#define EDOMAIN_processor       0
   23.28 -#define EDOMAIN_vcpu_info       4
   23.29 -#define EDOMAIN_event_sel       8
   23.30 -#define EDOMAIN_event_addr     12
   23.31 -#define EDOMAIN_failsafe_sel   16
   23.32 -#define EDOMAIN_failsafe_addr  20
   23.33 -
   23.34 -/* Offsets in vcpu_info_t --- AUTO-GENERATE ME! */
   23.35 -#define VCPUINFO_upcall_pending /* 0 */
   23.36 -#define VCPUINFO_upcall_mask       1
   23.37 -
   23.38 -/* Offsets in 'struct guest_trap_bounce' --- AUTO-GENERATE ME! */
   23.39 -#define GTB_error_code    0
   23.40 -#define GTB_cr2           4
   23.41 -#define GTB_flags         8
   23.42 -#define GTB_cs           10
   23.43 -#define GTB_eip          12
   23.44 -#define GTBF_TRAP         1
   23.45 -#define GTBF_TRAP_NOCODE  2
   23.46 -#define GTBF_TRAP_CR2     4
   23.47 -
   23.48 -/* EFLAGS masks. */
   23.49 -#define CF_MASK 0x00000001
   23.50 -#define IF_MASK 0x00000200
   23.51 -#define NT_MASK 0x00004000
   23.52 +/* NB. Auto-generated from arch/.../asm-offsets.c */
   23.53 +#include <asm/asm-offsets.h>
   23.54 +#include <asm/processor.h>
   23.55  
   23.56  #define __STR(x) #x
   23.57  #define STR(x) __STR(x)
   23.58  
   23.59 -/* AUTO-GENERATE the following two cases (quoted vs. unquoted). */
   23.60 +/* Maybe auto-generate the following two cases (quoted vs. unquoted). */
   23.61  #ifndef __ASSEMBLY__
   23.62  
   23.63  #define __SAVE_ALL_PRE(_reg) \
    24.1 --- a/xen/include/xen/sched.h	Thu Nov 18 17:43:29 2004 +0000
    24.2 +++ b/xen/include/xen/sched.h	Thu Nov 18 17:55:33 2004 +0000
    24.3 @@ -57,32 +57,9 @@ void destroy_event_channels(struct domai
    24.4  
    24.5  struct exec_domain 
    24.6  {
    24.7 -    /*
    24.8 -     * DO NOT CHANGE THE ORDER OF THE FOLLOWING.
    24.9 -     * Their offsets are hardcoded in entry.S
   24.10 -     */
   24.11 -
   24.12 -    u32 processor;               /* 00: current processor */
   24.13 -
   24.14 -    /* An unsafe pointer into a shared data area. */
   24.15 -    vcpu_info_t *vcpu_info;      /* 04: vcpu info pointer */
   24.16 +    u32 processor;
   24.17  
   24.18 -    /*
   24.19 -     * Return vectors pushed to us by guest OS.
   24.20 -     * The stack frame for events is exactly that of an x86 hardware interrupt.
   24.21 -     * The stack frame for a failsafe callback is augmented with saved values
   24.22 -     * for segment registers %ds, %es, %fs and %gs:
   24.23 -     * 	%ds, %es, %fs, %gs, %eip, %cs, %eflags [, %oldesp, %oldss]
   24.24 -     */
   24.25 -    unsigned long event_selector;    /* 08: entry CS  */
   24.26 -    unsigned long event_address;     /* 12: entry EIP */
   24.27 -
   24.28 -    unsigned long failsafe_selector; /* 16: entry CS  */
   24.29 -    unsigned long failsafe_address;  /* 20: entry EIP */
   24.30 -
   24.31 -    /*
   24.32 -     * From here on things can be added and shuffled without special attention
   24.33 -     */
   24.34 +    shared_info_t *shared_info;
   24.35  
   24.36      struct domain *domain;
   24.37      struct exec_domain *ed_next_list;