# HG changeset patch
# User cl349@xxxxxxxxxxxxxxxxxxxx
# Node ID 291e816acbf46071a69b5d1b12ac3b5c46eaa49b
# Parent edd1616cf8cb6f0d7ab32600a27d3a98ac8414b2
# Parent fc12b08bf4fe858b29317427cc0db82d29764c5f
merge?
diff -r edd1616cf8cb -r 291e816acbf4 extras/mini-os/README
--- a/extras/mini-os/README Fri Sep 2 14:15:49 2005
+++ b/extras/mini-os/README Fri Sep 2 14:17:08 2005
@@ -23,13 +23,8 @@
- to build it just type make.
-- copy image.final somewhere where dom0 can access it
+- to start it do the following in domain0 (assuming xend is running)
+ # xm create domain_config
-- in dom0
- # xi_create 16000 test
- <domid>
- # xi_build <domid> image.final 0
- # xi_start <domid>
-
-this prints out a bunch of stuff and then every 1000 timer interrupts the
-system time.
+this starts the kernel and prints out a bunch of stuff and then every
+1000 timer interrupts the system time.
diff -r edd1616cf8cb -r 291e816acbf4 extras/mini-os/include/hypervisor.h
--- a/extras/mini-os/include/hypervisor.h Fri Sep 2 14:15:49 2005
+++ b/extras/mini-os/include/hypervisor.h Fri Sep 2 14:17:08 2005
@@ -329,7 +329,7 @@
int ret;
__asm__ __volatile__ (
TRAP_INSTR
- : "=a" (ret) : "0" (__HYPERVISOR_dom_mem_op),
+ : "=a" (ret) : "0" (__HYPERVISOR_memory_op),
_a1 (dom_mem_op) : "memory" );
return ret;
diff -r edd1616cf8cb -r 291e816acbf4 linux-2.6-xen-sparse/arch/xen/Kconfig
--- a/linux-2.6-xen-sparse/arch/xen/Kconfig Fri Sep 2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/Kconfig Fri Sep 2 14:17:08 2005
@@ -109,15 +109,8 @@
dedicated device-driver domain, or your master control domain
(domain 0), then you almost certainly want to say Y here.
-config XEN_NETDEV_GRANT_TX
- bool "Grant table substrate for net drivers tx path (DANGEROUS)"
- default n
- help
- This introduces the use of grant tables as a data exhange mechanism
- between the frontend and backend network drivers.
-
-config XEN_NETDEV_GRANT_RX
- bool "Grant table substrate for net drivers rx path (DANGEROUS)"
+config XEN_NETDEV_GRANT
+ bool "Grant table substrate for network drivers (DANGEROUS)"
default n
help
This introduces the use of grant tables as a data exhange mechanism
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 Fri Sep
2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_32 Fri Sep
2 14:17:08 2005
@@ -19,8 +19,7 @@
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
@@ -1124,7 +1123,7 @@
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 Fri Sep
2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen0_defconfig_x86_64 Fri Sep
2 14:17:08 2005
@@ -19,8 +19,7 @@
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
@@ -1033,7 +1032,7 @@
# CONFIG_BEFS_FS is not set
# CONFIG_BFS_FS is not set
# CONFIG_EFS_FS is not set
-# CONFIG_CRAMFS is not set
+CONFIG_CRAMFS=y
# CONFIG_VXFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 Fri Sep
2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_32 Fri Sep
2 14:17:08 2005
@@ -16,8 +16,7 @@
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 Fri Sep
2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xenU_defconfig_x86_64 Fri Sep
2 14:17:08 2005
@@ -16,8 +16,7 @@
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 Fri Sep
2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_32 Fri Sep
2 14:17:08 2005
@@ -19,8 +19,7 @@
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64
--- a/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 Fri Sep
2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/arch/xen/configs/xen_defconfig_x86_64 Fri Sep
2 14:17:08 2005
@@ -19,8 +19,7 @@
# CONFIG_XEN_TPMDEV_BACKEND is not set
CONFIG_XEN_BLKDEV_FRONTEND=y
CONFIG_XEN_NETDEV_FRONTEND=y
-CONFIG_XEN_NETDEV_GRANT_TX=y
-CONFIG_XEN_NETDEV_GRANT_RX=y
+CONFIG_XEN_NETDEV_GRANT=y
# CONFIG_XEN_NETDEV_FRONTEND_PIPELINED_TRANSMITTER is not set
# CONFIG_XEN_BLKDEV_TAP is not set
# CONFIG_XEN_SHADOW_MODE is not set
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU
--- a/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU Fri Sep 2
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/char/tpm/Kconfig.domU Fri Sep 2
14:17:08 2005
@@ -19,7 +19,7 @@
config TCG_XEN
tristate "XEN TPM Interface"
- depends on TCG_TPM && ARCH_XEN
+ depends on TCG_TPM && ARCH_XEN && XEN_TPMDEV_FRONTEND
---help---
If you want to make TPM support available to a Xen
user domain, say Yes and it will
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c
--- a/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Fri Sep 2
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/console/xencons_ring.c Fri Sep 2
14:17:08 2005
@@ -105,7 +105,7 @@
xen_start_info.console_evtchn, handle_input,
0, "xencons", inring());
if (err) {
- xprintk(KERN_ERR "XEN console request irq failed %i\n", err);
+ xprintk("XEN console request irq failed %i\n", err);
unbind_evtchn_from_irq(xen_start_info.console_evtchn);
return err;
}
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/drivers/xen/netback/common.h
--- a/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Sep 2 14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/common.h Fri Sep 2 14:17:08 2005
@@ -20,9 +20,12 @@
#include <asm/io.h>
#include <asm/pgalloc.h>
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
+#ifdef CONFIG_XEN_NETDEV_GRANT
#include <asm-xen/xen-public/grant_table.h>
#include <asm-xen/gnttab.h>
+
+#define GRANT_INVALID_REF (0xFFFF)
+
#endif
@@ -37,6 +40,11 @@
#define ASSERT(_p) ((void)0)
#define DPRINTK(_f, _a...) ((void)0)
#endif
+#define IPRINTK(fmt, args...) \
+ printk(KERN_INFO "xen_net: " fmt, ##args)
+#define WPRINTK(fmt, args...) \
+ printk(KERN_WARNING "xen_net: " fmt, ##args)
+
typedef struct netif_st {
/* Unique identifier for this interface. */
@@ -47,13 +55,13 @@
/* Physical parameters of the comms window. */
unsigned long tx_shmem_frame;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
u16 tx_shmem_handle;
unsigned long tx_shmem_vaddr;
grant_ref_t tx_shmem_ref;
#endif
unsigned long rx_shmem_frame;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
u16 rx_shmem_handle;
unsigned long rx_shmem_vaddr;
grant_ref_t rx_shmem_ref;
@@ -68,7 +76,7 @@
/* Private indexes into shared ring. */
NETIF_RING_IDX rx_req_cons;
NETIF_RING_IDX rx_resp_prod; /* private version of shared variable */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
NETIF_RING_IDX rx_resp_prod_copy; /* private version of shared variable */
#endif
NETIF_RING_IDX tx_req_cons;
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/drivers/xen/netback/interface.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Fri Sep 2
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/interface.c Fri Sep 2
14:17:08 2005
@@ -111,91 +111,81 @@
return netif;
}
-static int map_frontend_page(netif_t *netif, unsigned long localaddr,
- unsigned long tx_ring_ref, unsigned long
rx_ring_ref)
-{
-#if !defined(CONFIG_XEN_NETDEV_GRANT_TX)||!defined(CONFIG_XEN_NETDEV_GRANT_RX)
+static int map_frontend_pages(netif_t *netif, unsigned long localaddr,
+ unsigned long tx_ring_ref,
+ unsigned long rx_ring_ref)
+{
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ struct gnttab_map_grant_ref op;
+
+ /* Map: Use the Grant table reference */
+ op.host_addr = localaddr;
+ op.flags = GNTMAP_host_map;
+ op.ref = tx_ring_ref;
+ op.dom = netif->domid;
+
+ BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+ if (op.handle < 0) {
+ DPRINTK(" Grant table operation failure mapping tx_ring_ref!\n");
+ return op.handle;
+ }
+
+ netif->tx_shmem_ref = tx_ring_ref;
+ netif->tx_shmem_handle = op.handle;
+ netif->tx_shmem_vaddr = localaddr;
+
+ /* Map: Use the Grant table reference */
+ op.host_addr = localaddr + PAGE_SIZE;
+ op.flags = GNTMAP_host_map;
+ op.ref = rx_ring_ref;
+ op.dom = netif->domid;
+
+ BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
+ if (op.handle < 0) {
+ DPRINTK(" Grant table operation failure mapping rx_ring_ref!\n");
+ return op.handle;
+ }
+
+ netif->rx_shmem_ref = rx_ring_ref;
+ netif->rx_shmem_handle = op.handle;
+ netif->rx_shmem_vaddr = localaddr + PAGE_SIZE;
+
+#else
pgprot_t prot = __pgprot(_KERNPG_TABLE);
int err;
-#endif
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX)
- {
- struct gnttab_map_grant_ref op;
-
- /* Map: Use the Grant table reference */
- op.host_addr = localaddr;
- op.flags = GNTMAP_host_map;
- op.ref = tx_ring_ref;
- op.dom = netif->domid;
-
- BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
- if (op.handle < 0) {
- DPRINTK(" Grant table operation failure !\n");
- return op.handle;
- }
-
- netif->tx_shmem_ref = tx_ring_ref;
- netif->tx_shmem_handle = op.handle;
- netif->tx_shmem_vaddr = localaddr;
- }
-#else
+
err = direct_remap_area_pages(&init_mm, localaddr,
tx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
prot, netif->domid);
+
+ err |= direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE,
+ rx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
+ prot, netif->domid);
+
if (err)
return err;
#endif
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX)
- {
- struct gnttab_map_grant_ref op;
-
- /* Map: Use the Grant table reference */
- op.host_addr = localaddr + PAGE_SIZE;
- op.flags = GNTMAP_host_map;
- op.ref = rx_ring_ref;
- op.dom = netif->domid;
-
- BUG_ON( HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1) );
- if (op.handle < 0) {
- DPRINTK(" Grant table operation failure !\n");
- return op.handle;
- }
-
- netif->rx_shmem_ref = rx_ring_ref;
- netif->rx_shmem_handle = op.handle;
- netif->rx_shmem_vaddr = localaddr + PAGE_SIZE;
- }
-#else
- err = direct_remap_area_pages(&init_mm, localaddr + PAGE_SIZE,
- rx_ring_ref<<PAGE_SHIFT, PAGE_SIZE,
- prot, netif->domid);
- if (err)
- return err;
-#endif
-
return 0;
}
-static void unmap_frontend_page(netif_t *netif)
-{
-#if defined(CONFIG_XEN_NETDEV_GRANT_RX) || defined(CONFIG_XEN_NETDEV_GRANT_TX)
+static void unmap_frontend_pages(netif_t *netif)
+{
+#ifdef CONFIG_XEN_NETDEV_GRANT
struct gnttab_unmap_grant_ref op;
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+
op.host_addr = netif->tx_shmem_vaddr;
op.handle = netif->tx_shmem_handle;
op.dev_bus_addr = 0;
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
op.host_addr = netif->rx_shmem_vaddr;
op.handle = netif->rx_shmem_handle;
op.dev_bus_addr = 0;
BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_unmap_grant_ref, &op, 1));
#endif
+
+ return;
}
int netif_map(netif_t *netif, unsigned long tx_ring_ref,
@@ -209,8 +199,8 @@
if (vma == NULL)
return -ENOMEM;
- err = map_frontend_page(netif, (unsigned long)vma->addr, tx_ring_ref,
- rx_ring_ref);
+ err = map_frontend_pages(netif, (unsigned long)vma->addr, tx_ring_ref,
+ rx_ring_ref);
if (err) {
vfree(vma->addr);
return err;
@@ -222,7 +212,7 @@
op.u.bind_interdomain.port2 = evtchn;
err = HYPERVISOR_event_channel_op(&op);
if (err) {
- unmap_frontend_page(netif);
+ unmap_frontend_pages(netif);
vfree(vma->addr);
return err;
}
@@ -267,7 +257,7 @@
unregister_netdev(netif->dev);
if (netif->tx) {
- unmap_frontend_page(netif);
+ unmap_frontend_pages(netif);
vfree(netif->tx); /* Frees netif->rx as well. */
}
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/drivers/xen/netback/netback.c
--- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri Sep 2
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri Sep 2
14:17:08 2005
@@ -14,23 +14,6 @@
#include <asm-xen/balloon.h>
#include <asm-xen/xen-public/memory.h>
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-#include <asm-xen/xen-public/grant_table.h>
-#include <asm-xen/gnttab.h>
-#ifdef GRANT_DEBUG
-static void
-dump_packet(int tag, u32 addr, unsigned char *p)
-{
- int i;
-
- printk(KERN_ALERT "#### rx_action %c %08x ", tag & 0xff, addr);
- for (i = 0; i < 20; i++) {
- printk("%02x", p[i]);
- }
- printk("\n");
-}
-#endif
-#endif
static void netif_idx_release(u16 pending_idx);
static void netif_page_release(struct page *page);
@@ -57,7 +40,8 @@
static struct sk_buff_head rx_queue;
static multicall_entry_t rx_mcl[NETIF_RX_RING_SIZE*2+1];
static mmu_update_t rx_mmu[NETIF_RX_RING_SIZE];
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
static gnttab_donate_t grant_rx_op[MAX_PENDING_REQS];
#else
static struct mmuext_op rx_mmuext[NETIF_RX_RING_SIZE];
@@ -88,16 +72,13 @@
static struct sk_buff_head tx_queue;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
static u16 grant_tx_ref[MAX_PENDING_REQS];
static gnttab_unmap_grant_ref_t tx_unmap_ops[MAX_PENDING_REQS];
static gnttab_map_grant_ref_t tx_map_ops[MAX_PENDING_REQS];
+
#else
static multicall_entry_t tx_mcl[MAX_PENDING_REQS];
-#endif
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-#define GRANT_INVALID_REF (0xFFFF)
#endif
static struct list_head net_schedule_list;
@@ -127,7 +108,7 @@
return mfn;
}
-#ifndef CONFIG_XEN_NETDEV_GRANT_RX
+#ifndef CONFIG_XEN_NETDEV_GRANT
static void free_mfn(unsigned long mfn)
{
unsigned long flags;
@@ -200,7 +181,7 @@
dev_kfree_skb(skb);
skb = nskb;
}
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
#ifdef DEBUG_GRANT
printk(KERN_ALERT "#### be_xmit: req_prod=%d req_cons=%d id=%04x
gr=%04x\n",
netif->rx->req_prod,
@@ -246,12 +227,12 @@
static void net_rx_action(unsigned long unused)
{
- netif_t *netif;
+ netif_t *netif = NULL;
s8 status;
u16 size, id, evtchn;
multicall_entry_t *mcl;
mmu_update_t *mmu;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gnttab_donate_t *gop;
#else
struct mmuext_op *mmuext;
@@ -266,7 +247,7 @@
mcl = rx_mcl;
mmu = rx_mmu;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gop = grant_rx_op;
#else
mmuext = rx_mmuext;
@@ -282,7 +263,7 @@
if ( (new_mfn = alloc_mfn()) == 0 )
{
if ( net_ratelimit() )
- printk(KERN_WARNING "Memory squeeze in netback driver.\n");
+ WPRINTK("Memory squeeze in netback driver.\n");
mod_timer(&net_timer, jiffies + HZ);
skb_queue_head(&rx_queue, skb);
break;
@@ -297,7 +278,7 @@
pfn_pte_ma(new_mfn, PAGE_KERNEL), 0);
mcl++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gop->mfn = old_mfn;
gop->domid = netif->domid;
gop->handle = netif->rx->ring[
@@ -340,7 +321,7 @@
mcl->args[3] = DOMID_SELF;
mcl++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mcl[-2].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
#else
mcl[-3].args[MULTI_UVMFLAGS_INDEX] = UVMF_TLB_FLUSH|UVMF_ALL;
@@ -349,9 +330,17 @@
BUG();
mcl = rx_mcl;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- BUG_ON(HYPERVISOR_grant_table_op(
- GNTTABOP_donate, grant_rx_op, gop - grant_rx_op));
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ if(HYPERVISOR_grant_table_op(GNTTABOP_donate, grant_rx_op,
+ gop - grant_rx_op)) {
+ /*
+ ** The other side has given us a bad grant ref, or has no headroom,
+ ** or has gone away. Unfortunately the current grant table code
+ ** doesn't inform us which is the case, so not much we can do.
+ */
+ DPRINTK("net_rx: donate to DOM%u failed; dropping (up to) %d "
+ "packets.\n", grant_rx_op[0].domid, gop - grant_rx_op);
+ }
gop = grant_rx_op;
#else
mmuext = rx_mmuext;
@@ -363,7 +352,7 @@
/* Rederive the machine addresses. */
new_mfn = mcl[0].args[1] >> PAGE_SHIFT;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
old_mfn = 0; /* XXX Fix this so we can free_mfn() on error! */
#else
old_mfn = mmuext[0].mfn;
@@ -380,8 +369,13 @@
/* Check the reassignment error code. */
status = NETIF_RSP_OKAY;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- BUG_ON(gop->status != 0); /* XXX */
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ if(gop->status != 0) {
+ DPRINTK("Bad status %d from grant donate to DOM%u\n",
+ gop->status, netif->domid);
+ /* XXX SMH: should free 'old_mfn' here */
+ status = NETIF_RSP_ERROR;
+ }
#else
if ( unlikely(mcl[1].result != 0) )
{
@@ -404,7 +398,7 @@
netif_put(netif);
dev_kfree_skb(skb);
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mcl++;
gop++;
#else
@@ -420,6 +414,7 @@
notify_via_evtchn(evtchn);
}
+ out:
/* More work to do? */
if ( !skb_queue_empty(&rx_queue) && !timer_pending(&net_timer) )
tasklet_schedule(&net_rx_tasklet);
@@ -496,7 +491,7 @@
inline static void net_tx_action_dealloc(void)
{
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gnttab_unmap_grant_ref_t *gop;
#else
multicall_entry_t *mcl;
@@ -508,7 +503,7 @@
dc = dealloc_cons;
dp = dealloc_prod;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
/*
* Free up any grants we have finished using
*/
@@ -542,7 +537,7 @@
#endif
while ( dealloc_cons != dp )
{
-#ifndef CONFIG_XEN_NETDEV_GRANT_TX
+#ifndef CONFIG_XEN_NETDEV_GRANT
/* The update_va_mapping() must not fail. */
BUG_ON(mcl[0].result != 0);
#endif
@@ -569,7 +564,7 @@
netif_put(netif);
-#ifndef CONFIG_XEN_NETDEV_GRANT_TX
+#ifndef CONFIG_XEN_NETDEV_GRANT
mcl++;
#endif
}
@@ -585,7 +580,7 @@
netif_tx_request_t txreq;
u16 pending_idx;
NETIF_RING_IDX i;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gnttab_map_grant_ref_t *mop;
#else
multicall_entry_t *mcl;
@@ -595,7 +590,7 @@
if ( dealloc_cons != dealloc_prod )
net_tx_action_dealloc();
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mop = tx_map_ops;
#else
mcl = tx_mcl;
@@ -696,7 +691,7 @@
/* Packets passed to netif_rx() must have some headroom. */
skb_reserve(skb, 16);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mop->host_addr = MMAP_VADDR(pending_idx);
mop->dom = netif->domid;
mop->ref = txreq.addr >> PAGE_SHIFT;
@@ -719,7 +714,7 @@
pending_cons++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
if ( (mop - tx_map_ops) >= ARRAY_SIZE(tx_map_ops) )
break;
#else
@@ -729,7 +724,7 @@
#endif
}
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
if ( mop == tx_map_ops )
return;
@@ -752,7 +747,7 @@
memcpy(&txreq, &pending_tx_info[pending_idx].req, sizeof(txreq));
/* Check the remap error code. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
/*
XXX SMH: error returns from grant operations are pretty poorly
specified/thought out, but the below at least conforms with
@@ -826,7 +821,7 @@
netif_rx(skb);
netif->dev->last_rx = jiffies;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mop++;
#else
mcl++;
@@ -949,12 +944,9 @@
!(xen_start_info.flags & SIF_INITDOMAIN) )
return 0;
- printk("Initialising Xen netif backend\n");
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
- printk("#### netback tx using grant tables\n");
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- printk("#### netback rx using grant tables\n");
+ IPRINTK("Initialising Xen netif backend.\n");
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ IPRINTK("Using grant tables.\n");
#endif
/* We can increase reservation by this much in net_rx_action(). */
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c
--- a/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Sep 2
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/netfront/netfront.c Fri Sep 2
14:17:08 2005
@@ -55,9 +55,18 @@
#include <asm/page.h>
#include <asm/uaccess.h>
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
+#ifdef CONFIG_XEN_NETDEV_GRANT
#include <asm-xen/xen-public/grant_table.h>
#include <asm-xen/gnttab.h>
+
+static grant_ref_t gref_tx_head;
+static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1];
+
+static grant_ref_t gref_rx_head;
+static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1];
+
+#define GRANT_INVALID_REF (0xFFFF)
+
#ifdef GRANT_DEBUG
static void
dump_packet(int tag, void *addr, u32 ap)
@@ -71,8 +80,17 @@
}
printk("\n");
}
-#endif
-#endif
+
+#define GDPRINTK(_f, _a...) printk(KERN_ALERT "(file=%s, line=%d) " _f, \
+ __FILE__ , __LINE__ , ## _a )
+#else
+#define dump_packet(x,y,z) ((void)0)
+#define GDPRINTK(_f, _a...) ((void)0)
+#endif
+
+#endif
+
+
#ifndef __GFP_NOWARN
#define __GFP_NOWARN 0
@@ -102,22 +120,10 @@
#define TX_TEST_IDX req_cons /* conservative: not seen all our requests? */
#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
-static grant_ref_t gref_tx_head;
-static grant_ref_t grant_tx_ref[NETIF_TX_RING_SIZE + 1];
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
-static grant_ref_t gref_rx_head;
-static grant_ref_t grant_rx_ref[NETIF_RX_RING_SIZE + 1];
-#endif
-
-#if defined(CONFIG_XEN_NETDEV_GRANT_TX) || defined(CONFIG_XEN_NETDEV_GRANT_RX)
-#define GRANT_INVALID_REF (0xFFFF)
-#endif
#define NETIF_STATE_DISCONNECTED 0
#define NETIF_STATE_CONNECTED 1
+
static unsigned int netif_state = NETIF_STATE_DISCONNECTED;
@@ -279,7 +285,7 @@
for (i = np->tx_resp_cons; i != prod; i++) {
id = np->tx->ring[MASK_NETIF_TX_IDX(i)].resp.id;
skb = np->tx_skbs[id];
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
if (unlikely(gnttab_query_foreign_access(grant_tx_ref[id]) != 0)) {
/* other domain is still using this grant - shouldn't happen
but if it does, we'll try to reclaim the grant later */
@@ -310,7 +316,7 @@
mb();
} while (prod != np->tx->resp_prod);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
out:
#endif
@@ -330,8 +336,8 @@
int i, batch_target;
NETIF_RING_IDX req_prod = np->rx->req_prod;
struct xen_memory_reservation reservation;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- int ref;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ grant_ref_t ref;
#endif
if (unlikely(np->backend_state != BEST_CONNECTED))
@@ -365,9 +371,9 @@
np->rx_skbs[id] = skb;
np->rx->ring[MASK_NETIF_RX_IDX(req_prod + i)].req.id = id;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
ref = gnttab_claim_grant_reference(&gref_rx_head);
- if (unlikely(ref < 0)) {
+ if (unlikely((signed short)ref < 0)) {
printk(KERN_ALERT "#### netfront can't claim rx reference\n");
BUG();
}
@@ -426,8 +432,8 @@
struct net_private *np = netdev_priv(dev);
netif_tx_request_t *tx;
NETIF_RING_IDX i;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
- unsigned int ref;
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ grant_ref_t ref;
unsigned long mfn;
#endif
@@ -464,9 +470,9 @@
tx = &np->tx->ring[MASK_NETIF_TX_IDX(i)].req;
tx->id = id;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
ref = gnttab_claim_grant_reference(&gref_tx_head);
- if (unlikely(ref < 0)) {
+ if (unlikely((signed short)ref < 0)) {
printk(KERN_ALERT "#### netfront can't claim tx grant reference\n");
BUG();
}
@@ -519,7 +525,7 @@
network_tx_buf_gc(dev);
spin_unlock_irqrestore(&np->tx_lock, flags);
- if ((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state ==
UST_OPEN))
+ if((np->rx_resp_cons != np->rx->resp_prod) && (np->user_state == UST_OPEN))
netif_rx_schedule(dev);
return IRQ_HANDLED;
@@ -537,7 +543,7 @@
int work_done, budget, more_to_do = 1;
struct sk_buff_head rxq;
unsigned long flags;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
unsigned long mfn;
grant_ref_t ref;
#endif
@@ -574,8 +580,19 @@
continue;
}
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- ref = grant_rx_ref[rx->id];
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ ref = grant_rx_ref[rx->id];
+
+ if(ref == GRANT_INVALID_REF) {
+ printk(KERN_WARNING "Bad rx grant reference %d from dom %d.\n",
+ ref, np->backend_id);
+ np->rx->ring[MASK_NETIF_RX_IDX(np->rx->req_prod)].req.id = rx->id;
+ wmb();
+ np->rx->req_prod++;
+ work_done--;
+ continue;
+ }
+
grant_rx_ref[rx->id] = GRANT_INVALID_REF;
mfn = gnttab_end_foreign_transfer_ref(ref);
gnttab_release_grant_reference(&gref_rx_head, ref);
@@ -585,7 +602,7 @@
ADD_ID_TO_FREELIST(np->rx_skbs, rx->id);
/* NB. We handle skb overflow later. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
skb->data = skb->head + rx->addr;
#else
skb->data = skb->head + (rx->addr & ~PAGE_MASK);
@@ -600,14 +617,14 @@
np->stats.rx_bytes += rx->status;
/* Remap the page. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
mmu->ptr = mfn << PAGE_SHIFT | MMU_MACHPHYS_UPDATE;
#else
mmu->ptr = (rx->addr & PAGE_MASK) | MMU_MACHPHYS_UPDATE;
#endif
mmu->val = __pa(skb->head) >> PAGE_SHIFT;
mmu++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
MULTI_update_va_mapping(mcl, (unsigned long)skb->head,
pfn_pte_ma(mfn, PAGE_KERNEL), 0);
#else
@@ -617,19 +634,19 @@
#endif
mcl++;
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] = mfn;
+ GDPRINTK("#### rx_poll enqueue vdata=%p mfn=%lu ref=%x\n",
+ skb->data, mfn, ref);
#else
phys_to_machine_mapping[__pa(skb->head) >> PAGE_SHIFT] =
rx->addr >> PAGE_SHIFT;
-#endif
-
-#ifdef GRANT_DEBUG
- printk(KERN_ALERT "#### rx_poll enqueue vdata=%p mfn=%lu ref=%x\n",
- skb->data, mfn, ref);
-#endif
+#endif
+
+
__skb_queue_tail(&rxq, skb);
}
+
/* Some pages are no longer absent... */
balloon_update_driver_allowance(-work_done);
@@ -646,9 +663,9 @@
}
while ((skb = __skb_dequeue(&rxq)) != NULL) {
-#ifdef GRANT_DEBUG
- printk(KERN_ALERT "#### rx_poll dequeue vdata=%p mfn=%lu\n",
- skb->data, virt_to_mfn(skb->data));
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ GDPRINTK("#### rx_poll dequeue vdata=%p mfn=%lu\n",
+ skb->data, virt_to_mfn(skb->data));
dump_packet('d', skb->data, (unsigned long)skb->data);
#endif
/*
@@ -747,7 +764,6 @@
return &np->stats;
}
-
static void network_connect(struct net_device *dev)
{
struct net_private *np;
@@ -787,8 +803,11 @@
tx = &np->tx->ring[requeue_idx++].req;
tx->id = i;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
- tx->addr = 0; /*(ref << PAGE_SHIFT) |*/
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ gnttab_grant_foreign_access_ref(grant_tx_ref[i], np->backend_id,
+ virt_to_mfn(np->tx_skbs[i]->data),
+ GNTMAP_readonly);
+ tx->addr = grant_tx_ref[i] << PAGE_SHIFT;
#else
tx->addr = virt_to_mfn(skb->data) << PAGE_SHIFT;
#endif
@@ -803,9 +822,20 @@
np->tx->req_prod = requeue_idx;
/* Rebuild the RX buffer freelist and the RX ring itself. */
- for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++)
- if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET)
- np->rx->ring[requeue_idx++].req.id = i;
+ for (requeue_idx = 0, i = 1; i <= NETIF_RX_RING_SIZE; i++) {
+ if ((unsigned long)np->rx_skbs[i] >= __PAGE_OFFSET) {
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ /* Reinstate the grant ref so backend can 'donate' mfn to us. */
+ gnttab_grant_foreign_transfer_ref(grant_rx_ref[i], np->backend_id,
+ virt_to_mfn(np->rx_skbs[i]->head)
+ );
+ np->rx->ring[requeue_idx].req.gref = grant_rx_ref[i];
+#endif
+ np->rx->ring[requeue_idx].req.id = i;
+ requeue_idx++;
+ }
+ }
+
wmb();
np->rx->req_prod = requeue_idx;
@@ -901,13 +931,14 @@
/* Initialise {tx,rx}_skbs to be a free chain containing every entry. */
for (i = 0; i <= NETIF_TX_RING_SIZE; i++) {
np->tx_skbs[i] = (void *)((unsigned long) i+1);
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
grant_tx_ref[i] = GRANT_INVALID_REF;
#endif
}
+
for (i = 0; i <= NETIF_RX_RING_SIZE; i++) {
np->rx_skbs[i] = (void *)((unsigned long) i+1);
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
grant_rx_ref[i] = GRANT_INVALID_REF;
#endif
}
@@ -991,10 +1022,8 @@
evtchn_op_t op = { .cmd = EVTCHNOP_alloc_unbound };
int err;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
info->tx_ring_ref = GRANT_INVALID_REF;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
info->rx_ring_ref = GRANT_INVALID_REF;
#endif
@@ -1014,7 +1043,7 @@
memset(info->rx, 0, PAGE_SIZE);
info->backend_state = BEST_DISCONNECTED;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
err = gnttab_grant_foreign_access(info->backend_id,
virt_to_mfn(info->tx), 0);
if (err < 0) {
@@ -1022,11 +1051,7 @@
goto out;
}
info->tx_ring_ref = err;
-#else
- info->tx_ring_ref = virt_to_mfn(info->tx);
-#endif
-
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
err = gnttab_grant_foreign_access(info->backend_id,
virt_to_mfn(info->rx), 0);
if (err < 0) {
@@ -1034,7 +1059,9 @@
goto out;
}
info->rx_ring_ref = err;
+
#else
+ info->tx_ring_ref = virt_to_mfn(info->tx);
info->rx_ring_ref = virt_to_mfn(info->rx);
#endif
@@ -1054,16 +1081,17 @@
if (info->rx)
free_page((unsigned long)info->rx);
info->rx = 0;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
if (info->tx_ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->tx_ring_ref, 0);
info->tx_ring_ref = GRANT_INVALID_REF;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
if (info->rx_ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->rx_ring_ref, 0);
info->rx_ring_ref = GRANT_INVALID_REF;
#endif
+
return err;
}
@@ -1075,16 +1103,17 @@
if (info->rx)
free_page((unsigned long)info->rx);
info->rx = 0;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
if (info->tx_ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->tx_ring_ref, 0);
info->tx_ring_ref = GRANT_INVALID_REF;
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+
if (info->rx_ring_ref != GRANT_INVALID_REF)
gnttab_end_foreign_access(info->rx_ring_ref, 0);
info->rx_ring_ref = GRANT_INVALID_REF;
#endif
+
unbind_evtchn_from_irqhandler(info->evtchn, info->netdev);
info->evtchn = 0;
}
@@ -1294,6 +1323,7 @@
int err;
err = talk_to_backend(dev, np);
+
return err;
}
@@ -1342,29 +1372,28 @@
if (xen_start_info.flags & SIF_INITDOMAIN)
return 0;
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
- /* A grant for every ring slot */
+ if ((err = xennet_proc_init()) != 0)
+ return err;
+
+ IPRINTK("Initialising virtual ethernet driver.\n");
+
+#ifdef CONFIG_XEN_NETDEV_GRANT
+ IPRINTK("Using grant tables.\n");
+
+ /* A grant for every tx ring slot */
if (gnttab_alloc_grant_references(NETIF_TX_RING_SIZE,
&gref_tx_head) < 0) {
printk(KERN_ALERT "#### netfront can't alloc tx grant refs\n");
return 1;
}
- printk(KERN_ALERT "Netdev frontend (TX) is using grant tables.\n");
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
- /* A grant for every ring slot */
+ /* A grant for every rx ring slot */
if (gnttab_alloc_grant_references(NETIF_RX_RING_SIZE,
&gref_rx_head) < 0) {
printk(KERN_ALERT "#### netfront can't alloc rx grant refs\n");
return 1;
}
- printk(KERN_ALERT "Netdev frontend (RX) is using grant tables.\n");
-#endif
-
- if ((err = xennet_proc_init()) != 0)
- return err;
-
- IPRINTK("Initialising virtual ethernet driver.\n");
+#endif
+
(void)register_inetaddr_notifier(¬ifier_inetdev);
@@ -1377,10 +1406,8 @@
static void netif_exit(void)
{
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
gnttab_free_grant_references(gref_tx_head);
-#endif
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
gnttab_free_grant_references(gref_rx_head);
#endif
}
diff -r edd1616cf8cb -r 291e816acbf4
linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c
--- a/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Fri Sep 2
14:15:49 2005
+++ b/linux-2.6-xen-sparse/drivers/xen/xenbus/xenbus_comms.c Fri Sep 2
14:17:08 2005
@@ -212,7 +212,7 @@
xen_start_info.store_evtchn, wake_waiting,
0, "xenbus", &xb_waitq);
if (err) {
- printk(KERN_ERR "XENBUS request irq failed %i\n", err);
+ xprintk("XENBUS request irq failed %i\n", err);
unbind_evtchn_from_irq(xen_start_info.store_evtchn);
return err;
}
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_brctl
--- a/tools/check/check_brctl Fri Sep 2 14:15:49 2005
+++ b/tools/check/check_brctl Fri Sep 2 14:17:08 2005
@@ -2,8 +2,9 @@
# CHECK-INSTALL
function error {
- echo 'Check for the bridge control utils (brctl) failed.'
+ echo
+ echo ' *** Check for the bridge control utils (brctl) FAILED'
exit 1
}
-brctl show || error
\ No newline at end of file
+which brctl 1>/dev/null 2>&1 || error
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_iproute
--- a/tools/check/check_iproute Fri Sep 2 14:15:49 2005
+++ b/tools/check/check_iproute Fri Sep 2 14:17:08 2005
@@ -2,9 +2,10 @@
# CHECK-INSTALL
function error {
- echo 'Check for iproute (ip addr) failed.'
+ echo
+ echo ' *** Check for iproute (ip addr) FAILED'
exit 1
}
-ip addr list || error
+ip addr list 1>/dev/null 2>&1 || error
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_logging
--- a/tools/check/check_logging Fri Sep 2 14:15:49 2005
+++ b/tools/check/check_logging Fri Sep 2 14:17:08 2005
@@ -18,11 +18,12 @@
import logging
except ImportError:
hline()
- msg("Python logging is not installed.")
- msg("Use 'make install-logging' at the xen root to install.")
msg("")
- msg("Alternatively download and install from")
- msg("http://www.red-dove.com/python_logging.html")
+ msg(" *** Python logging is not installed.")
+ msg(" *** Use 'make install-logging' at the xen root to install.")
+ msg(" *** ")
+ msg(" *** Alternatively download and install from")
+ msg(" *** http://www.red-dove.com/python_logging.html")
hline()
sys.exit(1)
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_python
--- a/tools/check/check_python Fri Sep 2 14:15:49 2005
+++ b/tools/check/check_python Fri Sep 2 14:17:08 2005
@@ -2,9 +2,9 @@
# CHECK-BUILD CHECK-INSTALL
function error {
- echo "Check for Python version 2.2 or higher failed."
+ echo
+ echo " *** Check for Python version >= 2.2 FAILED"
exit 1
}
-python -V
python -V 2>&1 | cut -d ' ' -f 2 | grep -q -E '^2.2|^2.3|^2.4' || error
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_zlib_devel
--- a/tools/check/check_zlib_devel Fri Sep 2 14:15:49 2005
+++ b/tools/check/check_zlib_devel Fri Sep 2 14:17:08 2005
@@ -2,9 +2,10 @@
# CHECK-BUILD
function error {
- echo 'Check for zlib includes failed.'
+ echo
+ echo " *** Check for zlib headers FAILED"
exit 1
}
set -e
-[ -e /usr/include/zlib.h ] || error
\ No newline at end of file
+[ -e /usr/include/zlib.h ] || error
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/check_zlib_lib
--- a/tools/check/check_zlib_lib Fri Sep 2 14:15:49 2005
+++ b/tools/check/check_zlib_lib Fri Sep 2 14:17:08 2005
@@ -2,9 +2,10 @@
# CHECK-BUILD CHECK-INSTALL
function error {
- echo 'Check for zlib library failed.'
+ echo
+ echo " *** Check for zlib library FAILED"
exit 1
}
set -e
-ldconfig -p | grep libz.so || error
\ No newline at end of file
+ldconfig -p | grep -q libz.so || error
diff -r edd1616cf8cb -r 291e816acbf4 tools/check/chk
--- a/tools/check/chk Fri Sep 2 14:15:49 2005
+++ b/tools/check/chk Fri Sep 2 14:17:08 2005
@@ -17,14 +17,11 @@
case $1 in
build)
check="CHECK-BUILD"
- info=".chkbuild"
;;
install)
check="CHECK-INSTALL"
- info=".chkinstall"
;;
clean)
- rm -f .chkbuild .chkinstall
exit 0
;;
*)
@@ -34,7 +31,7 @@
failed=0
-echo "Xen ${check} " $(date) > ${info}
+echo "Xen ${check} " $(date)
for f in check_* ; do
case $f in
*~)
@@ -49,24 +46,12 @@
if ! grep -q ${check} $f ; then
continue
fi
- echo ' ' >> ${info}
- echo "Checking $f" >> ${info}
- if ./$f 1>>${info} 2>&1 ; then
- echo OK >> ${info}
+ echo -n "Checking $f: "
+ if ./$f 2>&1 ; then
+ echo OK
else
failed=1
- echo "FAILED $f"
- echo FAILED >> ${info}
fi
done
-echo >> ${info}
-
-if [ "$failed" == "1" ] ; then
- echo "Checks failed. See `pwd`/${info} for details."
- echo "FAILED" >> ${info}
- exit 1
-else
- echo "OK" >> ${info}
- exit 0
-fi
+exit $failed
diff -r edd1616cf8cb -r 291e816acbf4 tools/console/daemon/utils.c
--- a/tools/console/daemon/utils.c Fri Sep 2 14:15:49 2005
+++ b/tools/console/daemon/utils.c Fri Sep 2 14:17:08 2005
@@ -234,7 +234,7 @@
}
if (!xs_watch(xs, "/console", "console")) {
- dolog(LOG_ERR, "xenstore watch on /console failes.");
+ dolog(LOG_ERR, "xenstore watch on /console fails.");
goto out_close_data;
}
diff -r edd1616cf8cb -r 291e816acbf4 tools/python/xen/xend/XendDomainInfo.py
--- a/tools/python/xen/xend/XendDomainInfo.py Fri Sep 2 14:15:49 2005
+++ b/tools/python/xen/xend/XendDomainInfo.py Fri Sep 2 14:17:08 2005
@@ -1028,6 +1028,7 @@
"""
try:
+ self.clear_shutdown()
self.state = STATE_VM_OK
self.shutdown_pending = None
self.restart_check()
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/Makefile
--- a/tools/security/Makefile Fri Sep 2 14:15:49 2005
+++ b/tools/security/Makefile Fri Sep 2 14:17:08 2005
@@ -45,6 +45,7 @@
$(MAKE) secpol_xml2bin
chmod 700 ./setlabel.sh
chmod 700 ./updategrub.sh
+ chmod 700 ./getlabel.sh
secpol_tool : secpol_tool.c secpol_compat.h
$(CC) $(CPPFLAGS) $(CFLAGS) -o $@ $<
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/secpol_tool.c
--- a/tools/security/secpol_tool.c Fri Sep 2 14:15:49 2005
+++ b/tools/security/secpol_tool.c Fri Sep 2 14:17:08 2005
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
+#include <getopt.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
@@ -40,6 +41,17 @@
#define PERROR(_m, _a...) \
fprintf(stderr, "ERROR: " _m " (%d = %s)\n" , ## _a , \
errno, strerror(errno))
+
+void usage(char *progname)
+{
+ printf("Use: %s \n"
+ "\t getpolicy\n"
+ "\t dumpstats\n"
+ "\t loadpolicy <binary policy file>\n"
+ "\t getssid -d <domainid> [-f]\n"
+ "\t getssid -s <ssidref> [-f]\n", progname);
+ exit(-1);
+}
static inline int do_policycmd(int xc_handle, unsigned int cmd,
unsigned long data)
@@ -320,7 +332,7 @@
if (ret)
printf
- ("ERROR setting policy. Use 'xm dmesg' to see details.\n");
+ ("ERROR setting policy. Try 'xm dmesg' to see details.\n");
else
printf("Successfully changed policy.\n");
@@ -370,7 +382,7 @@
if (ret < 0)
{
- printf("ERROR dumping policy stats. Use 'xm dmesg' to see details.\n");
+ printf("ERROR dumping policy stats. Try 'xm dmesg' to see details.\n");
return ret;
}
stats = (struct acm_stats_buffer *) stats_buffer;
@@ -421,17 +433,121 @@
}
return ret;
}
+/************************ get ssidref & types ******************************/
+/*
+ * the ssid (types) can be looked up either by domain id or by ssidref
+ */
+int acm_domain_getssid(int xc_handle, int argc, char * const argv[])
+{
+ /* this includes header and a set of types */
+ #define MAX_SSIDBUFFER 2000
+ int ret, i;
+ acm_op_t op;
+ struct acm_ssid_buffer *hdr;
+ unsigned char *buf;
+ int nice_print = 1;
+
+ op.cmd = ACM_GETSSID;
+ op.interface_version = ACM_INTERFACE_VERSION;
+ op.u.getssid.get_ssid_by = UNSET;
+ /* arguments
+ -d ... domain id to look up
+ -s ... ssidref number to look up
+ -f ... formatted print (scripts depend on this format)
+ */
+ while (1)
+ {
+ int c = getopt(argc, argv, "d:s:f");
+ if (c == -1)
+ break;
+ if (c == 'd')
+ {
+ if (op.u.getssid.get_ssid_by != UNSET)
+ usage(argv[0]);
+ op.u.getssid.get_ssid_by = DOMAINID;
+ op.u.getssid.id.domainid = strtoul(optarg, NULL, 0);
+ }
+ else if (c== 's')
+ {
+ if (op.u.getssid.get_ssid_by != UNSET)
+ usage(argv[0]);
+ op.u.getssid.get_ssid_by = SSIDREF;
+ op.u.getssid.id.ssidref = strtoul(optarg, NULL, 0);
+ }
+ else if (c== 'f')
+ {
+ nice_print = 0;
+ }
+ else
+ usage(argv[0]);
+ }
+ if (op.u.getssid.get_ssid_by == UNSET)
+ usage(argv[0]);
+
+ buf = malloc(MAX_SSIDBUFFER);
+ if (!buf)
+ return -ENOMEM;
+
+ /* dump it and then push it down into xen/acm */
+ op.u.getssid.ssidbuf = buf; /* out */
+ op.u.getssid.ssidbuf_size = MAX_SSIDBUFFER;
+ ret = do_acm_op(xc_handle, &op);
+
+ if (ret)
+ {
+ printf("ERROR getting ssidref. Try 'xm dmesg' to see details.\n");
+ goto out;
+ }
+ hdr = (struct acm_ssid_buffer *)buf;
+ if (hdr->len > MAX_SSIDBUFFER)
+ {
+ printf("ERROR: Buffer length inconsistent (ret=%d, hdr->len=%d)!\n",
+ ret, hdr->len);
+ return -EIO;
+ }
+ if (nice_print)
+ {
+ printf("SSID: ssidref = 0x%08x \n", hdr->ssidref);
+ printf(" P: %s, max_types = %d\n",
+ ACM_POLICY_NAME(hdr->primary_policy_code),
hdr->primary_max_types);
+ printf(" Types: ");
+ for (i=0; i< hdr->primary_max_types; i++)
+ if (buf[hdr->primary_types_offset + i])
+ printf("%02x ", i);
+ else
+ printf("-- ");
+ printf("\n");
+
+ printf(" S: %s, max_types = %d\n",
+ ACM_POLICY_NAME(hdr->secondary_policy_code),
hdr->secondary_max_types);
+ printf(" Types: ");
+ for (i=0; i< hdr->secondary_max_types; i++)
+ if (buf[hdr->secondary_types_offset + i])
+ printf("%02x ", i);
+ else
+ printf("-- ");
+ printf("\n");
+ }
+ else
+ {
+ /* formatted print for use with scripts (.sh)
+ * update scripts when updating here (usually
+ * used in combination with -d to determine a
+ * running domain's label
+ */
+ printf("SSID: ssidref = 0x%08x \n", hdr->ssidref);
+ }
+
+ /* return ste ssidref */
+ if (hdr->primary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+ ret = (hdr->ssidref) & 0xffff;
+ else if (hdr->secondary_policy_code == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+ ret = (hdr->ssidref) >> 16;
+ out:
+ return ret;
+}
/***************************** main **************************************/
-
-void usage(char *progname)
-{
- printf("Use: %s \n"
- "\t getpolicy\n"
- "\t dumpstats\n"
- "\t loadpolicy <binary policy file>\n", progname);
- exit(-1);
-}
int main(int argc, char **argv)
{
@@ -459,6 +575,8 @@
if (argc != 2)
usage(argv[0]);
ret = acm_domain_dumpstats(acm_cmd_fd);
+ } else if (!strcmp(argv[1], "getssid")) {
+ ret = acm_domain_getssid(acm_cmd_fd, argc, argv);
} else
usage(argv[0]);
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/setlabel.sh
--- a/tools/security/setlabel.sh Fri Sep 2 14:15:49 2005
+++ b/tools/security/setlabel.sh Fri Sep 2 14:17:08 2005
@@ -34,275 +34,27 @@
exec sh -c "bash $0 $*"
fi
+export PATH=$PATH:.
+source labelfuncs.sh
usage ()
{
- echo "Usage: $0 [Option] <vmfile> <label> <policy name> "
- echo " or $0 -l <policy name>"
+ echo "Usage: $0 [Option] <vmfile> <label> [<policy name>]"
+ echo " or $0 -l [<policy name>]"
echo ""
- echo "Valid Options are:"
+ echo "Valid options are:"
echo "-r : to relabel a file without being prompted"
echo ""
echo "vmfile : XEN vm configuration file"
- echo "label : the label to map"
+ echo "label : the label to map to an ssidref"
echo "policy name : the name of the policy, i.e. 'chwall'"
+ echo " If the policy name is omitted, it is attempted"
+ echo " to find the current policy's name in grub.conf."
echo ""
- echo "-l <policy name> is used to show valid labels in the map file"
+ echo "-l [<policy name>] is used to show valid labels in the map file
of"
+ echo " the given or current policy."
echo ""
}
-
-
-findMapFile ()
-{
- mapfile="./$1.map"
- if [ -r "$mapfile" ]; then
- return 1
- fi
-
- mapfile="./policies/$1/$1.map"
- if [ -r "$mapfile" ]; then
- return 1
- fi
-
- return 0
-}
-
-showLabels ()
-{
- mapfile=$1
- if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
- echo "Cannot read from vm configuration file $vmfile."
- return -1
- fi
-
- getPrimaryPolicy $mapfile
- getSecondaryPolicy $mapfile
-
- echo "The following labels are available:"
- let line=1
- while [ 1 ]; do
- ITEM=`cat $mapfile | \
- awk -vline=$line \
- -vprimary=$primary \
- '{ \
- if ($1 == "LABEL->SSID" && \
- $2 == "VM" && \
- $3 == primary ) { \
- ctr++; \
- if (ctr == line) { \
- print $4; \
- } \
- } \
- } END { \
- }'`
-
- if [ "$ITEM" == "" ]; then
- break
- fi
- if [ "$secondary" != "NULL" ]; then
- LABEL=`cat $mapfile | \
- awk -vitem=$ITEM \
- '{
- if ($1 == "LABEL->SSID" && \
- $2 == "VM" && \
- $3 == "CHWALL" && \
- $4 == item ) { \
- result = item; \
- } \
- } END { \
- print result \
- }'`
- else
- LABEL=$ITEM
- fi
-
- if [ "$LABEL" != "" ]; then
- echo "$LABEL"
- found=1
- fi
- let line=line+1
- done
- if [ "$found" != "1" ]; then
- echo "No labels found."
- fi
-}
-
-getPrimaryPolicy ()
-{
- mapfile=$1
- primary=`cat $mapfile | \
- awk ' \
- { \
- if ( $1 == "PRIMARY" ) { \
- res=$2; \
- } \
- } END { \
- print res; \
- } '`
-}
-
-getSecondaryPolicy ()
-{
- mapfile=$1
- secondary=`cat $mapfile | \
- awk ' \
- { \
- if ( $1 == "SECONDARY" ) { \
- res=$2; \
- } \
- } END { \
- print res; \
- } '`
-}
-
-
-getDefaultSsid ()
-{
- mapfile=$1
- pol=$2
- RES=`cat $mapfile \
- awk -vpol=$pol \
- { \
- if ($1 == "LABEL->SSID" && \
- $2 == "ANY" && \
- $3 == pol && \
- $4 == "DEFAULT" ) {\
- res=$5; \
- } \
- } END { \
- printf "%04x", strtonum(res) \
- }'`
- echo "default NULL mapping is $RES"
- defaultssid=$RES
-}
-
-relabel ()
-{
- vmfile=$1
- label=$2
- mapfile=$3
- mode=$4
-
- if [ ! -r "$vmfile" ]; then
- echo "Cannot read from vm configuration file $vmfile."
- return -1
- fi
-
- if [ ! -w "$vmfile" ]; then
- echo "Cannot write to vm configuration file $vmfile."
- return -1
- fi
-
- if [ ! -r "$mapfile" ] ; then
- echo "Cannot read mapping file $mapfile."
- return -1
- fi
-
- # Determine which policy is primary, which sec.
- getPrimaryPolicy $mapfile
- getSecondaryPolicy $mapfile
-
- # Calculate the primary policy's SSIDREF
- if [ "$primary" == "NULL" ]; then
- SSIDLO="0000"
- else
- SSIDLO=`cat $mapfile | \
- awk -vlabel=$label \
- -vprimary=$primary \
- '{ \
- if ( $1 == "LABEL->SSID" && \
- $2 == "VM" && \
- $3 == primary && \
- $4 == label ) { \
- result=$5 \
- } \
- } END { \
- if (result != "" ) \
- {printf "%04x", strtonum(result)}\
- }'`
- fi
-
- # Calculate the secondary policy's SSIDREF
- if [ "$secondary" == "NULL" ]; then
- SSIDHI="0000"
- else
- SSIDHI=`cat $mapfile | \
- awk -vlabel=$label \
- -vsecondary=$secondary \
- '{ \
- if ( $1 == "LABEL->SSID" && \
- $2 == "VM" && \
- $3 == secondary && \
- $4 == label ) { \
- result=$5 \
- } \
- } END { \
- if (result != "" ) \
- {printf "%04x", strtonum(result)}\
- }'`
- fi
-
- if [ "$SSIDLO" == "" -o \
- "$SSIDHI" == "" ]; then
- echo "Could not map the given label '$label'."
- return -1
- fi
-
- ACM_POLICY=`cat $mapfile | \
- awk ' { if ( $1 == "POLICY" ) { \
- result=$2 \
- } \
- } \
- END { \
- if (result != "") { \
- printf result \
- } \
- }'`
-
- if [ "$ACM_POLICY" == "" ]; then
- echo "Could not find 'POLICY' entry in map file."
- return -1
- fi
-
- SSIDREF="0x$SSIDHI$SSIDLO"
-
- if [ "$mode" != "relabel" ]; then
- RES=`cat $vmfile | \
- awk '{ \
- if ( substr($1,0,7) == "ssidref" ) {\
- print $0; \
- } \
- }'`
- if [ "$RES" != "" ]; then
- echo "Do you want to overwrite the existing mapping
($RES)? (y/N)"
- read user
- if [ "$user" != "y" -a "$user" != "Y" ]; then
- echo "Aborted."
- return 0
- fi
- fi
- fi
-
- #Write the output
- vmtmp1="/tmp/__setlabel.tmp1"
- vmtmp2="/tmp/__setlabel.tmp2"
- touch $vmtmp1
- touch $vmtmp2
- if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then
- echo "Cannot create temporary files. Aborting."
- return -1
- fi
- RES=`sed -e '/^#ACM_POLICY/d' $vmfile > $vmtmp1`
- RES=`sed -e '/^#ACM_LABEL/d' $vmtmp1 > $vmtmp2`
- RES=`sed -e '/^ssidref/d' $vmtmp2 > $vmtmp1`
- echo "#ACM_POLICY=$ACM_POLICY" >> $vmtmp1
- echo "#ACM_LABEL=$label" >> $vmtmp1
- echo "ssidref = $SSIDREF" >> $vmtmp1
- mv -f $vmtmp1 $vmfile
- rm -rf $vmtmp1 $vmtmp2
- echo "Mapped label '$label' to ssidref '$SSIDREF'."
-}
-
if [ "$1" == "-r" ]; then
@@ -317,10 +69,25 @@
if [ "$mode" == "show" ]; then
if [ "$1" == "" ]; then
- usage
- exit -1;
+ findGrubConf
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo "Could not find grub.conf"
+ exit -1;
+ fi
+ findPolicyInGrub $grubconf
+ if [ "$policy" != "" ]; then
+ echo "Assuming policy to be '$policy'.";
+ else
+ echo "Could not find policy."
+ exit -1;
+ fi
+ else
+ policy=$3;
fi
- findMapFile $1
+
+
+ findMapFile $policy
res=$?
if [ "$res" != "0" ]; then
showLabels $mapfile
@@ -330,11 +97,29 @@
elif [ "$mode" == "usage" ]; then
usage
else
+ if [ "$2" == "" ]; then
+ usage
+ exit -1
+ fi
if [ "$3" == "" ]; then
- usage
- exit -1;
+ findGrubConf
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo "Could not find grub.conf"
+ exit -1;
+ fi
+ findPolicyInGrub $grubconf
+ if [ "$policy" != "" ]; then
+ echo "Assuming policy to be '$policy'.";
+ else
+ echo "Could not find policy."
+ exit -1;
+ fi
+
+ else
+ policy=$3;
fi
- findMapFile $3
+ findMapFile $policy
res=$?
if [ "$res" != "0" ]; then
relabel $1 $2 $mapfile $mode
diff -r edd1616cf8cb -r 291e816acbf4 xen/Rules.mk
--- a/xen/Rules.mk Fri Sep 2 14:15:49 2005
+++ b/xen/Rules.mk Fri Sep 2 14:17:08 2005
@@ -7,7 +7,6 @@
perfc ?= n
perfc_arrays?= n
trace ?= n
-optimize ?= y
domu_debug ?= n
crash_debug ?= n
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_chinesewall_hooks.c
--- a/xen/acm/acm_chinesewall_hooks.c Fri Sep 2 14:15:49 2005
+++ b/xen/acm/acm_chinesewall_hooks.c Fri Sep 2 14:17:08 2005
@@ -310,6 +310,28 @@
return 0;
}
+static int
+chwall_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len)
+{
+ int i;
+
+ /* fill in buffer */
+ if (chwall_bin_pol.max_types > len)
+ return -EFAULT;
+
+ if (ssidref >= chwall_bin_pol.max_ssidrefs)
+ return -EFAULT;
+
+ /* read types for chwall ssidref */
+ for(i=0; i< chwall_bin_pol.max_types; i++) {
+ if (chwall_bin_pol.ssidrefs[ssidref * chwall_bin_pol.max_types + i])
+ buf[i] = 1;
+ else
+ buf[i] = 0;
+ }
+ return chwall_bin_pol.max_types;
+}
+
/***************************
* Authorization functions
***************************/
@@ -492,6 +514,7 @@
.dump_binary_policy = chwall_dump_policy,
.set_binary_policy = chwall_set_policy,
.dump_statistics = chwall_dump_stats,
+ .dump_ssid_types = chwall_dump_ssid_types,
/* domain management control hooks */
.pre_domain_create = chwall_pre_domain_create,
.post_domain_create = chwall_post_domain_create,
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_core.c
--- a/xen/acm/acm_core.c Fri Sep 2 14:15:49 2005
+++ b/xen/acm/acm_core.c Fri Sep 2 14:17:08 2005
@@ -64,16 +64,17 @@
void acm_set_endian(void)
{
u32 test = 1;
- if (*((u8 *)&test) == 1) {
+ if (*((u8 *)&test) == 1)
+ {
printk("ACM module running in LITTLE ENDIAN.\n");
- little_endian = 1;
- } else {
- printk("ACM module running in BIG ENDIAN.\n");
- little_endian = 0;
- }
-}
-
-#if (ACM_USE_SECURITY_POLICY != ACM_NULL_POLICY)
+ little_endian = 1;
+ }
+ else
+ {
+ printk("ACM module running in BIG ENDIAN.\n");
+ little_endian = 0;
+ }
+}
/* initialize global security policy for Xen; policy write-locked already */
static void
@@ -101,7 +102,8 @@
* Try all modules and see whichever could be the binary policy.
* Adjust the initrdidx if module[1] is the binary policy.
*/
- for (i = mbi->mods_count-1; i >= 1; i--) {
+ for (i = mbi->mods_count-1; i >= 1; i--)
+ {
struct acm_policy_buffer *pol;
char *_policy_start;
unsigned long _policy_len;
@@ -117,23 +119,32 @@
continue; /* not a policy */
pol = (struct acm_policy_buffer *)_policy_start;
- if (ntohl(pol->magic) == ACM_MAGIC) {
+ if (ntohl(pol->magic) == ACM_MAGIC)
+ {
rc = acm_set_policy((void *)_policy_start,
(u16)_policy_len,
0);
- if (rc == ACM_OK) {
+ if (rc == ACM_OK)
+ {
printf("Policy len 0x%lx, start at
%p.\n",_policy_len,_policy_start);
- if (i == 1) {
- if (mbi->mods_count > 2) {
+ if (i == 1)
+ {
+ if (mbi->mods_count > 2)
+ {
*initrdidx = 2;
- } else {
+ }
+ else {
*initrdidx = 0;
}
- } else {
+ }
+ else
+ {
*initrdidx = 1;
}
break;
- } else {
+ }
+ else
+ {
printk("Invalid policy. %d.th module line.\n", i+1);
}
} /* end if a binary policy definition, i.e., (ntohl(pol->magic) ==
ACM_MAGIC ) */
@@ -147,56 +158,84 @@
const multiboot_info_t *mbi,
unsigned long initial_images_start)
{
- int ret = -EINVAL;
-
- acm_set_endian();
+ int ret = ACM_OK;
+
+ acm_set_endian();
write_lock(&acm_bin_pol_rwlock);
-
- if (ACM_USE_SECURITY_POLICY == ACM_CHINESE_WALL_POLICY) {
- acm_init_binary_policy(NULL, NULL);
- acm_init_chwall_policy();
+ acm_init_binary_policy(NULL, NULL);
+
+ /* set primary policy component */
+ switch ((ACM_USE_SECURITY_POLICY) & 0x0f)
+ {
+
+ case ACM_CHINESE_WALL_POLICY:
+ acm_init_chwall_policy();
acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
acm_primary_ops = &acm_chinesewall_ops;
+ break;
+
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ acm_init_ste_policy();
+ acm_bin_pol.primary_policy_code =
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
+ acm_primary_ops = &acm_simple_type_enforcement_ops;
+ break;
+
+ default:
+ /* NULL or Unknown policy not allowed primary;
+ * NULL/NULL will not compile this code */
+ ret = -EINVAL;
+ goto out;
+ }
+
+ /* secondary policy component part */
+ switch ((ACM_USE_SECURITY_POLICY) >> 4) {
+ case ACM_NULL_POLICY:
acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
acm_secondary_ops = &acm_null_ops;
- ret = ACM_OK;
- } else if (ACM_USE_SECURITY_POLICY ==
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
- acm_init_binary_policy(NULL, NULL);
+ break;
+
+ case ACM_CHINESE_WALL_POLICY:
+ if (acm_bin_pol.primary_policy_code == ACM_CHINESE_WALL_POLICY)
+ { /* not a valid combination */
+ ret = -EINVAL;
+ goto out;
+ }
+ acm_init_chwall_policy();
+ acm_bin_pol.secondary_policy_code = ACM_CHINESE_WALL_POLICY;
+ acm_secondary_ops = &acm_chinesewall_ops;
+ break;
+
+ case ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY:
+ if (acm_bin_pol.primary_policy_code ==
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)
+ { /* not a valid combination */
+ ret = -EINVAL;
+ goto out;
+ }
acm_init_ste_policy();
- acm_bin_pol.primary_policy_code =
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
- acm_primary_ops = &acm_simple_type_enforcement_ops;
- acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
- acm_secondary_ops = &acm_null_ops;
- ret = ACM_OK;
- } else if (ACM_USE_SECURITY_POLICY ==
ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) {
- acm_init_binary_policy(NULL, NULL);
- acm_init_chwall_policy();
- acm_init_ste_policy();
- acm_bin_pol.primary_policy_code = ACM_CHINESE_WALL_POLICY;
- acm_primary_ops = &acm_chinesewall_ops;
acm_bin_pol.secondary_policy_code =
ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY;
acm_secondary_ops = &acm_simple_type_enforcement_ops;
- ret = ACM_OK;
- } else if (ACM_USE_SECURITY_POLICY == ACM_NULL_POLICY) {
- acm_init_binary_policy(NULL, NULL);
- acm_bin_pol.primary_policy_code = ACM_NULL_POLICY;
- acm_primary_ops = &acm_null_ops;
- acm_bin_pol.secondary_policy_code = ACM_NULL_POLICY;
- acm_secondary_ops = &acm_null_ops;
- ret = ACM_OK;
+ break;
+
+ default:
+ ret = -EINVAL;
+ goto out;
+ }
+
+ out:
+ write_unlock(&acm_bin_pol_rwlock);
+
+ if (ret != ACM_OK)
+ {
+ printk("%s: Error setting policies.\n", __func__);
+ /* here one could imagine a clean panic */
+ return -EINVAL;
}
- write_unlock(&acm_bin_pol_rwlock);
-
- if (ret != ACM_OK)
- return -EINVAL;
acm_setup(initrdidx, mbi, initial_images_start);
printk("%s: Enforcing Primary %s, Secondary %s.\n", __func__,
- ACM_POLICY_NAME(acm_bin_pol.primary_policy_code),
ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
+ ACM_POLICY_NAME(acm_bin_pol.primary_policy_code),
+ ACM_POLICY_NAME(acm_bin_pol.secondary_policy_code));
return ret;
}
-
-
-#endif
int
acm_init_domain_ssid(domid_t id, ssidref_t ssidref)
@@ -205,7 +244,8 @@
struct domain *subj = find_domain_by_id(id);
int ret1, ret2;
- if (subj == NULL) {
+ if (subj == NULL)
+ {
printk("%s: ACM_NULL_POINTER ERROR (id=%x).\n", __func__, id);
return ACM_NULL_POINTER_ERROR;
}
@@ -235,14 +275,16 @@
else
ret2 = ACM_OK;
- if ((ret1 != ACM_OK) || (ret2 != ACM_OK)) {
+ if ((ret1 != ACM_OK) || (ret2 != ACM_OK))
+ {
printk("%s: ERROR instantiating individual ssids for domain
0x%02x.\n",
__func__, subj->domain_id);
acm_free_domain_ssid(ssid);
put_domain(subj);
return ACM_INIT_SSID_ERROR;
}
- printk("%s: assigned domain %x the ssidref=%x.\n", __func__, id,
ssid->ssidref);
+ printk("%s: assigned domain %x the ssidref=%x.\n",
+ __func__, id, ssid->ssidref);
put_domain(subj);
return ACM_OK;
}
@@ -254,11 +296,12 @@
domid_t id;
/* domain is already gone, just ssid is left */
- if (ssid == NULL) {
+ if (ssid == NULL)
+ {
printk("%s: ACM_NULL_POINTER ERROR.\n", __func__);
return ACM_NULL_POINTER_ERROR;
}
- id = ssid->domainid;
+ id = ssid->domainid;
ssid->subject = NULL;
if (acm_primary_ops->free_domain_ssid != NULL) /* null policy */
@@ -268,6 +311,7 @@
acm_secondary_ops->free_domain_ssid(ssid->secondary_ssid);
ssid->secondary_ssid = NULL;
xfree(ssid);
- printkd("%s: Freed individual domain ssid (domain=%02x).\n",__func__,
id);
+ printkd("%s: Freed individual domain ssid (domain=%02x).\n",
+ __func__, id);
return ACM_OK;
}
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_null_hooks.c
--- a/xen/acm/acm_null_hooks.c Fri Sep 2 14:15:49 2005
+++ b/xen/acm/acm_null_hooks.c Fri Sep 2 14:17:08 2005
@@ -14,13 +14,13 @@
#include <acm/acm_hooks.h>
static int
-null_init_domain_ssid(void **chwall_ssid, ssidref_t ssidref)
+null_init_domain_ssid(void **ssid, ssidref_t ssidref)
{
return ACM_OK;
}
static void
-null_free_domain_ssid(void *chwall_ssid)
+null_free_domain_ssid(void *ssid)
{
return;
}
@@ -44,6 +44,14 @@
return 0;
}
+static int
+null_dump_ssid_types(ssidref_t ssidref, u8 *buffer, u16 buf_size)
+{
+ /* no types */
+ return 0;
+}
+
+
/* now define the hook structure similarly to LSM */
struct acm_operations acm_null_ops = {
.init_domain_ssid = null_init_domain_ssid,
@@ -51,6 +59,7 @@
.dump_binary_policy = null_dump_binary_policy,
.set_binary_policy = null_set_binary_policy,
.dump_statistics = null_dump_stats,
+ .dump_ssid_types = null_dump_ssid_types,
/* domain management control hooks */
.pre_domain_create = NULL,
.post_domain_create = NULL,
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_policy.c
--- a/xen/acm/acm_policy.c Fri Sep 2 14:15:49 2005
+++ b/xen/acm/acm_policy.c Fri Sep 2 14:17:08 2005
@@ -26,8 +26,8 @@
#include <xen/lib.h>
#include <xen/delay.h>
#include <xen/sched.h>
+#include <acm/acm_core.h>
#include <public/acm_ops.h>
-#include <acm/acm_core.h>
#include <acm/acm_hooks.h>
#include <acm/acm_endian.h>
@@ -37,14 +37,16 @@
u8 *policy_buffer = NULL;
struct acm_policy_buffer *pol;
- if (buf_size < sizeof(struct acm_policy_buffer))
+ if (buf_size < sizeof(struct acm_policy_buffer))
return -EFAULT;
/* 1. copy buffer from domain */
if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
- goto error_free;
+ return -ENOMEM;
+
if (isuserbuffer) {
- if (copy_from_user(policy_buffer, buf, buf_size)) {
+ if (copy_from_user(policy_buffer, buf, buf_size))
+ {
printk("%s: Error copying!\n",__func__);
goto error_free;
}
@@ -57,11 +59,13 @@
if ((ntohl(pol->magic) != ACM_MAGIC) ||
(ntohl(pol->policy_version) != ACM_POLICY_VERSION) ||
(ntohl(pol->primary_policy_code) !=
acm_bin_pol.primary_policy_code) ||
- (ntohl(pol->secondary_policy_code) !=
acm_bin_pol.secondary_policy_code)) {
+ (ntohl(pol->secondary_policy_code) !=
acm_bin_pol.secondary_policy_code))
+ {
printkd("%s: Wrong policy magics or versions!\n", __func__);
goto error_free;
}
- if (buf_size != ntohl(pol->len)) {
+ if (buf_size != ntohl(pol->len))
+ {
printk("%s: ERROR in buf size.\n", __func__);
goto error_free;
}
@@ -72,27 +76,25 @@
/* 3. set primary policy data */
if (acm_primary_ops->set_binary_policy(buf +
ntohl(pol->primary_buffer_offset),
ntohl(pol->secondary_buffer_offset) -
-
ntohl(pol->primary_buffer_offset))) {
+
ntohl(pol->primary_buffer_offset)))
goto error_lock_free;
- }
+
/* 4. set secondary policy data */
if (acm_secondary_ops->set_binary_policy(buf +
ntohl(pol->secondary_buffer_offset),
ntohl(pol->len) -
-
ntohl(pol->secondary_buffer_offset))) {
+
ntohl(pol->secondary_buffer_offset)))
goto error_lock_free;
- }
+
write_unlock(&acm_bin_pol_rwlock);
- if (policy_buffer != NULL)
- xfree(policy_buffer);
+ xfree(policy_buffer);
return ACM_OK;
error_lock_free:
write_unlock(&acm_bin_pol_rwlock);
error_free:
printk("%s: Error setting policy.\n", __func__);
- if (policy_buffer != NULL)
- xfree(policy_buffer);
- return -ENOMEM;
+ xfree(policy_buffer);
+ return -EFAULT;
}
int
@@ -102,11 +104,14 @@
int ret;
struct acm_policy_buffer *bin_pol;
+ if (buf_size < sizeof(struct acm_policy_buffer))
+ return -EFAULT;
+
if ((policy_buffer = xmalloc_array(u8, buf_size)) == NULL)
return -ENOMEM;
read_lock(&acm_bin_pol_rwlock);
- /* future: read policy from file and set it */
+
bin_pol = (struct acm_policy_buffer *)policy_buffer;
bin_pol->magic = htonl(ACM_MAGIC);
bin_pol->primary_policy_code = htonl(acm_bin_pol.primary_policy_code);
@@ -118,27 +123,30 @@
ret = acm_primary_ops->dump_binary_policy (policy_buffer +
ntohl(bin_pol->primary_buffer_offset),
buf_size -
ntohl(bin_pol->primary_buffer_offset));
- if (ret < 0) {
- printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
- read_unlock(&acm_bin_pol_rwlock);
- return -1;
- }
+ if (ret < 0)
+ goto error_free_unlock;
+
bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
bin_pol->secondary_buffer_offset = htonl(ntohl(bin_pol->len));
ret = acm_secondary_ops->dump_binary_policy(policy_buffer +
ntohl(bin_pol->secondary_buffer_offset),
buf_size -
ntohl(bin_pol->secondary_buffer_offset));
- if (ret < 0) {
- printk("%s: ERROR creating chwallpolicy buffer.\n", __func__);
- read_unlock(&acm_bin_pol_rwlock);
- return -1;
- }
+ if (ret < 0)
+ goto error_free_unlock;
+
bin_pol->len = htonl(ntohl(bin_pol->len) + ret);
- read_unlock(&acm_bin_pol_rwlock);
if (copy_to_user(buf, policy_buffer, ntohl(bin_pol->len)))
- return -EFAULT;
+ goto error_free_unlock;
+
+ read_unlock(&acm_bin_pol_rwlock);
xfree(policy_buffer);
return ACM_OK;
+
+ error_free_unlock:
+ read_unlock(&acm_bin_pol_rwlock);
+ printk("%s: Error getting policy.\n", __func__);
+ xfree(policy_buffer);
+ return -EFAULT;
}
int
@@ -185,4 +193,62 @@
return -EFAULT;
}
+
+int
+acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size)
+{
+ /* send stats to user space */
+ u8 *ssid_buffer;
+ int ret;
+ struct acm_ssid_buffer *acm_ssid;
+ if (buf_size < sizeof(struct acm_ssid_buffer))
+ return -EFAULT;
+
+ if ((ssid_buffer = xmalloc_array(u8, buf_size)) == NULL)
+ return -ENOMEM;
+
+ read_lock(&acm_bin_pol_rwlock);
+
+ acm_ssid = (struct acm_ssid_buffer *)ssid_buffer;
+ acm_ssid->len = sizeof(struct acm_ssid_buffer);
+ acm_ssid->ssidref = ssidref;
+ acm_ssid->primary_policy_code = acm_bin_pol.primary_policy_code;
+ acm_ssid->secondary_policy_code = acm_bin_pol.secondary_policy_code;
+ acm_ssid->primary_types_offset = acm_ssid->len;
+
+ /* ret >= 0 --> ret == max_types */
+ ret = acm_primary_ops->dump_ssid_types(ACM_PRIMARY(ssidref),
+ ssid_buffer +
acm_ssid->primary_types_offset,
+ buf_size -
acm_ssid->primary_types_offset);
+ if (ret < 0)
+ goto error_free_unlock;
+
+ acm_ssid->len += ret;
+ acm_ssid->primary_max_types = ret;
+
+ acm_ssid->secondary_types_offset = acm_ssid->len;
+
+ ret = acm_secondary_ops->dump_ssid_types(ACM_SECONDARY(ssidref),
+ ssid_buffer +
acm_ssid->secondary_types_offset,
+ buf_size -
acm_ssid->secondary_types_offset);
+ if (ret < 0)
+ goto error_free_unlock;
+
+ acm_ssid->len += ret;
+ acm_ssid->secondary_max_types = ret;
+
+ if (copy_to_user(buf, ssid_buffer, acm_ssid->len))
+ goto error_free_unlock;
+
+ read_unlock(&acm_bin_pol_rwlock);
+ xfree(ssid_buffer);
+ return ACM_OK;
+
+ error_free_unlock:
+ read_unlock(&acm_bin_pol_rwlock);
+ printk("%s: Error getting ssid.\n", __func__);
+ xfree(ssid_buffer);
+ return -ENOMEM;
+}
+
/*eof*/
diff -r edd1616cf8cb -r 291e816acbf4 xen/acm/acm_simple_type_enforcement_hooks.c
--- a/xen/acm/acm_simple_type_enforcement_hooks.c Fri Sep 2 14:15:49 2005
+++ b/xen/acm/acm_simple_type_enforcement_hooks.c Fri Sep 2 14:17:08 2005
@@ -383,6 +383,27 @@
return sizeof(struct acm_ste_stats_buffer);
}
+static int
+ste_dump_ssid_types(ssidref_t ssidref, u8 *buf, u16 len)
+{
+ int i;
+
+ /* fill in buffer */
+ if (ste_bin_pol.max_types > len)
+ return -EFAULT;
+
+ if (ssidref >= ste_bin_pol.max_ssidrefs)
+ return -EFAULT;
+
+ /* read types for chwall ssidref */
+ for(i=0; i< ste_bin_pol.max_types; i++) {
+ if (ste_bin_pol.ssidrefs[ssidref * ste_bin_pol.max_types + i])
+ buf[i] = 1;
+ else
+ buf[i] = 0;
+ }
+ return ste_bin_pol.max_types;
+}
/* we need to go through this before calling the hooks,
* returns 1 == cache hit */
@@ -625,22 +646,23 @@
/* policy management services */
.init_domain_ssid = ste_init_domain_ssid,
.free_domain_ssid = ste_free_domain_ssid,
- .dump_binary_policy = ste_dump_policy,
- .set_binary_policy = ste_set_policy,
+ .dump_binary_policy = ste_dump_policy,
+ .set_binary_policy = ste_set_policy,
.dump_statistics = ste_dump_stats,
+ .dump_ssid_types = ste_dump_ssid_types,
/* domain management control hooks */
.pre_domain_create = ste_pre_domain_create,
- .post_domain_create = NULL,
- .fail_domain_create = NULL,
- .post_domain_destroy = ste_post_domain_destroy,
+ .post_domain_create = NULL,
+ .fail_domain_create = NULL,
+ .post_domain_destroy = ste_post_domain_destroy,
/* event channel control hooks */
- .pre_eventchannel_unbound = ste_pre_eventchannel_unbound,
+ .pre_eventchannel_unbound = ste_pre_eventchannel_unbound,
.fail_eventchannel_unbound = NULL,
.pre_eventchannel_interdomain = ste_pre_eventchannel_interdomain,
.fail_eventchannel_interdomain = NULL,
/* grant table control hooks */
- .pre_grant_map_ref = ste_pre_grant_map_ref,
- .fail_grant_map_ref = NULL,
- .pre_grant_setup = ste_pre_grant_setup,
- .fail_grant_setup = NULL,
+ .pre_grant_map_ref = ste_pre_grant_map_ref,
+ .fail_grant_map_ref = NULL,
+ .pre_grant_setup = ste_pre_grant_setup,
+ .fail_grant_setup = NULL,
};
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/Makefile
--- a/xen/arch/x86/Makefile Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/Makefile Fri Sep 2 14:17:08 2005
@@ -17,7 +17,7 @@
OBJS := $(patsubst shadow%.o,,$(OBJS)) # drop all
ifeq ($(TARGET_SUBARCH),x86_64)
- OBJS += shadow.o shadow_public.o # x86_64: new code
+ OBJS += shadow.o shadow_public.o shadow_guest32.o # x86_64: new code
endif
ifeq ($(TARGET_SUBARCH),x86_32)
ifneq ($(pae),n)
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/Rules.mk
--- a/xen/arch/x86/Rules.mk Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/Rules.mk Fri Sep 2 14:17:08 2005
@@ -13,10 +13,8 @@
CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-generic
CFLAGS += -I$(BASEDIR)/include/asm-x86/mach-default
-ifeq ($(optimize),y)
+ifneq ($(debug),y)
CFLAGS += -O3 -fomit-frame-pointer
-else
-x86_32/usercopy.o: CFLAGS += -O1
endif
# Prevent floating-point variables from creeping into Xen.
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/boot/x86_32.S
--- a/xen/arch/x86/boot/x86_32.S Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/boot/x86_32.S Fri Sep 2 14:17:08 2005
@@ -9,6 +9,8 @@
.text
ENTRY(start)
+ENTRY(stext)
+ENTRY(_stext)
jmp __start
.align 4
@@ -260,6 +262,3 @@
.org 0x2000 + STACK_SIZE + PAGE_SIZE
#endif /* CONFIG_X86_PAE */
-
-ENTRY(stext)
-ENTRY(_stext)
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/boot/x86_64.S
--- a/xen/arch/x86/boot/x86_64.S Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/boot/x86_64.S Fri Sep 2 14:17:08 2005
@@ -10,6 +10,8 @@
.code32
ENTRY(start)
+ENTRY(stext)
+ENTRY(_stext)
jmp __start
.org 0x004
@@ -267,5 +269,3 @@
.org 0x4000 + STACK_SIZE + PAGE_SIZE
.code64
-ENTRY(stext)
-ENTRY(_stext)
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/shadow.c
--- a/xen/arch/x86/shadow.c Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/shadow.c Fri Sep 2 14:17:08 2005
@@ -53,6 +53,9 @@
struct domain *d, unsigned long gpfn, unsigned long gmfn);
static void shadow_map_into_current(struct vcpu *v,
unsigned long va, unsigned int from, unsigned int to);
+static inline void validate_bl2e_change( struct domain *d,
+ guest_root_pgentry_t *new_gle_p, pgentry_64_t *shadow_l3, int index);
+
#endif
/********
@@ -217,10 +220,38 @@
}
else
{
- page = alloc_domheap_page(NULL);
- void *l1 = map_domain_page(page_to_pfn(page));
- memset(l1, 0, PAGE_SIZE);
- unmap_domain_page(l1);
+ if (d->arch.ops->guest_paging_levels == PAGING_L2)
+ {
+#if CONFIG_PAGING_LEVELS >= 4
+ /* For 32-bit VMX guest, 2 shadow L1s to simulate 1 guest L1
+ * So need allocate 2 continues shadow L1 each time.
+ */
+ page = alloc_domheap_pages(NULL, SL1_ORDER, 0);
+ if (!page)
+ domain_crash_synchronous();
+
+ void *l1_0 = map_domain_page(page_to_pfn(page));
+ memset(l1_0,0,PAGE_SIZE);
+ unmap_domain_page(l1_0);
+ void *l1_1 = map_domain_page(page_to_pfn(page+1));
+ memset(l1_1,0,PAGE_SIZE);
+ unmap_domain_page(l1_1);
+#else
+ page = alloc_domheap_page(NULL);
+ if (!page)
+ domain_crash_synchronous();
+ void *l1 = map_domain_page(page_to_pfn(page));
+ memset(l1, 0, PAGE_SIZE);
+ unmap_domain_page(l1);
+#endif
+ }
+ else
+ {
+ page = alloc_domheap_page(NULL);
+ void *l1 = map_domain_page(page_to_pfn(page));
+ memset(l1, 0, PAGE_SIZE);
+ unmap_domain_page(l1);
+ }
}
}
else {
@@ -331,7 +362,21 @@
fail:
FSH_LOG("promotion of pfn=%lx mfn=%lx failed! external gnttab refs?",
gpfn, gmfn);
- free_domheap_page(page);
+ if (psh_type == PGT_l1_shadow)
+ {
+ if (d->arch.ops->guest_paging_levels == PAGING_L2)
+ {
+#if CONFIG_PAGING_LEVELS >=4
+ free_domheap_pages(page, SL1_ORDER);
+#else
+ free_domheap_page(page);
+#endif
+ }
+ else
+ free_domheap_page(page);
+ }
+ else
+ free_domheap_page(page);
return 0;
}
@@ -478,8 +523,10 @@
{
struct vcpu *v = current;
struct domain *d = v->domain;
- l1_pgentry_t *gpl1e, *spl1e;
- l2_pgentry_t gl2e, sl2e;
+ l1_pgentry_t *spl1e;
+ l2_pgentry_t sl2e;
+ guest_l1_pgentry_t *gpl1e;
+ guest_l2_pgentry_t gl2e;
unsigned long gl1pfn, gl1mfn, sl1mfn;
int i, init_table = 0;
@@ -523,28 +570,49 @@
ASSERT( !(l2e_get_flags(old_sl2e) & _PAGE_PRESENT) );
#endif
- if ( !get_shadow_ref(sl1mfn) )
- BUG();
- l2pde_general(d, &gl2e, &sl2e, sl1mfn);
- __guest_set_l2e(v, va, &gl2e);
- __shadow_set_l2e(v, va, &sl2e);
+#if CONFIG_PAGING_LEVELS >=4
+ if (d->arch.ops->guest_paging_levels == PAGING_L2)
+ {
+ /* for 32-bit VMX guest on 64-bit host,
+ * need update two L2 entries each time
+ */
+ if ( !get_shadow_ref(sl1mfn))
+ BUG();
+ l2pde_general(d, &gl2e, &sl2e, sl1mfn);
+ __guest_set_l2e(v, va, &gl2e);
+ __shadow_set_l2e(v, va & ~((1<<L2_PAGETABLE_SHIFT_32) - 1), &sl2e);
+ if ( !get_shadow_ref(sl1mfn+1))
+ BUG();
+ sl2e = l2e_empty();
+ l2pde_general(d, &gl2e, &sl2e, sl1mfn+1);
+ __shadow_set_l2e(v,((va & ~((1<<L2_PAGETABLE_SHIFT_32) - 1)) + (1 <<
L2_PAGETABLE_SHIFT)) , &sl2e);
+ } else
+#endif
+ {
+ if ( !get_shadow_ref(sl1mfn) )
+ BUG();
+ l2pde_general(d, &gl2e, &sl2e, sl1mfn);
+ __guest_set_l2e(v, va, &gl2e);
+ __shadow_set_l2e(v, va , &sl2e);
+ }
if ( init_table )
{
l1_pgentry_t sl1e;
- int index = l1_table_offset(va);
+ int index = guest_l1_table_offset(va);
int min = 1, max = 0;
unsigned long entries, pt_va;
l1_pgentry_t tmp_sl1e;
- l1_pgentry_t tmp_gl1e;//Prepare for double compile
-
-
- entries = PAGE_SIZE / sizeof(l1_pgentry_t);
+ guest_l1_pgentry_t tmp_gl1e;//Prepare for double compile
+
+
+ entries = PAGE_SIZE / sizeof(guest_l1_pgentry_t);
pt_va = ((va >> L1_PAGETABLE_SHIFT) & ~(entries - 1)) <<
L1_PAGETABLE_SHIFT;
- gpl1e = (l1_pgentry_t *) __guest_get_l1e(v, pt_va, &tmp_gl1e);
-
- entries = PAGE_SIZE / sizeof(l1_pgentry_t);
+ gpl1e = (guest_l1_pgentry_t *) __guest_get_l1e(v, pt_va, &tmp_gl1e);
+
+ /* If the PGT_l1_shadow has two continual pages */
+ entries = PAGE_SIZE / sizeof(guest_l1_pgentry_t); //1024 entry!!!
pt_va = ((va >> L1_PAGETABLE_SHIFT) & ~(entries - 1)) <<
L1_PAGETABLE_SHIFT;
spl1e = (l1_pgentry_t *) __shadow_get_l1e(v, pt_va, &tmp_sl1e);
@@ -555,7 +623,7 @@
spl1e = &(shadow_linear_pg_table[l1_linear_offset(va) &
~(L1_PAGETABLE_ENTRIES-1)]);*/
- for ( i = 0; i < L1_PAGETABLE_ENTRIES; i++ )
+ for ( i = 0; i < GUEST_L1_PAGETABLE_ENTRIES; i++ )
{
l1pte_propagate_from_guest(d, gpl1e[i], &sl1e);
if ( (l1e_get_flags(sl1e) & _PAGE_PRESENT) &&
@@ -584,7 +652,7 @@
}
}
-static void
+static void
shadow_set_l1e(unsigned long va, l1_pgentry_t new_spte, int create_l1_shadow)
{
struct vcpu *v = current;
@@ -616,7 +684,7 @@
perfc_incrc(shadow_set_l1e_unlinked);
if ( !get_shadow_ref(sl1mfn) )
BUG();
- l2pde_general(d, &gpde, &sl2e, sl1mfn);
+ l2pde_general(d, (guest_l2_pgentry_t *)&gpde, &sl2e, sl1mfn);
__guest_set_l2e(v, va, &gpde);
__shadow_set_l2e(v, va, &sl2e);
}
@@ -651,6 +719,7 @@
shadow_update_min_max(l2e_get_pfn(sl2e), l1_table_offset(va));
}
+#if CONFIG_PAGING_LEVELS <= 3
static void shadow_invlpg_32(struct vcpu *v, unsigned long va)
{
struct domain *d = v->domain;
@@ -679,6 +748,7 @@
shadow_unlock(d);
}
+#endif
static struct out_of_sync_entry *
shadow_alloc_oos_entry(struct domain *d)
@@ -759,8 +829,8 @@
length = max - min + 1;
perfc_incr_histo(snapshot_copies, length, PT_UPDATES);
- min *= sizeof(l1_pgentry_t);
- length *= sizeof(l1_pgentry_t);
+ min *= sizeof(guest_l1_pgentry_t);
+ length *= sizeof(guest_l1_pgentry_t);
original = map_domain_page(gmfn);
snapshot = map_domain_page(smfn);
@@ -841,7 +911,7 @@
__shadow_get_l4e(v, va, &sl4e);
if ( !(l4e_get_flags(sl4e) & _PAGE_PRESENT)) {
- shadow_map_into_current(v, va, L3, L4);
+ shadow_map_into_current(v, va, PAGING_L3, PAGING_L4);
}
if (!__shadow_get_l3e(v, va, &sl3e)) {
@@ -849,7 +919,7 @@
}
if ( !(l3e_get_flags(sl3e) & _PAGE_PRESENT)) {
- shadow_map_into_current(v, va, L2, L3);
+ shadow_map_into_current(v, va, PAGING_L2, PAGING_L3);
}
}
#endif
@@ -887,11 +957,11 @@
* Returns 0 otherwise.
*/
static int snapshot_entry_matches(
- struct domain *d, l1_pgentry_t *guest_pt,
+ struct domain *d, guest_l1_pgentry_t *guest_pt,
unsigned long gpfn, unsigned index)
{
unsigned long smfn = __shadow_status(d, gpfn, PGT_snapshot);
- l1_pgentry_t *snapshot, gpte; // could be L1s or L2s or ...
+ guest_l1_pgentry_t *snapshot, gpte; // could be L1s or L2s or ...
int entries_match;
perfc_incrc(snapshot_entry_matches_calls);
@@ -908,7 +978,7 @@
// This could probably be smarter, but this is sufficent for
// our current needs.
//
- entries_match = !l1e_has_changed(gpte, snapshot[index],
+ entries_match = !guest_l1e_has_changed(gpte, snapshot[index],
PAGE_FLAG_MASK);
unmap_domain_page(snapshot);
@@ -936,10 +1006,10 @@
unsigned long l2mfn = pagetable_get_pfn(v->arch.guest_table);
#endif
unsigned long l2pfn = __mfn_to_gpfn(d, l2mfn);
- l2_pgentry_t l2e;
+ guest_l2_pgentry_t l2e;
unsigned long l1pfn, l1mfn;
- l1_pgentry_t *guest_pt;
- l1_pgentry_t tmp_gle;
+ guest_l1_pgentry_t *guest_pt;
+ guest_l1_pgentry_t tmp_gle;
unsigned long pt_va;
ASSERT(shadow_lock_is_acquired(d));
@@ -948,7 +1018,7 @@
perfc_incrc(shadow_out_of_sync_calls);
#if CONFIG_PAGING_LEVELS >= 4
- if (d->arch.ops->guest_paging_levels == L4) { /* Mode F */
+ if (d->arch.ops->guest_paging_levels == PAGING_L4) { /* Mode F */
pgentry_64_t le;
unsigned long gmfn;
unsigned long gpfn;
@@ -956,9 +1026,9 @@
gmfn = l2mfn;
gpfn = l2pfn;
- guest_pt = (l1_pgentry_t *)v->arch.guest_vtable;
-
- for (i = L4; i >= L3; i--) {
+ guest_pt = (guest_l1_pgentry_t *)v->arch.guest_vtable;
+
+ for (i = PAGING_L4; i >= PAGING_L3; i--) {
if ( page_out_of_sync(&frame_table[gmfn]) &&
!snapshot_entry_matches(
d, guest_pt, gpfn, table_offset_64(va, i)) )
@@ -972,7 +1042,7 @@
if ( !VALID_MFN(gmfn) )
return 0;
/* Todo: check!*/
- guest_pt = (l1_pgentry_t *)map_domain_page(gmfn);
+ guest_pt = (guest_l1_pgentry_t *)map_domain_page(gmfn);
}
@@ -986,13 +1056,13 @@
#endif
if ( page_out_of_sync(&frame_table[l2mfn]) &&
- !snapshot_entry_matches(d, (l1_pgentry_t *)v->arch.guest_vtable,
- l2pfn, l2_table_offset(va)) )
+ !snapshot_entry_matches(d, (guest_l1_pgentry_t *)v->arch.guest_vtable,
+ l2pfn, guest_l2_table_offset(va)) )
return 1;
__guest_get_l2e(v, va, &l2e);
- if ( !(l2e_get_flags(l2e) & _PAGE_PRESENT) ||
- (l2e_get_flags(l2e) & _PAGE_PSE))
+ if ( !(guest_l2e_get_flags(l2e) & _PAGE_PRESENT) ||
+ (guest_l2e_get_flags(l2e) & _PAGE_PSE))
return 0;
l1pfn = l2e_get_pfn(l2e);
@@ -1001,20 +1071,20 @@
// If the l1 pfn is invalid, it can't be out of sync...
if ( !VALID_MFN(l1mfn) )
return 0;
-
- pt_va = ((va >> L1_PAGETABLE_SHIFT) & ~(L1_PAGETABLE_ENTRIES - 1))
+
+ pt_va = ((va >> L1_PAGETABLE_SHIFT) & ~(GUEST_L1_PAGETABLE_ENTRIES - 1))
<< L1_PAGETABLE_SHIFT;
- guest_pt = (l1_pgentry_t *) __guest_get_l1e(v, pt_va, &tmp_gle);
+ guest_pt = (guest_l1_pgentry_t *) __guest_get_l1e(v, pt_va, &tmp_gle);
if ( page_out_of_sync(&frame_table[l1mfn]) &&
!snapshot_entry_matches(
- d, guest_pt, l1pfn, l1_table_offset(va)) )
+ d, guest_pt, l1pfn, guest_l1_table_offset(va)) )
return 1;
return 0;
}
-#define GPFN_TO_GPTEPAGE(_gpfn) ((_gpfn) / (PAGE_SIZE / sizeof(l1_pgentry_t)))
+#define GPFN_TO_GPTEPAGE(_gpfn) ((_gpfn) / (PAGE_SIZE /
sizeof(guest_l1_pgentry_t)))
static inline unsigned long
predict_writable_pte_page(struct domain *d, unsigned long gpfn)
{
@@ -1108,7 +1178,7 @@
return (found == max_refs_to_find);
}
- i = readonly_gpfn & (L1_PAGETABLE_ENTRIES - 1);
+ i = readonly_gpfn & (GUEST_L1_PAGETABLE_ENTRIES - 1);
if ( !l1e_has_changed(pt[i], match, flags) && fix_entry(i) )
{
perfc_incrc(remove_write_fast_exit);
@@ -1117,7 +1187,7 @@
return found;
}
- for (i = 0; i < L1_PAGETABLE_ENTRIES; i++)
+ for (i = 0; i < GUEST_L1_PAGETABLE_ENTRIES; i++)
{
if ( unlikely(!l1e_has_changed(pt[i], match, flags)) && fix_entry(i) )
break;
@@ -1282,15 +1352,15 @@
switch ( stype ) {
case PGT_l1_shadow:
{
- l1_pgentry_t *guest1 = guest;
+ guest_l1_pgentry_t *guest1 = guest;
l1_pgentry_t *shadow1 = shadow;
- l1_pgentry_t *snapshot1 = snapshot;
+ guest_l1_pgentry_t *snapshot1 = snapshot;
ASSERT(VM_ASSIST(d, VMASST_TYPE_writable_pagetables) ||
shadow_mode_write_all(d));
if ( !shadow_mode_refcounts(d) )
- revalidate_l1(d, guest1, snapshot1);
+ revalidate_l1(d, (l1_pgentry_t *)guest1, (l1_pgentry_t
*)snapshot1);
if ( !smfn )
break;
@@ -1301,7 +1371,7 @@
for ( i = min_shadow; i <= max_shadow; i++ )
{
if ( (i < min_snapshot) || (i > max_snapshot) ||
- l1e_has_changed(guest1[i], snapshot1[i], PAGE_FLAG_MASK) )
+ guest_l1e_has_changed(guest1[i], snapshot1[i],
PAGE_FLAG_MASK) )
{
need_flush |= validate_pte_change(d, guest1[i],
&shadow1[i]);
@@ -1431,32 +1501,36 @@
{
int max = -1;
- l4_pgentry_t *guest4 = guest;
+ guest_root_pgentry_t *guest_root = guest;
l4_pgentry_t *shadow4 = shadow;
- l4_pgentry_t *snapshot4 = snapshot;
+ guest_root_pgentry_t *snapshot_root = snapshot;
changed = 0;
- for ( i = 0; i < L4_PAGETABLE_ENTRIES; i++ )
+ for ( i = 0; i < GUEST_ROOT_PAGETABLE_ENTRIES; i++ )
{
if ( !is_guest_l4_slot(i) && !external )
continue;
- l4_pgentry_t new_l4e = guest4[i];
- if ( l4e_has_changed(new_l4e, snapshot4[i], PAGE_FLAG_MASK))
+ guest_root_pgentry_t new_root_e = guest_root[i];
+ if ( root_entry_has_changed(
+ new_root_e, snapshot_root[i], PAGE_FLAG_MASK))
{
- need_flush |= validate_entry_change(
- d, (pgentry_64_t *)&new_l4e,
- (pgentry_64_t *)&shadow4[i],
shadow_type_to_level(stype));
-
+ if (d->arch.ops->guest_paging_levels == PAGING_L4) {
+ need_flush |= validate_entry_change(
+ d, (pgentry_64_t *)&new_root_e,
+ (pgentry_64_t *)&shadow4[i],
shadow_type_to_level(stype));
+ } else {
+ validate_bl2e_change(d, &new_root_e, shadow, i);
+ }
changed++;
ESH_LOG("%d: shadow4 mfn: %lx, shadow root: %lx\n", i,
smfn, pagetable_get_paddr(current->arch.shadow_table));
}
- if ( l4e_get_intpte(new_l4e) != 0 ) /* FIXME: check flags? */
+ if ( guest_root_get_intpte(new_root_e) != 0 ) /* FIXME: check
flags? */
max = i;
// Need a better solution in the long term.
- if ( !(l4e_get_flags(new_l4e) & _PAGE_PRESENT) &&
- unlikely(l4e_get_intpte(new_l4e) != 0) &&
+ if ( !(guest_root_get_flags(new_root_e) & _PAGE_PRESENT) &&
+ unlikely(guest_root_get_intpte(new_root_e) != 0) &&
!unshadow &&
(frame_table[smfn].u.inuse.type_info & PGT_pinned) )
unshadow = 1;
@@ -1555,8 +1629,14 @@
if ( shadow_mode_translate(d) )
need_flush |= resync_all(d, PGT_hl2_shadow);
#endif
- need_flush |= resync_all(d, PGT_l2_shadow);
- need_flush |= resync_all(d, PGT_l3_shadow);
+
+ /*
+ * Fixme: for i386 host
+ */
+ if (d->arch.ops->guest_paging_levels == PAGING_L4) {
+ need_flush |= resync_all(d, PGT_l2_shadow);
+ need_flush |= resync_all(d, PGT_l3_shadow);
+ }
need_flush |= resync_all(d, PGT_l4_shadow);
if ( need_flush && !unlikely(shadow_mode_external(d)) )
@@ -1566,11 +1646,11 @@
}
static inline int l1pte_write_fault(
- struct vcpu *v, l1_pgentry_t *gpte_p, l1_pgentry_t *spte_p,
+ struct vcpu *v, guest_l1_pgentry_t *gpte_p, l1_pgentry_t *spte_p,
unsigned long va)
{
struct domain *d = v->domain;
- l1_pgentry_t gpte = *gpte_p;
+ guest_l1_pgentry_t gpte = *gpte_p;
l1_pgentry_t spte;
unsigned long gpfn = l1e_get_pfn(gpte);
unsigned long gmfn = __gpfn_to_mfn(d, gpfn);
@@ -1585,8 +1665,8 @@
}
ASSERT(l1e_get_flags(gpte) & _PAGE_RW);
- l1e_add_flags(gpte, _PAGE_DIRTY | _PAGE_ACCESSED);
- spte = l1e_from_pfn(gmfn, l1e_get_flags(gpte) & ~_PAGE_GLOBAL);
+ guest_l1e_add_flags(gpte, _PAGE_DIRTY | _PAGE_ACCESSED);
+ spte = l1e_from_pfn(gmfn, guest_l1e_get_flags(gpte) & ~_PAGE_GLOBAL);
SH_VVLOG("l1pte_write_fault: updating spte=0x%" PRIpte " gpte=0x%" PRIpte,
l1e_get_intpte(spte), l1e_get_intpte(gpte));
@@ -1604,9 +1684,9 @@
}
static inline int l1pte_read_fault(
- struct domain *d, l1_pgentry_t *gpte_p, l1_pgentry_t *spte_p)
+ struct domain *d, guest_l1_pgentry_t *gpte_p, l1_pgentry_t *spte_p)
{
- l1_pgentry_t gpte = *gpte_p;
+ guest_l1_pgentry_t gpte = *gpte_p;
l1_pgentry_t spte = *spte_p;
unsigned long pfn = l1e_get_pfn(gpte);
unsigned long mfn = __gpfn_to_mfn(d, pfn);
@@ -1618,10 +1698,10 @@
return 0;
}
- l1e_add_flags(gpte, _PAGE_ACCESSED);
- spte = l1e_from_pfn(mfn, l1e_get_flags(gpte) & ~_PAGE_GLOBAL);
-
- if ( shadow_mode_log_dirty(d) || !(l1e_get_flags(gpte) & _PAGE_DIRTY) ||
+ guest_l1e_add_flags(gpte, _PAGE_ACCESSED);
+ spte = l1e_from_pfn(mfn, guest_l1e_get_flags(gpte) & ~_PAGE_GLOBAL);
+
+ if ( shadow_mode_log_dirty(d) || !(guest_l1e_get_flags(gpte) &
_PAGE_DIRTY) ||
mfn_is_page_table(mfn) )
{
l1e_remove_flags(spte, _PAGE_RW);
@@ -1634,7 +1714,7 @@
return 1;
}
-
+#if CONFIG_PAGING_LEVELS <= 3
static int shadow_fault_32(unsigned long va, struct cpu_user_regs *regs)
{
l1_pgentry_t gpte, spte, orig_gpte;
@@ -1768,6 +1848,7 @@
shadow_unlock(d);
return 0;
}
+#endif
static int do_update_va_mapping(unsigned long va,
l1_pgentry_t val,
@@ -1787,7 +1868,7 @@
//
__shadow_sync_va(v, va);
- l1pte_propagate_from_guest(d, val, &spte);
+ l1pte_propagate_from_guest(d, *(guest_l1_pgentry_t *)&val, &spte);
shadow_set_l1e(va, spte, 0);
/*
@@ -1848,7 +1929,7 @@
#if CONFIG_PAGING_LEVELS == 2
unsigned long hl2mfn;
#endif
-
+
int max_mode = ( shadow_mode_external(d) ? SHM_external
: shadow_mode_translate(d) ? SHM_translate
: shadow_mode_enabled(d) ? SHM_enable
@@ -1954,17 +2035,6 @@
#endif
}
-struct shadow_ops MODE_A_HANDLER = {
- .guest_paging_levels = 2,
- .invlpg = shadow_invlpg_32,
- .fault = shadow_fault_32,
- .update_pagetables = shadow_update_pagetables,
- .sync_all = sync_all,
- .remove_all_write_access = remove_all_write_access,
- .do_update_va_mapping = do_update_va_mapping,
- .mark_mfn_out_of_sync = mark_mfn_out_of_sync,
- .is_out_of_sync = is_out_of_sync,
-};
/************************************************************************/
/************************************************************************/
@@ -2445,12 +2515,90 @@
BUG(); /* not implemenated yet */
return 42;
}
+static unsigned long gva_to_gpa_pae(unsigned long gva)
+{
+ BUG();
+ return 43;
+}
#endif
#if CONFIG_PAGING_LEVELS >= 4
/****************************************************************************/
/* 64-bit shadow-mode code testing */
/****************************************************************************/
+/*
+ * validate_bl2e_change()
+ * The code is for 32-bit VMX gues on 64-bit host.
+ * To sync guest L2.
+ */
+
+static inline void
+validate_bl2e_change(
+ struct domain *d,
+ guest_root_pgentry_t *new_gle_p,
+ pgentry_64_t *shadow_l3,
+ int index)
+{
+ int sl3_idx, sl2_idx;
+ unsigned long sl2mfn, sl1mfn;
+ pgentry_64_t *sl2_p;
+
+ /* Using guest l2 pte index to get shadow l3&l2 index
+ * index: 0 ~ 1023, PAGETABLE_ENTRIES: 512
+ */
+ sl3_idx = index / (PAGETABLE_ENTRIES / 2);
+ sl2_idx = (index % (PAGETABLE_ENTRIES / 2)) * 2;
+
+ sl2mfn = entry_get_pfn(shadow_l3[sl3_idx]);
+ sl2_p = (pgentry_64_t *)map_domain_page(sl2mfn);
+
+ validate_pde_change(
+ d, *(guest_l2_pgentry_t *)new_gle_p, (l2_pgentry_t *)&sl2_p[sl2_idx]);
+
+ /* Mapping the second l1 shadow page */
+ if (entry_get_flags(sl2_p[sl2_idx]) & _PAGE_PRESENT) {
+ sl1mfn = entry_get_pfn(sl2_p[sl2_idx]);
+ sl2_p[sl2_idx + 1] =
+ entry_from_pfn(sl1mfn + 1, entry_get_flags(sl2_p[sl2_idx]));
+ }
+ unmap_domain_page(sl2_p);
+
+}
+
+/*
+ * init_bl2() is for 32-bit VMX guest on 64-bit host
+ * Using 1 shadow L4(l3) and 4 shadow L2s to simulate guest L2
+ */
+static inline unsigned long init_bl2(l4_pgentry_t *spl4e, unsigned long smfn)
+{
+ unsigned int count;
+ unsigned long sl2mfn;
+ struct pfn_info *page;
+
+ memset(spl4e, 0, PAGE_SIZE);
+
+ /* Map the self entry, L4&L3 share the same page */
+ spl4e[PAE_SHADOW_SELF_ENTRY] = l4e_from_pfn(smfn, __PAGE_HYPERVISOR);
+
+ /* Allocate 4 shadow L2s */
+ page = alloc_domheap_pages(NULL, SL2_ORDER, 0);
+ if (!page)
+ domain_crash_synchronous();
+
+ for (count = 0; count < PDP_ENTRIES; count++)
+ {
+ sl2mfn = page_to_pfn(page+count);
+ void *l2 = map_domain_page(sl2mfn);
+ memset(l2, 0, PAGE_SIZE);
+ unmap_domain_page(l2);
+ spl4e[count] = l4e_from_pfn(sl2mfn, _PAGE_PRESENT);
+ }
+
+ unmap_domain_page(spl4e);
+ return smfn;
+
+
+}
static unsigned long shadow_l4_table(
struct domain *d, unsigned long gpfn, unsigned long gmfn)
@@ -2464,11 +2612,16 @@
if ( unlikely(!(smfn = alloc_shadow_page(d, gpfn, gmfn, PGT_l4_shadow))) )
{
- printk("Couldn't alloc an L2 shadow for pfn=%lx mfn=%lx\n", gpfn,
gmfn);
+ printk("Couldn't alloc an L4 shadow for pfn=%lx mfn=%lx\n", gpfn,
gmfn);
BUG(); /* XXX Deal gracefully with failure. */
}
spl4e = (l4_pgentry_t *)map_domain_page(smfn);
+
+ if (d->arch.ops->guest_paging_levels == PAGING_L2) {
+ return init_bl2(spl4e, smfn);
+ }
+
/* Install hypervisor and 4x linear p.t. mapings. */
if ( (PGT_base_page_table == PGT_l4_page_table) &&
!shadow_mode_external(d) )
@@ -2576,7 +2729,7 @@
pgentry_64_t gle, sle;
unsigned long gpfn, smfn;
- if (from == L1 && to == L2) {
+ if (from == PAGING_L1 && to == PAGING_L2) {
shadow_map_l1_into_current_l2(va);
return;
}
@@ -2608,7 +2761,7 @@
if (!(l4e_get_flags(sl4e) & _PAGE_PRESENT)) {
if (create_l2_shadow) {
perfc_incrc(shadow_set_l3e_force_map);
- shadow_map_into_current(v, va, L3, L4);
+ shadow_map_into_current(v, va, PAGING_L3, PAGING_L4);
__shadow_get_l4e(v, va, &sl4e);
} else {
printk("For non VMX shadow, create_l1_shadow:%d\n",
create_l2_shadow);
@@ -2619,7 +2772,7 @@
if (!(l3e_get_flags(sl3e) & _PAGE_PRESENT)) {
if (create_l2_shadow) {
perfc_incrc(shadow_set_l2e_force_map);
- shadow_map_into_current(v, va, L2, L3);
+ shadow_map_into_current(v, va, PAGING_L2, PAGING_L3);
__shadow_get_l3e(v, va, &sl3e);
} else {
printk("For non VMX shadow, create_l1_shadow:%d\n",
create_l2_shadow);
@@ -2655,8 +2808,15 @@
l1_pgentry_t old_spte;
l1_pgentry_t sl1e = *(l1_pgentry_t *)sl1e_p;
int i;
-
- for (i = L4; i >= L2; i--) {
+ unsigned long orig_va = 0;
+
+ if (d->arch.ops->guest_paging_levels == PAGING_L2) {
+ /* This is for 32-bit VMX guest on 64-bit host */
+ orig_va = va;
+ va = va & (~((1<<L2_PAGETABLE_SHIFT_32)-1));
+ }
+
+ for (i = PAGING_L4; i >= PAGING_L2; i--) {
if (!__rw_entry(v, va, &sle, SHADOW_ENTRY | GET_ENTRY | i)) {
printk("<%s> i = %d\n", __func__, i);
BUG();
@@ -2672,9 +2832,13 @@
#endif
}
}
- if(i < L4)
+ if(i < PAGING_L4)
shadow_update_min_max(entry_get_pfn(sle_up), table_offset_64(va,
i));
sle_up = sle;
+ }
+
+ if (d->arch.ops->guest_paging_levels == PAGING_L2) {
+ va = orig_va;
}
if ( shadow_mode_refcounts(d) )
@@ -2692,9 +2856,13 @@
}
__shadow_set_l1e(v, va, &sl1e);
- shadow_update_min_max(entry_get_pfn(sle_up), table_offset_64(va, L1));
-}
-
+
+ shadow_update_min_max(entry_get_pfn(sle_up), guest_l1_table_offset(va));
+}
+
+/* As 32-bit guest don't support 4M page yet,
+ * we don't concern double compile for this function
+ */
static inline int l2e_rw_fault(
struct vcpu *v, l2_pgentry_t *gl2e_p, unsigned long va, int rw)
{
@@ -2825,12 +2993,120 @@
}
+/*
+ * Check P, R/W, U/S bits in the guest page table.
+ * If the fault belongs to guest return 1,
+ * else return 0.
+ */
+#if defined( GUEST_PGENTRY_32 )
+static inline int guest_page_fault(struct vcpu *v,
+ unsigned long va, unsigned int error_code,
+ guest_l2_pgentry_t *gpl2e, guest_l1_pgentry_t *gpl1e)
+{
+ /* The following check for 32-bit guest on 64-bit host */
+
+ __guest_get_l2e(v, va, gpl2e);
+
+ /* Check the guest L2 page-table entry first*/
+ if (unlikely(!(guest_l2e_get_flags(*gpl2e) & _PAGE_PRESENT)))
+ return 1;
+
+ if (error_code & ERROR_W) {
+ if (unlikely(!(guest_l2e_get_flags(*gpl2e) & _PAGE_RW)))
+ return 1;
+ }
+ if (error_code & ERROR_U) {
+ if (unlikely(!(guest_l2e_get_flags(*gpl2e) & _PAGE_USER)))
+ return 1;
+ }
+
+ if (guest_l2e_get_flags(*gpl2e) & _PAGE_PSE)
+ return 0;
+
+ __guest_get_l1e(v, va, gpl1e);
+
+ /* Then check the guest L1 page-table entry */
+ if (unlikely(!(guest_l1e_get_flags(*gpl1e) & _PAGE_PRESENT)))
+ return 1;
+
+ if (error_code & ERROR_W) {
+ if (unlikely(!(guest_l1e_get_flags(*gpl1e) & _PAGE_RW)))
+ return 1;
+ }
+ if (error_code & ERROR_U) {
+ if (unlikely(!(guest_l1e_get_flags(*gpl1e) & _PAGE_USER)))
+ return 1;
+ }
+
+ return 0;
+}
+#else
+static inline int guest_page_fault(struct vcpu *v,
+ unsigned long va, unsigned int error_code,
+ guest_l2_pgentry_t *gpl2e, guest_l1_pgentry_t *gpl1e)
+{
+ struct domain *d = v->domain;
+ pgentry_64_t gle, *lva;
+ unsigned long mfn;
+ int i;
+
+ __rw_entry(v, va, &gle, GUEST_ENTRY | GET_ENTRY | PAGING_L4);
+ if (unlikely(!(entry_get_flags(gle) & _PAGE_PRESENT)))
+ return 1;
+
+ if (error_code & ERROR_W) {
+ if (unlikely(!(entry_get_flags(gle) & _PAGE_RW)))
+ return 1;
+ }
+ if (error_code & ERROR_U) {
+ if (unlikely(!(entry_get_flags(gle) & _PAGE_USER)))
+ return 1;
+ }
+ for (i = PAGING_L3; i >= PAGING_L1; i--) {
+ /*
+ * If it's not external mode, then mfn should be machine physical.
+ */
+ mfn = __gpfn_to_mfn(d, (entry_get_value(gle) >> PAGE_SHIFT));
+
+ lva = (pgentry_64_t *) phys_to_virt(
+ mfn << PAGE_SHIFT);
+ gle = lva[table_offset_64(va, i)];
+
+ if (unlikely(!(entry_get_flags(gle) & _PAGE_PRESENT)))
+ return 1;
+
+ if (error_code & ERROR_W) {
+ if (unlikely(!(entry_get_flags(gle) & _PAGE_RW)))
+ return 1;
+ }
+ if (error_code & ERROR_U) {
+ if (unlikely(!(entry_get_flags(gle) & _PAGE_USER)))
+ return 1;
+ }
+
+ if (i == PAGING_L2) {
+ if (gpl2e)
+ gpl2e->l2 = gle.lo;
+
+ if (likely(entry_get_flags(gle) & _PAGE_PSE))
+ return 0;
+
+ }
+
+ if (i == PAGING_L1)
+ if (gpl1e)
+ gpl1e->l1 = gle.lo;
+ }
+ return 0;
+}
+#endif
static int shadow_fault_64(unsigned long va, struct cpu_user_regs *regs)
{
struct vcpu *v = current;
struct domain *d = v->domain;
- l2_pgentry_t gl2e;
- l1_pgentry_t sl1e, gl1e;
+ guest_l2_pgentry_t gl2e;
+ guest_l1_pgentry_t gl1e;
+ l1_pgentry_t sl1e;
perfc_incrc(shadow_fault_calls);
@@ -2853,12 +3129,11 @@
* STEP 2. Check if the fault belongs to guest
*/
if ( guest_page_fault(
- v, va, regs->error_code,
- (pgentry_64_t *)&gl2e, (pgentry_64_t *)&gl1e) ) {
+ v, va, regs->error_code, &gl2e, &gl1e) ) {
goto fail;
}
- if ( unlikely(!(l2e_get_flags(gl2e) & _PAGE_PSE)) ) {
+ if ( unlikely(!(guest_l2e_get_flags(gl2e) & _PAGE_PSE)) ) {
/*
* Handle 4K pages here
*/
@@ -2892,11 +3167,11 @@
*/
/* Write fault? */
if ( regs->error_code & 2 ) {
- if ( !l2e_rw_fault(v, &gl2e, va, WRITE_FAULT) ) {
+ if ( !l2e_rw_fault(v, (l2_pgentry_t *)&gl2e, va, WRITE_FAULT) ) {
goto fail;
}
} else {
- l2e_rw_fault(v, &gl2e, va, READ_FAULT);
+ l2e_rw_fault(v, (l2_pgentry_t *)&gl2e, va, READ_FAULT);
}
/*
@@ -2944,7 +3219,27 @@
shadow_unlock(d);
}
-#ifndef PGENTRY_32
+static unsigned long gva_to_gpa_64(unsigned long gva)
+{
+ struct vcpu *v = current;
+ guest_l1_pgentry_t gl1e = {0};
+ guest_l2_pgentry_t gl2e = {0};
+ unsigned long gpa;
+
+ if (guest_page_fault(v, gva, 0, &gl2e, &gl1e))
+ return 0;
+
+ if (guest_l2e_get_flags(gl2e) & _PAGE_PSE)
+ gpa = guest_l2e_get_paddr(gl2e) + (gva & ((1 <<
GUEST_L2_PAGETABLE_SHIFT) - 1));
+ else
+ gpa = guest_l1e_get_paddr(gl1e) + (gva & ~PAGE_MASK);
+
+ return gpa;
+
+}
+
+#ifndef GUEST_PGENTRY_32
+
struct shadow_ops MODE_F_HANDLER = {
.guest_paging_levels = 4,
.invlpg = shadow_invlpg_64,
@@ -2955,10 +3250,42 @@
.do_update_va_mapping = do_update_va_mapping,
.mark_mfn_out_of_sync = mark_mfn_out_of_sync,
.is_out_of_sync = is_out_of_sync,
+ .gva_to_gpa = gva_to_gpa_64,
};
#endif
#endif
+
+#if CONFIG_PAGING_LEVELS == 2
+struct shadow_ops MODE_A_HANDLER = {
+ .guest_paging_levels = 2,
+ .invlpg = shadow_invlpg_32,
+ .fault = shadow_fault_32,
+ .update_pagetables = shadow_update_pagetables,
+ .sync_all = sync_all,
+ .remove_all_write_access = remove_all_write_access,
+ .do_update_va_mapping = do_update_va_mapping,
+ .mark_mfn_out_of_sync = mark_mfn_out_of_sync,
+ .is_out_of_sync = is_out_of_sync,
+ .gva_to_gpa = gva_to_gpa_64,
+};
+
+#elif CONFIG_PAGING_LEVELS == 3
+struct shadow_ops MODE_B_HANDLER = {
+ .guest_paging_levels = 3,
+ .invlpg = shadow_invlpg_32,
+ .fault = shadow_fault_32,
+ .update_pagetables = shadow_update_pagetables,
+ .sync_all = sync_all,
+ .remove_all_write_access = remove_all_write_access,
+ .do_update_va_mapping = do_update_va_mapping,
+ .mark_mfn_out_of_sync = mark_mfn_out_of_sync,
+ .is_out_of_sync = is_out_of_sync,
+ .gva_to_gpa = gva_to_gpa_pae,
+};
+
+#endif
+
/*
* Local variables:
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/shadow_public.c
--- a/xen/arch/x86/shadow_public.c Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/shadow_public.c Fri Sep 2 14:17:08 2005
@@ -33,11 +33,15 @@
#if CONFIG_PAGING_LEVELS >= 3
#include <asm/shadow_64.h>
+#endif
+#if CONFIG_PAGING_LEVELS == 4
extern struct shadow_ops MODE_F_HANDLER;
+extern struct shadow_ops MODE_D_HANDLER;
#endif
extern struct shadow_ops MODE_A_HANDLER;
+#define SHADOW_MAX_GUEST32(_encoded) ((L1_PAGETABLE_ENTRIES_32 - 1) -
((_encoded) >> 16))
/****************************************************************************/
/************* export interface functions ***********************************/
/****************************************************************************/
@@ -48,7 +52,7 @@
shadow_lock(d);
switch(levels) {
-#if CONFIG_PAGING_LEVELS >= 4
+#if CONFIG_PAGING_LEVELS >= 4
case 4:
if ( d->arch.ops != &MODE_F_HANDLER )
d->arch.ops = &MODE_F_HANDLER;
@@ -56,9 +60,14 @@
return 1;
#endif
case 3:
- case 2:
+ case 2:
+#if CONFIG_PAGING_LEVELS == 2
if ( d->arch.ops != &MODE_A_HANDLER )
d->arch.ops = &MODE_A_HANDLER;
+#elif CONFIG_PAGING_LEVELS == 4
+ if ( d->arch.ops != &MODE_D_HANDLER )
+ d->arch.ops = &MODE_D_HANDLER;
+#endif
shadow_unlock(d);
return 1;
default:
@@ -122,13 +131,17 @@
return d->arch.ops->is_out_of_sync(v, va);
}
+unsigned long gva_to_gpa(unsigned long gva)
+{
+ struct domain *d = current->domain;
+ return d->arch.ops->gva_to_gpa(gva);
+}
/****************************************************************************/
/****************************************************************************/
#if CONFIG_PAGING_LEVELS >= 4
/*
* Convert PAE 3-level page-table to 4-level page-table
*/
-#define PDP_ENTRIES 4
static pagetable_t page_table_convert(struct domain *d)
{
struct pfn_info *l4page, *l3page;
@@ -203,19 +216,41 @@
/*
* Free l2, l3, l4 shadow tables
*/
+
+void free_fake_shadow_l2(struct domain *d,unsigned long smfn);
+
static void inline
free_shadow_tables(struct domain *d, unsigned long smfn, u32 level)
{
pgentry_64_t *ple = map_domain_page(smfn);
int i, external = shadow_mode_external(d);
-
- for ( i = 0; i < PAGETABLE_ENTRIES; i++ )
- if ( external || is_guest_l4_slot(i) )
- if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
- put_shadow_ref(entry_get_pfn(ple[i]));
-
- unmap_domain_page(ple);
-}
+ struct pfn_info *page = &frame_table[smfn];
+
+ if (d->arch.ops->guest_paging_levels == PAGING_L2)
+ {
+#if CONFIG_PAGING_LEVELS >=4
+ for ( i = 0; i < PDP_ENTRIES; i++ )
+ {
+ if (entry_get_flags(ple[i]) & _PAGE_PRESENT )
+ free_fake_shadow_l2(d,entry_get_pfn(ple[i]));
+ }
+
+ page = &frame_table[entry_get_pfn(ple[0])];
+ free_domheap_pages(page, SL2_ORDER);
+ unmap_domain_page(ple);
+#endif
+ }
+ else
+ {
+ for ( i = 0; i < PAGETABLE_ENTRIES; i++ )
+ if ( external || is_guest_l4_slot(i) )
+ if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
+ put_shadow_ref(entry_get_pfn(ple[i]));
+
+ unmap_domain_page(ple);
+ }
+}
+
void free_monitor_pagetable(struct vcpu *v)
{
@@ -453,7 +488,12 @@
struct pfn_info *spage = pfn_to_page(smfn);
u32 min_max = spage->tlbflush_timestamp;
int min = SHADOW_MIN(min_max);
- int max = SHADOW_MAX(min_max);
+ int max;
+
+ if (d->arch.ops->guest_paging_levels == PAGING_L2)
+ max = SHADOW_MAX_GUEST32(min_max);
+ else
+ max = SHADOW_MAX(min_max);
for ( i = min; i <= max; i++ )
{
@@ -512,9 +552,24 @@
unmap_domain_page(pl2e);
}
+void free_fake_shadow_l2(struct domain *d, unsigned long smfn)
+{
+ pgentry_64_t *ple = map_domain_page(smfn);
+ int i;
+
+ for ( i = 0; i < PAGETABLE_ENTRIES; i = i + 2 )
+ {
+ if ( entry_get_flags(ple[i]) & _PAGE_PRESENT )
+ put_shadow_ref(entry_get_pfn(ple[i]));
+ }
+
+ unmap_domain_page(ple);
+}
+
void free_shadow_page(unsigned long smfn)
{
struct pfn_info *page = &frame_table[smfn];
+
unsigned long gmfn = page->u.inuse.type_info & PGT_mfn_mask;
struct domain *d = page_get_owner(pfn_to_page(gmfn));
unsigned long gpfn = __mfn_to_gpfn(d, gmfn);
@@ -531,6 +586,7 @@
gpfn |= (1UL << 63);
}
#endif
+
delete_shadow_status(d, gpfn, gmfn, type);
switch ( type )
@@ -687,7 +743,7 @@
int i;
struct shadow_status *x;
struct vcpu *v;
-
+
/*
* WARNING! The shadow page table must not currently be in use!
* e.g., You are expected to have paused the domain and synchronized CR3.
@@ -794,7 +850,16 @@
perfc_decr(free_l1_pages);
struct pfn_info *page = list_entry(list_ent, struct pfn_info, list);
- free_domheap_page(page);
+ if (d->arch.ops->guest_paging_levels == PAGING_L2)
+ {
+#if CONFIG_PAGING_LEVELS >=4
+ free_domheap_pages(page, SL1_ORDER);
+#else
+ free_domheap_page(page);
+#endif
+ }
+ else
+ free_domheap_page(page);
}
shadow_audit(d, 0);
@@ -1191,7 +1256,7 @@
{
DPRINTK("Don't try to do a shadow op on yourself!\n");
return -EINVAL;
- }
+ }
domain_pause(d);
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/traps.c
--- a/xen/arch/x86/traps.c Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/traps.c Fri Sep 2 14:17:08 2005
@@ -100,7 +100,14 @@
static int debug_stack_lines = 20;
integer_param("debug_stack_lines", debug_stack_lines);
-#define stack_words_per_line (32 / BYTES_PER_LONG)
+
+#ifdef CONFIG_X86_32
+#define stack_words_per_line 8
+#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)®s->esp)
+#else
+#define stack_words_per_line 4
+#define ESP_BEFORE_EXCEPTION(regs) ((unsigned long *)regs->esp)
+#endif
int is_kernel_text(unsigned long addr)
{
@@ -118,17 +125,16 @@
return (unsigned long) &_etext;
}
-void show_guest_stack(void)
+static void show_guest_stack(struct cpu_user_regs *regs)
{
int i;
- struct cpu_user_regs *regs = guest_cpu_user_regs();
unsigned long *stack = (unsigned long *)regs->esp, addr;
printk("Guest stack trace from "__OP"sp=%p:\n ", stack);
for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
{
- if ( ((long)stack & (STACK_SIZE-1)) == 0 )
+ if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
break;
if ( get_user(addr, stack) )
{
@@ -148,38 +154,98 @@
printk("\n");
}
-void show_trace(unsigned long *esp)
-{
- unsigned long *stack = esp, addr;
- int i = 0;
-
- printk("Xen call trace from "__OP"sp=%p:\n ", stack);
-
- while ( ((long) stack & (STACK_SIZE-1)) != 0 )
+#ifdef NDEBUG
+
+static void show_trace(struct cpu_user_regs *regs)
+{
+ unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
+
+ printk("Xen call trace:\n ");
+
+ printk("[<%p>]", _p(regs->eip));
+ print_symbol(" %s\n ", regs->eip);
+
+ while ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) != 0 )
{
addr = *stack++;
if ( is_kernel_text(addr) )
{
printk("[<%p>]", _p(addr));
print_symbol(" %s\n ", addr);
- i++;
- }
- }
- if ( i == 0 )
- printk("Trace empty.");
+ }
+ }
+
printk("\n");
}
-void show_stack(unsigned long *esp)
-{
- unsigned long *stack = esp, addr;
+#else
+
+static void show_trace(struct cpu_user_regs *regs)
+{
+ unsigned long *frame, next, addr, low, high;
+
+ printk("Xen call trace:\n ");
+
+ printk("[<%p>]", _p(regs->eip));
+ print_symbol(" %s\n ", regs->eip);
+
+ /* Bounds for range of valid frame pointer. */
+ low = (unsigned long)(ESP_BEFORE_EXCEPTION(regs) - 2);
+ high = (low & ~(STACK_SIZE - 1)) + (STACK_SIZE - sizeof(struct cpu_info));
+
+ /* The initial frame pointer. */
+ next = regs->ebp;
+
+ for ( ; ; )
+ {
+ /* Valid frame pointer? */
+ if ( (next < low) || (next > high) )
+ {
+ /*
+ * Exception stack frames have a different layout, denoted by an
+ * inverted frame pointer.
+ */
+ next = ~next;
+ if ( (next < low) || (next > high) )
+ break;
+ frame = (unsigned long *)next;
+ next = frame[0];
+ addr = frame[(offsetof(struct cpu_user_regs, eip) -
+ offsetof(struct cpu_user_regs, ebp))
+ / BYTES_PER_LONG];
+ }
+ else
+ {
+ /* Ordinary stack frame. */
+ frame = (unsigned long *)next;
+ next = frame[0];
+ addr = frame[1];
+ }
+
+ printk("[<%p>]", _p(addr));
+ print_symbol(" %s\n ", addr);
+
+ low = (unsigned long)&frame[2];
+ }
+
+ printk("\n");
+}
+
+#endif
+
+void show_stack(struct cpu_user_regs *regs)
+{
+ unsigned long *stack = ESP_BEFORE_EXCEPTION(regs), addr;
int i;
+ if ( GUEST_MODE(regs) )
+ return show_guest_stack(regs);
+
printk("Xen stack trace from "__OP"sp=%p:\n ", stack);
for ( i = 0; i < (debug_stack_lines*stack_words_per_line); i++ )
{
- if ( ((long)stack & (STACK_SIZE-1)) == 0 )
+ if ( ((long)stack & (STACK_SIZE-BYTES_PER_LONG)) == 0 )
break;
if ( (i != 0) && ((i % stack_words_per_line) == 0) )
printk("\n ");
@@ -190,7 +256,7 @@
printk("Stack empty.");
printk("\n");
- show_trace(esp);
+ show_trace(regs);
}
/*
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/vmx.c
--- a/xen/arch/x86/vmx.c Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/vmx.c Fri Sep 2 14:17:08 2005
@@ -412,7 +412,7 @@
if ( !result )
{
__vmread(GUEST_RIP, &eip);
- printk("vmx pgfault to guest va=%p eip=%p\n", va, eip);
+ printk("vmx pgfault to guest va=%lx eip=%lx\n", va, eip);
}
#endif
@@ -456,7 +456,16 @@
clear_bit(X86_FEATURE_PSE, &edx);
clear_bit(X86_FEATURE_PAE, &edx);
clear_bit(X86_FEATURE_PSE36, &edx);
+#else
+ struct vcpu *d = current;
+ if (d->domain->arch.ops->guest_paging_levels == PAGING_L2)
+ {
+ clear_bit(X86_FEATURE_PSE, &edx);
+ clear_bit(X86_FEATURE_PAE, &edx);
+ clear_bit(X86_FEATURE_PSE36, &edx);
+ }
#endif
+
}
regs->eax = (unsigned long) eax;
@@ -650,7 +659,7 @@
p->df = (eflags & X86_EFLAGS_DF) ? 1 : 0;
if (test_bit(5, &exit_qualification)) /* "rep" prefix */
- p->count = vm86 ? regs->ecx & 0xFFFF : regs->ecx;
+ p->count = vm86 ? regs->ecx & 0xFFFF : regs->ecx;
/*
* Split up string I/O operations that cross page boundaries. Don't
@@ -1006,6 +1015,15 @@
#if CONFIG_PAGING_LEVELS >= 4
if(!shadow_set_guest_paging_levels(d->domain, 4)) {
+ printk("Unsupported guest paging levels\n");
+ domain_crash_synchronous(); /* need to take a clean path */
+ }
+#endif
+ }
+ else
+ {
+#if CONFIG_PAGING_LEVELS >= 4
+ if(!shadow_set_guest_paging_levels(d->domain, 2)) {
printk("Unsupported guest paging levels\n");
domain_crash_synchronous(); /* need to take a clean path */
}
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/x86_32/traps.c
--- a/xen/arch/x86/x86_32/traps.c Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/x86_32/traps.c Fri Sep 2 14:17:08 2005
@@ -79,11 +79,8 @@
"ss: %04lx cs: %04lx\n",
ds, es, fs, gs, ss, cs);
- if ( GUEST_MODE(regs) )
- show_guest_stack();
- else
- show_stack((unsigned long *)®s->esp);
-}
+ show_stack(regs);
+}
void show_page_walk(unsigned long addr)
{
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/x86_64/traps.c
--- a/xen/arch/x86/x86_64/traps.c Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/x86_64/traps.c Fri Sep 2 14:17:08 2005
@@ -32,10 +32,7 @@
regs->r12, regs->r13, regs->r14);
printk("r15: %016lx\n", regs->r15);
- if ( GUEST_MODE(regs) )
- show_guest_stack();
- else
- show_stack((unsigned long *)regs->rsp);
+ show_stack(regs);
}
void show_page_walk(unsigned long addr)
diff -r edd1616cf8cb -r 291e816acbf4 xen/common/acm_ops.c
--- a/xen/common/acm_ops.c Fri Sep 2 14:15:49 2005
+++ b/xen/common/acm_ops.c Fri Sep 2 14:17:08 2005
@@ -19,6 +19,7 @@
#include <xen/types.h>
#include <xen/lib.h>
#include <xen/mm.h>
+#include <public/acm.h>
#include <public/acm_ops.h>
#include <xen/sched.h>
#include <xen/event.h>
@@ -41,7 +42,8 @@
POLICY, /* access to policy interface (early drop) */
GETPOLICY, /* dump policy cache */
SETPOLICY, /* set policy cache (controls security) */
- DUMPSTATS /* dump policy statistics */
+ DUMPSTATS, /* dump policy statistics */
+ GETSSID /* retrieve ssidref for domain id */
} acm_operation_t;
int acm_authorize_acm_ops(struct domain *d, acm_operation_t pops)
@@ -117,6 +119,35 @@
}
break;
+ case ACM_GETSSID:
+ {
+ ssidref_t ssidref;
+
+ if (acm_authorize_acm_ops(current->domain, GETSSID))
+ return -EACCES;
+
+ if (op->u.getssid.get_ssid_by == SSIDREF)
+ ssidref = op->u.getssid.id.ssidref;
+ else if (op->u.getssid.get_ssid_by == DOMAINID) {
+ struct domain *subj =
find_domain_by_id(op->u.getssid.id.domainid);
+ if (!subj)
+ return -ESRCH; /* domain not found */
+
+ ssidref = ((struct acm_ssid_domain
*)(subj->ssid))->ssidref;
+ put_domain(subj);
+ } else
+ return -ESRCH;
+
+ ret = acm_get_ssid(ssidref,
+ op->u.getssid.ssidbuf,
+ op->u.getssid.ssidbuf_size);
+ if (ret == ACM_OK)
+ ret = 0;
+ else
+ ret = -ESRCH;
+ }
+ break;
+
default:
ret = -ESRCH;
diff -r edd1616cf8cb -r 291e816acbf4 xen/common/domain.c
--- a/xen/common/domain.c Fri Sep 2 14:15:49 2005
+++ b/xen/common/domain.c Fri Sep 2 14:17:08 2005
@@ -178,6 +178,9 @@
struct domain *d = current->domain;
struct vcpu *v;
+ if(reason == SHUTDOWN_crash)
+ printk("Domain %d crash detected.\n", d->domain_id);
+
if ( d->domain_id == 0 )
{
extern void machine_restart(char *);
diff -r edd1616cf8cb -r 291e816acbf4 xen/common/grant_table.c
--- a/xen/common/grant_table.c Fri Sep 2 14:15:49 2005
+++ b/xen/common/grant_table.c Fri Sep 2 14:17:08 2005
@@ -887,21 +887,21 @@
e->tot_pages, e->max_pages);
spin_unlock(&e->page_alloc_lock);
put_domain(e);
- result = GNTST_general_error;
+ gop->status = result = GNTST_general_error;
break;
}
if (unlikely(test_bit(DOMFLAGS_DYING, &e->domain_flags))) {
printk("gnttab_donate: target domain is dying\n");
spin_unlock(&e->page_alloc_lock);
put_domain(e);
- result = GNTST_general_error;
+ gop->status = result = GNTST_general_error;
break;
}
if (unlikely(!gnttab_prepare_for_transfer(e, d, gop->handle))) {
- printk("gnttab_donate: gnttab_prepare_for_transfer fails\n");
+ printk("gnttab_donate: gnttab_prepare_for_transfer fails.\n");
spin_unlock(&e->page_alloc_lock);
put_domain(e);
- result = GNTST_general_error;
+ gop->status = result = GNTST_general_error;
break;
}
#else
@@ -914,7 +914,8 @@
e->tot_pages, e->max_pages, gop->handle, e->d_flags);
spin_unlock(&e->page_alloc_lock);
put_domain(e);
- result = GNTST_general_error;
+ /* XXX SMH: better error return here would be useful */
+ gop->status = result = GNTST_general_error;
break;
}
#endif
@@ -1020,7 +1021,7 @@
lgt = ld->grant_table;
#if GRANT_DEBUG_VERBOSE
- if ( ld->domain_ id != 0 ) {
+ if ( ld->domain_id != 0 ) {
DPRINTK("Foreign unref rd(%d) ld(%d) frm(%lx) flgs(%x).\n",
rd->domain_id, ld->domain_id, frame, readonly);
}
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/acm/acm_core.h
--- a/xen/include/acm/acm_core.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/acm/acm_core.h Fri Sep 2 14:17:08 2005
@@ -101,9 +101,15 @@
* primary ssidref = lower 16 bit
* secondary ssidref = higher 16 bit
*/
+#define ACM_PRIMARY(ssidref) \
+ ((ssidref) & 0xffff)
+
+#define ACM_SECONDARY(ssidref) \
+ ((ssidref) >> 16)
+
#define GET_SSIDREF(POLICY, ssidref) \
((POLICY) == acm_bin_pol.primary_policy_code) ? \
- ((ssidref) & 0xffff) : ((ssidref) >> 16)
+ ACM_PRIMARY(ssidref) : ACM_SECONDARY(ssidref)
/* macros to access ssid pointer for primary / secondary policy */
#define GET_SSIDP(POLICY, ssid) \
@@ -116,6 +122,7 @@
int acm_set_policy(void *buf, u16 buf_size, int isuserbuffer);
int acm_get_policy(void *buf, u16 buf_size);
int acm_dump_statistics(void *buf, u16 buf_size);
+int acm_get_ssid(ssidref_t ssidref, u8 *buf, u16 buf_size);
#endif
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/acm/acm_hooks.h
--- a/xen/include/acm/acm_hooks.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/acm/acm_hooks.h Fri Sep 2 14:17:08 2005
@@ -92,6 +92,7 @@
int (*dump_binary_policy) (u8 *buffer, u16 buf_size);
int (*set_binary_policy) (u8 *buffer, u16 buf_size);
int (*dump_statistics) (u8 *buffer, u16 buf_size);
+ int (*dump_ssid_types) (ssidref_t ssidref, u8 *buffer, u16
buf_size);
/* domain management control hooks (can be NULL) */
int (*pre_domain_create) (void *subject_ssid, ssidref_t ssidref);
void (*post_domain_create) (domid_t domid, ssidref_t ssidref);
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/page-guest32.h
--- a/xen/include/asm-x86/page-guest32.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/asm-x86/page-guest32.h Fri Sep 2 14:17:08 2005
@@ -32,6 +32,11 @@
/* Get pte access flags (unsigned int). */
#define l1e_get_flags_32(x) (get_pte_flags_32((x).l1))
#define l2e_get_flags_32(x) (get_pte_flags_32((x).l2))
+
+#define l1e_get_paddr_32(x) \
+ ((physaddr_t)(((x).l1 & (PADDR_MASK&PAGE_MASK))))
+#define l2e_get_paddr_32(x) \
+ ((physaddr_t)(((x).l2 & (PADDR_MASK&PAGE_MASK))))
/* Construct an empty pte. */
#define l1e_empty_32() ((l1_pgentry_32_t) { 0 })
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/processor.h
--- a/xen/include/asm-x86/processor.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/asm-x86/processor.h Fri Sep 2 14:17:08 2005
@@ -496,9 +496,7 @@
#endif
-void show_guest_stack();
-void show_trace(unsigned long *esp);
-void show_stack(unsigned long *esp);
+void show_stack(struct cpu_user_regs *regs);
void show_registers(struct cpu_user_regs *regs);
void show_page_walk(unsigned long addr);
asmlinkage void fatal_trap(int trapnr, struct cpu_user_regs *regs);
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/shadow.h
--- a/xen/include/asm-x86/shadow.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/asm-x86/shadow.h Fri Sep 2 14:17:08 2005
@@ -34,6 +34,8 @@
#include <asm/vmx.h>
#include <public/dom0_ops.h>
#include <asm/shadow_public.h>
+#include <asm/page-guest32.h>
+#include <asm/shadow_ops.h>
/* Shadow PT operation mode : shadow-mode variable in arch_domain. */
@@ -104,9 +106,9 @@
} while (0)
#endif
-#define SHADOW_ENCODE_MIN_MAX(_min, _max) ((((L1_PAGETABLE_ENTRIES - 1) -
(_max)) << 16) | (_min))
+#define SHADOW_ENCODE_MIN_MAX(_min, _max) ((((GUEST_L1_PAGETABLE_ENTRIES - 1)
- (_max)) << 16) | (_min))
#define SHADOW_MIN(_encoded) ((_encoded) & ((1u<<16) - 1))
-#define SHADOW_MAX(_encoded) ((L1_PAGETABLE_ENTRIES - 1) - ((_encoded) >> 16))
+#define SHADOW_MAX(_encoded) ((GUEST_L1_PAGETABLE_ENTRIES - 1) - ((_encoded)
>> 16))
extern void shadow_mode_init(void);
extern int shadow_mode_control(struct domain *p, dom0_shadow_control_t *sc);
@@ -132,6 +134,7 @@
struct domain_mmap_cache *cache);
#if CONFIG_PAGING_LEVELS >= 3
#include <asm/page-guest32.h>
+extern unsigned long gva_to_gpa(unsigned long gva);
extern void shadow_l3_normal_pt_update(struct domain *d,
unsigned long pa, l3_pgentry_t l3e,
struct domain_mmap_cache *cache);
@@ -794,22 +797,22 @@
#endif
static inline void l1pte_propagate_from_guest(
- struct domain *d, l1_pgentry_t gpte, l1_pgentry_t *spte_p)
+ struct domain *d, guest_l1_pgentry_t gpte, l1_pgentry_t *spte_p)
{
unsigned long mfn;
l1_pgentry_t spte;
spte = l1e_empty();
- if ( ((l1e_get_flags(gpte) & (_PAGE_PRESENT|_PAGE_ACCESSED) ) ==
+ if ( ((guest_l1e_get_flags(gpte) & (_PAGE_PRESENT|_PAGE_ACCESSED) ) ==
(_PAGE_PRESENT|_PAGE_ACCESSED)) &&
VALID_MFN(mfn = __gpfn_to_mfn(d, l1e_get_pfn(gpte))) )
{
spte = l1e_from_pfn(
- mfn, l1e_get_flags(gpte) & ~(_PAGE_GLOBAL | _PAGE_AVAIL));
+ mfn, guest_l1e_get_flags(gpte) & ~(_PAGE_GLOBAL | _PAGE_AVAIL));
if ( shadow_mode_log_dirty(d) ||
- !(l1e_get_flags(gpte) & _PAGE_DIRTY) ||
+ !(guest_l1e_get_flags(gpte) & _PAGE_DIRTY) ||
mfn_is_page_table(mfn) )
{
l1e_remove_flags(spte, _PAGE_RW);
@@ -859,22 +862,22 @@
static inline void l2pde_general(
struct domain *d,
- l2_pgentry_t *gpde_p,
+ guest_l2_pgentry_t *gpde_p,
l2_pgentry_t *spde_p,
unsigned long sl1mfn)
{
- l2_pgentry_t gpde = *gpde_p;
+ guest_l2_pgentry_t gpde = *gpde_p;
l2_pgentry_t spde;
spde = l2e_empty();
- if ( (l2e_get_flags(gpde) & _PAGE_PRESENT) && (sl1mfn != 0) )
+ if ( (guest_l2e_get_flags(gpde) & _PAGE_PRESENT) && (sl1mfn != 0) )
{
spde = l2e_from_pfn(
- sl1mfn,
- (l2e_get_flags(gpde) | _PAGE_RW | _PAGE_ACCESSED) & ~_PAGE_AVAIL);
+ sl1mfn,
+ (guest_l2e_get_flags(gpde) | _PAGE_RW | _PAGE_ACCESSED) &
~_PAGE_AVAIL);
/* N.B. PDEs do not have a dirty bit. */
- l2e_add_flags(gpde, _PAGE_ACCESSED);
+ guest_l2e_add_flags(gpde, _PAGE_ACCESSED);
*gpde_p = gpde;
}
@@ -887,12 +890,12 @@
}
static inline void l2pde_propagate_from_guest(
- struct domain *d, l2_pgentry_t *gpde_p, l2_pgentry_t *spde_p)
-{
- l2_pgentry_t gpde = *gpde_p;
+ struct domain *d, guest_l2_pgentry_t *gpde_p, l2_pgentry_t *spde_p)
+{
+ guest_l2_pgentry_t gpde = *gpde_p;
unsigned long sl1mfn = 0;
- if ( l2e_get_flags(gpde) & _PAGE_PRESENT )
+ if ( guest_l2e_get_flags(gpde) & _PAGE_PRESENT )
sl1mfn = __shadow_status(d, l2e_get_pfn(gpde), PGT_l1_shadow);
l2pde_general(d, gpde_p, spde_p, sl1mfn);
}
@@ -904,7 +907,7 @@
static int inline
validate_pte_change(
struct domain *d,
- l1_pgentry_t new_pte,
+ guest_l1_pgentry_t new_pte,
l1_pgentry_t *shadow_pte_p)
{
l1_pgentry_t old_spte, new_spte;
@@ -1004,7 +1007,7 @@
static int inline
validate_pde_change(
struct domain *d,
- l2_pgentry_t new_gpde,
+ guest_l2_pgentry_t new_gpde,
l2_pgentry_t *shadow_pde_p)
{
l2_pgentry_t old_spde, new_spde;
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/shadow_64.h
--- a/xen/include/asm-x86/shadow_64.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/asm-x86/shadow_64.h Fri Sep 2 14:17:08 2005
@@ -27,6 +27,7 @@
#ifndef _XEN_SHADOW_64_H
#define _XEN_SHADOW_64_H
#include <asm/shadow.h>
+#include <asm/shadow_ops.h>
#define READ_FAULT 0
#define WRITE_FAULT 1
@@ -42,14 +43,14 @@
#define ESH_LOG(_f, _a...) ((void)0)
#endif
-#define L4 4UL
-#define L3 3UL
-#define L2 2UL
-#define L1 1UL
+#define PAGING_L4 4UL
+#define PAGING_L3 3UL
+#define PAGING_L2 2UL
+#define PAGING_L1 1UL
#define L_MASK 0xff
-#define ROOT_LEVEL_64 L4
-#define ROOT_LEVEL_32 L2
+#define ROOT_LEVEL_64 PAGING_L4
+#define ROOT_LEVEL_32 PAGING_L2
#define SHADOW_ENTRY (2UL << 16)
#define GUEST_ENTRY (1UL << 16)
@@ -58,6 +59,10 @@
#define SET_ENTRY (1UL << 8)
#define PAGETABLE_ENTRIES (1<<PAGETABLE_ORDER)
+
+/* For 32-bit VMX guest to allocate shadow L1 & L2*/
+#define SL1_ORDER 1
+#define SL2_ORDER 2
typedef struct { intpte_t lo; } pgentry_64_t;
#define shadow_level_to_type(l) (l << 29)
@@ -76,6 +81,10 @@
#define entry_remove_flags(x, flags) ((x).lo &= ~put_pte_flags(flags))
#define entry_has_changed(x,y,flags) \
( !!(((x).lo ^ (y).lo) &
((PADDR_MASK&PAGE_MASK)|put_pte_flags(flags))) )
+
+#define PAE_SHADOW_SELF_ENTRY 259
+#define PDP_ENTRIES 4
+
static inline int table_offset_64(unsigned long va, int level)
{
switch(level) {
@@ -86,8 +95,13 @@
case 3:
return (((va) >> L3_PAGETABLE_SHIFT) & (L3_PAGETABLE_ENTRIES -
1));
#if CONFIG_PAGING_LEVELS >= 4
+#ifndef GUEST_PGENTRY_32
case 4:
return (((va) >> L4_PAGETABLE_SHIFT) & (L4_PAGETABLE_ENTRIES -
1));
+#else
+ case 4:
+ return PAE_SHADOW_SELF_ENTRY;
+#endif
#endif
default:
//printk("<table_offset_64> level %d is too big\n", level);
@@ -165,30 +179,30 @@
return le_e;
}
#define __shadow_set_l4e(v, va, value) \
- __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | L4)
+ __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | PAGING_L4)
#define __shadow_get_l4e(v, va, sl4e) \
- __rw_entry(v, va, sl4e, SHADOW_ENTRY | GET_ENTRY | L4)
+ __rw_entry(v, va, sl4e, SHADOW_ENTRY | GET_ENTRY | PAGING_L4)
#define __shadow_set_l3e(v, va, value) \
- __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | L3)
+ __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | PAGING_L3)
#define __shadow_get_l3e(v, va, sl3e) \
- __rw_entry(v, va, sl3e, SHADOW_ENTRY | GET_ENTRY | L3)
+ __rw_entry(v, va, sl3e, SHADOW_ENTRY | GET_ENTRY | PAGING_L3)
#define __shadow_set_l2e(v, va, value) \
- __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | L2)
+ __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | PAGING_L2)
#define __shadow_get_l2e(v, va, sl2e) \
- __rw_entry(v, va, sl2e, SHADOW_ENTRY | GET_ENTRY | L2)
+ __rw_entry(v, va, sl2e, SHADOW_ENTRY | GET_ENTRY | PAGING_L2)
#define __shadow_set_l1e(v, va, value) \
- __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | L1)
+ __rw_entry(v, va, value, SHADOW_ENTRY | SET_ENTRY | PAGING_L1)
#define __shadow_get_l1e(v, va, sl1e) \
- __rw_entry(v, va, sl1e, SHADOW_ENTRY | GET_ENTRY | L1)
+ __rw_entry(v, va, sl1e, SHADOW_ENTRY | GET_ENTRY | PAGING_L1)
#define __guest_set_l4e(v, va, value) \
- __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | L4)
+ __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | PAGING_L4)
#define __guest_get_l4e(v, va, gl4e) \
- __rw_entry(v, va, gl4e, GUEST_ENTRY | GET_ENTRY | L4)
+ __rw_entry(v, va, gl4e, GUEST_ENTRY | GET_ENTRY | PAGING_L4)
#define __guest_set_l3e(v, va, value) \
- __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | L3)
+ __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | PAGING_L3)
#define __guest_get_l3e(v, va, sl3e) \
- __rw_entry(v, va, gl3e, GUEST_ENTRY | GET_ENTRY | L3)
+ __rw_entry(v, va, gl3e, GUEST_ENTRY | GET_ENTRY | PAGING_L3)
static inline void * __guest_set_l2e(
struct vcpu *v, u64 va, void *value, int size)
@@ -205,7 +219,7 @@
return &l2va[l2_table_offset_32(va)];
}
case 8:
- return __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | L2);
+ return __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY |
PAGING_L2);
default:
BUG();
return NULL;
@@ -230,7 +244,7 @@
return &l2va[l2_table_offset_32(va)];
}
case 8:
- return __rw_entry(v, va, gl2e, GUEST_ENTRY | GET_ENTRY | L2);
+ return __rw_entry(v, va, gl2e, GUEST_ENTRY | GET_ENTRY |
PAGING_L2);
default:
BUG();
return NULL;
@@ -269,7 +283,7 @@
}
case 8:
- return __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY | L1);
+ return __rw_entry(v, va, value, GUEST_ENTRY | SET_ENTRY |
PAGING_L1);
default:
BUG();
return NULL;
@@ -310,7 +324,7 @@
}
case 8:
// 64-bit guest
- return __rw_entry(v, va, gl1e, GUEST_ENTRY | GET_ENTRY | L1);
+ return __rw_entry(v, va, gl1e, GUEST_ENTRY | GET_ENTRY |
PAGING_L1);
default:
BUG();
return NULL;
@@ -334,7 +348,7 @@
sle = entry_empty();
if ( (entry_get_flags(gle) & _PAGE_PRESENT) && (smfn != 0) )
{
- if ((entry_get_flags(gle) & _PAGE_PSE) && level == L2) {
+ if ((entry_get_flags(gle) & _PAGE_PSE) && level == PAGING_L2) {
sle = entry_from_pfn(smfn, entry_get_flags(gle));
entry_remove_flags(sle, _PAGE_PSE);
@@ -376,7 +390,7 @@
unsigned long smfn = 0;
if ( entry_get_flags(gle) & _PAGE_PRESENT ) {
- if ((entry_get_flags(gle) & _PAGE_PSE) && level == L2) {
+ if ((entry_get_flags(gle) & _PAGE_PSE) && level == PAGING_L2) {
smfn = __shadow_status(d, entry_get_value(gle) >> PAGE_SHIFT,
PGT_fl1_shadow);
} else {
smfn = __shadow_status(d, entry_get_pfn(gle),
@@ -421,88 +435,6 @@
return 1;
}
-/*
- * Check P, R/W, U/S bits in the guest page table.
- * If the fault belongs to guest return 1,
- * else return 0.
- */
-static inline int guest_page_fault(struct vcpu *v,
- unsigned long va, unsigned int error_code, pgentry_64_t *gpl2e, pgentry_64_t
*gpl1e)
-{
- struct domain *d = v->domain;
- pgentry_64_t gle, *lva;
- unsigned long mfn;
- int i;
-
- __rw_entry(v, va, &gle, GUEST_ENTRY | GET_ENTRY | L4);
- if (unlikely(!(entry_get_flags(gle) & _PAGE_PRESENT)))
- return 1;
-
- if (error_code & ERROR_W) {
- if (unlikely(!(entry_get_flags(gle) & _PAGE_RW)))
- return 1;
- }
- if (error_code & ERROR_U) {
- if (unlikely(!(entry_get_flags(gle) & _PAGE_USER)))
- return 1;
- }
- for (i = L3; i >= L1; i--) {
- /*
- * If it's not external mode, then mfn should be machine physical.
- */
- mfn = __gpfn_to_mfn(d, (entry_get_paddr(gle) >> PAGE_SHIFT));
- if (mfn == -1)
- return 1;
-
- lva = (pgentry_64_t *) phys_to_virt(
- mfn << PAGE_SHIFT);
- gle = lva[table_offset_64(va, i)];
-
- if (unlikely(!(entry_get_flags(gle) & _PAGE_PRESENT)))
- return 1;
-
- if (error_code & ERROR_W) {
- if (unlikely(!(entry_get_flags(gle) & _PAGE_RW)))
- return 1;
- }
- if (error_code & ERROR_U) {
- if (unlikely(!(entry_get_flags(gle) & _PAGE_USER)))
- return 1;
- }
-
- if (i == L2) {
- if (gpl2e)
- *gpl2e = gle;
-
- if (likely(entry_get_flags(gle) & _PAGE_PSE))
- return 0;
-
- }
-
- if (i == L1)
- if (gpl1e)
- *gpl1e = gle;
- }
- return 0;
-}
-
-static inline unsigned long gva_to_gpa(unsigned long gva)
-{
- struct vcpu *v = current;
- pgentry_64_t gl1e = {0};
- pgentry_64_t gl2e = {0};
- unsigned long gpa;
-
- if (guest_page_fault(v, gva, 0, &gl2e, &gl1e))
- return 0;
- if (entry_get_flags(gl2e) & _PAGE_PSE)
- gpa = entry_get_paddr(gl2e) + (gva & ((1 << L2_PAGETABLE_SHIFT) - 1));
- else
- gpa = entry_get_paddr(gl1e) + (gva & ~PAGE_MASK);
-
- return gpa;
-
-}
#endif
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/shadow_public.h
--- a/xen/include/asm-x86/shadow_public.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/asm-x86/shadow_public.h Fri Sep 2 14:17:08 2005
@@ -49,6 +49,7 @@
(*mark_mfn_out_of_sync)(struct vcpu *v, unsigned long gpfn,
unsigned long mfn);
int (*is_out_of_sync)(struct vcpu *v, unsigned long va);
+ unsigned long (*gva_to_gpa)(unsigned long gva);
};
#endif
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/x86_32/asm_defns.h
--- a/xen/include/asm-x86/x86_32/asm_defns.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/asm-x86/x86_32/asm_defns.h Fri Sep 2 14:17:08 2005
@@ -1,10 +1,20 @@
#ifndef __X86_32_ASM_DEFNS_H__
#define __X86_32_ASM_DEFNS_H__
+
+#ifndef NDEBUG
+/* Indicate special exception stack frame by inverting the frame pointer. */
+#define SETUP_EXCEPTION_FRAME_POINTER \
+ movl %esp,%ebp; \
+ notl %ebp
+#else
+#define SETUP_EXCEPTION_FRAME_POINTER
+#endif
#define __SAVE_ALL_PRE \
cld; \
pushl %eax; \
pushl %ebp; \
+ SETUP_EXCEPTION_FRAME_POINTER; \
pushl %edi; \
pushl %esi; \
pushl %edx; \
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/x86_64/asm_defns.h
--- a/xen/include/asm-x86/x86_64/asm_defns.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/asm-x86/x86_64/asm_defns.h Fri Sep 2 14:17:08 2005
@@ -1,5 +1,14 @@
#ifndef __X86_64_ASM_DEFNS_H__
#define __X86_64_ASM_DEFNS_H__
+
+#ifndef NDEBUG
+/* Indicate special exception stack frame by inverting the frame pointer. */
+#define SETUP_EXCEPTION_FRAME_POINTER \
+ movq %rsp,%rbp; \
+ notq %rbp
+#else
+#define SETUP_EXCEPTION_FRAME_POINTER
+#endif
#define SAVE_ALL \
cld; \
@@ -14,6 +23,7 @@
pushq %r11; \
pushq %rbx; \
pushq %rbp; \
+ SETUP_EXCEPTION_FRAME_POINTER; \
pushq %r12; \
pushq %r13; \
pushq %r14; \
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/public/acm.h
--- a/xen/include/public/acm.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/public/acm.h Fri Sep 2 14:17:08 2005
@@ -56,20 +56,22 @@
#define ACM_ACCESS_DENIED -111
#define ACM_NULL_POINTER_ERROR -200
-#define ACM_MAX_POLICY 3
-
+/* primary policy in lower 4 bits */
#define ACM_NULL_POLICY 0
#define ACM_CHINESE_WALL_POLICY 1
#define ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY 2
-#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY 3
+
+/* combinations have secondary policy component in higher 4bit */
+#define ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY \
+ ((ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY << 4) | ACM_CHINESE_WALL_POLICY)
/* policy: */
#define ACM_POLICY_NAME(X) \
- (X == ACM_NULL_POLICY) ? "NULL policy" : \
- (X == ACM_CHINESE_WALL_POLICY) ? "CHINESE WALL policy" : \
- (X == ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "SIMPLE TYPE ENFORCEMENT
policy" : \
- (X == ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY) ? "CHINESE
WALL AND SIMPLE TYPE ENFORCEMENT policy" : \
- "UNDEFINED policy"
+ ((X) == (ACM_NULL_POLICY)) ? "NULL policy" : \
+ ((X) == (ACM_CHINESE_WALL_POLICY)) ? "CHINESE WALL policy" : \
+ ((X) == (ACM_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "SIMPLE TYPE ENFORCEMENT
policy" : \
+ ((X) == (ACM_CHINESE_WALL_AND_SIMPLE_TYPE_ENFORCEMENT_POLICY)) ? "CHINESE
WALL AND SIMPLE TYPE ENFORCEMENT policy" : \
+ "UNDEFINED policy"
/* the following policy versions must be increased
* whenever the interpretation of the related
@@ -122,7 +124,7 @@
*/
struct acm_policy_buffer {
u32 policy_version; /* ACM_POLICY_VERSION */
- u32 magic;
+ u32 magic;
u32 len;
u32 primary_policy_code;
u32 primary_buffer_offset;
@@ -151,7 +153,7 @@
};
struct acm_stats_buffer {
- u32 magic;
+ u32 magic;
u32 len;
u32 primary_policy_code;
u32 primary_stats_offset;
@@ -168,5 +170,15 @@
u32 gt_cachehit_count;
};
+struct acm_ssid_buffer {
+ u32 len;
+ ssidref_t ssidref;
+ u32 primary_policy_code;
+ u32 primary_max_types;
+ u32 primary_types_offset;
+ u32 secondary_policy_code;
+ u32 secondary_max_types;
+ u32 secondary_types_offset;
+};
#endif
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/public/acm_ops.h
--- a/xen/include/public/acm_ops.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/public/acm_ops.h Fri Sep 2 14:17:08 2005
@@ -1,3 +1,4 @@
+
/******************************************************************************
* acm_ops.h
*
@@ -27,7 +28,7 @@
* This makes sure that old versions of acm tools will stop working in a
* well-defined way (rather than crashing the machine, for instance).
*/
-#define ACM_INTERFACE_VERSION 0xAAAA0003
+#define ACM_INTERFACE_VERSION 0xAAAA0004
/************************************************************************/
@@ -46,12 +47,25 @@
u16 pullcache_size;
} acm_getpolicy_t;
+
#define ACM_DUMPSTATS 6
typedef struct acm_dumpstats {
void *pullcache;
u16 pullcache_size;
} acm_dumpstats_t;
+
+#define ACM_GETSSID 7
+enum get_type {UNSET, SSIDREF, DOMAINID};
+typedef struct acm_getssid {
+ enum get_type get_ssid_by;
+ union {
+ domaintype_t domainid;
+ ssidref_t ssidref;
+ } id;
+ void *ssidbuf;
+ u16 ssidbuf_size;
+} acm_getssid_t;
typedef struct acm_op {
u32 cmd;
@@ -60,6 +74,7 @@
acm_setpolicy_t setpolicy;
acm_getpolicy_t getpolicy;
acm_dumpstats_t dumpstats;
+ acm_getssid_t getssid;
} u;
} acm_op_t;
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/public/io/netif.h
--- a/xen/include/public/io/netif.h Fri Sep 2 14:15:49 2005
+++ b/xen/include/public/io/netif.h Fri Sep 2 14:17:08 2005
@@ -23,13 +23,13 @@
typedef struct {
u16 id; /* Echoed in response message. */
-#ifdef CONFIG_XEN_NETDEV_GRANT_RX
+#ifdef CONFIG_XEN_NETDEV_GRANT
grant_ref_t gref; /* 2: Reference to incoming granted frame */
#endif
} netif_rx_request_t;
typedef struct {
-#ifdef CONFIG_XEN_NETDEV_GRANT_TX
+#ifdef CONFIG_XEN_NETDEV_GRANT
u32 addr; /* 0: Offset in page of start of received packet */
#else
unsigned long addr; /* Machine address of packet. */
diff -r edd1616cf8cb -r 291e816acbf4 extras/mini-os/domain_config
--- /dev/null Fri Sep 2 14:15:49 2005
+++ b/extras/mini-os/domain_config Fri Sep 2 14:17:08 2005
@@ -0,0 +1,17 @@
+# -*- mode: python; -*-
+#============================================================================
+# Python configuration setup for 'xm create'.
+# This script sets the parameters used when a domain is created using 'xm
create'.
+# You use a separate script for each domain you want to create, or
+# you can set the parameters for the domain on the xm command line.
+#============================================================================
+
+#----------------------------------------------------------------------------
+# Kernel image file.
+kernel = "mini-os.elf"
+
+# Initial memory allocation (in megabytes) for the new domain.
+memory = 32
+
+# A name for your domain. All domains must have different names.
+name = "Mini-OS"
diff -r edd1616cf8cb -r 291e816acbf4 extras/mini-os/include/list.h
--- /dev/null Fri Sep 2 14:15:49 2005
+++ b/extras/mini-os/include/list.h Fri Sep 2 14:17:08 2005
@@ -0,0 +1,184 @@
+#ifndef _LINUX_LIST_H
+#define _LINUX_LIST_H
+
+/*
+ * Simple doubly linked list implementation.
+ *
+ * Some of the internal functions ("__xxx") are useful when
+ * manipulating whole lists rather than single entries, as
+ * sometimes we already know the next/prev entries and we can
+ * generate better code by using them directly rather than
+ * using the generic single-entry routines.
+ */
+
+struct list_head {
+ struct list_head *next, *prev;
+};
+
+#define LIST_HEAD_INIT(name) { &(name), &(name) }
+
+#define LIST_HEAD(name) \
+ struct list_head name = LIST_HEAD_INIT(name)
+
+#define INIT_LIST_HEAD(ptr) do { \
+ (ptr)->next = (ptr); (ptr)->prev = (ptr); \
+} while (0)
+
+/*
+ * Insert a new entry between two known consecutive entries.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static __inline__ void __list_add(struct list_head * new,
+ struct list_head * prev,
+ struct list_head * next)
+{
+ next->prev = new;
+ new->next = next;
+ new->prev = prev;
+ prev->next = new;
+}
+
+/**
+ * list_add - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it after
+ *
+ * Insert a new entry after the specified head.
+ * This is good for implementing stacks.
+ */
+static __inline__ void list_add(struct list_head *new, struct list_head *head)
+{
+ __list_add(new, head, head->next);
+}
+
+/**
+ * list_add_tail - add a new entry
+ * @new: new entry to be added
+ * @head: list head to add it before
+ *
+ * Insert a new entry before the specified head.
+ * This is useful for implementing queues.
+ */
+static __inline__ void list_add_tail(struct list_head *new, struct list_head
*head)
+{
+ __list_add(new, head->prev, head);
+}
+
+/*
+ * Delete a list entry by making the prev/next entries
+ * point to each other.
+ *
+ * This is only for internal list manipulation where we know
+ * the prev/next entries already!
+ */
+static __inline__ void __list_del(struct list_head * prev,
+ struct list_head * next)
+{
+ next->prev = prev;
+ prev->next = next;
+}
+
+/**
+ * list_del - deletes entry from list.
+ * @entry: the element to delete from the list.
+ * Note: list_empty on entry does not return true after this, the entry is in
an undefined state.
+ */
+static __inline__ void list_del(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+}
+
+/**
+ * list_del_init - deletes entry from list and reinitialize it.
+ * @entry: the element to delete from the list.
+ */
+static __inline__ void list_del_init(struct list_head *entry)
+{
+ __list_del(entry->prev, entry->next);
+ INIT_LIST_HEAD(entry);
+}
+
+/**
+ * list_empty - tests whether a list is empty
+ * @head: the list to test.
+ */
+static __inline__ int list_empty(struct list_head *head)
+{
+ return head->next == head;
+}
+
+/**
+ * list_splice - join two lists
+ * @list: the new list to add.
+ * @head: the place to add it in the first list.
+ */
+static __inline__ void list_splice(struct list_head *list, struct list_head
*head)
+{
+ struct list_head *first = list->next;
+
+ if (first != list) {
+ struct list_head *last = list->prev;
+ struct list_head *at = head->next;
+
+ first->prev = head;
+ head->next = first;
+
+ last->next = at;
+ at->prev = last;
+ }
+}
+
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+/**
+ * list_for_each - iterate over a list
+ * @pos: the &struct list_head to use as a loop counter.
+ * @head: the head for your list.
+ */
+#define list_for_each(pos, head) \
+ for (pos = (head)->next; pos != (head); pos = pos->next)
+
+/**
+ * list_for_each_safe - iterate over a list safe against removal of
list entry
+ * @pos: the &struct list_head to use as a loop counter.
+ * @n: another &struct list_head to use as temporary storage
+ * @head: the head for your list.
+ */
+#define list_for_each_safe(pos, n, head) \
+ for (pos = (head)->next, n = pos->next; pos != (head); \
+ pos = n, n = pos->next)
+
+/**
+ * list_for_each_entry - iterate over list of given type
+ * @pos: the type * to use as a loop counter.
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry(pos, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = list_entry(pos->member.next, typeof(*pos), member))
+
+/**
+ * list_for_each_entry_safe - iterate over list of given type safe against
removal of list entry
+ * @pos: the type * to use as a loop counter.
+ * @n: another type * to use as temporary storage
+ * @head: the head for your list.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_for_each_entry_safe(pos, n, head, member) \
+ for (pos = list_entry((head)->next, typeof(*pos), member), \
+ n = list_entry(pos->member.next, typeof(*pos), member); \
+ &pos->member != (head); \
+ pos = n, n = list_entry(n->member.next, typeof(*n), member))
+#endif /* _LINUX_LIST_H */
+
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/getlabel.sh
--- /dev/null Fri Sep 2 14:15:49 2005
+++ b/tools/security/getlabel.sh Fri Sep 2 14:17:08 2005
@@ -0,0 +1,130 @@
+#!/bin/sh
+# *
+# * getlabel
+# *
+# * Copyright (C) 2005 IBM Corporation
+# *
+# * Authors:
+# * Stefan Berger <stefanb@xxxxxxxxxx>
+# *
+# * This program is free software; you can redistribute it and/or
+# * modify it under the terms of the GNU General Public License as
+# * published by the Free Software Foundation, version 2 of the
+# * License.
+# *
+# * 'getlabel' tries to find the labels corresponding to the ssidref
+# *
+# * 'getlabel -?' shows the usage of the program
+# *
+# * 'getlabel -sid <ssidref> [<policy name>]' lists the label corresponding
+# * to the given ssidref.
+# *
+# * 'getlabel -dom <domain id> [<policy name>]' lists the label of the
+# * domain with given id
+# *
+#
+
+if [ -z "$runbash" ]; then
+ runbash="1"
+ export runbash
+ exec sh -c "bash $0 $*"
+fi
+
+
+export PATH=$PATH:.
+source labelfuncs.sh
+
+usage ()
+{
+ echo "Usage: $0 -sid <ssidref> [<policy name>] or"
+ echo " $0 -dom <domid> [<policy name>] "
+ echo ""
+ echo "policy name : the name of the policy, i.e. 'chwall'"
+ echo " If the policy name is omitted, the grub.conf"
+ echo " entry of the running system is tried to be read"
+ echo " and the policy name determined from there."
+ echo "ssidref : an ssidref in hex or decimal format, i.e.,
'0x00010002'"
+ echo " or '65538'"
+ echo "domid : id of the domain, i.e., '1'; Use numbers from the
2nd"
+ echo " column shown when invoking 'xm list'"
+ echo ""
+}
+
+
+
+if [ "$1" == "-?" ]; then
+ mode="usage"
+elif [ "$1" == "-dom" ]; then
+ mode="domid"
+ shift
+elif [ "$1" == "-sid" ]; then
+ mode="sid"
+ shift
+elif [ "$1" == "" ]; then
+ usage
+ exit -1
+fi
+
+
+if [ "$mode" == "usage" ]; then
+ usage
+elif [ "$mode" == "domid" ]; then
+ if [ "$2" == "" ]; then
+ findGrubConf
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo "Could not find grub.conf"
+ exit -1;
+ fi
+ findPolicyInGrub $grubconf
+ if [ "$policy" != "" ]; then
+ echo "Assuming policy to be '$policy'.";
+ else
+ echo "Could not find policy."
+ exit -1;
+ fi
+ else
+ policy=$2
+ fi
+ findMapFile $policy
+ res=$?
+ if [ "$res" != "0" ]; then
+ getSSIDUsingSecpolTool $1
+ res=$?
+ if [ "$res" != "0" ]; then
+ translateSSIDREF $ssid $mapfile
+ else
+ echo "Could not determine the SSID of the domain."
+ fi
+ else
+ echo "Could not find map file for policy '$policy'."
+ fi
+elif [ "$mode" == "sid" ]; then
+ if [ "$2" == "" ]; then
+ findGrubConf
+ ret=$?
+ if [ $ret -eq 0 ]; then
+ echo "Could not find grub.conf"
+ exit -1;
+ fi
+ findPolicyInGrub $grubconf
+ if [ "$policy" != "" ]; then
+ echo "Assuming policy to be '$policy'.";
+ else
+ echo "Could not find policy."
+ exit -1;
+ fi
+ else
+ policy=$2
+ fi
+ findMapFile $policy
+ res=$?
+ if [ "$res" != "0" ]; then
+ translateSSIDREF $1 $mapfile
+ else
+ echo "Could not find map file for policy '$policy'."
+ fi
+
+else
+ usage
+fi
diff -r edd1616cf8cb -r 291e816acbf4 tools/security/labelfuncs.sh
--- /dev/null Fri Sep 2 14:15:49 2005
+++ b/tools/security/labelfuncs.sh Fri Sep 2 14:17:08 2005
@@ -0,0 +1,675 @@
+# *
+# * labelfuncs.sh
+# *
+# * Copyright (C) 2005 IBM Corporation
+# *
+# * Authors:
+# * Stefan Berger <stefanb@xxxxxxxxxx>
+# *
+# * This program is free software; you can redistribute it and/or
+# * modify it under the terms of the GNU General Public License as
+# * published by the Free Software Foundation, version 2 of the
+# * License.
+# *
+# *
+# * A collection of functions to handle polcies, mapfiles,
+# * and ssidrefs.
+#
+
+
+# Find the mapfile given a policy nmame
+# Parameters:
+# 1st : the name of the policy whose map file is to be found, i.e.,
+# chwall
+# Results:
+# The variable mapfile will hold the realtive path to the mapfile
+# for the given policy.
+# In case the mapfile could be found, the functions returns a '1',
+# a '0' otherwise.
+findMapFile ()
+{
+ mapfile="./$1.map"
+ if [ -r "$mapfile" ]; then
+ return 1
+ fi
+
+ mapfile="./policies/$1/$1.map"
+ if [ -r "$mapfile" ]; then
+ return 1
+ fi
+
+ return 0
+}
+
+
+# Determine the name of the primary policy
+# Parameters
+# 1st : the path to the mapfile; the path may be relative
+# to the current directory
+# Results
+# The variable primary will hold the name of the primary policy
+getPrimaryPolicy ()
+{
+ mapfile=$1
+ primary=`cat $mapfile | \
+ awk ' \
+ { \
+ if ( $1 == "PRIMARY" ) { \
+ res=$2; \
+ } \
+ } END { \
+ print res; \
+ } '`
+}
+
+
+# Determine the name of the secondary policy
+# Parameters
+# 1st : the path to the mapfile; the path may be relative
+# to the current directory
+# Results
+# The variable secondary will hold the name of the secondary policy
+getSecondaryPolicy ()
+{
+ mapfile=$1
+ secondary=`cat $mapfile | \
+ awk ' \
+ { \
+ if ( $1 == "SECONDARY" ) { \
+ res=$2; \
+ } \
+ } END { \
+ print res; \
+ } '`
+}
+
+
+#Return where the grub.conf file is.
+#I only know of one place it can be.
+findGrubConf()
+{
+ grubconf="/boot/grub/grub.conf"
+ if [ -w $grubconf ]; then
+ return 1
+ fi
+ if [ -r $grubconf ]; then
+ return 2
+ fi
+ return 0
+}
+
+
+# This function sets the global variable 'linux'
+# to the name and version of the Linux kernel that was compiled
+# for domain 0.
+# If this variable could not be found, the variable 'linux'
+# will hold a pattern
+# Parameters:
+# 1st: the path to reach the root directory of the XEN build tree
+# where linux-*-xen0 is located at
+# Results:
+# The variable linux holds then name and version of the compiled
+# kernel, i.e., 'vmlinuz-2.6.12-xen0'
+getLinuxVersion ()
+{
+ path=$1
+ linux=""
+ for f in $path/linux-*-xen0 ; do
+ versionfile=$f/include/linux/version.h
+ if [ -r $versionfile ]; then
+ lnx=`cat $versionfile | \
+ grep UTS_RELEASE | \
+ awk '{ \
+ len=length($3); \
+ print substr($3,2,len-2) }'`
+ fi
+ if [ "$lnx" != "" ]; then
+ linux="[./0-9a-zA-z]*$lnx"
+ return;
+ fi
+ done
+
+ #Last resort.
+ linux="vmlinuz-2.[45678].[0-9]*[.0-9]*-xen0$"
+}
+
+
+# Find out with which policy the hypervisor was booted with.
+# Parameters
+# 1st : The complete path to grub.conf, i.e., /boot/grub/grub.conf
+#
+findPolicyInGrub ()
+{
+ grubconf=$1
+ linux=`uname -r`
+ policy=`cat $grubconf | \
+ awk -vlinux=$linux '{ \
+ if ( $1 == "title" ) { \
+ kernelfound = 0; \
+ policymaycome = 0; \
+ } \
+ else if ( $1 == "kernel" ) { \
+ if ( match($2,"xen.gz$") ) { \
+ pathlen=RSTART; \
+ kernelfound = 1; \
+ } \
+ } \
+ else if ( $1 == "module" && \
+ kernelfound == 1 && \
+ match($2,linux) ) { \
+ policymaycome = 1; \
+ } \
+ else if ( $1 == "module" && \
+ kernelfound == 1 && \
+ policymaycome == 1 && \
+ match($2,"[0-9a-zA-Z_]*.bin$") ) { \
+ policymaycome = 0; \
+ kernelfound = 0; \
+ polname = substr($2,pathlen); \
+ len=length(polname); \
+ polname = substr(polname,0,len-4); \
+ } \
+ } END { \
+ print polname \
+ }'`
+}
+
+
+# Get the SSID of a domain
+# Parameters:
+# 1st : domain ID, i.e. '1'
+# Results
+# If the ssid could be found, the variable 'ssid' will hold
+# the currently used ssid in the hex format, i.e., '0x00010001'.
+# The funtion returns '1' on success, '0' on failure
+getSSIDUsingSecpolTool ()
+{
+ domid=$1
+ export PATH=$PATH:.
+ ssid=`secpol_tool getssid -d $domid -f | \
+ grep -E "SSID:" | \
+ awk '{ print $4 }'`
+
+ if [ "$ssid" != "" ]; then
+ return 1
+ fi
+ return 0
+}
+
+
+# Break the ssid identifier into its high and low values,
+# which are equal to the secondary and primary policy references.
+# Parameters:
+# 1st: ssid to break into high and low value, i.e., '0x00010002'
+# Results:
+# The variable ssidlo_int and ssidhi_int will hold the low and
+# high ssid values as integers.
+getSSIDLOHI ()
+{
+ ssid=$1
+ ssidlo_int=`echo $ssid | awk \
+ '{ \
+ len=length($0); \
+ beg=substr($0,1,2); \
+ if ( beg == "0x" ) { \
+ dig = len - 2; \
+ if (dig <= 0) { \
+ exit; \
+ } \
+ if (dig > 4) { \
+ dig=4; \
+ } \
+ lo=sprintf("0x%s",substr($0,len-dig+1,dig)); \
+ print strtonum(lo);\
+ } else { \
+ lo=strtonum($0); \
+ if (lo < 65536) { \
+ print lo; \
+ } else { \
+ hi=lo; \
+ hi2= (hi / 65536);\
+ hi2_str=sprintf("%d",hi2); \
+ hi2=strtonum(hi2_str);\
+ lo=hi-(hi2*65536); \
+ printf("%d",lo); \
+ } \
+ } \
+ }'`
+ ssidhi_int=`echo $ssid | awk \
+ '{ \
+ len=length($0); \
+ beg=substr($0,1,2); \
+ if ( beg == "0x" ) { \
+ dig = len - 2; \
+ if (dig <= 0 || \
+ dig > 8) { \
+ exit; \
+ } \
+ if (dig < 4) { \
+ print 0; \
+ exit; \
+ } \
+ dig -= 4; \
+ hi=sprintf("0x%s",substr($0,len-4-dig+1,dig)); \
+ print strtonum(hi);\
+ } else { \
+ hi=strtonum($0); \
+ if (hi >= 65536) { \
+ hi = hi / 65536; \
+ printf ("%d",hi);\
+ } else { \
+ printf ("0"); \
+ } \
+ } \
+ }'`
+ if [ "$ssidhi_int" == "" -o \
+ "$ssidlo_int" == "" ]; then
+ return 0;
+ fi
+ return 1
+}
+
+
+#Update the grub configuration file.
+#Search for existing entries and replace the current
+#policy entry with the policy passed to this script
+#
+#Arguments passed to this function
+# 1st : the grub configuration file with full path
+# 2nd : the binary policy file name, i.e. chwall.bin
+# 3rd : the name or pattern of the linux kernel name to match
+# (this determines where the module entry will be made)
+#
+# The algorithm here is based on pattern matching
+# and is working correctly if
+# - under a title a line beginning with 'kernel' is found
+# whose following item ends with "xen.gz"
+# Example: kernel /xen.gz dom0_mem=....
+# - a module line matching the 3rd parameter is found
+#
+updateGrub ()
+{
+ grubconf=$1
+ policyfile=$2
+ linux=$3
+
+ tmpfile="/tmp/new_grub.conf"
+
+ cat $grubconf | \
+ awk -vpolicy=$policyfile \
+ -vlinux=$linux '{ \
+ if ( $1 == "title" ) { \
+ kernelfound = 0; \
+ if ( policymaycome == 1 ){ \
+ printf ("\tmodule %s%s\n", path, policy); \
+ } \
+ policymaycome = 0; \
+ } \
+ else if ( $1 == "kernel" ) { \
+ if ( match($2,"xen.gz$") ) { \
+ path=substr($2,1,RSTART-1); \
+ kernelfound = 1; \
+ } \
+ } \
+ else if ( $1 == "module" && \
+ kernelfound == 1 && \
+ match($2,linux) ) { \
+ policymaycome = 1; \
+ } \
+ else if ( $1 == "module" && \
+ kernelfound == 1 && \
+ policymaycome == 1 && \
+ match($2,"[0-9a-zA-Z]*.bin$") ) { \
+ printf ("\tmodule %s%s\n", path, policy); \
+ policymaycome = 0; \
+ kernelfound = 0; \
+ dontprint = 1; \
+ } \
+ else if ( $1 == "" && \
+ kernelfound == 1 && \
+ policymaycome == 1) { \
+ dontprint = 1; \
+ } \
+ if (dontprint == 0) { \
+ printf ("%s\n", $0); \
+ } \
+ dontprint = 0; \
+ } END { \
+ if ( policymaycome == 1 ) { \
+ printf ("\tmodule %s%s\n", path, policy); \
+ } \
+ }' > $tmpfile
+ if [ ! -r $tmpfile ]; then
+ echo "Could not create temporary file! Aborting."
+ exit -1
+ fi
+ mv -f $tmpfile $grubconf
+}
+
+
+# Display all the labels in a given mapfile
+# Parameters
+# 1st: Full or relative path to the policy's mapfile
+showLabels ()
+{
+ mapfile=$1
+ if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
+ echo "Cannot read from vm configuration file $vmfile."
+ return -1
+ fi
+
+ getPrimaryPolicy $mapfile
+ getSecondaryPolicy $mapfile
+
+ echo "The following labels are available:"
+ let line=1
+ while [ 1 ]; do
+ ITEM=`cat $mapfile | \
+ awk -vline=$line \
+ -vprimary=$primary \
+ '{ \
+ if ($1 == "LABEL->SSID" && \
+ $2 == "VM" && \
+ $3 == primary ) { \
+ ctr++; \
+ if (ctr == line) { \
+ print $4; \
+ } \
+ } \
+ } END { \
+ }'`
+
+ if [ "$ITEM" == "" ]; then
+ break
+ fi
+ if [ "$secondary" != "NULL" ]; then
+ LABEL=`cat $mapfile | \
+ awk -vitem=$ITEM \
+ '{
+ if ($1 == "LABEL->SSID" && \
+ $2 == "VM" && \
+ $3 == "CHWALL" && \
+ $4 == item ) { \
+ result = item; \
+ } \
+ } END { \
+ print result \
+ }'`
+ else
+ LABEL=$ITEM
+ fi
+
+ if [ "$LABEL" != "" ]; then
+ echo "$LABEL"
+ found=1
+ fi
+ let line=line+1
+ done
+ if [ "$found" != "1" ]; then
+ echo "No labels found."
+ fi
+}
+
+
+# Get the default SSID given a mapfile and the policy name
+# Parameters
+# 1st: Full or relative path to the policy's mapfile
+# 2nd: the name of the policy
+getDefaultSsid ()
+{
+ mapfile=$1
+ pol=$2
+ RES=`cat $mapfile \
+ awk -vpol=$pol \
+ { \
+ if ($1 == "LABEL->SSID" && \
+ $2 == "ANY" && \
+ $3 == pol && \
+ $4 == "DEFAULT" ) {\
+ res=$5; \
+ } \
+ } END { \
+ printf "%04x", strtonum(res) \
+ }'`
+ echo "default NULL mapping is $RES"
+ defaultssid=$RES
+}
+
+
+#Relabel a VM configuration file
+# Parameters
+# 1st: Full or relative path to the VM configuration file
+# 2nd: The label to translate into an ssidref
+# 3rd: Full or relative path to the policy's map file
+# 4th: The mode this function is supposed to operate in:
+# 'relabel' : Relabels the file without querying the user
+# other : Prompts the user whether to proceed
+relabel ()
+{
+ vmfile=$1
+ label=$2
+ mapfile=$3
+ mode=$4
+
+ if [ ! -r "$vmfile" ]; then
+ echo "Cannot read from vm configuration file $vmfile."
+ return -1
+ fi
+
+ if [ ! -w "$vmfile" ]; then
+ echo "Cannot write to vm configuration file $vmfile."
+ return -1
+ fi
+
+ if [ ! -r "$mapfile" ] ; then
+ echo "Cannot read mapping file $mapfile."
+ return -1
+ fi
+
+ # Determine which policy is primary, which sec.
+ getPrimaryPolicy $mapfile
+ getSecondaryPolicy $mapfile
+
+ # Calculate the primary policy's SSIDREF
+ if [ "$primary" == "NULL" ]; then
+ SSIDLO="0001"
+ else
+ SSIDLO=`cat $mapfile | \
+ awk -vlabel=$label \
+ -vprimary=$primary \
+ '{ \
+ if ( $1 == "LABEL->SSID" && \
+ $2 == "VM" && \
+ $3 == primary && \
+ $4 == label ) { \
+ result=$5 \
+ } \
+ } END { \
+ if (result != "" ) \
+ {printf "%04x", strtonum(result)}\
+ }'`
+ fi
+
+ # Calculate the secondary policy's SSIDREF
+ if [ "$secondary" == "NULL" ]; then
+ if [ "$primary" == "NULL" ]; then
+ SSIDHI="0001"
+ else
+ SSIDHI="0000"
+ fi
+ else
+ SSIDHI=`cat $mapfile | \
+ awk -vlabel=$label \
+ -vsecondary=$secondary \
+ '{ \
+ if ( $1 == "LABEL->SSID" && \
+ $2 == "VM" && \
+ $3 == secondary && \
+ $4 == label ) { \
+ result=$5 \
+ } \
+ } END { \
+ if (result != "" ) \
+ {printf "%04x", strtonum(result)}\
+ }'`
+ fi
+
+ if [ "$SSIDLO" == "" -o \
+ "$SSIDHI" == "" ]; then
+ echo "Could not map the given label '$label'."
+ return -1
+ fi
+
+ ACM_POLICY=`cat $mapfile | \
+ awk ' { if ( $1 == "POLICY" ) { \
+ result=$2 \
+ } \
+ } \
+ END { \
+ if (result != "") { \
+ printf result \
+ } \
+ }'`
+
+ if [ "$ACM_POLICY" == "" ]; then
+ echo "Could not find 'POLICY' entry in map file."
+ return -1
+ fi
+
+ SSIDREF="0x$SSIDHI$SSIDLO"
+
+ if [ "$mode" != "relabel" ]; then
+ RES=`cat $vmfile | \
+ awk '{ \
+ if ( substr($1,0,7) == "ssidref" ) {\
+ print $0; \
+ } \
+ }'`
+ if [ "$RES" != "" ]; then
+ echo "Do you want to overwrite the existing mapping
($RES)? (y/N)"
+ read user
+ if [ "$user" != "y" -a "$user" != "Y" ]; then
+ echo "Aborted."
+ return 0
+ fi
+ fi
+ fi
+
+ #Write the output
+ vmtmp1="/tmp/__setlabel.tmp1"
+ vmtmp2="/tmp/__setlabel.tmp2"
+ touch $vmtmp1
+ touch $vmtmp2
+ if [ ! -w "$vmtmp1" -o ! -w "$vmtmp2" ]; then
+ echo "Cannot create temporary files. Aborting."
+ return -1
+ fi
+ RES=`sed -e '/^#ACM_POLICY/d' $vmfile > $vmtmp1`
+ RES=`sed -e '/^#ACM_LABEL/d' $vmtmp1 > $vmtmp2`
+ RES=`sed -e '/^ssidref/d' $vmtmp2 > $vmtmp1`
+ echo "#ACM_POLICY=$ACM_POLICY" >> $vmtmp1
+ echo "#ACM_LABEL=$label" >> $vmtmp1
+ echo "ssidref = $SSIDREF" >> $vmtmp1
+ mv -f $vmtmp1 $vmfile
+ rm -rf $vmtmp1 $vmtmp2
+ echo "Mapped label '$label' to ssidref '$SSIDREF'."
+}
+
+
+# Translate an ssidref into its label. This does the reverse lookup
+# to the relabel function above.
+# This function displays the results.
+# Parameters:
+# 1st: The ssidref to translate; must be in the form '0x00010002'
+# 2nd: Full or relative path to the policy's mapfile
+translateSSIDREF ()
+{
+ ssidref=$1
+ mapfile=$2
+
+ if [ ! -r "$mapfile" -o "$mapfile" == "" ]; then
+ echo "Cannot read from vm configuration file $vmfile."
+ return -1
+ fi
+
+ getPrimaryPolicy $mapfile
+ getSecondaryPolicy $mapfile
+
+ if [ "$primary" == "NULL" -a "$secondary" == "NULL" ]; then
+ echo "There are no labels for the NULL policy."
+ return
+ fi
+
+ getSSIDLOHI $ssidref
+ ret=$?
+ if [ $ret -ne 1 ]; then
+ echo "Error while parsing the ssid ref number '$ssidref'."
+ fi;
+
+ let line1=0
+ let line2=0
+ while [ 1 ]; do
+ ITEM1=`cat $mapfile | \
+ awk -vprimary=$primary \
+ -vssidlo=$ssidlo_int \
+ -vline=$line1 \
+ '{ \
+ if ( $1 == "LABEL->SSID" && \
+ $3 == primary && \
+ int($5) == ssidlo ) { \
+ if (l == line) { \
+ print $4; \
+ exit; \
+ } \
+ l++; \
+ } \
+ }'`
+
+ ITEM2=`cat $mapfile | \
+ awk -vsecondary=$secondary \
+ -vssidhi=$ssidhi_int \
+ -vline=$line2 \
+ '{ \
+ if ( $1 == "LABEL->SSID" && \
+ $3 == secondary && \
+ int($5) == ssidhi ) { \
+ if (l == line) { \
+ print $4; \
+ exit; \
+ } \
+ l++; \
+ } \
+ }'`
+
+ if [ "$secondary" != "NULL" ]; then
+ if [ "$ITEM1" == "" ]; then
+ let line1=0
+ let line2=line2+1
+ else
+ let line1=line1+1
+ fi
+
+ if [ "$ITEM1" == "" -a \
+ "$ITEM2" == "" ]; then
+ echo "Could not determine the referenced label."
+ break
+ fi
+
+ if [ "$ITEM1" == "$ITEM2" ]; then
+ echo "Label: $ITEM1"
+ break
+ fi
+ else
+ if [ "$ITEM1" != "" ]; then
+ echo "Label: $ITEM1"
+ else
+ if [ "$found" == "0" ]; then
+ found=1
+ else
+ break
+ fi
+ fi
+ let line1=line1+1
+ fi
+ done
+}
diff -r edd1616cf8cb -r 291e816acbf4 xen/arch/x86/shadow_guest32.c
--- /dev/null Fri Sep 2 14:15:49 2005
+++ b/xen/arch/x86/shadow_guest32.c Fri Sep 2 14:17:08 2005
@@ -0,0 +1,18 @@
+#define GUEST_PGENTRY_32
+#if defined (__x86_64__)
+
+#include "shadow.c"
+struct shadow_ops MODE_D_HANDLER = {
+ .guest_paging_levels = 2,
+ .invlpg = shadow_invlpg_64,
+ .fault = shadow_fault_64,
+ .update_pagetables = shadow_update_pagetables,
+ .sync_all = sync_all,
+ .remove_all_write_access = remove_all_write_access,
+ .do_update_va_mapping = do_update_va_mapping,
+ .mark_mfn_out_of_sync = mark_mfn_out_of_sync,
+ .is_out_of_sync = is_out_of_sync,
+ .gva_to_gpa = gva_to_gpa_64,
+};
+
+#endif
diff -r edd1616cf8cb -r 291e816acbf4 xen/include/asm-x86/shadow_ops.h
--- /dev/null Fri Sep 2 14:15:49 2005
+++ b/xen/include/asm-x86/shadow_ops.h Fri Sep 2 14:17:08 2005
@@ -0,0 +1,130 @@
+/******************************************************************************
+ * include/asm-x86/shadow_ops.h
+ *
+ * Copyright (c) 2005 Michael A Fetterman
+ * Based on an earlier implementation by Ian Pratt et al
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef _XEN_SHADOW_OPS_H
+#define _XEN_SHADOW_OPS_H
+
+#if defined( GUEST_PGENTRY_32 )
+
+#define GUEST_L1_PAGETABLE_ENTRIES L1_PAGETABLE_ENTRIES_32
+#define GUEST_L2_PAGETABLE_ENTRIES L2_PAGETABLE_ENTRIES_32
+#define GUEST_ROOT_PAGETABLE_ENTRIES ROOT_PAGETABLE_ENTRIES_32
+#define GUEST_L2_PAGETABLE_SHIFT L2_PAGETABLE_SHIFT_32
+
+#define guest_l1_pgentry_t l1_pgentry_32_t
+#define guest_l2_pgentry_t l2_pgentry_32_t
+#define guest_root_pgentry_t l2_pgentry_32_t
+
+#define guest_l1e_get_paddr l1e_get_paddr_32
+#define guest_l2e_get_paddr l2e_get_paddr_32
+
+#define guest_get_pte_flags get_pte_flags_32
+#define guest_put_pte_flags put_pte_flags_32
+
+#define guest_l1e_get_flags l1e_get_flags_32
+#define guest_l2e_get_flags l2e_get_flags_32
+#define guest_root_get_flags l2e_get_flags_32
+#define guest_root_get_intpte l2e_get_intpte
+
+#define guest_l1e_empty l1e_empty_32
+#define guest_l2e_empty l2e_empty_32
+
+#define guest_l1e_from_pfn l1e_from_pfn_32
+#define guest_l2e_from_pfn l2e_from_pfn_32
+
+#define guest_l1e_from_paddr l1e_from_paddr_32
+#define guest_l2e_from_paddr l2e_from_paddr_32
+
+#define guest_l1e_from_page l1e_from_page_32
+#define guest_l2e_from_page l2e_from_page_32
+
+#define guest_l1e_add_flags l1e_add_flags_32
+#define guest_l2e_add_flags l2e_add_flags_32
+
+#define guest_l1e_remove_flag l1e_remove_flags_32
+#define guest_l2e_remove_flag l2e_remove_flags_32
+
+#define guest_l1e_has_changed l1e_has_changed_32
+#define guest_l2e_has_changed l2e_has_changed_32
+#define root_entry_has_changed l2e_has_changed_32
+
+#define guest_l1_table_offset l1_table_offset_32
+#define guest_l2_table_offset l2_table_offset_32
+
+#define guest_linear_l1_table linear_pg_table_32
+#define guest_linear_l2_table linear_l2_table_32
+
+#define guest_va_to_l1mfn va_to_l1mfn_32
+
+#else
+
+#define GUEST_L1_PAGETABLE_ENTRIES L1_PAGETABLE_ENTRIES
+#define GUEST_L2_PAGETABLE_ENTRIES L2_PAGETABLE_ENTRIES
+#define GUEST_ROOT_PAGETABLE_ENTRIES ROOT_PAGETABLE_ENTRIES
+#define GUEST_L2_PAGETABLE_SHIFT L2_PAGETABLE_SHIFT
+
+#define guest_l1_pgentry_t l1_pgentry_t
+#define guest_l2_pgentry_t l2_pgentry_t
+#define guest_root_pgentry_t l4_pgentry_t
+
+#define guest_l1e_get_paddr l1e_get_paddr
+#define guest_l2e_get_paddr l2e_get_paddr
+
+#define guest_get_pte_flags get_pte_flags
+#define guest_put_pte_flags put_pte_flags
+
+#define guest_l1e_get_flags l1e_get_flags
+#define guest_l2e_get_flags l2e_get_flags
+#define guest_root_get_flags l4e_get_flags
+#define guest_root_get_intpte l4e_get_intpte
+
+#define guest_l1e_empty l1e_empty
+#define guest_l2e_empty l2e_empty
+
+#define guest_l1e_from_pfn l1e_from_pfn
+#define guest_l2e_from_pfn l2e_from_pfn
+
+#define guest_l1e_from_paddr l1e_from_paddr
+#define guest_l2e_from_paddr l2e_from_paddr
+
+#define guest_l1e_from_page l1e_from_page
+#define guest_l2e_from_page l2e_from_page
+
+#define guest_l1e_add_flags l1e_add_flags
+#define guest_l2e_add_flags l2e_add_flags
+
+#define guest_l1e_remove_flag l1e_remove_flags
+#define guest_l2e_remove_flag l2e_remove_flags
+
+#define guest_l1e_has_changed l1e_has_changed
+#define guest_l2e_has_changed l2e_has_changed
+#define root_entry_has_changed l4e_has_changed
+
+#define guest_l1_table_offset l1_table_offset
+#define guest_l2_table_offset l2_table_offset
+
+#define guest_linear_l1_table linear_pg_table
+#define guest_linear_l2_table linear_l2_table
+
+#define guest_va_to_l1mfn va_to_l1mfn
+#endif
+
+#endif /* _XEN_SHADOW_OPS_H */
_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog
|